fix #151: introduce generic trigger for CRUD operations

This commit is contained in:
Davide Alberani 2016-07-30 19:39:58 +02:00
parent bb4af3b3a4
commit 3ce3cf08c8
3 changed files with 33 additions and 5 deletions

View file

@ -239,6 +239,9 @@ class EventManDB(object):
:type _id_or_query: str or :class:`~bson.objectid.ObjectId` or dict
:param force: force the deletion of all documents, when `_id_or_query` is empty
:type force: bool
:returns: how many documents were removed
:rtype: int
"""
if not _id_or_query and not force:
return
@ -246,5 +249,5 @@ class EventManDB(object):
if not isinstance(_id_or_query, dict):
_id_or_query = {'_id': _id_or_query}
_id_or_query = convert(_id_or_query)
db[collection].remove(_id_or_query)
return db[collection].remove(_id_or_query)

View file

@ -90,7 +90,12 @@ Sometimes we have to execute one or more scripts in reaction to an action.
In the **data/triggers** we have a series of directories; scripts inside of them will be executed when the related action was performed on the GUI or calling the controller.
Available triggers:
In the data/trigger directory you can create a directory named with this schema: *crudAction_document[_resource]*, where crudAction is one in "create", "update", "delete" (there're no triggers for "read"). So, for example you can create scripts in directories named:
- create\_user
- delete\_event
- update\_event\_tickets
We also have some special triggers, which will contain more information (for example: both the old and the new ticket, updating one):
- **update\_ticket\_in\_event**: executed every time a ticket in a given event is updated.
- **attends**: executed only when a person is marked as attending an event.

View file

@ -416,6 +416,9 @@ class CollectionHandler(BaseHandler):
now = datetime.datetime.now()
user_info = self.current_user_info
user_id = user_info.get('_id')
env = {}
if id_ is not None:
env['%s_ID' % self.document.upper()] = id_
if crud_method == 'create':
data['created_by'] = user_id
data['created_at'] = now
@ -431,6 +434,11 @@ class CollectionHandler(BaseHandler):
data = self.apply_filter(data, 'input_%s_%s' % (method, resource))
output = handler(id_, resource_id, data, **kwargs)
output = self.apply_filter(output, 'get_%s' % resource)
env['RESOURCE'] = resource
if resource_id:
env['%s_ID' % resource] = resource_id
self.run_triggers('%s_%s_%s' % ('create' if resource_id is None else 'update', self.document, resource),
stdin_data=output, env=env)
self.write(output)
return
return self.build_error(status=404, message='unable to access resource: %s' % resource)
@ -441,6 +449,7 @@ class CollectionHandler(BaseHandler):
data = self.apply_filter(data, 'input_%s' % method)
merged, newData = self.db.update(self.collection, id_, data)
newData = self.apply_filter(newData, method)
self.run_triggers('update_%s' % self.document, stdin_data=newData, env=env)
else:
permission = '%s|%s' % (self.collection, crud_method)
if not self.has_permission(permission):
@ -448,6 +457,7 @@ class CollectionHandler(BaseHandler):
data = self.apply_filter(data, 'input_%s_all' % method)
newData = self.db.add(self.collection, data, _id=self.gen_id())
newData = self.apply_filter(newData, '%s_all' % method)
self.run_triggers('create_%s' % self.document, stdin_data=newData, env=env)
self.write(newData)
# PUT (update an existing document) is handled by the POST (create a new document) method;
@ -457,6 +467,9 @@ class CollectionHandler(BaseHandler):
@gen.coroutine
@authenticated
def delete(self, id_=None, resource=None, resource_id=None, **kwargs):
env = {}
if id_ is not None:
env['%s_ID' % self.document.upper()] = id_
if resource:
# Handle access to sub-resources.
permission = '%s:%s%s|delete' % (self.document, resource, '-all' if resource_id is None else '')
@ -464,14 +477,21 @@ class CollectionHandler(BaseHandler):
return self.build_error(status=401, message='insufficient permissions: %s' % permission)
method = getattr(self, 'handle_delete_%s' % resource, None)
if method and callable(method):
self.write(method(id_, resource_id, **kwargs))
output = method(id_, resource_id, **kwargs)
env['RESOURCE'] = resource
if resource_id:
env['%s_ID' % resource] = resource_id
self.run_triggers('delete_%s_%s' % (self.document, resource), stdin_data=env, env=env)
self.write(output)
return
return self.build_error(status=404, message='unable to access resource: %s' % resource)
if id_:
if id_ is not None:
permission = '%s|delete' % self.document
if not self.has_permission(permission):
return self.build_error(status=401, message='insufficient permissions: %s' % permission)
self.db.delete(self.collection, id_)
howMany = self.db.delete(self.collection, id_)
env['DELETED_ITEMS'] = howMany
self.run_triggers('delete_%s' % self.document, stdin_data=env, env=env)
else:
self.write({'success': False})
self.write({'success': True})