From fe2ec65900c1b7f4b394d56170e7b02a381bc5b5 Mon Sep 17 00:00:00 2001 From: nagem <meganhenning@flywheel.io> Date: Sun, 10 Apr 2016 19:38:14 -0500 Subject: [PATCH] Propagate group tag changes down heirarchy --- api/api.py | 10 ++++---- api/handlers/listhandler.py | 51 +++++++++++++++++++++++++++++++++++++ api/schemas/input/tag.json | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/api/api.py b/api/api.py index 097315e9..882669a3 100644 --- a/api/api.py +++ b/api/api.py @@ -61,7 +61,7 @@ routing_regexes = { # tag regex # length between 3 and 24 characters # any character allowed except '/'' - 'tag_re': '[^/]{3,24}', + 'tag_re': '[^/]{1,32}', # filename regex # any character allowed except '/' 'filename_re': '[^/]+', @@ -127,11 +127,11 @@ routes = [ webapp2.Route(_format(r'/api/<cont_name:groups>/<cid:{group_id_re}>/<list_name:roles>/<site:{site_id_re}>/<_id:{user_id_re}>'), listhandler.ListHandler, name='group_roles', methods=['GET', 'PUT', 'DELETE']), - webapp2.Route(_format(r'/api/<cont_name:groups>/<cid:{group_id_re}>/<list_name:tags>'), listhandler.ListHandler, methods=['POST'], name='tags_post'), - webapp2.Route(_format(r'/api/<cont_name:groups>/<cid:{group_id_re}>/<list_name:tags>/<value:{tag_re}>'), listhandler.ListHandler, name='tags'), + webapp2.Route(_format(r'/api/<cont_name:groups>/<cid:{group_id_re}>/<list_name:tags>'), listhandler.TagsListHandler, methods=['POST'], name='tags_post'), + webapp2.Route(_format(r'/api/<cont_name:groups>/<cid:{group_id_re}>/<list_name:tags>/<value:{tag_re}>'), listhandler.TagsListHandler, name='tags'), - webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/<list_name:tags>'), listhandler.ListHandler, methods=['POST'], name='tags_post'), - webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/<list_name:tags>/<value:{tag_re}>'), listhandler.ListHandler, name='tags'), + webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/<list_name:tags>'), listhandler.TagsListHandler, methods=['POST'], name='tags_post'), + webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/<list_name:tags>/<value:{tag_re}>'), listhandler.TagsListHandler, name='tags'), webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/packfile'), listhandler.FileListHandler, name='packfile', handler_method='packfile', methods=['POST']), webapp2.Route(_format(r'/api/<cont_name:{cont_name_re}>/<cid:{cid_re}>/<list_name:files>'), listhandler.FileListHandler, name='files_post', methods=['POST']), diff --git a/api/handlers/listhandler.py b/api/handlers/listhandler.py index ac119a2e..2c646d54 100644 --- a/api/handlers/listhandler.py +++ b/api/handlers/listhandler.py @@ -212,6 +212,7 @@ class PermissionsListHandler(ListHandler): def put(self, cont_name, list_name, **kwargs): _id = kwargs.get('cid') + result = super(PermissionsListHandler, self).put(cont_name, list_name, **kwargs) if cont_name == 'projects': self._propagate_project_permissions(_id) @@ -282,6 +283,56 @@ class NotesListHandler(ListHandler): return {'modified':result.modified_count} +class TagsListHandler(ListHandler): + """ + TagsListHandler overrides put, delete methods of ListHandler to propagate changes to group tags + If a tag is renamed or deleted at the group level, project, session and acquisition tags will also be renamed/deleted + """ + + def put(self, cont_name, list_name, **kwargs): + _id = kwargs.get('cid') + result = super(TagsListHandler, self).put(cont_name, list_name, **kwargs) + if cont_name == 'groups': + payload = self.request.json_body + current_value = kwargs.get('value') + new_value = payload.get('value') + query = {'$and':[{'tags': current_value}, {'tags': {'$ne': new_value}}]} + update = {'$set': {'tags.$': new_value}} + self._propagate_group_tags(_id, query, update) + return result + + def delete(self, cont_name, list_name, **kwargs): + _id = kwargs.get('cid') + result = super(TagsListHandler, self).delete(cont_name, list_name, **kwargs) + if cont_name == 'groups': + payload = self.request.json_body + deleted_tag = payload.get('value') + query = {} + update = {'$pull': {'tags': deleted_tag}} + self._propagate_group_tags(_id, query, update) + + def _propagate_group_tags(self, _id, query, update): + """ + method to propagate tag changes from a group to its projects, sessions and acquisitions + """ + try: + project_ids = [p['_id'] for p in config.db.projects.find({'group': _id}, [])] + session_ids = [s['_id'] for s in config.db.sessions.find({'project': {'$in': project_ids}}, [])] + + project_q = query.copy() + project_q['_id'] = {'$in': project_ids} + session_q = query.copy() + session_q['_id'] = {'$in': session_ids} + acquisition_q = query.copy() + acquisition_q['session'] = {'$in': session_ids} + + config.db.projects.update_many(project_q, update) + config.db.sessions.update_many(session_q, update) + config.db.acquisitions.update_many(acquisition_q, update) + except: + log.debug(e) + self.abort(500, 'tag change not propagated down heirarchy from group {}'.format(_id)) + class FileListHandler(ListHandler): """ diff --git a/api/schemas/input/tag.json b/api/schemas/input/tag.json index 1475459e..5621558e 100644 --- a/api/schemas/input/tag.json +++ b/api/schemas/input/tag.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "value": {"type": "string"} + "value": {"type": "string", "minLength": 1, "maxLength": 32} }, "required": ["value"], "additionalProperties": false -- GitLab