Browse Source

starting places

master
Julio Biason 11 years ago
parent
commit
0423900df9
  1. 17
      luncho/blueprints/groups.py
  2. 103
      luncho/blueprints/places.py
  3. 16
      luncho/exceptions.py
  4. 41
      luncho/server.py
  5. 51
      tests/place_tests.py

17
luncho/blueprints/groups.py

@ -18,22 +18,7 @@ from luncho.server import db
from luncho.exceptions import LunchoException from luncho.exceptions import LunchoException
from luncho.exceptions import ElementNotFoundException from luncho.exceptions import ElementNotFoundException
from luncho.exceptions import AccountNotVerifiedException
class AccountNotVerifiedException(LunchoException):
"""The account isn't verified.
.. sourcecode:: http
HTTP/1.1 412 Precondition Failed
Content-Type: test/json
{ "status": "ERROR", "message": "Account not verified" }
"""
def __init__(self):
super(AccountNotVerifiedException, self).__init__()
self.status = 412
self.message = 'Account not verified'
class NewMaintainerDoesNotExistException(LunchoException): class NewMaintainerDoesNotExistException(LunchoException):

103
luncho/blueprints/places.py

@ -0,0 +1,103 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from flask import Blueprint
from flask import request
from flask import jsonify
from luncho.server import Place
from luncho.server import db
from luncho.helpers import auth
from luncho.helpers import ForceJSON
from luncho.exceptions import AccountNotVerifiedException
places = Blueprint('places', __name__)
@places.route('', methods=['POST'])
@ForceJSON(required=['name'])
@auth
def create_place():
"""*Authenticated request* Create a new place. The user becomes the
maintainer of the place once it is created.
**Example request**:
.. sourcecode:: http
{ "name": "<place name>" }
**Success (200)**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: text/json
{ "status": "OK", "id": <new group id> }
**User not found (via token) (404)**:
:py:class:`UserNotFoundException`
**Authorization required (412)**:
:py:class:`AuthorizationRequiredException`
**Account not verified (412)**:
:py:class:`AccountNotVerifiedException`
"""
if not request.user.verified:
raise AccountNotVerifiedException()
json = request.get_json(force=True)
new_place = Place(name=json['name'], owner=request.user.username)
db.session.add(new_place)
db.session.commit()
return jsonify(status='OK',
id=new_place.id)
@places.route('', methods=['GET'])
@auth
def get_places():
"""*Authenticated request* Return the list of places the user is the
maintainer or belongs to one of the user's groups.
**Success (200)**
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: text/json
{ "status": "OK", "places": [ { "id": "<placeId>",
"name": "<place name>",
"maintainer": <true if the user is the
group maintainer>},
...] }
**User not found (via token) (404)**:
:py:class:`UserNotFoundException`
**Authorization required (412)**:
:py:class:`AuthorizationRequiredException`
"""
user = request.user
places = {}
for group in user.groups:
for place in group.places:
maintainer = place.owner == user.username
places[place.id] = {'id': place.id,
'name': place.name,
'maintainer': maintainer}
for place in Place.query.filter_by(owner=user.username):
maintainer = place.owner == user.username
places[place.id] = {'id': place.id,
'name': place.name,
'maintainer': maintainer}
return jsonify(status='OK',
places=places.values())

16
luncho/exceptions.py

@ -122,3 +122,19 @@ class AuthorizationRequiredException(LunchoException):
super(AuthorizationRequiredException, self).__init__() super(AuthorizationRequiredException, self).__init__()
self.status = 401 self.status = 401
self.message = 'Request requires authorization' self.message = 'Request requires authorization'
class AccountNotVerifiedException(LunchoException):
"""The account isn't verified.
.. sourcecode:: http
HTTP/1.1 412 Precondition Failed
Content-Type: test/json
{ "status": "ERROR", "message": "Account not verified" }
"""
def __init__(self):
super(AccountNotVerifiedException, self).__init__()
self.status = 412
self.message = 'Account not verified'

41
luncho/server.py

@ -36,13 +36,22 @@ app.config.from_envvar('LUCNHO_CONFIG', True)
from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(app) db = SQLAlchemy(app)
userGroups = db.Table('user_groups', user_groups = db.Table('user_groups',
db.Column('username', db.Column('username',
db.String, db.String,
db.ForeignKey('user.username')), db.ForeignKey('user.username')),
db.Column('group_id', db.Column('group_id',
db.Integer, db.Integer,
db.ForeignKey('group.id'))) db.ForeignKey('group.id')))
group_places = db.Table('group_places',
db.Column('group',
db.Integer,
db.ForeignKey('group.id')),
db.Column('place',
db.Integer,
db.ForeignKey('place.id')))
class User(db.Model): class User(db.Model):
@ -54,7 +63,7 @@ class User(db.Model):
validated = db.Column(db.Boolean, default=False) validated = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, nullable=False) created_at = db.Column(db.DateTime, nullable=False)
groups = db.relationship('Group', groups = db.relationship('Group',
secondary=userGroups, secondary=user_groups,
backref=db.backref('users', lazy='dynamic')) backref=db.backref('users', lazy='dynamic'))
def __init__(self, username, fullname, passhash, token=None, def __init__(self, username, fullname, passhash, token=None,
@ -88,6 +97,10 @@ class Group(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False) name = db.Column(db.String, nullable=False)
owner = db.Column(db.String, db.ForeignKey('user.username')) owner = db.Column(db.String, db.ForeignKey('user.username'))
places = db.relationship('Place',
secondary=group_places,
backref='groups',
lazy='dynamic')
def __init__(self, name, owner): def __init__(self, name, owner):
self.name = name self.name = name
@ -98,16 +111,28 @@ class Group(db.Model):
name=self.name, name=self.name,
owner=self.owner) owner=self.owner)
class Place(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
owner = db.Column(db.String, db.ForeignKey('user.username'))
def __init__(self, name, owner=None):
self.name = name
self.owner = owner
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Blueprints # Blueprints
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
from blueprints.users import users from blueprints.users import users
from blueprints.token import token from blueprints.token import token
from blueprints.groups import groups from blueprints.groups import groups
from blueprints.places import places
app.register_blueprint(token, url_prefix='/token/') app.register_blueprint(token, url_prefix='/token/')
app.register_blueprint(users, url_prefix='/user/') app.register_blueprint(users, url_prefix='/user/')
app.register_blueprint(groups, url_prefix='/group/') app.register_blueprint(groups, url_prefix='/group/')
app.register_blueprint(places, url_prefix='/place/')
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------

51
tests/place_tests.py

@ -0,0 +1,51 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import unittest
from json import loads
from luncho import server
from luncho.server import User
from base import LunchoTests
class TestPlaces(LunchoTests):
"""Test places."""
def setUp(self):
super(TestPlaces, self).setUp()
self.user = User(username='test',
fullname='Test User',
passhash='hash')
self.user.verified = True
server.db.session.add(self.user)
server.db.session.commit()
self.user.get_token()
def test_create_place(self):
"""Try to create a place."""
request = {'name': 'New Place'}
rv = self.post('/place/',
request,
token=self.user.token)
self.assertJsonOk(rv)
json = loads(rv.data)
self.assertTrue('id' in json)
def test_get_places(self):
"""Try to get the user places."""
token = self.user.token
self.test_create_place() # create a place
rv = self.get('/place/',
token=token)
self.assertJsonOk(rv)
json = loads(rv.data)
self.assertTrue('places' in json)
self.assertEqual(len(json['places']), 1) # just the new place
if __name__ == '__main__':
unittest.main()
Loading…
Cancel
Save