improve REST path
This commit is contained in:
parent
7ee23b3b7e
commit
05dac7f4fb
5 changed files with 82 additions and 28 deletions
|
@ -21,10 +21,13 @@ Web server
|
||||||
- /attendees POST - write a new entry
|
- /attendees POST - write a new entry
|
||||||
- /attendees/:id GET - a single entry
|
- /attendees/:id GET - a single entry
|
||||||
- /attendees/:id PUT - update an entry
|
- /attendees/:id PUT - update an entry
|
||||||
|
- /attendees/:id DELETE - delete an entry
|
||||||
- /days GET - all entries, grouped by day and by group
|
- /days GET - all entries, grouped by day and by group
|
||||||
- /days PUT - write or update information about the day
|
|
||||||
- /groups PUT - write or update information about a group
|
|
||||||
- /days/:day GET - a single day entries, grouped by group (yyyy-mm-dd format)
|
- /days/:day GET - a single day entries, grouped by group (yyyy-mm-dd format)
|
||||||
|
- /days/:day/info PUT - write or update information about a day
|
||||||
|
- /days/:day/groups/:group PUT - used to rename a group (with the newName key)
|
||||||
|
- /days/:day/groups/:group DELETE - delete a group
|
||||||
|
- /days/:day/groups/:group/info PUT - write or update information about a group (the :group key is its name)
|
||||||
- /users GET - list of all users
|
- /users GET - list of all users
|
||||||
- /users POST - create a new user
|
- /users POST - create a new user
|
||||||
- /users/:id GET - a single user
|
- /users/:id GET - a single user
|
||||||
|
|
70
ibt2.py
70
ibt2.py
|
@ -261,8 +261,7 @@ class AttendeesHandler(BaseHandler):
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def delete(self, id_=None, **kwargs):
|
def delete(self, id_=None, **kwargs):
|
||||||
if id_ is None:
|
if id_ is None:
|
||||||
self.write({'success': False})
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
return
|
|
||||||
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
||||||
if not doc:
|
if not doc:
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
|
@ -274,7 +273,6 @@ class AttendeesHandler(BaseHandler):
|
||||||
|
|
||||||
class DaysHandler(BaseHandler):
|
class DaysHandler(BaseHandler):
|
||||||
"""Handle requests for Days."""
|
"""Handle requests for Days."""
|
||||||
|
|
||||||
def _summarize(self, days):
|
def _summarize(self, days):
|
||||||
res = []
|
res = []
|
||||||
for day in days:
|
for day in days:
|
||||||
|
@ -342,12 +340,15 @@ class DaysHandler(BaseHandler):
|
||||||
else:
|
else:
|
||||||
self.write(base)
|
self.write(base)
|
||||||
|
|
||||||
|
|
||||||
|
class DaysInfoHandler(BaseHandler):
|
||||||
|
"""Handle requests for Days info."""
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def put(self, **kwargs):
|
def put(self, day='', **kwargs):
|
||||||
data = self.clean_body
|
day = day.strip()
|
||||||
day = (data.get('day') or '').strip()
|
|
||||||
if not day:
|
if not day:
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
|
data = self.clean_body
|
||||||
data['day'] = day
|
data['day'] = day
|
||||||
self.add_access_info(data)
|
self.add_access_info(data)
|
||||||
merged, doc = self.db.update('days', {'day': day}, data)
|
merged, doc = self.db.update('days', {'day': day}, data)
|
||||||
|
@ -357,23 +358,26 @@ class DaysHandler(BaseHandler):
|
||||||
class GroupsHandler(BaseHandler):
|
class GroupsHandler(BaseHandler):
|
||||||
"""Handle requests for Groups."""
|
"""Handle requests for Groups."""
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def put(self, **kwargs):
|
def put(self, day='', group='', **kwargs):
|
||||||
data = self.clean_body
|
day = day.strip()
|
||||||
day = (data.get('day') or '').strip()
|
group = group.strip()
|
||||||
group = (data.get('group') or '').strip()
|
|
||||||
if not (day and group):
|
if not (day and group):
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
data['day'] = day
|
data = self.clean_body
|
||||||
data['group'] = group
|
newName = (data.get('newName') or '').strip()
|
||||||
self.add_access_info(data)
|
if newName:
|
||||||
merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
|
query = {'day': day, 'group': group}
|
||||||
self.write(doc)
|
data = {'group': newName}
|
||||||
|
self.db.updateMany('attendees', query, data)
|
||||||
|
self.db.updateMany('groups', query, data)
|
||||||
|
self.write({'success': True})
|
||||||
|
else:
|
||||||
|
self.write({'success': False})
|
||||||
|
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def delete(self, **kwargs):
|
def delete(self, day='', group='', **kwargs):
|
||||||
data = self.clean_arguments
|
day = day.strip()
|
||||||
day = (data.get('day') or '').strip()
|
group = group.strip()
|
||||||
group = (data.get('group') or '').strip()
|
|
||||||
if not (day and group):
|
if not (day and group):
|
||||||
return self.build_error(status=404, message='unable to access the resource')
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
if not self.current_user_info.get('isAdmin'):
|
if not self.current_user_info.get('isAdmin'):
|
||||||
|
@ -385,6 +389,22 @@ class GroupsHandler(BaseHandler):
|
||||||
self.write({'success': True, 'deleted entries': howMany.get('n')})
|
self.write({'success': True, 'deleted entries': howMany.get('n')})
|
||||||
|
|
||||||
|
|
||||||
|
class GroupsInfoHandler(BaseHandler):
|
||||||
|
"""Handle requests for Groups Info."""
|
||||||
|
@gen.coroutine
|
||||||
|
def put(self, day='', group='', **kwargs):
|
||||||
|
day = day.strip()
|
||||||
|
group = group.strip()
|
||||||
|
if not (day and group):
|
||||||
|
return self.build_error(status=404, message='unable to access the resource')
|
||||||
|
data = self.clean_body
|
||||||
|
data['day'] = day
|
||||||
|
data['group'] = group
|
||||||
|
self.add_access_info(data)
|
||||||
|
merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
|
||||||
|
self.write(doc)
|
||||||
|
|
||||||
|
|
||||||
class UsersHandler(BaseHandler):
|
class UsersHandler(BaseHandler):
|
||||||
"""Handle requests for Users."""
|
"""Handle requests for Users."""
|
||||||
document = 'user'
|
document = 'user'
|
||||||
|
@ -574,17 +594,23 @@ def run():
|
||||||
{'setting': 'server_cookie_secret', 'cookie_secret': cookie_secret})
|
{'setting': 'server_cookie_secret', 'cookie_secret': cookie_secret})
|
||||||
|
|
||||||
_days_path = r"/days/?(?P<day>[\d_-]+)?"
|
_days_path = r"/days/?(?P<day>[\d_-]+)?"
|
||||||
_groups_path = r"/groups/?"
|
_days_info_path = r"/days/(?P<day>[\d_-]+)/info"
|
||||||
|
_groups_path = r"/days/(?P<day>[\d_-]+)/groups/(?P<group>.+?)"
|
||||||
|
_groups_info_path = r"/days/(?P<day>[\d_-]+)/groups/(?P<group>.+?)/info"
|
||||||
_attendees_path = r"/attendees/?(?P<id_>[\w\d_-]+)?"
|
_attendees_path = r"/attendees/?(?P<id_>[\w\d_-]+)?"
|
||||||
_current_user_path = r"/users/current/?"
|
_current_user_path = r"/users/current/?"
|
||||||
_users_path = r"/users/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
_users_path = r"/users/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
||||||
application = tornado.web.Application([
|
application = tornado.web.Application([
|
||||||
(_attendees_path, AttendeesHandler, init_params),
|
(_attendees_path, AttendeesHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _attendees_path), AttendeesHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _attendees_path), AttendeesHandler, init_params),
|
||||||
(_days_path, DaysHandler, init_params),
|
(_groups_info_path, GroupsInfoHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _groups_path), GroupsHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _groups_info_path), GroupsInfoHandler, init_params),
|
||||||
(_groups_path, GroupsHandler, init_params),
|
(_groups_path, GroupsHandler, init_params),
|
||||||
|
(r'/v%s%s' % (API_VERSION, _groups_path), GroupsHandler, init_params),
|
||||||
|
(_days_path, DaysHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _days_path), DaysHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _days_path), DaysHandler, init_params),
|
||||||
|
(_days_info_path, DaysInfoHandler, init_params),
|
||||||
|
(r'/v%s%s' % (API_VERSION, _days_info_path), DaysInfoHandler, init_params),
|
||||||
(_current_user_path, CurrentUserHandler, init_params),
|
(_current_user_path, CurrentUserHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _current_user_path), CurrentUserHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _current_user_path), CurrentUserHandler, init_params),
|
||||||
(_users_path, UsersHandler, init_params),
|
(_users_path, UsersHandler, init_params),
|
||||||
|
|
24
monco.py
24
monco.py
|
@ -262,6 +262,30 @@ class Monco(object):
|
||||||
lastErrorObject = res.get('lastErrorObject') or {}
|
lastErrorObject = res.get('lastErrorObject') or {}
|
||||||
return lastErrorObject.get('updatedExisting', False), res.get('value') or {}
|
return lastErrorObject.get('updatedExisting', False), res.get('value') or {}
|
||||||
|
|
||||||
|
def updateMany(self, collection, query, data):
|
||||||
|
"""Update multiple existing documents.
|
||||||
|
|
||||||
|
query can be an ID or a dict representing a query.
|
||||||
|
|
||||||
|
:param collection: update documents in this collection
|
||||||
|
:type collection: str
|
||||||
|
:param query: a query or a list of attributes in the data that must match
|
||||||
|
:type query: str or :class:`~bson.objectid.ObjectId` or iterable
|
||||||
|
:param data: the updated information to store
|
||||||
|
:type data: dict
|
||||||
|
|
||||||
|
:returns: a dict with the success state and number of updated items
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
db = self.connect()
|
||||||
|
data = convert(data or {})
|
||||||
|
query = convert(query)
|
||||||
|
if not isinstance(query, dict):
|
||||||
|
query = {'_id': query}
|
||||||
|
if '_id' in data:
|
||||||
|
del data['_id']
|
||||||
|
return db[collection].update(query, {'$set': data}, multi=True)
|
||||||
|
|
||||||
def delete(self, collection, _id_or_query=None, force=False):
|
def delete(self, collection, _id_or_query=None, force=False):
|
||||||
"""Remove one or more documents from a collection.
|
"""Remove one or more documents from a collection.
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ export default {
|
||||||
|
|
||||||
beforeCreate: function() {
|
beforeCreate: function() {
|
||||||
this.daysUrl = this.$resource('days{/day}');
|
this.daysUrl = this.$resource('days{/day}');
|
||||||
|
this.daysInfoUrl = this.$resource('days{/day}/info');
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
|
@ -184,7 +185,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var data = {day: this.day.day, notes: this.dayNotes};
|
var data = {day: this.day.day, notes: this.dayNotes};
|
||||||
this.daysUrl.update(data).then((response) => {
|
this.daysInfoUrl.update({day: this.day.day}, data).then((response) => {
|
||||||
return response.json();
|
return response.json();
|
||||||
}, (response) => {
|
}, (response) => {
|
||||||
this.$refs.dialogObj.show({text: 'unable to edit day notes'});
|
this.$refs.dialogObj.show({text: 'unable to edit day notes'});
|
||||||
|
|
|
@ -187,7 +187,7 @@ class Ibt2Tests(unittest.TestCase):
|
||||||
def test_put_day(self):
|
def test_put_day(self):
|
||||||
day = {'day': '2017-01-16', 'notes': 'A day note'}
|
day = {'day': '2017-01-16', 'notes': 'A day note'}
|
||||||
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'group C'})
|
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'group C'})
|
||||||
r = requests.put(BASE_URL + 'days', json=day)
|
r = requests.put(BASE_URL + 'days/2017-01-16/info', json=day)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
rj = r.json()
|
rj = r.json()
|
||||||
self.assertTrue(dictInDict(day, rj))
|
self.assertTrue(dictInDict(day, rj))
|
||||||
|
@ -199,7 +199,7 @@ class Ibt2Tests(unittest.TestCase):
|
||||||
def test_put_group(self):
|
def test_put_group(self):
|
||||||
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
|
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
|
||||||
group = {'group': 'A group', 'day': '2017-01-16', 'notes': 'A group note'}
|
group = {'group': 'A group', 'day': '2017-01-16', 'notes': 'A group note'}
|
||||||
r = requests.put(BASE_URL + 'groups', json=group)
|
r = requests.put(BASE_URL + 'days/2017-01-16/groups/A group/info', json=group)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
rj = r.json()
|
rj = r.json()
|
||||||
self.assertTrue(dictInDict(group, rj))
|
self.assertTrue(dictInDict(group, rj))
|
||||||
|
@ -211,7 +211,7 @@ class Ibt2Tests(unittest.TestCase):
|
||||||
def test_delete_group(self):
|
def test_delete_group(self):
|
||||||
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
|
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
|
||||||
s = self.login('admin', 'ibt2')
|
s = self.login('admin', 'ibt2')
|
||||||
r = s.delete(BASE_URL + 'groups', params={'day': '2017-01-16', 'group': 'A group'})
|
r = s.delete(BASE_URL + 'days/2017-01-16/groups/A group', params={'day': '2017-01-16', 'group': 'A group'})
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
rj = r.json()
|
rj = r.json()
|
||||||
r = requests.get(BASE_URL + 'days/2017-01-16')
|
r = requests.get(BASE_URL + 'days/2017-01-16')
|
||||||
|
|
Loading…
Reference in a new issue