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 post(self): # Require folios or admin_folios permission to create a portfolio permissions_engine.ensure_permitted(SystemPermissions.PERMIT_FOLIOS, get_session_user()) db_session = data_engine.db_get_session() try: params = self._get_validated_object_parameters(request.form) folio = Folio(params['human_id'] or Folio.create_human_id(), params['name'], params['description'], get_session_user()) self._set_permissions(folio, params, db_session) data_engine.create_portfolio( folio, get_session_user(), _db_session=db_session, _commit=True # fail here if human_id not unique ) # Return a clean object the same as for get(id) folio = data_engine.get_portfolio(folio.id, load_images=True, load_history=True) folio = _prep_folio_object(folio) return make_api_success_response( object_to_dict(folio, _omit_fields)) finally: db_session.close()
def trace_permissions(): embed = request.args.get('embed', '') user_id = request.args.get('user', '') folder_path = request.args.get('path', '') if folder_path == '': folder_path = os.path.sep folder = None user = None users = [] user_has_admin = False trace = None err_msg = None db_session = data_engine.db_get_session() try: # Get folder and selected user info # User can be None for an anonymous user user_id = parse_int(user_id) if user_id != 0: user = data_engine.get_user(user_id, _db_session=db_session) if user is None: raise DoesNotExistError('This user no longer exists') folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session) if folder is None or folder.status == Folder.STATUS_DELETED: raise DoesNotExistError('This folder no longer exists') # Get users list users = data_engine.list_users(status=User.STATUS_ACTIVE, order_field=User.username, _db_session=db_session) # Get the folder+user traced permissions trace = permissions_engine._trace_folder_permissions(folder, user) # Flag on the UI if the user has admin for gdict in trace['groups']: gperms = gdict['group'].permissions if gperms.admin_files or gperms.admin_all: user_has_admin = True break except Exception as e: log_security_error(e, request) err_msg = safe_error_str(e) finally: try: return render_template( 'admin_trace_permissions.html', embed=embed, folder=folder, folder_is_root=folder.is_root() if folder else False, user=user, user_list=users, trace=trace, user_has_admin=user_has_admin, err_msg=err_msg, GROUP_ID_PUBLIC=Group.ID_PUBLIC) finally: db_session.close()
def post(self): params = self._get_validated_object_parameters(request.form) db_session = data_engine.db_get_session() db_commit = False try: db_group = data_engine.get_group(params['group_id'], _db_session=db_session) if db_group is None: raise DoesNotExistError(str(params['group_id'])) db_folder = data_engine.get_folder(params['folder_id'], _db_session=db_session) if db_folder is None: raise DoesNotExistError(str(params['folder_id'])) # This commits (needed for refresh to get the new ID) fp = FolderPermission(db_folder, db_group, params['access']) fp = data_engine.save_object(fp, refresh=True, _db_session=db_session, _commit=True) db_commit = True return make_api_success_response(object_to_dict(fp)) finally: try: if db_commit: db_session.commit() permissions_engine.reset_folder_permissions() else: db_session.rollback() finally: db_session.close()
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(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 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 get(self, folio_id, image_id=None): if image_id is None: # List images in the portfolio folio = data_engine.get_portfolio(folio_id, load_images=True) if folio is None: raise DoesNotExistError(str(folio_id)) # Check permissions permissions_engine.ensure_portfolio_permitted( folio, FolioPermission.ACCESS_VIEW, get_session_user()) image_list = [_prep_folioimage_object(fi) for fi in folio.images] return make_api_success_response( object_to_dict_list(image_list, _omit_fields)) else: # Get a single portfolio-image 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_VIEW, get_session_user()) return make_api_success_response( object_to_dict(_prep_folioimage_object(folio_image), _omit_fields + ['portfolio'])) finally: db_session.close()
def post(self): params = self._get_validated_object_parameters(request.form) db_session = data_engine.db_get_session() db_commit = False try: db_group = data_engine.get_group(params['group_id'], _db_session=db_session) if db_group is None: raise DoesNotExistError(str(params['group_id'])) db_folder = data_engine.get_folder(params['folder_id'], _db_session=db_session) if db_folder is None: raise DoesNotExistError(str(params['folder_id'])) # This commits (needed for refresh to get the new ID) fp = FolderPermission(db_folder, db_group, params['access']) fp = data_engine.save_object( fp, refresh=True, _db_session=db_session, _commit=True ) db_commit = True return make_api_success_response(object_to_dict(fp)) finally: try: if db_commit: db_session.commit() permissions_engine.reset() else: db_session.rollback() 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 folder_permissions(): folder_path = request.args.get('path', '') if folder_path == '': folder_path = os.path.sep group_id = request.args.get('group', '') if group_id == '': group_id = Group.ID_PUBLIC group = None folder = None current_perms = None groups = [] err_msg = None db_session = data_engine.db_get_session() try: # Get folder and group info group = data_engine.get_group(group_id, _db_session=db_session) if group is None: raise DoesNotExistError('This group no longer exists') folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session) if folder is None or folder.status == Folder.STATUS_DELETED: raise DoesNotExistError('This folder no longer exists') # Get groups list groups = data_engine.list_objects(Group, Group.name, _db_session=db_session) # Get the current permissions for the folder+group, which can be None. # Note that permissions_manager might fall back to the Public group if # this is None, but to keep the admin manageable we're going to deal # only with folder inheritance, not group inheritance too. current_perms = data_engine.get_nearest_folder_permission( folder, group, _load_nearest_folder=True, _db_session=db_session ) except Exception as e: log_security_error(e, request) err_msg = str(e) finally: try: return render_template( 'admin_folder_permissions.html', group=group, folder=folder, folder_is_root=folder.is_root() if folder else False, current_permissions=current_perms, group_list=groups, err_msg=err_msg, GROUP_ID_PUBLIC=Group.ID_PUBLIC, GROUP_ID_EVERYONE=Group.ID_EVERYONE ) finally: db_session.close()
def folder_permissions(): folder_path = request.args.get('path', '') if folder_path == '': folder_path = os.path.sep group_id = request.args.get('group', '') if group_id == '': group_id = Group.ID_PUBLIC group = None folder = None current_perms = None groups = [] err_msg = None db_session = data_engine.db_get_session() try: # Get folder and group info group = data_engine.get_group(group_id, _db_session=db_session) if group is None: raise DoesNotExistError('This group no longer exists') folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session) if folder is None or folder.status == Folder.STATUS_DELETED: raise DoesNotExistError('This folder no longer exists') # Get groups list groups = data_engine.list_objects(Group, Group.name, _db_session=db_session) # Get the current permissions for the folder+group, which can be None. # Note that permissions_manager might fall back to the Public group if # this is None, but to keep the admin manageable we're going to deal # only with folder inheritance, not group inheritance too. current_perms = data_engine.get_nearest_folder_permission( folder, group, _load_nearest_folder=True, _db_session=db_session) except Exception as e: log_security_error(e, request) err_msg = safe_error_str(e) finally: try: return render_template( 'admin_folder_permissions.html', group=group, folder=folder, folder_is_root=folder.is_root() if folder else False, current_permissions=current_perms, group_list=groups, err_msg=err_msg, GROUP_ID_PUBLIC=Group.ID_PUBLIC, GROUP_ID_EVERYONE=Group.ID_EVERYONE) finally: db_session.close()
def post(self, folio_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 portfolio permissions permissions_engine.ensure_portfolio_permitted( folio, FolioPermission.ACCESS_EDIT, get_session_user()) # Get the image by either ID or src params = self._get_validated_object_parameters(request.form, True) if 'image_id' in params: image = data_engine.get_image(params['image_id'], _db_session=db_session) if image is None: raise DoesNotExistError(str(params['image_id'])) else: image = auto_sync_file(params['image_src'], data_engine, task_engine, anon_history=True, burst_pdf=False, _db_session=db_session) if image is None or image.status == Image.STATUS_DELETED: raise DoesNotExistError(params['image_src']) # Check image permissions permissions_engine.ensure_folder_permitted( image.folder, FolderPermission.ACCESS_VIEW, get_session_user(), False) # Add history first so that we only commit once at the end data_engine.add_portfolio_history(folio, get_session_user(), FolioHistory.ACTION_IMAGE_CHANGE, '%s added' % image.src, _db_session=db_session, _commit=False) # Flag that exported zips are now out of date folio.last_updated = datetime.utcnow() # Add the image and commit changes db_folio_image = data_engine.save_object(FolioImage( folio, image, params['image_parameters'], params['filename'], params['index']), refresh=True, _db_session=db_session, _commit=True) return make_api_success_response( object_to_dict(_prep_folioimage_object(db_folio_image), _omit_fields + ['portfolio'])) finally: db_session.close()
def put(self, folio_id): db_session = data_engine.db_get_session() try: # Get 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()) # Update the object params = self._get_validated_object_parameters(request.form) permissions_changed = self._set_permissions( folio, params, db_session) changes = [] if params['human_id'] != folio.human_id: changes.append('short URL changed') if params['name'] != folio.name: changes.append('name changed') if params['description'] != folio.description: changes.append('description changed') if permissions_changed: changes.append('permissions changed') folio.human_id = params['human_id'] or Folio.create_human_id() folio.name = params['name'] folio.description = params['description'] # Note: folio.last_updated is only for image changes # (to know when to invalidate the exported zips) data_engine.add_portfolio_history(folio, get_session_user(), FolioHistory.ACTION_EDITED, ', '.join(changes).capitalize(), _db_session=db_session, _commit=False) data_engine.save_object( folio, _db_session=db_session, _commit=True # fail here if human_id not unique ) if permissions_changed: permissions_engine.reset_portfolio_permissions() # Return a clean object the same as for get(id) folio = data_engine.get_portfolio(folio.id, load_images=True, load_history=True) folio = _prep_folio_object(folio) return make_api_success_response( object_to_dict(folio, _omit_fields)) finally: db_session.close()
def put(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()) # Update the object with any/all parameters that were passed in params = self._get_validated_object_parameters(request.form, False) changes = [] affects_zips = False if (params['image_parameters'] is not None and params['image_parameters'] != folio_image.parameters): folio_image.parameters = params['image_parameters'] changes.append('image attributes changed') affects_zips = True if (params['filename'] is not None and params['filename'] != folio_image.filename): folio_image.filename = params['filename'] changes.append('filename changed') affects_zips = True if (params['index'] is not None and params['index'] != folio_image.order_num): folio_image.order_num = params['index'] changes.append('set as position %d' % (params['index'] + 1)) if changes: # Flag if exported zips will be out of date if affects_zips: folio_image.portfolio.last_updated = datetime.utcnow() # Add history and commit changes data_engine.add_portfolio_history( folio_image.portfolio, get_session_user(), FolioHistory.ACTION_IMAGE_CHANGE, '%s updated: %s' % (folio_image.image.src, ', '.join(changes)), _db_session=db_session, _commit=True) return make_api_success_response( object_to_dict(_prep_folioimage_object(folio_image), _omit_fields + ['portfolio'])) finally: db_session.close()
def post(self, folio_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()) # Block the export now if it would create an empty zip file if len(folio.images) == 0: raise ParameterError( 'this portfolio is empty and cannot be published') # Create a folio-export record and start the export as a background task params = self._get_validated_object_parameters(request.form) folio_export = FolioExport(folio, params['description'], params['originals'], params['image_parameters'], params['expiry_time']) data_engine.add_portfolio_history(folio, get_session_user(), FolioHistory.ACTION_PUBLISHED, folio_export.describe(True), _db_session=db_session, _commit=False) folio_export = data_engine.save_object(folio_export, refresh=True, _db_session=db_session, _commit=True) export_task = task_engine.add_task( get_session_user(), 'Export portfolio %d / export %d' % (folio.id, folio_export.id), 'export_portfolio', { 'export_id': folio_export.id, 'ignore_errors': False }, Task.PRIORITY_NORMAL, 'info', 'error', 60) # Update and return the folio-export record with the task ID folio_export.task_id = export_task.id data_engine.save_object(folio_export, _db_session=db_session, _commit=True) return make_api_success_response(object_to_dict( _prep_folioexport_object(folio, folio_export), _omit_fields + ['portfolio']), task_accepted=True) finally: db_session.close()
def delete_image_ids(): try: from imageserver.flask_app import cache_engine, data_engine from imageserver import models log('Deleting cached image IDs') dbs = data_engine.db_get_session() try: for src in dbs.query(models.Image.src).all(): cache_key = data_engine._get_id_cache_key(src[0]) cache_engine.raw_delete(cache_key) print '.', finally: dbs.close() log('Done') return RETURN_OK except Exception as e: error(str(e))
def delete_image_ids(): try: from imageserver.flask_app import cache_engine, data_engine from imageserver import models log('Deleting cached image IDs') dbs = data_engine.db_get_session() try: for src in dbs.query(models.Image.src).all(): cache_key = data_engine._get_id_cache_key(src[0]) cache_engine.raw_delete(cache_key) print('.', end=' ') finally: dbs.close() log('Done') return RETURN_OK except Exception as e: error(str(e))
def put(self, folio_id, image_id): db_session = data_engine.db_get_session() try: # Get data 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()) # Update the portfolio params = self._get_validated_object_parameters(request.form) chd_folio_image = data_engine.reorder_portfolio( folio_image, params['index']) data_engine.add_portfolio_history( folio_image.portfolio, get_session_user(), FolioHistory.ACTION_IMAGE_CHANGE, '%s moved to position %d' % (folio_image.image.src, chd_folio_image.order_num + 1), _db_session=db_session, _commit=True) # Return the updated image list db_session.expire(folio_image) folio = data_engine.get_portfolio(folio_id, load_images=True, _db_session=db_session) image_list = [_prep_folioimage_object(fi) for fi in folio.images] return make_api_success_response( object_to_dict_list(image_list, _omit_fields + ['portfolio'])) finally: db_session.close()
def topten(): # Get parameters days = request.args.get('days', '1') limit = request.args.get('number', '10') data_type = request.args.get('data_type', '2') try: results = [] db_session = data_engine.db_get_session() try: # Convert params to ints days = parse_int(days) limit = parse_int(limit) data_type = parse_int(data_type) # Set options if days < 1: days = 1 if days > 30: days = 30 if limit < 10: limit = 10 if limit > 100: limit = 100 if data_type == 1: order = '-total_requests' elif data_type == 2: order = '-total_views' elif data_type == 3: order = '-total_cached_views' elif data_type == 4: order = '-total_downloads' elif data_type == 5: order = '-total_bytes' elif data_type == 6: order = '-total_seconds' elif data_type == 7: order = '-max_seconds' else: raise ValueError('Invalid data_type %d' % data_type) # Get initial stats top_stats = data_engine.summarise_image_stats( datetime.utcnow() - timedelta(days=days), datetime.utcnow(), limit=limit, order_by=order, _db_session=db_session) # Convert stats list to an image list for result in top_stats: db_image = data_engine.get_image(image_id=result[0], _db_session=db_session) if db_image: results.append({ 'id': db_image.id, 'src': db_image.src, 'requests': result[1], 'views': result[2], 'cached_views': result[3], 'downloads': result[4], 'bytes': result[5], 'seconds': result[6], 'max_seconds': result[7] }) finally: db_session.close() return render_template('reports_topten.html', days=days, data_type=data_type, number=limit, results=results) except Exception as e: log_security_error(e, request) if app.config['DEBUG']: raise raise InternalServerError(safe_error_str(e))
def trace_permissions(): embed = request.args.get('embed', '') user_id = request.args.get('user', '') folder_path = request.args.get('path', '') if folder_path == '': folder_path = os.path.sep folder = None user = None users = [] user_has_admin = False trace = None err_msg = None db_session = data_engine.db_get_session() try: # Get folder and selected user info # User can be None for an anonymous user user_id = parse_int(user_id) if user_id != 0: user = data_engine.get_user(user_id, _db_session=db_session) if user is None: raise DoesNotExistError('This user no longer exists') folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session) if folder is None or folder.status == Folder.STATUS_DELETED: raise DoesNotExistError('This folder no longer exists') # Get users list users = data_engine.list_users( status=User.STATUS_ACTIVE, order_field=User.username, _db_session=db_session ) # Get the folder+user traced permissions trace = permissions_engine._trace_folder_permissions(folder, user) # Flag on the UI if the user has admin for gdict in trace['groups']: gperms = gdict['group'].permissions if gperms.admin_files or gperms.admin_all: user_has_admin = True break except Exception as e: log_security_error(e, request) err_msg = str(e) finally: try: return render_template( 'admin_trace_permissions.html', embed=embed, folder=folder, folder_is_root=folder.is_root() if folder else False, user=user, user_list=users, trace=trace, user_has_admin=user_has_admin, err_msg=err_msg, GROUP_ID_PUBLIC=Group.ID_PUBLIC ) finally: db_session.close()
def imagelist(): # Check parameters try: from_path = request.args.get('path', '') want_info = parse_boolean(request.args.get('attributes', '')) start = parse_int(request.args.get('start', '0')) limit = parse_int(request.args.get('limit', '1000')) validate_string(from_path, 1, 1024) validate_number(start, 0, 999999999) validate_number(limit, 1, 1000) except ValueError as e: raise ParameterError(e) # Get extra parameters for image URL construction, remove API parameters image_params = request.args.to_dict() image_params.pop('path', None) image_params.pop('attributes', None) image_params.pop('start', None) image_params.pop('limit', None) # Get directory listing directory_info = get_directory_listing(from_path, False, 2, start, limit) if not directory_info.exists(): raise DoesNotExistError('Invalid path') ret_list = [] db_session = data_engine.db_get_session() db_commit = False try: # Auto-populate the folders database db_folder = auto_sync_folder( from_path, data_engine, task_engine, _db_session=db_session ) db_session.commit() # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_folder, FolderPermission.ACCESS_VIEW, get_session_user() ) # Get download permission in case we need to return it later can_download = permissions_engine.is_folder_permitted( db_folder, FolderPermission.ACCESS_DOWNLOAD, get_session_user() ) # Create the response file_list = directory_info.contents() supported_img_types = image_engine.get_image_formats(supported_only=True) base_folder = add_sep(directory_info.name()) for f in file_list: # v2.6.4 Return unsupported files too. If you want to reverse this change, # the filtering needs to be elsewhere for 'start' and 'limit' to work properly supported_file = get_file_extension(f['filename']) in supported_img_types file_path = base_folder + f['filename'] if want_info: # Need to return the database fields too if supported_file: db_entry = auto_sync_existing_file( file_path, data_engine, task_engine, burst_pdf=False, # Don't burst a PDF just by finding it here _db_session=db_session ) db_entry = _prep_image_object(db_entry, can_download, **image_params) else: db_entry = _prep_blank_image_object() db_entry.filename = f['filename'] db_entry.supported = False # Return images in full (standard) image dict format entry = object_to_dict(db_entry, _omit_fields) else: # Return images in short dict format entry = { 'filename': f['filename'], 'supported': supported_file, 'url': (external_url_for('image', src=file_path, **image_params) if supported_file else '') } ret_list.append(entry) db_commit = True finally: try: if db_commit: db_session.commit() else: db_session.rollback() finally: db_session.close() return make_api_success_response(ret_list)
def imagelist(): # Check parameters try: from_path = request.args.get('path', '') want_info = parse_boolean(request.args.get('attributes', '')) limit = parse_int(request.args.get('limit', '1000')) validate_string(from_path, 1, 1024) except ValueError as e: raise ParameterError(e) # Get extra parameters for image URL construction image_params = request.args.to_dict() if 'path' in image_params: del image_params['path'] if 'attributes' in image_params: del image_params['attributes'] if 'limit' in image_params: del image_params['limit'] # Get directory listing directory_info = get_directory_listing(from_path, False, limit) if not directory_info.exists(): raise DoesNotExistError('Invalid path') ret_list = [] db_session = data_engine.db_get_session() db_commit = False try: # Auto-populate the folders database db_folder = auto_sync_folder( from_path, data_engine, task_engine, _db_session=db_session ) db_session.commit() # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_folder, FolderPermission.ACCESS_VIEW, get_session_user() ) # Create the response file_list = directory_info.contents() img_types = image_engine.get_image_formats() base_folder = add_sep(directory_info.name()) for f in file_list: # Filter out non-images if get_file_extension(f['filename']) in img_types: entry_path = base_folder + f['filename'] entry = { 'filename': f['filename'], 'url': external_url_for('image', src=entry_path, **image_params) } if want_info: db_entry = auto_sync_existing_file( entry_path, data_engine, task_engine, burst_pdf=False, # Don't burst a PDF just by finding it here _db_session=db_session ) entry['id'] = db_entry.id if db_entry else 0 entry['folder_id'] = db_entry.folder_id if db_entry else 0 entry['title'] = db_entry.title if db_entry else '' entry['description'] = db_entry.description if db_entry else '' entry['width'] = db_entry.width if db_entry else 0 entry['height'] = db_entry.height if db_entry else 0 ret_list.append(entry) db_commit = True finally: try: if db_commit: db_session.commit() else: db_session.rollback() finally: db_session.close() return make_api_success_response(ret_list)
def topten(): # Get parameters days = request.args.get('days', '1') limit = request.args.get('number', '10') data_type = request.args.get('data_type', '2') try: results = [] db_session = data_engine.db_get_session() try: # Convert params to ints days = parse_int(days) limit = parse_int(limit) data_type = parse_int(data_type) # Set options if days < 1: days = 1 if days > 30: days = 30 if limit < 10: limit = 10 if limit > 100: limit = 100 if data_type == 1: order = '-total_requests' elif data_type == 2: order = '-total_views' elif data_type == 3: order = '-total_cached_views' elif data_type == 4: order = '-total_downloads' elif data_type == 5: order = '-total_bytes' elif data_type == 6: order = '-total_seconds' elif data_type == 7: order = '-max_seconds' else: raise ValueError('Invalid data_type %d' % data_type) # Get initial stats top_stats = data_engine.summarise_image_stats( datetime.utcnow() - timedelta(days=days), datetime.utcnow(), limit=limit, order_by=order, _db_session=db_session ) # Convert stats list to an image list for result in top_stats: db_image = data_engine.get_image(image_id=result[0], _db_session=db_session) if db_image: results.append({ 'id': db_image.id, 'src': db_image.src, 'requests': result[1], 'views': result[2], 'cached_views': result[3], 'downloads': result[4], 'bytes': result[5], 'seconds': result[6], 'max_seconds': result[7] }) finally: db_session.close() return render_template( 'reports_topten.html', days=days, data_type=data_type, number=limit, results=results ) except Exception as e: log_security_error(e, request) if app.config['DEBUG']: raise raise InternalServerError(str(e))