Commit 70c4498b authored by Francesca Sargent's avatar Francesca Sargent
Browse files

Retrying upload of flask

parent 416a998b
alembic-sqlite @ 0133d306
Subproject commit 0133d306c9484a128dbe9b6e110ceb99ae6eb63f
from flask import Flask
from flask.ext.bootstrap import Bootstrap
from flask.ext.mail import Mail
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager
from flask.ext.pagedown import PageDown
from config import config
bootstrap = Bootstrap()
mail = Mail()
moment = Moment()
db = SQLAlchemy()
pagedown = PageDown()
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'auth.login'
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
login_manager.init_app(app)
pagedown.init_app(app)
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
return app
from flask import Blueprint
auth = Blueprint('auth', __name__)
from . import views
from flask.ext.wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import Required, Length, Email, Regexp, EqualTo
from wtforms import ValidationError
from ..models import User
class LoginForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
password = PasswordField('Password', validators=[Required()])
remember_me = BooleanField('Keep me logged in')
submit = SubmitField('Log In')
class RegistrationForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
username = StringField('Username', validators=[
Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
'Usernames must have only letters, '
'numbers, dots or underscores')])
password = PasswordField('Password', validators=[
Required(), EqualTo('password2', message='Passwords must match.')])
password2 = PasswordField('Confirm password', validators=[Required()])
submit = SubmitField('Register')
def validate_email(self, field):
if User.query.filter_by(email=field.data).first():
raise ValidationError('Email already registered.')
def validate_username(self, field):
if User.query.filter_by(username=field.data).first():
raise ValidationError('Username already in use.')
class ChangePasswordForm(Form):
old_password = PasswordField('Old password', validators=[Required()])
password = PasswordField('New password', validators=[
Required(), EqualTo('password2', message='Passwords must match')])
password2 = PasswordField('Confirm new password', validators=[Required()])
submit = SubmitField('Update Password')
class PasswordResetRequestForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
submit = SubmitField('Reset Password')
class PasswordResetForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
password = PasswordField('New Password', validators=[
Required(), EqualTo('password2', message='Passwords must match')])
password2 = PasswordField('Confirm password', validators=[Required()])
submit = SubmitField('Reset Password')
def validate_email(self, field):
if User.query.filter_by(email=field.data).first() is None:
raise ValidationError('Unknown email address.')
class ChangeEmailForm(Form):
email = StringField('New Email', validators=[Required(), Length(1, 64),
Email()])
password = PasswordField('Password', validators=[Required()])
submit = SubmitField('Update Email Address')
def validate_email(self, field):
if User.query.filter_by(email=field.data).first():
raise ValidationError('Email already registered.')
from flask import render_template, redirect, request, url_for, flash
from flask.ext.login import login_user, logout_user, login_required, \
current_user
from . import auth
from .. import db
from ..models import User
from ..email import send_email
from .forms import LoginForm, RegistrationForm, ChangePasswordForm,\
PasswordResetRequestForm, PasswordResetForm, ChangeEmailForm
@auth.before_app_request
def before_request():
if current_user.is_authenticated():
current_user.ping()
if not current_user.confirmed \
and request.endpoint[:5] != 'auth.' \
and request.endpoint != 'static':
return redirect(url_for('auth.unconfirmed'))
@auth.route('/unconfirmed')
def unconfirmed():
if current_user.is_anonymous() or current_user.confirmed:
return redirect(url_for('main.index'))
return render_template('auth/unconfirmed.html')
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.verify_password(form.password.data):
login_user(user, form.remember_me.data)
return redirect(request.args.get('next') or url_for('main.index'))
flash('Invalid username or password.')
return render_template('auth/login.html', form=form)
@auth.route('/logout')
@login_required
def logout():
logout_user()
flash('You have been logged out.')
return redirect(url_for('main.index'))
@auth.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(email=form.email.data,
username=form.username.data,
password=form.password.data)
db.session.add(user)
db.session.commit()
token = user.generate_confirmation_token()
send_email(user.email, 'Confirm Your Account',
'auth/email/confirm', user=user, token=token)
flash('A confirmation email has been sent to you by email.')
return redirect(url_for('auth.login'))
return render_template('auth/register.html', form=form)
@auth.route('/confirm/<token>')
@login_required
def confirm(token):
if current_user.confirmed:
return redirect(url_for('main.index'))
if current_user.confirm(token):
flash('You have confirmed your account. Thanks!')
else:
flash('The confirmation link is invalid or has expired.')
return redirect(url_for('main.index'))
@auth.route('/confirm')
@login_required
def resend_confirmation():
token = current_user.generate_confirmation_token()
send_email(current_user.email, 'Confirm Your Account',
'auth/email/confirm', user=current_user, token=token)
flash('A new confirmation email has been sent to you by email.')
return redirect(url_for('main.index'))
@auth.route('/change-password', methods=['GET', 'POST'])
@login_required
def change_password():
form = ChangePasswordForm()
if form.validate_on_submit():
if current_user.verify_password(form.old_password.data):
current_user.password = form.password.data
db.session.add(current_user)
flash('Your password has been updated.')
return redirect(url_for('main.index'))
else:
flash('Invalid password.')
return render_template("auth/change_password.html", form=form)
@auth.route('/reset', methods=['GET', 'POST'])
def password_reset_request():
if not current_user.is_anonymous():
return redirect(url_for('main.index'))
form = PasswordResetRequestForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user:
token = user.generate_reset_token()
send_email(user.email, 'Reset Your Password',
'auth/email/reset_password',
user=user, token=token,
next=request.args.get('next'))
flash('An email with instructions to reset your password has been '
'sent to you.')
return redirect(url_for('auth.login'))
return render_template('auth/reset_password.html', form=form)
@auth.route('/reset/<token>', methods=['GET', 'POST'])
def password_reset(token):
if not current_user.is_anonymous():
return redirect(url_for('main.index'))
form = PasswordResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is None:
return redirect(url_for('main.index'))
if user.reset_password(token, form.password.data):
flash('Your password has been updated.')
return redirect(url_for('auth.login'))
else:
return redirect(url_for('main.index'))
return render_template('auth/reset_password.html', form=form)
@auth.route('/change-email', methods=['GET', 'POST'])
@login_required
def change_email_request():
form = ChangeEmailForm()
if form.validate_on_submit():
if current_user.verify_password(form.password.data):
new_email = form.email.data
token = current_user.generate_email_change_token(new_email)
send_email(new_email, 'Confirm your email address',
'auth/email/change_email',
user=current_user, token=token)
flash('An email with instructions to confirm your new email '
'address has been sent to you.')
return redirect(url_for('main.index'))
else:
flash('Invalid email or password.')
return render_template("auth/change_email.html", form=form)
@auth.route('/change-email/<token>')
@login_required
def change_email(token):
if current_user.change_email(token):
flash('Your email address has been updated.')
else:
flash('Invalid request.')
return redirect(url_for('main.index'))
from functools import wraps
from flask import abort
from flask.ext.login import current_user
from .models import Permission
def permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def admin_required(f):
return permission_required(Permission.ADMINISTER)(f)
from threading import Thread
from flask import current_app, render_template
from flask.ext.mail import Message
from . import mail
def send_async_email(app, msg):
with app.app_context():
mail.send(msg)
def send_email(to, subject, template, **kwargs):
app = current_app._get_current_object()
msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject,
sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.html', **kwargs)
thr = Thread(target=send_async_email, args=[app, msg])
thr.start()
return thr
from flask import Blueprint
main = Blueprint('main', __name__)
from . import views, errors
from ..models import Permission
@main.app_context_processor
def inject_permissions():
return dict(Permission=Permission)
from flask import render_template
from . import main
@main.app_errorhandler(403)
def forbidden(e):
return render_template('403.html'), 403
@main.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
@main.app_errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500
from flask.ext.wtf import Form
from wtforms import StringField, TextAreaField, BooleanField, SelectField,\
SubmitField, FormField
from wtforms.validators import Required, Length, Email, Regexp
from wtforms import ValidationError
from flask.ext.pagedown.fields import PageDownField
from .. import db
from ..models import Role, User, Cuisine, Recipe, RecipeSteps
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
class EditProfileForm(Form):
name = StringField('Real name', validators=[Length(0, 64)])
location = StringField('Location', validators=[Length(0, 64)])
about_me = TextAreaField('About me')
submit = SubmitField('Submit')
class EditProfileAdminForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),
Email()])
username = StringField('Username', validators=[
Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
'Usernames must have only letters, '
'numbers, dots or underscores')])
confirmed = BooleanField('Confirmed')
role = SelectField('Role', coerce=int)
name = StringField('Real name', validators=[Length(0, 64)])
location = StringField('Location', validators=[Length(0, 64)])
about_me = TextAreaField('About me')
submit = SubmitField('Submit')
def __init__(self, user, *args, **kwargs):
super(EditProfileAdminForm, self).__init__(*args, **kwargs)
self.role.choices = [(role.id, role.name)
for role in Role.query.order_by(Role.name).all()]
self.user = user
def validate_email(self, field):
if field.data != self.user.email and \
User.query.filter_by(email=field.data).first():
raise ValidationError('Email already registered.')
def validate_username(self, field):
if field.data != self.user.username and \
User.query.filter_by(username=field.data).first():
raise ValidationError('Username already in use.')
class RecipeStepForm(Form):
recipe_step_id = StringField('Step Number', validators=[Required(), Length(0,2)])
recipe_step_text = TextAreaField(validators=[Required()])
class RecipeForm(Form):
name = StringField('Recipe Name', validators=[Required(), Length(0, 64)])
description = PageDownField('Recipe Description')
# recipestep = FormField(RecipeStepForm)
cuisine = StringField('Cuisine')
method = StringField('Method')
submit = SubmitField('Submit')
def __init__(self, *args, **kwargs):
super(RecipeForm, self).__init__(*args, **kwargs)
self.cuisine.choices = [(cuisine.id, cuisine.name)
for cuisine in Cuisine.query.order_by(Cuisine.name).all()]
class CuisineForm(Form):
name = TextAreaField("Cuisine Name", validators=[Required()])
description = PageDownField("Cuisine Description", validators=[Required()])
submit = SubmitField('Submit')
class MethodForm(Form):
name = StringField("Method Name", validators=[Required()])
description = PageDownField('Method Description')
method_text = PageDownField('Method Instructions')
# cuisine = StringField('Cuisine')
submit = SubmitField('Submit')
# def __init__(self, *args, **kwargs):
# super(MethodForm, self).__init__(*args, **kwargs)
# self.cuisine.choices = [(cuisine.id, cuisine.name)
# for cuisine in Cuisine.query.order_by(Cuisine.name).all()]
class CommentForm(Form):
body = StringField('Enter your comment', validators=[Required()])
submit = SubmitField('Submit')
from flask import render_template, redirect, url_for, abort, flash, request,\
current_app, make_response, jsonify
from flask.ext.login import login_required, current_user
from . import main
from .forms import EditProfileForm, EditProfileAdminForm, RecipeForm,\
CommentForm, CuisineForm, RecipeStepForm, MethodForm
from .. import db
from ..models import Permission, Role, User, Recipe, Comment, Cuisine, RecipeSteps, Method
from ..decorators import admin_required, permission_required
@main.route('/')
def index():
page = request.args.get('page', 1, type=int)
show_followed = False
if current_user.is_authenticated():
show_followed = bool(request.cookies.get('show_followed', ''))
if show_followed:
query = current_user.followed_recipes
else:
query = Recipe.query
pagination = query.order_by(Recipe.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
recipes = pagination.items
return render_template('index.html', recipes=recipes,
show_followed=show_followed, pagination=pagination)
@main.route('/<type>/all')
def postall(type):
if type == 'cuisine':
query = Cuisine.query
page = request.args.get('page', 1, type=int)
pagination = query.order_by(Cuisine.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
cuisines = pagination.items
return render_template('all_cuisines.html', user=user, cuisines=cuisines,
pagination=pagination, type=type)
if type == 'recipe':
query = Recipe.query
page = request.args.get('page', 1, type=int)
pagination = query.order_by(Recipe.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
recipes = pagination.items
return render_template('all_recipes.html', user=user, recipes=recipes,
pagination=pagination, type=type)
# if type == 'method':
# query = Method.query
# page = request.args.get('page', 1, type=int)
# pagination = query.order_by(Method.timestamp.desc()).paginate(
# page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
# error_out=False)
# methods = pagination.items
# return render_template('all_methods.html', user=user, methods=methods,
# pagination=pagination, type=type)
@main.route('/post/<type>/', methods=['GET', 'POST'])
def poststuff(type):
if type == 'recipe':
form = RecipeForm()
if current_user.can(Permission.WRITE_ARTICLES) and \
form.validate_on_submit():
recipe = Recipe(
name=form.name.data,
description=form.description.data,
body=form.body.data,
cuisine=form.cuisine.data,
author=current_user._get_current_object())
db.session.add(recipe)
return redirect(url_for('.index'))
if type == 'cuisine':
form = CuisineForm()
if current_user.can(Permission.WRITE_ARTICLES) and \
form.validate_on_submit():
cuisine = Cuisine(name=form.name.data, description=form.description.data,
author=current_user._get_current_object())
db.session.add(cuisine)
return redirect(url_for('.index'))
if type == 'method':
form = MethodForm()
if current_user.can(Permission.WRITE_ARTICLES) and \
form.validate_on_submit():
recipe = Method(
name=form.name.data,
description=form.description.data,
method_text=form.method_text.data,
# cuisines=form.cuisine.data,
author=current_user._get_current_object())
db.session.add(recipe)
return redirect(url_for('.index'))
return render_template('post.html', form=form,
show_followed=show_followed, type=type)
@main.route('/autocomplete',methods=['GET'])
def autocomplete():
cuisines=[(cuisine.name)
for cuisine in Cuisine.query.order_by(Cuisine.name).all()]
# main.logger.debug(search)
return jsonify(json_list=cuisines)
#Recipe Page#
@main.route('/<usr>/recipe/', methods=['GET', 'POST'])
def recipelist(usr):
user = User.query.filter_by(username=usr).first_or_404()
page = request.args.get('page', 1, type=int)
pagination = user.recipes.order_by(Recipe.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
recipes = pagination.items
return render_template('recipes.html', user=user, recipes=recipes,
pagination=pagination)
#Cuisine Page#
@main.route('/<usr>/cuisine/', methods=['GET', 'POST'])
def cuisinelist(usr):
user = User.query.filter_by(username=usr).first_or_404()
page = request.args.get('page', 1, type=int)
pagination = user.cuisines.order_by(Cuisine.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
cuisines = pagination.items
return render_template('cuisines.html', user=user, cuisines=cuisines,
pagination=pagination)
@main.route('/<username>')
def user(username):
user = User.query.filter_by(username=username).first_or_404()
page = request.args.get('page', 1, type=int)
pagination = user.recipes.order_by(Recipe.timestamp.desc()).paginate(
page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],