def _task_response(self, task, timeout_secs): task_completed = False try: # Wait for task to complete task = task_engine.wait_for_task(task.id, timeout_secs) if task is None: # Someone else deleted it? Shouldn't normally get here. raise TimeoutError() task_completed = True # Return the updated folder (or raise the exception) if isinstance(task.result, Exception): raise task.result return make_api_success_response(object_to_dict(task.result)) except TimeoutError: # Return a 202 "task ongoing" response task_dict = object_to_dict(task) if task is not None else None # Decode the params before returning if task_dict and task_dict.get('params'): task_dict['params'] = pickle.loads(task_dict['params']) return make_api_success_response(task_dict, task_accepted=True) finally: if task and task_completed: try: # Delete the task so another API call can be made immediately data_engine.delete_object(task) except Exception: pass
def delete(self, folio_id, image_id): db_session = data_engine.db_get_session() try: folio_image = data_engine.get_portfolio_image( AttrObject(id=folio_id), AttrObject(id=image_id), _db_session=db_session) if folio_image is None: raise DoesNotExistError(str(folio_id) + '/' + str(image_id)) # Check permissions permissions_engine.ensure_portfolio_permitted( folio_image.portfolio, FolioPermission.ACCESS_EDIT, get_session_user()) # Add history first so that we only commit once at the end folio = folio_image.portfolio data_engine.add_portfolio_history(folio, get_session_user(), FolioHistory.ACTION_IMAGE_CHANGE, '%s removed' % folio_image.image.src, _db_session=db_session, _commit=False) # Flag that exported zips will be out of date folio.last_updated = datetime.utcnow() # Delete the image from the portfolio and commit changes data_engine.delete_object(folio_image, _db_session=db_session, _commit=True) return make_api_success_response() finally: db_session.close()
def delete_portfolio_export(folio_export, history_user, history_info, _db_session=None): """ Deletes a portfolio export record and the associated zip file (if it exists), and adds an audit trail entry for the parent portfolio. If you supply a database session it will be committed before the zip file is deleted, so that files are only deleted once the database operations are known to have worked. Raises a ServerTooBusyError if the export is still in progress. Raises an OSError if the zip file or directory cannot be deleted. """ db_session = _db_session or data_engine.db_get_session() try: # Ensure we can access folio_export.portfolio if not data_engine.object_in_session(folio_export, db_session): folio_export = data_engine.get_object(FolioExport, folio_export.id, _db_session=db_session) # Check whether the export task is running if folio_export.task_id: task = task_engine.get_task(folio_export.task_id, _db_session=db_session) if (task and task.status == Task.STATUS_ACTIVE) or ( task and task.status == Task.STATUS_PENDING and not task_engine.cancel_task(task)): raise ServerTooBusyError( 'this export is currently in progress, wait a while then try again' ) # Delete and add history in one commit data_engine.add_portfolio_history(folio_export.portfolio, history_user, FolioHistory.ACTION_UNPUBLISHED, history_info, _db_session=db_session, _commit=False) data_engine.delete_object(folio_export, _db_session=db_session, _commit=True) # If we got this far the database delete worked and we now need to # delete the exported zip file zip_rel_path = get_portfolio_export_file_path(folio_export) if folio_export.filename: delete_file(zip_rel_path) # And if the zip directory is now empty, delete the directory too zip_rel_dir = get_portfolio_directory(folio_export.portfolio) if path_exists(zip_rel_dir, require_directory=True): zips_count = count_files(zip_rel_dir, recurse=False) if zips_count[0] == 0: delete_dir(zip_rel_dir) finally: if not _db_session: db_session.close()
def test_task_result_none(self): # Test no return value task_obj = tm.add_task(None, 'Test return values', 'test_result_task', { 'raise_exception': False, 'return_value': None }, Task.PRIORITY_NORMAL, 'info', 'error', 5) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 10) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsNone(task_obj.result) dm.delete_object(task_obj)
def test_task_result_object(self): # Test normal return value task_obj = tm.add_task( None, 'Test return values', 'test_result_task', {'raise_exception': False, 'return_value': {'my_bool': True}}, Task.PRIORITY_NORMAL, 'info', 'error', 5 ) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 20) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertEqual(task_obj.result, {'my_bool': True}) dm.delete_object(task_obj)
def test_task_result_exception(self): # Test exception raised task_obj = tm.add_task( None, 'Test return values', 'test_result_task', {'raise_exception': True, 'return_value': None}, Task.PRIORITY_NORMAL, 'info', 'error', 5 ) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 20) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsInstance(task_obj.result, ValueError) self.assertEqual(repr(task_obj.result), repr(ValueError('An error happened'))) dm.delete_object(task_obj)
def delete(self, template_id): permissions_engine.ensure_permitted( SystemPermissions.PERMIT_SUPER_USER, get_session_user()) template_info = data_engine.get_image_template(template_id) if template_info is None: raise DoesNotExistError(str(template_id)) db_default_template = data_engine.get_object(Property, Property.DEFAULT_TEMPLATE) if template_info.name.lower() == db_default_template.value.lower(): raise ParameterError( 'The system default template cannot be deleted') data_engine.delete_object(template_info) image_engine.reset_templates() return make_api_success_response()
def test_task_result_exception(self): # Test exception raised task_obj = tm.add_task(None, 'Test return values', 'test_result_task', { 'raise_exception': True, 'return_value': None }, Task.PRIORITY_NORMAL, 'info', 'error', 5) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 10) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsInstance(task_obj.result, ValueError) self.assertEqual(repr(task_obj.result), repr(ValueError('An error happened'))) dm.delete_object(task_obj)
def delete(self, folio_id): # Get portfolio folio = data_engine.get_portfolio(folio_id) if folio is None: raise DoesNotExistError(str(folio_id)) # Check permissions permissions_engine.ensure_portfolio_permitted( folio, FolioPermission.ACCESS_DELETE, get_session_user()) # Double check the downloads were eager-loaded before we try to use them below if not data_engine.attr_is_loaded(folio, 'downloads'): raise ValueError('bug: folio.downloads should be present') # Delete - cascades to folio images, permissions, history, and exports data_engine.delete_object(folio) # If we got this far the database delete worked and we now need to # delete the exported zip files (if any) delete_dir(get_portfolio_directory(folio), recursive=True) return make_api_success_response()