aboutsummaryrefslogtreecommitdiff
path: root/budget
diff options
context:
space:
mode:
Diffstat (limited to 'budget')
-rw-r--r--budget/templates/add_bill.html4
-rw-r--r--budget/templates/add_member.html2
-rw-r--r--budget/templates/edit_bill.html4
-rw-r--r--budget/templates/invitation_mail4
-rw-r--r--budget/templates/list_bills.html18
-rw-r--r--budget/templates/send_invites.html4
-rw-r--r--budget/web.py122
7 files changed, 86 insertions, 72 deletions
diff --git a/budget/templates/add_bill.html b/budget/templates/add_bill.html
index d844b6a..5b3a768 100644
--- a/budget/templates/add_bill.html
+++ b/budget/templates/add_bill.html
@@ -1,14 +1,14 @@
{% extends "layout.html" %}
{% block top_menu %}
-<a href="{{ url_for('list_bills', project_id=project.id) }}">Back to the list</a>
+<a href="{{ url_for('list_bills') }}">Back to the list</a>
{% endblock %}
{% block content %}
<h2>Add a new bill</h2>
<div class="container span-24 add-bill uniForm" style="width: 400px">
- <form action="{{ url_for('add_bill', project_id=project.id) }}" method="post" class=uniForm">
+ <form action="{{ url_for('add_bill') }}" method="post" class=uniForm">
{{ forms.add_bill(form) }}
</form>
</div>
diff --git a/budget/templates/add_member.html b/budget/templates/add_member.html
index 8d24aee..5739791 100644
--- a/budget/templates/add_member.html
+++ b/budget/templates/add_member.html
@@ -1,6 +1,6 @@
{% extends "layout.html" %}
{% block content %}
- <form action="{{ url_for("add_member", project_id=project.id) }}" method="post">
+ <form action="{{ url_for("add_member") }}" method="post">
{{ forms.add_member(form) }}
</form>
{% endblock %}
diff --git a/budget/templates/edit_bill.html b/budget/templates/edit_bill.html
index c78eb09..03a1a26 100644
--- a/budget/templates/edit_bill.html
+++ b/budget/templates/edit_bill.html
@@ -1,14 +1,14 @@
{% extends "layout.html" %}
{% block top_menu %}
-<a href="{{ url_for('list_bills', project_id=project.id) }}">Back to the list</a>
+<a href="{{ url_for('list_bills') }}">Back to the list</a>
{% endblock %}
{% block content %}
<h2>Edit a bill</h2>
<div class="container span-24 add-bill uniForm" style="width: 400px">
- <form action="{{ url_for('edit_bill', project_id=project.id, bill_id=bill_id) }}" method="post" class=uniForm">
+ <form action="{{ url_for('edit_bill', bill_id=bill_id) }}" method="post" class=uniForm">
{{ forms.add_bill(form) }}
</form>
</div>
diff --git a/budget/templates/invitation_mail b/budget/templates/invitation_mail
index 53991ed..83a7840 100644
--- a/budget/templates/invitation_mail
+++ b/budget/templates/invitation_mail
@@ -1,10 +1,10 @@
Hi,
-Someone using the email adress {{ email }} invited you to share your expenses for {{ project.name }} on our application.
+Someone using the email adress {{ g.project.contact_email }} invited you to share your expenses for {{ g.project.name }} on our application.
It's as simple as saying what did you paid for, for who, and how much did it cost you, we are caring about the rest.
-You can access it here: {{ SITE_URL }}{{ url_for("list_bills", project_id=project.id) }}, the password is "{{ project.password }}".
+You can access it here: {{ SITE_URL }}{{ url_for("list_bills") }}, the password is "{{ g.project.password }}".
Enjoy,
Some weird guys
diff --git a/budget/templates/list_bills.html b/budget/templates/list_bills.html
index fe564e1..94b0f8f 100644
--- a/budget/templates/list_bills.html
+++ b/budget/templates/list_bills.html
@@ -42,24 +42,24 @@ $('.members li').hover(function(){
{% block content %}
<div id="leftmenu" class="span-6">
<ul class="members">
- {% set balance = project.get_balance() %}
- {% for member in project.active_members %}
+ {% set balance = g.project.get_balance() %}
+ {% for member in g.project.active_members %}
<li class="{{ loop.cycle("even", "odd") }}">
<span class="balance {% if balance[member] > 0 %}positive{% elif balance[member] < 0 %}negative{% endif %}">{{ balance[member] }}</span>
{{ member.name }}
- <a class="remove" href="{{ url_for("remove_member", project_id=project.id, member_id=member.id) }}">delete</a></li>
+ <a class="remove" href="{{ url_for("remove_member", member_id=member.id) }}">delete</a></li>
{% endfor %}
</ul>
- <form action="{{ url_for("add_member", project_id=project.id) }}" method="post">
+ <form action="{{ url_for("add_member") }}" method="post">
{{ forms.add_member(member_form) }}
</form>
</div>
<div id="content" class="uniForm span-18 last">
- <a id="add_bill_button" class="awesome large green button fright" href="{{ url_for('add_bill', project_id=project.id) }}">Add a bill</a>
+ <a id="add_bill_button" class="awesome large green button fright" href="{{ url_for('add_bill') }}">Add a bill</a>
<a id="hide_bill_form" class="awesome button fright" style="display: none;" href="#">Hide form</a>
-<form id="add_bill" action="{{ url_for('add_bill', project_id=project.id) }}" method="post" style="width: 400px; display: none">{{ forms.add_bill(bill_form) }}</form>
+<form id="add_bill" action="{{ url_for('add_bill') }}" method="post" style="width: 400px; display: none">{{ forms.add_bill(bill_form) }}</form>
{% if bills.count() > 0 %}
<table class="list_bills">
@@ -72,15 +72,15 @@ $('.members li').hover(function(){
<td>{{ bill.what }}</td>
<td>{% for ower in bill.owers %}{{ ower.name }} {% endfor %}</td>
<td>{{ bill.amount }} ({{ bill.pay_each() }} each)</td>
- <td><a href="{{ url_for("edit_bill", bill_id=bill.id, project_id=project.id) }}">edit</a>
- <a href="{{ url_for("delete_bill", bill_id=bill.id, project_id=project.id) }}">delete</a></td>
+ <td><a href="{{ url_for("edit_bill", bill_id=bill.id) }}">edit</a>
+ <a href="{{ url_for("delete_bill", bill_id=bill.id) }}">delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
- <p>Nothing to list yet. You probably want to <a href="{{ url_for("add_bill", project_id=project.id) }}">add a bill</a> ?</p>
+ <p>Nothing to list yet. You probably want to <a href="{{ url_for("add_bill") }}">add a bill</a> ?</p>
{% endif %}
</div>
{% endblock %}
diff --git a/budget/templates/send_invites.html b/budget/templates/send_invites.html
index f618803..fa46c81 100644
--- a/budget/templates/send_invites.html
+++ b/budget/templates/send_invites.html
@@ -3,12 +3,12 @@
<h2>Invite people to join this project</h2>
<p>Specify a (coma separated) list of email adresses you want to notify about the
creation of this budget management project and we will send them an email for you.</p>
-<p>If you prefer, you can <a href="{{ url_for("list_bills", project_id=project.id) }}">skip this step</a> and notify them yourself</p>
+<p>If you prefer, you can <a href="{{ url_for("list_bills") }}">skip this step</a> and notify them yourself</p>
{% include "display_errors.html" %}
<form method="post" accept-charset="utf-8">
{{ form.hidden_tag() }}
<p>{{ form.emails.label }}<br /> {{ form.emails }}</p>
- <p>{{ form.submit }} <a href="{{ url_for("list_bills", project_id=project.id) }}">No, thanks</a></p>
+ <p>{{ form.submit }} <a href="{{ url_for("list_bills") }}">No, thanks</a></p>
</form>
{% endblock %}
diff --git a/budget/web.py b/budget/web.py
index e952109..14e058c 100644
--- a/budget/web.py
+++ b/budget/web.py
@@ -1,8 +1,8 @@
from collections import defaultdict
-from flask import (Flask, session, request, redirect, url_for, render_template,
- flash)
+from flask import *
from flaskext.mail import Mail, Message
+from werkzeug.routing import RequestRedirect
# local modules
from models import db, Project, Person, Bill
@@ -35,8 +35,6 @@ def authenticate(redirect_url=None):
form = AuthenticationForm()
project_id = form.id.data
-
- redirect_url = redirect_url or url_for("list_bills", project_id=project_id)
project = Project.query.get(project_id)
create_project = False # We don't want to create the project by default
if not project:
@@ -47,6 +45,7 @@ def authenticate(redirect_url=None):
else:
# if credentials are already in session, redirect
if project_id in session and project.password == session[project_id]:
+ redirect_url = redirect_url or url_for("list_bills")
return redirect(redirect_url)
# else process the form
@@ -62,6 +61,8 @@ def authenticate(redirect_url=None):
session["projects"].insert(0, (project_id, project.name))
session[project_id] = form.password.data
session.update()
+ setattr(g, 'project', project)
+ redirect_url = redirect_url or url_for("list_bills")
return redirect(redirect_url)
return render_template("authenticate.html", form=form,
@@ -95,9 +96,32 @@ def exit():
session.clear()
return redirect(url_for("home"))
-@app.route("/<string:project_id>/invite", methods=["GET", "POST"])
-@requires_auth
-def invite(project):
+@app.url_defaults
+def add_project_id(endpoint, values):
+ if 'project_id' in values or not hasattr(g, 'project'):
+ return
+ if app.url_map.is_endpoint_expecting(endpoint, 'project_id'):
+ values['project_id'] = g.project.id
+
+@app.url_value_preprocessor
+def pull_project(endpoint, values):
+ if not values:
+ values = {}
+ project_id = values.pop('project_id', None)
+ if project_id:
+ project = Project.query.get(project_id)
+ if not project:
+ raise RequestRedirect(url_for("create_project"))
+ if project.id in session and session[project.id] == project.password:
+ # add project into kwargs and call the original function
+ g.project = project
+ else:
+ # redirect to authentication page
+ raise RequestRedirect(
+ url_for("authenticate", redirect_url=request.url))
+
+@app.route("/<project_id>/invite", methods=["GET", "POST"])
+def invite():
form = InviteForm()
@@ -105,51 +129,46 @@ def invite(project):
if form.validate():
# send the email
- message_body = render_template("invitation_mail",
- email=project.contact_email, project=project)
+ message_body = render_template("invitation_mail")
message_title = "You have been invited to share your"\
- + " expenses for %s" % project.name
+ + " expenses for %s" % g.project.name
msg = Message(message_title,
body=message_body,
recipients=[email.strip()
for email in form.emails.data.split(",")])
mail.send(msg)
- return redirect(url_for("list_bills", project_id=project.id))
+ return redirect(url_for("list_bills"))
- return render_template("send_invites.html", form=form, project=project)
+ return render_template("send_invites.html", form=form)
-@app.route("/<string:project_id>/")
-@requires_auth
-def list_bills(project):
+@app.route("/<project_id>/")
+def list_bills():
bills = Bill.query.join(Person, Project)\
.filter(Bill.payer_id == Person.id)\
.filter(Person.project_id == Project.id)\
- .filter(Project.id == project.id)\
+ .filter(Project.id == g.project.id)\
.order_by(Bill.date.desc())
return render_template("list_bills.html",
- bills=bills, project=project,
- member_form=MemberForm(project),
- bill_form=get_billform_for(project)
+ bills=bills, member_form=MemberForm(g.project),
+ bill_form=get_billform_for(g.project)
)
-@app.route("/<string:project_id>/members/add", methods=["GET", "POST"])
-@requires_auth
-def add_member(project):
+@app.route("/<project_id>/members/add", methods=["GET", "POST"])
+def add_member():
# FIXME manage form errors on the list_bills page
- form = MemberForm(project)
+ form = MemberForm(g.project)
if request.method == "POST":
if form.validate():
- db.session.add(Person(name=form.name.data, project=project))
+ db.session.add(Person(name=form.name.data, project=g.project))
db.session.commit()
- return redirect(url_for("list_bills", project_id=project.id))
- return render_template("add_member.html", form=form, project=project)
+ return redirect(url_for("list_bills"))
+ return render_template("add_member.html", form=form)
-@app.route("/<string:project_id>/members/<int:member_id>/delete", methods=["GET", "POST"])
-@requires_auth
-def remove_member(project, member_id):
+@app.route("/<project_id>/members/<member_id>/delete", methods=["GET", "POST"])
+def remove_member(member_id):
person = Person.query.get_or_404(member_id)
- if person.project == project:
+ if person.project == g.project:
if not person.has_bills():
db.session.delete(person)
db.session.commit()
@@ -158,12 +177,11 @@ def remove_member(project, member_id):
person.activated = False
db.session.commit()
flash("User '%s' has been desactivated" % person.name)
- return redirect(url_for("list_bills", project_id=project.id))
+ return redirect(url_for("list_bills"))
-@app.route("/<string:project_id>/add", methods=["GET", "POST"])
-@requires_auth
-def add_bill(project):
- form = get_billform_for(project)
+@app.route("/<project_id>/add", methods=["GET", "POST"])
+def add_bill():
+ form = get_billform_for(g.project)
if request.method == 'POST':
if form.validate():
bill = Bill()
@@ -171,47 +189,43 @@ def add_bill(project):
db.session.commit()
flash("The bill has been added")
- return redirect(url_for('list_bills', project_id=project.id))
+ return redirect(url_for('list_bills'))
- return render_template("add_bill.html", form=form, project=project)
+ return render_template("add_bill.html", form=form)
-@app.route("/<string:project_id>/delete/<int:bill_id>")
-@requires_auth
-def delete_bill(project, bill_id):
+@app.route("/<project_id>/delete/<int:bill_id>")
+def delete_bill(bill_id):
bill = Bill.query.get_or_404(bill_id)
db.session.delete(bill)
db.session.commit()
flash("The bill has been deleted")
- return redirect(url_for('list_bills', project_id=project.id))
+ return redirect(url_for('list_bills'))
-@app.route("/<string:project_id>/edit/<int:bill_id>", methods=["GET", "POST"])
-@requires_auth
-def edit_bill(project, bill_id):
+@app.route("/<project_id>/edit/<int:bill_id>", methods=["GET", "POST"])
+def edit_bill(bill_id):
bill = Bill.query.get_or_404(bill_id)
- form = get_billform_for(project, set_default=False)
+ form = get_billform_for(g.project, set_default=False)
if request.method == 'POST' and form.validate():
form.save(bill)
db.session.commit()
flash("The bill has been modified")
- return redirect(url_for('list_bills', project_id=project.id))
+ return redirect(url_for('list_bills'))
form.fill(bill)
- return render_template("edit_bill.html", form=form, project=project, bill_id=bill_id)
+ return render_template("edit_bill.html", form=form, bill_id=bill_id)
-@app.route("/<string:project_id>/compute")
-@requires_auth
-def compute_bills(project):
+@app.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", project=project)
+ return render_template("compute_bills.html")
-@app.route("/<string:project_id>/reset")
-@requires_auth
-def reset_bills(project):
+@app.route("/<project_id>/reset")
+def reset_bills():
"""Reset the list of bills"""
# FIXME replace with the archive feature
# get all the bills which are not processed