def test_task_server(self): # Create some stats t_now = datetime.utcnow() dm.save_object(SystemStats( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, t_now - timedelta(minutes=5), t_now )) # We should now have stats sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertGreater(len(sys_stats), 0) # Check current task list entries tasks = dm.list_objects(Task, order_field=Task.id) task_list_len = len(tasks) # Post a background task to purge the stats KEEP_SECS = 10 task_obj = tm.add_task( None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS ) self.assertIsNotNone(task_obj) # Check it really got added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len + 1) task_list_len = len(tasks) # Post it again, make sure there is no dupe added dupe_task_obj = tm.add_task( None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS ) self.assertIsNone(dupe_task_obj) # Check it really didn't get re-added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len) task = tasks[-1] self.assertEqual(task.id, task_obj.id) # Wait for task completion tm.wait_for_task(task_obj.id, 20) # We should now have no stats t_now = datetime.utcnow() sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertEqual(len(sys_stats), 0) # The completed task should only be removed after the delay we specified task = dm.get_object(Task, task_obj.id) self.assertIsNotNone(task) self.assertEqual(task.status, Task.STATUS_COMPLETE) # Wait for keep time + task server's poll time time.sleep(KEEP_SECS + 10) # Should now be gone task = dm.get_object(Task, task_obj.id) self.assertIsNone(task)
def test_task_server(self): # Create some stats t_now = datetime.utcnow() dm.save_object( SystemStats(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, t_now - timedelta(minutes=5), t_now)) # We should now have stats sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertGreater(len(sys_stats), 0) # Check current task list entries tasks = dm.list_objects(Task, order_field=Task.id) task_list_len = len(tasks) # Post a background task to purge the stats KEEP_SECS = 10 task_obj = tm.add_task(None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS) self.assertIsNotNone(task_obj) # Check it really got added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len + 1) task_list_len = len(tasks) # Post it again, make sure there is no dupe added dupe_task_obj = tm.add_task(None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS) self.assertIsNone(dupe_task_obj) # Check it really didn't get re-added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len) task = tasks[-1] self.assertEqual(task.id, task_obj.id) # Wait for task completion tm.wait_for_task(task_obj.id, 10) # We should now have no stats t_now = datetime.utcnow() sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertEqual(len(sys_stats), 0) # The completed task should only be removed after the delay we specified task = dm.get_object(Task, task_obj.id) self.assertIsNotNone(task) self.assertEqual(task.status, Task.STATUS_COMPLETE) # Wait for keep time + task server's poll time time.sleep(KEEP_SECS + 10) # Should now be gone task = dm.get_object(Task, task_obj.id) self.assertIsNone(task)
def delete(self, folio_id, export_id): db_session = data_engine.db_get_session() try: # Get the portfolio folio = data_engine.get_portfolio(folio_id, _db_session=db_session) if folio is None: raise DoesNotExistError(str(folio_id)) # Check permissions permissions_engine.ensure_portfolio_permitted( folio, FolioPermission.ACCESS_EDIT, get_session_user()) # Get the single portfolio-export folio_export = data_engine.get_object(FolioExport, export_id, _db_session=db_session) if folio_export is None: raise DoesNotExistError(str(export_id)) if folio_export.folio_id != folio_id: raise ParameterError( 'export ID %d does not belong to portfolio ID %d' % (export_id, folio_id)) # Delete it and the export files delete_portfolio_export(folio_export, get_session_user(), 'Deleted: ' + folio_export.describe(True), _db_session=db_session) return make_api_success_response() finally: db_session.close()
def get(self, folio_id, export_id=None): # Get the 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_VIEW, get_session_user()) if export_id is None: # List portfolio exports exports_list = [ _prep_folioexport_object(folio, fe) for fe in folio.downloads ] return make_api_success_response( object_to_dict_list(exports_list, _omit_fields)) else: # Get a single portfolio-export folio_export = data_engine.get_object(FolioExport, export_id) if folio_export is None: raise DoesNotExistError(str(export_id)) if folio_export.folio_id != folio_id: raise ParameterError( 'export ID %d does not belong to portfolio ID %d' % (export_id, folio_id)) return make_api_success_response( object_to_dict(_prep_folioexport_object(folio, folio_export), _omit_fields))
def delete(self, permission_id): db_session = data_engine.db_get_session() db_commit = False try: fp = data_engine.get_object(FolderPermission, permission_id, _db_session=db_session) if fp is None: raise DoesNotExistError(str(permission_id)) try: data_engine.delete_folder_permission(fp, _db_session=db_session, _commit=False) except ValueError as e: raise ParameterError(str(e)) db_commit = True return make_api_success_response() finally: if db_commit: db_session.commit() permissions_engine.reset_folder_permissions() else: db_session.rollback() db_session.close()
def delete(self, permission_id): db_session = data_engine.db_get_session() db_commit = False try: fp = data_engine.get_object( FolderPermission, permission_id, _db_session=db_session ) if fp is None: raise DoesNotExistError(str(permission_id)) try: data_engine.delete_folder_permission( fp, _db_session=db_session, _commit=False ) except ValueError as e: raise ParameterError(str(e)) db_commit = True return make_api_success_response() finally: if db_commit: db_session.commit() permissions_engine.reset() else: db_session.rollback() db_session.close()
def template_list(): db_default_template = data_engine.get_object(Property, Property.DEFAULT_TEMPLATE) return render_template('admin_template_list.html', templates=data_engine.list_objects( ImageTemplate, order_field=ImageTemplate.name), system_template_key=db_default_template.key, system_template_value=db_default_template.value)
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 put(self, permission_id): params = self._get_validated_object_parameters(request.form) fp = data_engine.get_object(FolderPermission, permission_id) if fp is None: raise DoesNotExistError(str(permission_id)) fp.access = params['access'] data_engine.save_object(fp) permissions_engine.reset_folder_permissions() return make_api_success_response(object_to_dict(fp))
def put(self, permission_id): params = self._get_validated_object_parameters(request.form) fp = data_engine.get_object(FolderPermission, permission_id) if fp is None: raise DoesNotExistError(str(permission_id)) fp.access = params['access'] data_engine.save_object(fp) permissions_engine.reset() return make_api_success_response(object_to_dict(fp))
def put(self, property_id): params = self._get_validated_object_parameters(request.form) db_prop = data_engine.get_object(Property, property_id) if db_prop is None: raise DoesNotExistError(str(property_id)) db_prop.value = params['value'] data_engine.save_object(db_prop) if property_id == Property.DEFAULT_TEMPLATE: image_engine.reset_templates() return make_api_success_response(object_to_dict(db_prop))
def get(self, permission_id=None): if permission_id is None: # List all permissions fp_list = data_engine.list_objects(FolderPermission) return make_api_success_response(object_to_dict_list(fp_list)) else: # Get permission entry fp = data_engine.get_object(FolderPermission, permission_id) if fp is None: raise DoesNotExistError(str(permission_id)) return make_api_success_response(object_to_dict(fp))
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 get(self, property_id): db_prop = data_engine.get_object(Property, property_id) if db_prop is None: raise DoesNotExistError(str(property_id)) return make_api_success_response(object_to_dict(db_prop))