diff options
| author | Frédéric Sureau <frederic.sureau@gmail.com> | 2012-03-28 17:02:02 +0200 |
|---|---|---|
| committer | Frédéric Sureau <frederic.sureau@gmail.com> | 2012-03-28 17:02:02 +0200 |
| commit | c343bf96ea971b7a4d1dd75320f316844a0b3262 (patch) | |
| tree | 6f0228993d7a437f7ee8eb00ab8e71850832a0aa /budget/web.py | |
| parent | 71cb07a92b65579f45152ca09c0597e90fd7b484 (diff) | |
| parent | 757e86baa1ae3b2bc980fc7a1af2a085b702224c (diff) | |
| download | ihatemoney-mirror-c343bf96ea971b7a4d1dd75320f316844a0b3262.zip ihatemoney-mirror-c343bf96ea971b7a4d1dd75320f316844a0b3262.tar.gz ihatemoney-mirror-c343bf96ea971b7a4d1dd75320f316844a0b3262.tar.bz2 | |
Merge branch 'master' of git://github.com/spiral-project/ihatemoney
Diffstat (limited to 'budget/web.py')
| -rw-r--r-- | budget/web.py | 122 |
1 files changed, 77 insertions, 45 deletions
diff --git a/budget/web.py b/budget/web.py index bee07e0..6097d80 100644 --- a/budget/web.py +++ b/budget/web.py @@ -1,15 +1,3 @@ -from collections import defaultdict - -from flask import * -from flaskext.mail import Mail, Message -from flaskext.babel import get_locale, gettext as _ -import werkzeug - -# local modules -from models import db, Project, Person, Bill -from forms import * -from utils import Redirect303 - """ The blueprint for the web interface. @@ -17,13 +5,28 @@ Contains all the interaction logic with the end user (except forms which are directly handled in the forms module. Basically, this blueprint takes care of the authentication and provides -some shortcuts to make your life better when coding (see `pull_project` +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. @@ -35,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 @@ -50,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 @@ -59,17 +64,18 @@ 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""" form = AuthenticationForm() if not form.id.data and request.args.get('project_id'): form.id.data = request.args['project_id'] - project_id = form.id.data + 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 + # But if the user try to connect to an unexisting project, we will # propose him a link to the creation form. if request.method == "POST": form.validate() @@ -86,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: @@ -98,16 +105,18 @@ def authenticate(project_id=None): setattr(g, 'project', project) return redirect(url_for(".list_bills")) - return render_template("authenticate.html", form=form, + return render_template("authenticate.html", form=form, create_project=create_project) + @main.route("/") def home(): project_form = ProjectForm() auth_form = AuthenticationForm() - return render_template("home.html", project_form=project_form, + 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() @@ -116,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(): @@ -133,23 +143,32 @@ 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_body = render_template("reminder_mail.%s" % get_locale().language) + message_title = _("You have just created '%(project)s' " + "to share your expenses", project=g.project.name) - msg = Message(message_title, - body=message_body, + message_body = render_template("reminder_mail.%s" % + get_locale().language) + + msg = Message(message_title, + body=message_body, recipients=[project.contact_email]) - mail.send(msg) + try: + mail.send(msg) + except SMTPRecipientsRefused: + msg_compl = 'Problem sending mail. ' + # TODO: destroy the project and cancel instead? + else: + msg_compl = '' # redirect the user to the next step (invite) - flash(_("The project identifier is %(project)s", project=project.id)) + flash(_("%(msg_compl)sThe project identifier is %(project)s", + msg_compl=msg_compl, project=project.id)) return redirect(url_for(".invite", project_id=project.id)) return render_template("create_project.html", form=form) + @main.route("/password-reminder", methods=["GET", "POST"]) def remind_password(): form = PasswordReminder() @@ -159,9 +178,9 @@ def remind_password(): project = Project.query.get(form.id.data) # send the password reminder - mail.send(Message("password recovery", - body=render_template("password_reminder.%s" % get_locale().language, - project=project), + password_reminder = "password_reminder.%s" % get_locale().language + mail.send(Message("password recovery", + body=render_template(password_reminder, project=project), recipients=[project.contact_email])) flash(_("a mail has been sent to you with the password")) @@ -185,18 +204,21 @@ def edit_project(): return render_template("edit_project.html", form=form) + @main.route("/<project_id>/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(): """ @@ -207,30 +229,32 @@ def demo(): """ project = Project.query.get("demo") if not project: - project = Project(id="demo", name=u"demonstration", password="demo", + project = Project(id="demo", name=u"demonstration", password="demo", contact_email="demo@notmyidea.org") db.session.add(project) db.session.commit() session[project.id] = project.password return redirect(url_for(".list_bills", project_id=project.id)) + @main.route("/<project_id>/invite", methods=["GET", "POST"]) def invite(): """Send invitations for this particular project""" form = InviteForm() - if request.method == "POST": + if request.method == "POST": 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) - msg = Message(message_title, - body=message_body, - recipients=[email.strip() + 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() for email in form.emails.data.split(",")]) mail.send(msg) flash(_("Your invitations have been sent")) @@ -238,20 +262,22 @@ def invite(): return render_template("send_invites.html", form=form) + @main.route("/<project_id>/") 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'] bills = g.project.get_bills() - return render_template("list_bills.html", + return render_template("list_bills.html", bills=bills, member_form=MemberForm(g.project), bill_form=bill_form, add_bill=request.values.get('add_bill', False) ) + @main.route("/<project_id>/members/add", methods=["GET", "POST"]) def add_member(): # FIXME manage form errors on the list_bills page @@ -265,6 +291,7 @@ def add_member(): return render_template("add_member.html", form=form) + @main.route("/<project_id>/members/<member_id>/reactivate", methods=["POST"]) def reactivate(member_id): person = Person.query.filter(Person.id == member_id)\ @@ -286,6 +313,7 @@ def remove_member(member_id): return redirect(url_for(".list_bills")) + @main.route("/<project_id>/add", methods=["GET", "POST"]) def add_bill(): form = get_billform_for(g.project) @@ -345,6 +373,7 @@ def edit_bill(bill_id): return render_template("add_bill.html", form=form, edit=True) + @main.route("/lang/<lang>") def change_lang(lang): session['lang'] = lang @@ -352,14 +381,16 @@ def change_lang(lang): return redirect(request.headers.get('Referer') or url_for('.home')) + @main.route("/<project_id>/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("/<project_id>/archives/create") def create_archive(): - form = CreateArchiveForm() + form = CreateArchiveForm() if request.method == "POST": if form.validate(): pass @@ -367,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()) |
