diff --git a/config/default.py b/config/default.py index a68e1fbe4..b3c99bbb8 100644 --- a/config/default.py +++ b/config/default.py @@ -47,6 +47,7 @@ IIIF_ACTIVATE = False IIIF_DIR = '' +IIIF_PREFIX = '' # For system checks WRITABLE_DIRS = [ diff --git a/openatlas/display/util.py b/openatlas/display/util.py index bd67dc883..e197c00b1 100644 --- a/openatlas/display/util.py +++ b/openatlas/display/util.py @@ -431,13 +431,11 @@ def system_warnings(_context: str, _unneeded_string: str) -> str: warnings.append( f"Database version {app.config['DATABASE_VERSION']} is needed but " f"current version is {g.settings['database_version']}") - if app.config['IIIF_ACTIVATE']: - app.config['WRITABLE_DIRS'].append(app.config['IIIF_DIR']) + if app.config['IIIF_ACTIVATE'] and app.config['IIIF_DIR']: + path = Path(app.config['IIIF_DIR']) / app.config['IIIF_PREFIX'] + check_write_access(path, warnings) for path in app.config['WRITABLE_DIRS']: - if not os.access(path, os.W_OK): - warnings.append( - '

' + _('directory not writable') + - f" {str(path).replace(app.root_path, '')}

") + check_write_access(path, warnings) if is_authorized('admin'): from openatlas.models.user import User user = User.get_by_username('OpenAtlas') @@ -455,6 +453,14 @@ def system_warnings(_context: str, _unneeded_string: str) -> str: f'{"
".join(warnings)}' if warnings else '' +def check_write_access(path, warnings): + if not os.access(path, os.W_OK): + warnings.append( + '

' + _('directory not writable') + + f" {str(path).replace(app.root_path, '')}

") + return warnings + + @app.template_filter() def tooltip(text: str) -> str: if not text: diff --git a/openatlas/templates/admin/data.html b/openatlas/templates/admin/data.html index c2c1d269e..e062e735d 100644 --- a/openatlas/templates/admin/data.html +++ b/openatlas/templates/admin/data.html @@ -32,6 +32,7 @@

{{ _('image processing')|uc_first }}

{{ 'admin/file'|manual|safe }}
{{ _('create resized images')|button(url_for('admin_resize_images'))|safe }}
{{ _('delete orphaned resized images')|button(url_for('admin_delete_orphaned_resized_images'))|safe }}
+
{{ _('convert all images to iiif')|button(url_for('admin_convert_all_to_iiif'))|safe }}
{% endif %} {% if 'manager'|is_authorized %} diff --git a/openatlas/views/admin.py b/openatlas/views/admin.py index 39a4be31f..1240d7914 100644 --- a/openatlas/views/admin.py +++ b/openatlas/views/admin.py @@ -38,6 +38,7 @@ from openatlas.models.settings import Settings from openatlas.models.type import Type from openatlas.models.user import User +from openatlas.views.file import convert_image_to_iiif @app.route('/admin', methods=['GET', 'POST'], strict_slashes=False) @@ -777,3 +778,14 @@ def get_disk_space_info() -> Optional[dict[str, Any]]: 'percent_used': percent_free, 'percent_project': percent_files, 'percent_other': 100 - (percent_files + percent_free)} + + +@app.route('/admin/admin_convert_all_to_iiif') +@required_group('admin') +def admin_convert_all_to_iiif() -> Response: + for entity in Entity.get_by_class('file'): + if entity.id in g.file_stats \ + and g.file_stats[entity.id]['ext'] \ + in app.config['ALLOWED_IMAGE_EXT']: + convert_image_to_iiif(entity.id) + return redirect(url_for('admin_index') + '#tab-data') diff --git a/openatlas/views/file.py b/openatlas/views/file.py index ea310a172..15d230d2a 100644 --- a/openatlas/views/file.py +++ b/openatlas/views/file.py @@ -1,6 +1,5 @@ import subprocess from pathlib import Path -from subprocess import call, run from typing import Any, Union from flask import g, render_template, request, send_from_directory, url_for @@ -74,18 +73,20 @@ def file_add(id_: int, view: str) -> Union[str, Response]: @app.route('/file/iiif/', methods=['GET']) @required_group('contributor') def make_iiif_available(id_: int): + convert_image_to_iiif(id_) + return redirect(url_for('view', id_=id_)) + + +def convert_image_to_iiif(id_): + path = Path(app.config['IIIF_DIR']) / app.config['IIIF_PREFIX'] / str(id_) command = \ - (f"vips.exe tiffsave " - f"{get_file_path(id_)} {Path(app.config['IIIF_DIR']) / str(id_)} " + (f"vips.exe tiffsave {get_file_path(id_)} {path} " f"--tile --pyramid --compression deflate " f"--tile-width 256 --tile-height 256") subprocess.Popen(command, shell=True) - return redirect(url_for('view', id_=id_)) @app.route('/iiif/', methods=['GET']) @required_group('contributor') def view_iiif(id_: int): return redirect(url_for('view', id_=id_)) - -