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/:id GET - a single entry
|
||||
- /attendees/:id PUT - update an entry
|
||||
- /attendees/:id DELETE - delete an entry
|
||||
- /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/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 POST - create a new user
|
||||
- /users/:id GET - a single user
|
||||
|
|
70
ibt2.py
70
ibt2.py
|
@ -261,8 +261,7 @@ class AttendeesHandler(BaseHandler):
|
|||
@gen.coroutine
|
||||
def delete(self, id_=None, **kwargs):
|
||||
if id_ is None:
|
||||
self.write({'success': False})
|
||||
return
|
||||
return self.build_error(status=404, message='unable to access the resource')
|
||||
doc = self.db.getOne(self.collection, {'_id': id_}) or {}
|
||||
if not doc:
|
||||
return self.build_error(status=404, message='unable to access the resource')
|
||||
|
@ -274,7 +273,6 @@ class AttendeesHandler(BaseHandler):
|
|||
|
||||
class DaysHandler(BaseHandler):
|
||||
"""Handle requests for Days."""
|
||||
|
||||
def _summarize(self, days):
|
||||
res = []
|
||||
for day in days:
|
||||
|
@ -342,12 +340,15 @@ class DaysHandler(BaseHandler):
|
|||
else:
|
||||
self.write(base)
|
||||
|
||||
|
||||
class DaysInfoHandler(BaseHandler):
|
||||
"""Handle requests for Days info."""
|
||||
@gen.coroutine
|
||||
def put(self, **kwargs):
|
||||
data = self.clean_body
|
||||
day = (data.get('day') or '').strip()
|
||||
def put(self, day='', **kwargs):
|
||||
day = day.strip()
|
||||
if not day:
|
||||
return self.build_error(status=404, message='unable to access the resource')
|
||||
data = self.clean_body
|
||||
data['day'] = day
|
||||
self.add_access_info(data)
|
||||
merged, doc = self.db.update('days', {'day': day}, data)
|
||||
|
@ -357,23 +358,26 @@ class DaysHandler(BaseHandler):
|
|||
class GroupsHandler(BaseHandler):
|
||||
"""Handle requests for Groups."""
|
||||
@gen.coroutine
|
||||
def put(self, **kwargs):
|
||||
data = self.clean_body
|
||||
day = (data.get('day') or '').strip()
|
||||
group = (data.get('group') or '').strip()
|
||||
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['day'] = day
|
||||
data['group'] = group
|
||||
self.add_access_info(data)
|
||||
merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
|
||||
self.write(doc)
|
||||
data = self.clean_body
|
||||
newName = (data.get('newName') or '').strip()
|
||||
if newName:
|
||||
query = {'day': day, 'group': group}
|
||||
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
|
||||
def delete(self, **kwargs):
|
||||
data = self.clean_arguments
|
||||
day = (data.get('day') or '').strip()
|
||||
group = (data.get('group') or '').strip()
|
||||
def delete(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')
|
||||
if not self.current_user_info.get('isAdmin'):
|
||||
|
@ -385,6 +389,22 @@ class GroupsHandler(BaseHandler):
|
|||
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):
|
||||
"""Handle requests for Users."""
|
||||
document = 'user'
|
||||
|
@ -574,17 +594,23 @@ def run():
|
|||
{'setting': 'server_cookie_secret', 'cookie_secret': cookie_secret})
|
||||
|
||||
_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_-]+)?"
|
||||
_current_user_path = r"/users/current/?"
|
||||
_users_path = r"/users/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
||||
application = tornado.web.Application([
|
||||
(_attendees_path, AttendeesHandler, init_params),
|
||||
(r'/v%s%s' % (API_VERSION, _attendees_path), AttendeesHandler, init_params),
|
||||
(_days_path, DaysHandler, init_params),
|
||||
(r'/v%s%s' % (API_VERSION, _groups_path), GroupsHandler, init_params),
|
||||
(_groups_info_path, GroupsInfoHandler, init_params),
|
||||
(r'/v%s%s' % (API_VERSION, _groups_info_path), GroupsInfoHandler, 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),
|
||||
(_days_info_path, DaysInfoHandler, init_params),
|
||||
(r'/v%s%s' % (API_VERSION, _days_info_path), DaysInfoHandler, init_params),
|
||||
(_current_user_path, CurrentUserHandler, init_params),
|
||||
(r'/v%s%s' % (API_VERSION, _current_user_path), CurrentUserHandler, 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 {}
|
||||
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):
|
||||
"""Remove one or more documents from a collection.
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ export default {
|
|||
|
||||
beforeCreate: function() {
|
||||
this.daysUrl = this.$resource('days{/day}');
|
||||
this.daysInfoUrl = this.$resource('days{/day}/info');
|
||||
},
|
||||
|
||||
mounted: function() {
|
||||
|
@ -184,7 +185,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
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();
|
||||
}, (response) => {
|
||||
this.$refs.dialogObj.show({text: 'unable to edit day notes'});
|
||||
|
|
|
@ -187,7 +187,7 @@ class Ibt2Tests(unittest.TestCase):
|
|||
def test_put_day(self):
|
||||
day = {'day': '2017-01-16', 'notes': 'A day note'}
|
||||
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()
|
||||
rj = r.json()
|
||||
self.assertTrue(dictInDict(day, rj))
|
||||
|
@ -199,7 +199,7 @@ class Ibt2Tests(unittest.TestCase):
|
|||
def test_put_group(self):
|
||||
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'}
|
||||
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()
|
||||
rj = r.json()
|
||||
self.assertTrue(dictInDict(group, rj))
|
||||
|
@ -211,7 +211,7 @@ class Ibt2Tests(unittest.TestCase):
|
|||
def test_delete_group(self):
|
||||
self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
|
||||
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()
|
||||
rj = r.json()
|
||||
r = requests.get(BASE_URL + 'days/2017-01-16')
|
||||
|
|
Loading…
Reference in a new issue