aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Metaireau <alexis@notmyidea.org>2011-09-13 22:58:53 +0200
committerAlexis Metaireau <alexis@notmyidea.org>2011-09-13 22:58:53 +0200
commitb0d41291afade8aec86502d07d1d29d000ff1bca (patch)
tree75116f45eaa6915e554d0c6158069462063733fa
parent8528526f0b6dc8828247ef03f11e4894580f8dd5 (diff)
downloadihatemoney-mirror-b0d41291afade8aec86502d07d1d29d000ff1bca.zip
ihatemoney-mirror-b0d41291afade8aec86502d07d1d29d000ff1bca.tar.gz
ihatemoney-mirror-b0d41291afade8aec86502d07d1d29d000ff1bca.tar.bz2
API: Create and Update support
-rw-r--r--budget/api.py65
-rw-r--r--budget/forms.py24
-rw-r--r--budget/models.py19
-rw-r--r--budget/rest.py16
-rw-r--r--budget/web.py13
5 files changed, 100 insertions, 37 deletions
diff --git a/budget/api.py b/budget/api.py
index ddaf65c..3df8ab2 100644
--- a/budget/api.py
+++ b/budget/api.py
@@ -2,6 +2,7 @@
from flask import *
from models import db, Project, Person, Bill
+from forms import ProjectForm
from utils import for_all_methods
from rest import RESTResource, need_auth# FIXME make it an ext
@@ -21,7 +22,7 @@ def check_project(*args, **kwargs):
if auth and "project_id" in kwargs and \
auth.username == kwargs["project_id"]:
project = Project.query.get(auth.username)
- if project.password == auth.password:
+ if project and project.password == auth.password:
return project
return False
@@ -29,7 +30,13 @@ def check_project(*args, **kwargs):
class ProjectHandler(object):
def add(self):
- pass
+ form = ProjectForm(csrf_enabled=False)
+ if form.validate():
+ project = form.save(Project())
+ db.session.add(project)
+ db.session.commit()
+ return 201, project.id
+ return 400, form.errors
@need_auth(check_project, "project")
def get(self, project):
@@ -37,11 +44,18 @@ class ProjectHandler(object):
@need_auth(check_project, "project")
def delete(self, project):
- return "delete"
+ db.session.delete(project)
+ db.session.commit()
+ return 200, "DELETED"
@need_auth(check_project, "project")
def update(self, project):
- return "update"
+ form = ProjectForm(csrf_enabled=False)
+ if form.validate():
+ form.save(project)
+ db.session.commit()
+ return 200, "UPDATED"
+ return 400, form.errors
class MemberHandler(object):
@@ -49,23 +63,34 @@ class MemberHandler(object):
def get(self, project, member_id):
member = Person.query.get(member_id)
if not member or member.project != project:
- return Response('Not Found', status=404)
+ return 404, "Not Found"
return member
def list(self, project):
return project.members
def add(self, project):
- pass
+ form = MemberForm(csrf_enabled=False)
+ if form.validate():
+ member = Person()
+ form.save(project, member)
+ db.session.commit()
+ return 200, member.id
+ return 400, form.errors
def update(self, project, member_id):
- pass
+ form = MemberForm(csrf_enabled=False)
+ if form.validate():
+ member = Person.query.get(member_id, project)
+ form.save(project, member)
+ db.session.commit()
+ return 200, member
+ return 400, form.errors
def delete(self, project, member_id):
if project.remove_member(member_id):
- return Response('OK', status=200)
- else:
- return Response('Not Found', status=404)
+ return 200, "OK"
+ return 404, "Not Found"
class BillHandler(object):
@@ -73,22 +98,34 @@ class BillHandler(object):
def get(self, project, bill_id):
bill = Bill.query.get(project, bill_id)
if not bill:
- return Response('Not Found', status=404)
+ return 404, "Not Found"
return bill
def list(self, project):
return project.get_bills().all()
def add(self, project):
- pass
+ form = BillForm(csrf_enabled=False)
+ if form.validate():
+ bill = Bill()
+ form.save(bill)
+ db.session.add(bill)
+ db.session.commit()
+ return 200, bill.id
+ return 400, form.errors
def update(self, project, bill_id):
- pass
+ form = BillForm(csrf_enabled=False)
+ if form.validate():
+ form.save(bill)
+ db.session.commit()
+ return 200, bill.id
+ return 400, form.errors
def delete(self, project, bill_id):
bill = Bill.query.delete(project, bill_id)
if not bill:
- return Response('Not Found', status=404)
+ return 404, "Not Found"
return bill
diff --git a/budget/forms.py b/budget/forms.py
index 7ac48cc..cfd5788 100644
--- a/budget/forms.py
+++ b/budget/forms.py
@@ -1,6 +1,6 @@
from flaskext.wtf import *
from wtforms.widgets import html_params
-from models import Project, Person, Bill
+from models import Project, Person, Bill, db
from datetime import datetime
@@ -39,6 +39,15 @@ class ProjectForm(Form):
contact_email=self.contact_email.data)
return project
+ def update(self, project):
+ """Update the project with the information from the form"""
+ project.name = self.name.data
+ project.id = self.id.data
+ project.password = self.password.data
+ project.contact_email = self.contact_email.data
+
+ return project
+
class AuthenticationForm(Form):
id = TextField("Project identifier", validators=[Required()])
@@ -76,19 +85,26 @@ class BillForm(Form):
class MemberForm(Form):
- def __init__(self, project, *args, **kwargs):
- super(MemberForm, self).__init__(*args, **kwargs)
- self.project = project
name = TextField("Name", validators=[Required()])
submit = SubmitField("Add a member")
+ def __init__(self, project, *args, **kwargs):
+ super(MemberForm, self).__init__(*args, **kwargs)
+ self.project = project
+
def validate_name(form, field):
if Person.query.filter(Person.name == field.data)\
.filter(Person.project == form.project)\
.filter(Person.activated == True).all():
raise ValidationError("This project already have this member")
+ def save(self, project, person):
+ # if the user is already bound to the project, just reactivate him
+ person.name = self.name.data
+ person.project = project
+
+ return person
class InviteForm(Form):
emails = TextAreaField("People to notify")
diff --git a/budget/models.py b/budget/models.py
index e56ae4e..5ee7b07 100644
--- a/budget/models.py
+++ b/budget/models.py
@@ -1,7 +1,8 @@
from collections import defaultdict
from datetime import datetime
-from flaskext.sqlalchemy import SQLAlchemy
+from flaskext.sqlalchemy import SQLAlchemy, BaseQuery
+from flask import g
from sqlalchemy import orm
@@ -75,6 +76,20 @@ class Project(db.Model):
class Person(db.Model):
+ class PersonQuery(BaseQuery):
+ def get_by_name(self, name, project):
+ return Person.query.filter(Person.name == name)\
+ .filter(Project.id == project.id).one()
+
+ def get(self, id, project=None):
+ if not project:
+ project = g.project
+ return Person.query.filter(Person.id == id)\
+ .filter(Project.id == project.id).one()
+
+
+ query_class = PersonQuery
+
_to_serialize = ("id", "name", "activated")
id = db.Column(db.Integer, primary_key=True)
@@ -106,7 +121,7 @@ billowers = db.Table('billowers',
class Bill(db.Model):
- class BillQuery(orm.query.Query):
+ class BillQuery(BaseQuery):
def get(self, project, id):
try:
diff --git a/budget/rest.py b/budget/rest.py
index 8ade14b..f237217 100644
--- a/budget/rest.py
+++ b/budget/rest.py
@@ -114,7 +114,7 @@ def need_auth(authentifier, name=None, remove_attr=True):
del kwargs["%s_id" % name]
return func(*args, **kwargs)
else:
- raise werkzeug.exceptions.Forbidden()
+ return 403, "Forbidden"
return wrapped
return wrapper
@@ -128,13 +128,15 @@ def serialize(func):
# get the mimetype
mime = request.accept_mimetypes.best_match(SERIALIZERS.keys())
data = func(*args, **kwargs)
+ serializer = SERIALIZERS[mime]
- if isinstance(data, werkzeug.Response):
- return data
- else:
- # serialize it
- return werkzeug.Response(SERIALIZERS[mime].encode(data),
- status=200, mimetype=mime)
+ status = 200
+ if len(data) == 2:
+ status, data = data
+
+ # serialize it
+ return werkzeug.Response(serializer.encode(data),
+ status=status, mimetype=mime)
return wrapped
diff --git a/budget/web.py b/budget/web.py
index 61d67e5..5667b05 100644
--- a/budget/web.py
+++ b/budget/web.py
@@ -188,18 +188,11 @@ def add_member():
form = MemberForm(g.project)
if request.method == "POST":
if form.validate():
- # if the user is already bound to the project, just reactivate him
- person = Person.query.filter(Person.name == form.name.data)\
- .filter(Project.id == g.project.id).all()
- if person:
- person[0].activated = True
- db.session.commit()
- flash("%s is part of this project again" % person[0].name)
- return redirect(url_for(".list_bills"))
-
- db.session.add(Person(name=form.name.data, project=g.project))
+ member = form.save(g.project, Person())
db.session.commit()
+ flash("%s is had been added" % member.name)
return redirect(url_for(".list_bills"))
+
return render_template("add_member.html", form=form)
@main.route("/<project_id>/members/<member_id>/reactivate", methods=["GET",])