diff --git a/budget/web.py b/budget/web.py index b8ae71d..6097d80 100644 --- a/budget/web.py +++ b/budget/web.py @@ -1,16 +1,3 @@ -from collections import defaultdict - -from flask import * -from flaskext.mail import Mail, Message -from flaskext.babel import get_locale, gettext as _ -from smtplib import SMTPRecipientsRefused -import werkzeug - -# local modules -from models import db, Project, Person, Bill -from forms import * -from utils import Redirect303 - """ The blueprint for the web interface. @@ -22,9 +9,24 @@ some shortcuts to make your life better when coding (see `pull_project` and `add_project_id` for a quick overview) """ +from flask import Blueprint, current_app, flash, g, redirect, \ + render_template, request, session, url_for +from flaskext.mail import Mail, Message +from flaskext.babel import get_locale, gettext as _ +from smtplib import SMTPRecipientsRefused +import werkzeug + +# local modules +from models import db, Project, Person, Bill +from forms import AuthenticationForm, CreateArchiveForm, EditProjectForm, \ + InviteForm, MemberForm, PasswordReminder, ProjectForm, get_billform_for +from utils import Redirect303 + + main = Blueprint("main", __name__) mail = Mail() + @main.url_defaults def add_project_id(endpoint, values): """Add the project id to the url calls if it is expected. @@ -36,6 +38,7 @@ def add_project_id(endpoint, values): if current_app.url_map.is_endpoint_expecting(endpoint, 'project_id'): values['project_id'] = g.project.id + @main.url_value_preprocessor def pull_project(endpoint, values): """When a request contains a project_id value, transform it directly @@ -51,7 +54,8 @@ def pull_project(endpoint, values): if project_id: project = Project.query.get(project_id) if not project: - raise Redirect303(url_for(".create_project", project_id=project_id)) + raise Redirect303(url_for(".create_project", + project_id=project_id)) if project.id in session and session[project.id] == project.password: # add project into kwargs and call the original function g.project = project @@ -60,6 +64,7 @@ def pull_project(endpoint, values): raise Redirect303( url_for(".authenticate", project_id=project_id)) + @main.route("/authenticate", methods=["GET", "POST"]) def authenticate(project_id=None): """Authentication form""" @@ -68,7 +73,7 @@ def authenticate(project_id=None): form.id.data = request.args['project_id'] project_id = form.id.data project = Project.query.get(project_id) - create_project = False # We don't want to create the project by default + create_project = False # We don't want to create the project by default if not project: # But if the user try to connect to an unexisting project, we will # propose him a link to the creation form. @@ -87,7 +92,8 @@ def authenticate(project_id=None): if request.method == "POST": if form.validate(): if not form.password.data == project.password: - form.errors['password'] = [_("This private code is not the right one")] + msg = _("This private code is not the right one") + form.errors['password'] = [msg] else: # maintain a list of visited projects if "projects" not in session: @@ -102,6 +108,7 @@ def authenticate(project_id=None): return render_template("authenticate.html", form=form, create_project=create_project) + @main.route("/") def home(): project_form = ProjectForm() @@ -109,6 +116,7 @@ def home(): return render_template("home.html", project_form=project_form, auth_form=auth_form, session=session) + @main.route("/create", methods=["GET", "POST"]) def create_project(): form = ProjectForm() @@ -117,9 +125,10 @@ def create_project(): if request.method == "POST": # At first, we don't want the user to bother with the identifier - # so it will automatically be missing because not displayed into the form - # Thus we fill it with the same value as the filled name, the validation will - # take care of the slug + # so it will automatically be missing because not displayed into + # the form + # Thus we fill it with the same value as the filled name, + # the validation will take care of the slug if not form.id.data: form.id.data = form.name.data if form.validate(): @@ -135,10 +144,11 @@ def create_project(): # send reminder email g.project = project - message_title = _("You have just created '%(project)s' to share your expenses", - project=g.project.name) + message_title = _("You have just created '%(project)s' " + "to share your expenses", project=g.project.name) - message_body = render_template("reminder_mail.%s" % get_locale().language) + message_body = render_template("reminder_mail.%s" % + get_locale().language) msg = Message(message_title, body=message_body, @@ -158,6 +168,7 @@ def create_project(): return render_template("create_project.html", form=form) + @main.route("/password-reminder", methods=["GET", "POST"]) def remind_password(): form = PasswordReminder() @@ -167,9 +178,9 @@ def remind_password(): project = Project.query.get(form.id.data) # send the password reminder + password_reminder = "password_reminder.%s" % get_locale().language mail.send(Message("password recovery", - body=render_template("password_reminder.%s" % get_locale().language, - project=project), + body=render_template(password_reminder, project=project), recipients=[project.contact_email])) flash(_("a mail has been sent to you with the password")) @@ -193,18 +204,21 @@ def edit_project(): return render_template("edit_project.html", form=form) + @main.route("//delete", methods=["POST"]) def remove_project(): g.project.remove_project() return redirect(url_for(".home")) + @main.route("/exit") def exit(): # delete the session session.clear() return redirect(url_for(".home")) + @main.route("/demo") def demo(): """ @@ -222,6 +236,7 @@ def demo(): session[project.id] = project.password return redirect(url_for(".list_bills", project_id=project.id)) + @main.route("//invite", methods=["GET", "POST"]) def invite(): """Send invitations for this particular project""" @@ -232,10 +247,11 @@ def invite(): if form.validate(): # send the email - message_body = render_template("invitation_mail.%s" % get_locale().language) + message_body = render_template("invitation_mail.%s" % + get_locale().language) - message_title = _("You have been invited to share your expenses for %(project)s", - project=g.project.name) + message_title = _("You have been invited to share your " + "expenses for %(project)s", project=g.project.name) msg = Message(message_title, body=message_body, recipients=[email.strip() @@ -246,9 +262,10 @@ def invite(): return render_template("send_invites.html", form=form) + @main.route("//") def list_bills(): - bill_form=get_billform_for(g.project) + bill_form = get_billform_for(g.project) # set the last selected payer as default choice if exists if 'last_selected_payer' in session: bill_form.payer.data = session['last_selected_payer'] @@ -260,6 +277,7 @@ def list_bills(): add_bill=request.values.get('add_bill', False) ) + @main.route("//members/add", methods=["GET", "POST"]) def add_member(): # FIXME manage form errors on the list_bills page @@ -273,6 +291,7 @@ def add_member(): return render_template("add_member.html", form=form) + @main.route("//members//reactivate", methods=["POST"]) def reactivate(member_id): person = Person.query.filter(Person.id == member_id)\ @@ -294,6 +313,7 @@ def remove_member(member_id): return redirect(url_for(".list_bills")) + @main.route("//add", methods=["GET", "POST"]) def add_bill(): form = get_billform_for(g.project) @@ -353,6 +373,7 @@ def edit_bill(bill_id): return render_template("add_bill.html", form=form, edit=True) + @main.route("/lang/") def change_lang(lang): session['lang'] = lang @@ -360,11 +381,13 @@ def change_lang(lang): return redirect(request.headers.get('Referer') or url_for('.home')) + @main.route("//compute") def compute_bills(): """Compute the sum each one have to pay to each other and display it""" return render_template("compute_bills.html") + @main.route("//archives/create") def create_archive(): form = CreateArchiveForm() @@ -375,6 +398,7 @@ def create_archive(): return render_template("create_archive.html", form=form) + @main.route("/dashboard") def dashboard(): return render_template("dashboard.html", projects=Project.query.all())