Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 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()
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
 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)
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 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()
Exemplo n.º 8
0
 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)
Exemplo n.º 9
0
 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()