def insert_file(form: FlaskForm, origin: Optional[Entity] = None) -> Union[str, Response]: filenames = [] url = url_for('index', view=g.classes['file'].view) try: Transaction.begin() entity_name = form.name.data.strip() for count, file in enumerate(form.file.data): entity = Entity.insert('file', file.filename) url = link_and_get_redirect_url(form, entity, 'file', origin) # Add 'a' to prevent emtpy temporary filename, has no side effects filename = secure_filename(f'a{file.filename}') # type: ignore new_name = f"{entity.id}.{filename.rsplit('.', 1)[1].lower()}" file.save(f"{app.config['UPLOAD_DIR']}/{new_name}") filenames.append(new_name) if session['settings']['image_processing']: ImageProcessing.resize_image(new_name) if len(form.file.data) > 1: form.name.data = f'{entity_name}_{str(count + 1).zfill(2)}' if origin: url = f"{url_for('entity_view', id_=origin.id)}#tab-file" entity.update(form) update_links(entity, form, 'insert', origin) logger.log_user(entity.id, 'insert') Transaction.commit() flash(_('entity created'), 'info') except Exception as e: # pragma: no cover Transaction.rollback() for filename in filenames: (app.config['UPLOAD_DIR'] / filename).unlink() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') url = url_for('index', view=g.classes['file'].view) return url
def file_preview(entity_id: int) -> str: icon_path = get_file_path(entity_id, app.config['IMAGE_SIZE']['table']) size = app.config['IMAGE_SIZE']['table'] parameter = f"loading='lazy' alt='image' width='{size}'" if icon_path: url = url_for('display_file', filename=icon_path.name, size=size) return f"<img src='{url}' {parameter}>" path = get_file_path(entity_id) if path and ImageProcessing.check_processed_image(path.name): icon_path = get_file_path(entity_id, app.config['IMAGE_SIZE']['table']) url = url_for('display_file', filename=icon_path.name, size=size) return f"<img src='{url}' {parameter}>" return ''
def file_preview(entity_id: int) -> str: icon_path = get_file_path(entity_id, app.config['IMAGE_SIZE']['table']) size = app.config['IMAGE_SIZE']['table'] if icon_path: url = url_for('display_file', filename=icon_path.name, size=size) return f"<img src='{url}' loading='lazy'>" "" path = get_file_path(entity_id) if not path: return '' if ImageProcessing.check_processed_image(path.name): icon_path = get_file_path(entity_id, app.config['IMAGE_SIZE']['table']) url = url_for('display_file', filename=icon_path.name, size=size) return f"<img src='{url}' loading='lazy' alt='image'>" return ''
def display_profile_image(entity: Entity) -> str: if not entity.image_id: return '' path = get_file_path(entity.image_id) if not path: return '' # pragma: no cover resized = None size = app.config['IMAGE_SIZE']['thumbnail'] if session['settings']['image_processing'] \ and ImageProcessing.check_processed_image(path.name): resized = url_for('display_file', filename=get_file_path(entity.image_id, size).name, size=size) return Markup( render_template('util/profile_image.html', entity=entity, path=path, resized=resized))
def admin_delete_orphaned_resized_images() -> Response: ImageProcessing.delete_orphaned_resized_images() flash(_('resized orphaned images were deleted'), 'info') return redirect(url_for('admin_index') + '#tab-data')
def admin_resize_images() -> Response: ImageProcessing.create_resized_images() flash(_('images were created'), 'info') return redirect(url_for('admin_index') + '#tab-data')
def test_image(self) -> None: app.config['IMAGE_SIZE']['tmp'] = '1' with app.app_context(): # type: ignore with app.test_request_context(): app.preprocess_request() # type: ignore place = insert_entity('Nostromos', 'place', description='That is the Nostromos') logo = \ pathlib.Path(app.root_path) \ / 'static' / 'images' / 'layout' / 'logo.png' # Resizing through UI insert with open(logo, 'rb') as img: rv = self.app.post(url_for('insert', class_='file', origin_id=place.id), data={ 'name': 'OpenAtlas logo', 'file': img }, follow_redirects=True) assert b'An entry has been created' in rv.data with app.test_request_context(): app.preprocess_request() # type: ignore files = Entity.get_by_class('file') file_id = files[0].id # Set and unset as main image self.app.get(url_for('set_profile_image', id_=file_id, origin_id=place.id), follow_redirects=True) # Delete through UI rv = self.app.get(url_for('index', view='file', delete_id=file_id)) assert b'The entry has been deleted' in rv.data # Create entities for file with app.test_request_context(): app.preprocess_request() # type: ignore file_pathless = insert_entity('Pathless_File', 'file') file = insert_entity('Test_File', 'file') file.link('P2', g.nodes[Node.get_hierarchy('License').subs[0]]) file_name = f'{file.id}.jpeg' src_png = \ pathlib.Path(app.root_path) \ / 'static' / 'images' / 'layout' / 'logo.png' dst_png = \ pathlib.Path(app.config['UPLOAD_DIR'] / file_name) copyfile(src_png, dst_png) file2 = insert_entity('Test_File2', 'file') file2.link('P2', g.nodes[Node.get_hierarchy('License').subs[0]]) file2_name = f'{file2.id}.jpeg' src2_png = \ pathlib.Path(app.root_path) \ / 'static' / 'images' / 'layout' / 'logo.png' dst2_png = pathlib.Path(app.config['UPLOAD_DIR'] / file2_name) copyfile(src2_png, dst2_png) file_py = insert_entity('Test_Py', 'file') file_name_py = f'{file_py.id}.py' src_py = pathlib.Path(app.root_path) / 'views' / 'index.py' dst_py = pathlib.Path(app.config['UPLOAD_DIR'] / file_name_py) copyfile(src_py, dst_py) # Exception ImageProcessing.safe_resize_image(file2.id, '.png', size="???") display_profile_image(file_pathless) # Resizing images (don't change order!) rv = self.app.get(url_for('entity_view', id_=file.id)) assert b'Test_File' in rv.data rv = self.app.get(url_for('entity_view', id_=file_py.id)) assert b'No preview available' in rv.data rv = self.app.get(url_for('entity_view', id_=file_pathless.id)) assert b'Missing file' in rv.data rv = self.app.get(url_for('index', view='file')) assert b'Test_File' in rv.data # Display file rv = self.app.get(url_for('display_file', filename=file_name)) assert b'\xff' in rv.data rv = self.app.get( url_for('display_file', filename=file_name, size=app.config['IMAGE_SIZE']['thumbnail'])) assert b'\xff' in rv.data rv = self.app.get( url_for('display_file', filename=file_name, size=app.config['IMAGE_SIZE']['table'])) assert b'\xff' in rv.data rv = self.app.get( url_for('display_file', filename=file_name_py, size=app.config['IMAGE_SIZE']['table'])) assert b'404' in rv.data # Make directory if not exist rv = self.app.get(url_for('entity_view', id_=file.id)) assert b'Test_File' in rv.data # Exception app.config['IMAGE_SIZE']['tmp'] = '<' rv = self.app.get(url_for('entity_view', id_=file.id)) assert b'Test_File' in rv.data app.config['IMAGE_SIZE']['tmp'] = '1' rv = self.app.get(url_for('admin_resize_images'), follow_redirects=True) assert b'Images were created' in rv.data rv = self.app.get(url_for('admin_delete_orphaned_resized_images'), follow_redirects=True) assert b'Resized orphaned images were deleted' in rv.data rv = self.app.get(url_for('index', view='file', delete_id=file.id)) assert b'The entry has been deleted' in rv.data rv = self.app.get(url_for('index', view='file', delete_id=file2.id)) assert b'The entry has been deleted' in rv.data shutil.rmtree( pathlib.Path(app.config['RESIZED_IMAGES'] / app.config['IMAGE_SIZE']['tmp'])) dst_py.unlink() del app.config['IMAGE_SIZE']['tmp']