def get(self, folder_id=None): """ Gets a folder by path or ID, returning 1 level of children (sub-folders) """ if folder_id is None: # Get folder from path, using auto_sync to pick up new and deleted disk folders path = self._get_validated_path_arg(request) db_folder = auto_sync_folder(path, data_engine, task_engine) if db_folder is None: raise DoesNotExistError(path) else: # Get folder from ID db_folder = data_engine.get_folder(folder_id) if db_folder is None: raise DoesNotExistError(str(folder_id)) # View permission is required (ignoring view permission on parent+children) permissions_engine.ensure_folder_permitted( db_folder, FolderPermission.ACCESS_VIEW, get_session_user()) # Get the folder again, this time with parent and children # (children possibly faked - see the get_folder() docs - which is why # we can't use db_folder mk2 normally, only serialize it and exit) status_filter = self._get_validated_status_arg(request) db_folder = data_engine.get_folder(db_folder.id, load_parent=True, load_children=True, children_status=status_filter) if db_folder is None: raise DoesNotExistError(str(folder_id)) return make_api_success_response(object_to_dict(db_folder))
def imagedetails(): # Get/check parameters try: src = request.args.get('src', '') validate_string(src, 1, 1024) except ValueError as e: raise ParameterError(e) # v2.6.4 Don't allow this call to populate the database with unsupported files supported_file = ( get_file_extension(src) in image_engine.get_image_formats(supported_only=True) ) if not supported_file and path_exists(src, require_file=True): raise ImageError('The file is not a supported image format') # Get the image database entry db_image = auto_sync_file(src, data_engine, task_engine) if not db_image or db_image.status == Image.STATUS_DELETED: raise DoesNotExistError(src) # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_image.folder, FolderPermission.ACCESS_VIEW, get_session_user() ) return make_api_success_response(object_to_dict( _prep_image_object(db_image), _omit_fields ))
def get(self, image_id): db_img = data_engine.get_image(image_id=image_id) if not db_img: raise DoesNotExistError(str(image_id)) else: # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_img.folder, FolderPermission.ACCESS_VIEW, get_session_user()) return make_api_success_response( object_to_dict(_prep_image_object(db_img)))
def put(self, image_id): params = self._get_validated_object_parameters(request.form) # Get image and update it db_img = data_engine.get_image(image_id=image_id) if not db_img: raise DoesNotExistError(str(image_id)) # Require edit permission or file admin permissions_engine.ensure_folder_permitted( db_img.folder, FolderPermission.ACCESS_EDIT, get_session_user() ) old_title = db_img.title old_description = db_img.description db_img.title = params['title'] db_img.description = params['description'] data_engine.save_object(db_img) # Get text changes. Max info length = # 100 + 200 + len('()' + '()' + 'Title: ' + ' / ' + 'Description: ') ==> 327 title_diff = get_string_changes(old_title, params['title'], char_limit=100).strip() if not title_diff: # Try for deletions from title title_diff = get_string_changes(params['title'], old_title, char_limit=100).strip() if title_diff: title_diff = '(' + title_diff + ')' desc_diff = get_string_changes( old_description, params['description'], char_limit=200 ).strip() if not desc_diff: # Try for deletions from description desc_diff = get_string_changes( params['description'], old_description, char_limit=200 ).strip() if desc_diff: desc_diff = '(' + desc_diff + ')' info = '' if title_diff: info += 'Title: ' + title_diff if info and desc_diff: info += ' / ' if desc_diff: info += 'Description: ' + desc_diff # Add change history data_engine.add_image_history( db_img, get_session_user(), ImageHistory.ACTION_EDITED, info ) return make_api_success_response(object_to_dict(db_img))
def get(self, image_id): db_img = data_engine.get_image(image_id=image_id) if not db_img: raise DoesNotExistError(str(image_id)) else: # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_img.folder, FolderPermission.ACCESS_VIEW, get_session_user() ) return make_api_success_response(object_to_dict(db_img))
def put(self, image_id): params = self._get_validated_object_parameters(request.form) # Get image and update it db_img = data_engine.get_image(image_id=image_id) if not db_img: raise DoesNotExistError(str(image_id)) # Require edit permission or file admin permissions_engine.ensure_folder_permitted( db_img.folder, FolderPermission.ACCESS_EDIT, get_session_user()) old_title = db_img.title old_description = db_img.description db_img.title = params['title'] db_img.description = params['description'] data_engine.save_object(db_img) # Get text changes. Max info length = # 100 + 200 + len('()' + '()' + 'Title: ' + ' / ' + 'Description: ') ==> 327 title_diff = get_string_changes(old_title, params['title'], char_limit=100).strip() if not title_diff: # Try for deletions from title title_diff = get_string_changes(params['title'], old_title, char_limit=100).strip() if title_diff: title_diff = '(' + title_diff + ')' desc_diff = get_string_changes(old_description, params['description'], char_limit=200).strip() if not desc_diff: # Try for deletions from description desc_diff = get_string_changes(params['description'], old_description, char_limit=200).strip() if desc_diff: desc_diff = '(' + desc_diff + ')' info = '' if title_diff: info += 'Title: ' + title_diff if info and desc_diff: info += ' / ' if desc_diff: info += 'Description: ' + desc_diff # Add change history data_engine.add_image_history(db_img, get_session_user(), ImageHistory.ACTION_EDITED, info) return make_api_success_response( object_to_dict(_prep_image_object(db_img)))
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 imagedetails(): # Get/check parameters try: src = request.args.get('src', '') validate_string(src, 1, 1024) except ValueError as e: raise ParameterError(e) # Get the image database entry db_image = auto_sync_file(src, data_engine, task_engine) if not db_image or db_image.status == Image.STATUS_DELETED: raise DoesNotExistError(src) # Require view permission or file admin permissions_engine.ensure_folder_permitted( db_image.folder, FolderPermission.ACCESS_VIEW, get_session_user() ) return make_api_success_response(_image_dict(db_image))
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 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)