diff --git a/api/api.py b/api/api.py index 19ae8c42520722ad665bb6bbfd84eb5aa625dcc9..3852f3cb7a4540f6256c08f2733cd3efcc29ba06 100644 --- a/api/api.py +++ b/api/api.py @@ -248,11 +248,11 @@ endpoints = [ route('/<list_name:files>/<name:{fname}>', FileListHandler, m=['GET', 'DELETE']), route('/<list_name:files>/<name:{fname}>/info', FileListHandler, h='get_info', m=['GET']), - route( '/analyses', AnalysesHandler, m=['POST']), + route( '/analyses', AnalysesHandler, m=['POST']), prefix('/analyses', [ - route('/<_id:{cid}>', AnalysesHandler, m=['GET', 'DELETE']), - route('/<_id:{cid}>/files', AnalysesHandler, h='download', m=['GET']), - route('/<_id:{cid}>/files/<name:{fname}>', AnalysesHandler, h='download', m=['GET']), + route('/<_id:{cid}>', AnalysesHandler, m=['GET', 'DELETE']), + route('/<_id:{cid}>/files', AnalysesHandler, h='download', m=['GET']), + route('/<_id:{cid}>/files/<filename:{fname}>', AnalysesHandler, h='download', m=['GET']), ]), route('/<list_name:notes>', NotesListHandler, m=['POST']), diff --git a/api/dao/containerstorage.py b/api/dao/containerstorage.py index 0fd27d88dafd300d0ff5555665e330019f78de5f..e58c15780462a5c328f88eca0f1c41a27ecab797 100644 --- a/api/dao/containerstorage.py +++ b/api/dao/containerstorage.py @@ -447,6 +447,16 @@ class AnalysisStorage(ContainerStorage): return parent_storage.get_container(parent_id) + def get_analyses(self, parent_type, parent_id, inflate_job_info=False): + parent_type = containerutil.singularize(parent_type) + parent_id = bson.objectid.ObjectId(parent_id) + analyses = self.get_all_el({'parent.type': parent_type, 'parent.id': parent_id}, None, None) + if inflate_job_info: + for analysis in analyses: + self.inflate_job_info(analysis) + return analyses + + def get_fileinfo(self, _id, filename=None): analysis = self.get_container(_id) files = analysis.get('files') diff --git a/api/dao/containerutil.py b/api/dao/containerutil.py index a875f7c1db6fc2acf95854ddaa4763a50eec7952..58f72a732abffc5ede0007215d0727a42c21cd80 100644 --- a/api/dao/containerutil.py +++ b/api/dao/containerutil.py @@ -9,6 +9,7 @@ SINGULAR_TO_PLURAL = { 'project': 'projects', 'session': 'sessions', 'acquisition': 'acquisitions', + 'collection': 'collections', 'analysis': 'analyses', } PLURAL_TO_SINGULAR = {p: s for s, p in SINGULAR_TO_PLURAL.iteritems()} diff --git a/api/handlers/containerhandler.py b/api/handlers/containerhandler.py index 475214937489faaf5a45e23451e27758614f5a93..1e813c7ad5e1f82d394a6fae4f2a4a29778956b2 100644 --- a/api/handlers/containerhandler.py +++ b/api/handlers/containerhandler.py @@ -110,8 +110,8 @@ class ContainerHandler(base.RequestHandler): for fileinfo in result['files']: fileinfo['path'] = util.path_from_hash(fileinfo['hash']) - if cont_name == 'sessions': - result = self.handle_analyses(result) + inflate_job_info = cont_name == 'sessions' + result['analyses'] = AnalysisStorage().get_analyses(cont_name, _id, inflate_job_info) return self.handle_origin(result) def handle_origin(self, result): @@ -203,14 +203,6 @@ class ContainerHandler(base.RequestHandler): return results - def handle_analyses(self, result): - """ - Given an object with an `analyses` array key, inflate job info for job-based analyses - """ - for analysis in result.get('analyses', []): - AnalysisStorage.inflate_job_info(analysis) - return result - def _filter_permissions(self, result, uid, site): """ if the user is not admin only her permissions are returned. @@ -240,7 +232,7 @@ class ContainerHandler(base.RequestHandler): permchecker(noop)('GET', cid) - analyses = config.db.analyses.find({'parent.type': 'session', 'parent.id': cont['_id']}).sort('created', -1) + analyses = list(config.db.analyses.find({'parent.type': 'session', 'parent.id': cont['_id']}).sort('created', -1)) acquisitions = cont.get('acquisitions', []) results = [] @@ -343,8 +335,6 @@ class ContainerHandler(base.RequestHandler): modified_results = [] for result in results: - if cont_name == 'sessions': - result = self.handle_analyses(result) if self.is_true('stats'): result = containerutil.get_stats(result, cont_name) result = self.handle_origin(result) diff --git a/api/handlers/refererhandler.py b/api/handlers/refererhandler.py index e00bdeb501533af8aafed9f2bc98f003f251e2af..8174b53fac0b67c8d98449c158059eb52593cdcd 100644 --- a/api/handlers/refererhandler.py +++ b/api/handlers/refererhandler.py @@ -102,7 +102,7 @@ class AnalysesHandler(RefererHandler): parent = self.storage.get_parent(cont_name, cid) permchecker = self.get_permchecker(parent) permchecker(noop)('GET') - return self._get_container(_id) + return self.storage.get_container(_id) @log_access(AccessType.delete_analysis) @@ -122,7 +122,7 @@ class AnalysesHandler(RefererHandler): self.abort(404, 'Analysis {} not removed from container {} {}'.format(_id, cont_name, cid)) - def download(self, cont_name, cid, _id, fname=None): + def download(self, cont_name, cid, _id, filename=None): """ .. http:get:: /api/(cont_name)/(cid)/analyses/(analysis_id)/files/(file_name) @@ -225,46 +225,46 @@ class AnalysesHandler(RefererHandler): if ticket_id is None: permchecker(noop)('GET') elif ticket_id != '': - ticket = self._check_ticket(ticket_id, cid, fname) + ticket = self._check_ticket(ticket_id, cid, filename) if not self.origin.get('id'): self.origin = ticket.get('origin') - fileinfo = self.storage.get_fileinfo(_id, fname) + fileinfo = self.storage.get_fileinfo(_id, filename) if fileinfo is None: error_msg = 'No files on analysis {}'.format(_id) - if fname: - error_msg = 'Could not find file {} on analysis {}'.format(fname, _id) + if filename: + error_msg = 'Could not find file {} on analysis {}'.format(filename, _id) self.abort(404, error_msg) if ticket_id == '': - if fname: + if filename: total_size = fileinfo[0]['size'] file_cnt = 1 - ticket = util.download_ticket(self.request.client_addr, 'file', cid, fname, total_size, origin=self.origin) + ticket = util.download_ticket(self.request.client_addr, 'file', cid, filename, total_size, origin=self.origin) else: targets, total_size, file_cnt = self._prepare_batch(fileinfo) label = util.sanitize_string_to_filename(self.storage.get_container(_id).get('label', 'No Label')) - fname = 'analysis_' + label + '.tar' - ticket = util.download_ticket(self.request.client_addr, 'batch', targets, fname, total_size, origin=self.origin) + filename = 'analysis_' + label + '.tar' + ticket = util.download_ticket(self.request.client_addr, 'batch', targets, filename, total_size, origin=self.origin) return { 'ticket': config.db.downloads.insert_one(ticket).inserted_id, 'size': total_size, 'file_cnt': file_cnt, - 'filename': fname + 'filename': filename } else: - if not fname: + if not filename: if ticket: self._send_batch(ticket) else: self.abort(400, 'batch downloads require a ticket') elif not fileinfo: - self.abort(404, "{} doesn't exist".format(fname)) + self.abort(404, "{} doesn't exist".format(filename)) else: fileinfo = fileinfo[0] filepath = os.path.join( config.get_item('persistent', 'data_path'), util.path_from_hash(fileinfo['hash']) ) - fname = fileinfo['name'] + filename = fileinfo['name'] # Request for info about zipfile if self.is_true('info'): @@ -301,7 +301,7 @@ class AnalysesHandler(RefererHandler): self.response.headers['Content-Type'] = str(fileinfo.get('mimetype', 'application/octet-stream')) else: self.response.headers['Content-Type'] = 'application/octet-stream' - self.response.headers['Content-Disposition'] = 'attachment; filename=' + str(fname) + self.response.headers['Content-Disposition'] = 'attachment; filename=' + str(filename) # log download if we haven't already for this ticket if ticket: