2013-02-20 06:59:54 +00:00
|
|
|
from flask import render_template, flash, redirect, session, url_for, request, g, jsonify
|
2012-12-16 08:30:41 +00:00
|
|
|
from flask.ext.login import login_user, logout_user, current_user, login_required
|
2013-03-10 04:17:06 +00:00
|
|
|
from flask.ext.sqlalchemy import get_debug_queries
|
2013-02-01 05:48:20 +00:00
|
|
|
from flask.ext.babel import gettext
|
|
|
|
from app import app, db, lm, oid, babel
|
2012-12-16 08:35:16 +00:00
|
|
|
from forms import LoginForm, EditForm, PostForm, SearchForm
|
2012-12-16 08:34:46 +00:00
|
|
|
from models import User, ROLE_USER, ROLE_ADMIN, Post
|
2012-12-16 08:31:21 +00:00
|
|
|
from datetime import datetime
|
2012-12-16 08:36:04 +00:00
|
|
|
from emails import follower_notification
|
2013-02-20 06:59:54 +00:00
|
|
|
from guess_language import guessLanguage
|
|
|
|
from translate import microsoft_translate
|
2013-04-23 05:19:12 +00:00
|
|
|
from config import POSTS_PER_PAGE, MAX_SEARCH_RESULTS, LANGUAGES, DATABASE_QUERY_TIMEOUT, WHOOSH_ENABLED
|
2012-12-16 08:24:07 +00:00
|
|
|
|
2012-12-16 08:30:41 +00:00
|
|
|
@lm.user_loader
|
|
|
|
def load_user(id):
|
|
|
|
return User.query.get(int(id))
|
|
|
|
|
2013-02-01 05:48:20 +00:00
|
|
|
@babel.localeselector
|
|
|
|
def get_locale():
|
|
|
|
return request.accept_languages.best_match(LANGUAGES.keys())
|
|
|
|
|
2012-12-16 08:30:41 +00:00
|
|
|
@app.before_request
|
|
|
|
def before_request():
|
|
|
|
g.user = current_user
|
2012-12-16 08:31:21 +00:00
|
|
|
if g.user.is_authenticated():
|
|
|
|
g.user.last_seen = datetime.utcnow()
|
|
|
|
db.session.add(g.user)
|
|
|
|
db.session.commit()
|
2012-12-16 08:35:16 +00:00
|
|
|
g.search_form = SearchForm()
|
2013-02-01 05:48:20 +00:00
|
|
|
g.locale = get_locale()
|
2013-04-23 05:19:12 +00:00
|
|
|
g.search_enabled = WHOOSH_ENABLED
|
2012-12-16 08:32:38 +00:00
|
|
|
|
2013-03-10 04:17:06 +00:00
|
|
|
@app.after_request
|
|
|
|
def after_request(response):
|
|
|
|
for query in get_debug_queries():
|
|
|
|
if query.duration >= DATABASE_QUERY_TIMEOUT:
|
|
|
|
app.logger.warning("SLOW QUERY: %s\nParameters: %s\nDuration: %fs\nContext: %s\n" % (query.statement, query.parameters, query.duration, query.context))
|
|
|
|
return response
|
|
|
|
|
2012-12-16 08:32:38 +00:00
|
|
|
@app.errorhandler(404)
|
|
|
|
def internal_error(error):
|
|
|
|
return render_template('404.html'), 404
|
|
|
|
|
|
|
|
@app.errorhandler(500)
|
|
|
|
def internal_error(error):
|
|
|
|
db.session.rollback()
|
|
|
|
return render_template('500.html'), 500
|
|
|
|
|
2012-12-16 08:34:46 +00:00
|
|
|
@app.route('/', methods = ['GET', 'POST'])
|
|
|
|
@app.route('/index', methods = ['GET', 'POST'])
|
|
|
|
@app.route('/index/<int:page>', methods = ['GET', 'POST'])
|
2012-12-16 08:30:41 +00:00
|
|
|
@login_required
|
2012-12-16 08:34:46 +00:00
|
|
|
def index(page = 1):
|
|
|
|
form = PostForm()
|
|
|
|
if form.validate_on_submit():
|
2013-02-20 06:59:54 +00:00
|
|
|
language = guessLanguage(form.post.data)
|
|
|
|
if language == 'UNKNOWN' or len(language) > 5:
|
|
|
|
language = ''
|
|
|
|
post = Post(body = form.post.data,
|
|
|
|
timestamp = datetime.utcnow(),
|
|
|
|
author = g.user,
|
|
|
|
language = language)
|
2012-12-16 08:34:46 +00:00
|
|
|
db.session.add(post)
|
|
|
|
db.session.commit()
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('Your post is now live!'))
|
2012-12-16 08:34:46 +00:00
|
|
|
return redirect(url_for('index'))
|
|
|
|
posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False)
|
2012-12-16 08:28:52 +00:00
|
|
|
return render_template('index.html',
|
2012-12-16 08:26:19 +00:00
|
|
|
title = 'Home',
|
2012-12-16 08:34:46 +00:00
|
|
|
form = form,
|
2012-12-16 08:26:19 +00:00
|
|
|
posts = posts)
|
2012-12-16 08:28:52 +00:00
|
|
|
|
|
|
|
@app.route('/login', methods = ['GET', 'POST'])
|
2012-12-16 08:30:41 +00:00
|
|
|
@oid.loginhandler
|
2012-12-16 08:28:52 +00:00
|
|
|
def login():
|
2012-12-16 08:30:41 +00:00
|
|
|
if g.user is not None and g.user.is_authenticated():
|
|
|
|
return redirect(url_for('index'))
|
2012-12-16 08:28:52 +00:00
|
|
|
form = LoginForm()
|
|
|
|
if form.validate_on_submit():
|
2012-12-16 08:30:41 +00:00
|
|
|
session['remember_me'] = form.remember_me.data
|
|
|
|
return oid.try_login(form.openid.data, ask_for = ['nickname', 'email'])
|
2012-12-16 08:28:52 +00:00
|
|
|
return render_template('login.html',
|
|
|
|
title = 'Sign In',
|
|
|
|
form = form,
|
|
|
|
providers = app.config['OPENID_PROVIDERS'])
|
2012-12-16 08:30:41 +00:00
|
|
|
|
|
|
|
@oid.after_login
|
|
|
|
def after_login(resp):
|
|
|
|
if resp.email is None or resp.email == "":
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('Invalid login. Please try again.'))
|
2012-12-16 08:30:41 +00:00
|
|
|
redirect(url_for('login'))
|
|
|
|
user = User.query.filter_by(email = resp.email).first()
|
|
|
|
if user is None:
|
|
|
|
nickname = resp.nickname
|
|
|
|
if nickname is None or nickname == "":
|
|
|
|
nickname = resp.email.split('@')[0]
|
2013-02-01 05:48:20 +00:00
|
|
|
nickname = User.make_valid_nickname(nickname)
|
2013-01-05 20:03:15 +00:00
|
|
|
nickname = User.make_unique_nickname(nickname)
|
2012-12-16 08:30:41 +00:00
|
|
|
user = User(nickname = nickname, email = resp.email, role = ROLE_USER)
|
|
|
|
db.session.add(user)
|
|
|
|
db.session.commit()
|
2012-12-16 08:34:24 +00:00
|
|
|
# make the user follow him/herself
|
|
|
|
db.session.add(user.follow(user))
|
|
|
|
db.session.commit()
|
2012-12-16 08:30:41 +00:00
|
|
|
remember_me = False
|
|
|
|
if 'remember_me' in session:
|
|
|
|
remember_me = session['remember_me']
|
|
|
|
session.pop('remember_me', None)
|
|
|
|
login_user(user, remember = remember_me)
|
|
|
|
return redirect(request.args.get('next') or url_for('index'))
|
|
|
|
|
|
|
|
@app.route('/logout')
|
|
|
|
def logout():
|
|
|
|
logout_user()
|
2012-12-16 08:31:21 +00:00
|
|
|
return redirect(url_for('index'))
|
|
|
|
|
|
|
|
@app.route('/user/<nickname>')
|
2012-12-16 08:34:46 +00:00
|
|
|
@app.route('/user/<nickname>/<int:page>')
|
2012-12-16 08:31:21 +00:00
|
|
|
@login_required
|
2012-12-16 08:34:46 +00:00
|
|
|
def user(nickname, page = 1):
|
2012-12-16 08:31:21 +00:00
|
|
|
user = User.query.filter_by(nickname = nickname).first()
|
|
|
|
if user == None:
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('User %(nickname)s not found.', nickname = nickname))
|
2012-12-16 08:31:21 +00:00
|
|
|
return redirect(url_for('index'))
|
2012-12-16 08:34:46 +00:00
|
|
|
posts = user.posts.paginate(page, POSTS_PER_PAGE, False)
|
2012-12-16 08:31:21 +00:00
|
|
|
return render_template('user.html',
|
|
|
|
user = user,
|
|
|
|
posts = posts)
|
|
|
|
|
|
|
|
@app.route('/edit', methods = ['GET', 'POST'])
|
|
|
|
@login_required
|
|
|
|
def edit():
|
2012-12-16 08:32:38 +00:00
|
|
|
form = EditForm(g.user.nickname)
|
2012-12-16 08:31:21 +00:00
|
|
|
if form.validate_on_submit():
|
|
|
|
g.user.nickname = form.nickname.data
|
|
|
|
g.user.about_me = form.about_me.data
|
|
|
|
db.session.add(g.user)
|
|
|
|
db.session.commit()
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('Your changes have been saved.'))
|
2012-12-16 08:31:21 +00:00
|
|
|
return redirect(url_for('edit'))
|
2012-12-16 08:32:38 +00:00
|
|
|
elif request.method != "POST":
|
2012-12-16 08:31:21 +00:00
|
|
|
form.nickname.data = g.user.nickname
|
|
|
|
form.about_me.data = g.user.about_me
|
|
|
|
return render_template('edit.html',
|
|
|
|
form = form)
|
2012-12-16 08:34:24 +00:00
|
|
|
|
|
|
|
@app.route('/follow/<nickname>')
|
2012-12-16 08:35:16 +00:00
|
|
|
@login_required
|
2012-12-16 08:34:24 +00:00
|
|
|
def follow(nickname):
|
|
|
|
user = User.query.filter_by(nickname = nickname).first()
|
|
|
|
if user == None:
|
|
|
|
flash('User ' + nickname + ' not found.')
|
|
|
|
return redirect(url_for('index'))
|
2012-12-16 08:34:46 +00:00
|
|
|
if user == g.user:
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('You can\'t follow yourself!'))
|
2012-12-16 08:34:46 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
2012-12-16 08:34:24 +00:00
|
|
|
u = g.user.follow(user)
|
|
|
|
if u is None:
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('Cannot follow %(nickname)s.', nickname = nickname))
|
2012-12-16 08:34:24 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
|
|
|
db.session.add(u)
|
|
|
|
db.session.commit()
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('You are now following %(nickname)s!', nickname = nickname))
|
2012-12-16 08:36:04 +00:00
|
|
|
follower_notification(user, g.user)
|
2012-12-16 08:34:24 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
|
|
|
|
|
|
|
@app.route('/unfollow/<nickname>')
|
2012-12-16 08:35:16 +00:00
|
|
|
@login_required
|
2012-12-16 08:34:24 +00:00
|
|
|
def unfollow(nickname):
|
|
|
|
user = User.query.filter_by(nickname = nickname).first()
|
|
|
|
if user == None:
|
|
|
|
flash('User ' + nickname + ' not found.')
|
|
|
|
return redirect(url_for('index'))
|
2012-12-16 08:34:46 +00:00
|
|
|
if user == g.user:
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('You can\'t unfollow yourself!'))
|
2012-12-16 08:34:46 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
2012-12-16 08:34:24 +00:00
|
|
|
u = g.user.unfollow(user)
|
|
|
|
if u is None:
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('Cannot unfollow %(nickname)s.', nickname = nickname))
|
2012-12-16 08:34:24 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
|
|
|
db.session.add(u)
|
|
|
|
db.session.commit()
|
2013-02-01 05:48:20 +00:00
|
|
|
flash(gettext('You have stopped following %(nickname)s.', nickname = nickname))
|
2012-12-16 08:34:24 +00:00
|
|
|
return redirect(url_for('user', nickname = nickname))
|
2012-12-16 08:35:16 +00:00
|
|
|
|
2013-03-10 04:17:06 +00:00
|
|
|
@app.route('/delete/<int:id>')
|
|
|
|
@login_required
|
|
|
|
def delete(id):
|
|
|
|
post = Post.query.get(id)
|
|
|
|
if post == None:
|
|
|
|
flash('Post not found.')
|
|
|
|
return redirect(url_for('index'))
|
|
|
|
if post.author.id != g.user.id:
|
|
|
|
flash('You cannot delete this post.')
|
|
|
|
return redirect(url_for('index'))
|
|
|
|
db.session.delete(post)
|
|
|
|
db.session.commit()
|
|
|
|
flash('Your post has been deleted.')
|
|
|
|
return redirect(url_for('index'))
|
|
|
|
|
2012-12-16 08:35:16 +00:00
|
|
|
@app.route('/search', methods = ['POST'])
|
|
|
|
@login_required
|
|
|
|
def search():
|
|
|
|
if not g.search_form.validate_on_submit():
|
|
|
|
return redirect(url_for('index'))
|
|
|
|
return redirect(url_for('search_results', query = g.search_form.search.data))
|
|
|
|
|
|
|
|
@app.route('/search_results/<query>')
|
|
|
|
@login_required
|
|
|
|
def search_results(query):
|
|
|
|
results = Post.query.whoosh_search(query, MAX_SEARCH_RESULTS).all()
|
|
|
|
return render_template('search_results.html',
|
|
|
|
query = query,
|
|
|
|
results = results)
|
|
|
|
|
2013-02-20 06:59:54 +00:00
|
|
|
@app.route('/translate', methods = ['POST'])
|
|
|
|
@login_required
|
|
|
|
def translate():
|
|
|
|
return jsonify({
|
|
|
|
'text': microsoft_translate(
|
|
|
|
request.form['text'],
|
|
|
|
request.form['sourceLang'],
|
|
|
|
request.form['destLang']) })
|
|
|
|
|