diff --git a/openatlas/__init__.py b/openatlas/__init__.py index 92a75bf56..b5599c352 100644 --- a/openatlas/__init__.py +++ b/openatlas/__init__.py @@ -1,6 +1,5 @@ import locale -from pathlib import Path -from typing import Any, Optional +from typing import Optional from flask import Flask, Response, g, request, session from flask_babel import Babel @@ -50,6 +49,7 @@ def before_request() -> None: if request.path.startswith('/static'): return # Avoid files overhead if not using Apache with static alias + g.logger = Logger() g.db = open_connection(app.config) g.db.autocommit = True @@ -64,8 +64,10 @@ def before_request() -> None: g.view_class_mapping = view_class_mapping g.class_view_mapping = OpenatlasClass.get_class_view_mapping() g.table_headers = OpenatlasClass.get_table_headers() - g.file_stats = get_file_stats() - + g.files = {} + for file_ in app.config['UPLOAD_DIR'].iterdir(): + if file_.stem.isdigit(): + g.files[int(file_.stem)] = file_ # Set max file upload in MB app.config['MAX_CONTENT_LENGTH'] = \ g.settings['file_upload_max_size'] * 1024 * 1024 @@ -91,14 +93,3 @@ def apply_caching(response: Response) -> Response: @app.teardown_request def teardown_request(_exception: Optional[Exception]) -> None: close_connection() - - -def get_file_stats( - path: Path = app.config['UPLOAD_DIR']) -> dict[int, dict[str, Any]]: - stats: dict[int, dict[str, Any]] = {} - for file_ in filter(lambda x: x.stem.isdigit(), path.iterdir()): - stats[int(file_.stem)] = { - 'ext': file_.suffix, - 'size': convert_size(file_.stat().st_size), - 'date': file_.stat().st_ctime} - return stats diff --git a/openatlas/display/display.py b/openatlas/display/display.py index ac2727700..88f6236e8 100644 --- a/openatlas/display/display.py +++ b/openatlas/display/display.py @@ -65,10 +65,8 @@ class FileDisplay(BaseDisplay): def add_data(self) -> None: super().add_data() - self.data[_('size')] = g.file_stats[self.entity.id]['size'] \ - if self.entity.id in g.file_stats else 'N/A' - self.data[_('extension')] = g.file_stats[self.entity.id]['ext'] \ - if self.entity.id in g.file_stats else 'N/A' + self.data[_('size')] = self.entity.get_file_size() + self.data[_('extension')] = self.entity.get_file_extension() def add_button_others(self) -> None: if path := get_file_path(self.entity.id): diff --git a/openatlas/display/image_processing.py b/openatlas/display/image_processing.py index 8cea34e5b..25ee3ab3a 100644 --- a/openatlas/display/image_processing.py +++ b/openatlas/display/image_processing.py @@ -91,14 +91,13 @@ def delete_orphaned_resized_images() -> None: path = Path(app.config['RESIZED_IMAGES']) / size for file in path.glob('**/*'): file_name = file.name.rsplit('.', 1)[0].lower() - if not file_name.isdigit() or int(file_name) not in g.file_stats: + if not file_name.isdigit() or int(file_name) not in g.files: file.unlink() # pragma: no cover def create_resized_images() -> None: from openatlas.models.entity import Entity 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']: - resize_image(f"{entity.id}{g.file_stats[entity.id]['ext']}") + if entity.id in g.files: + if entity.get_file_extension() in app.config['ALLOWED_IMAGE_EXT']: + resize_image(f"{entity.id}{entity.get_file_extension()}") diff --git a/openatlas/display/util.py b/openatlas/display/util.py index a89a01596..7419897d1 100644 --- a/openatlas/display/util.py +++ b/openatlas/display/util.py @@ -338,12 +338,8 @@ def get_base_table_data(entity: Entity, show_links: bool = True) -> list[Any]: if entity.class_.standard_type_id: data.append(entity.standard_type.name if entity.standard_type else '') if entity.class_.name == 'file': - data.append( - g.file_stats[entity.id]['size'] - if entity.id in g.file_stats else 'N/A') - data.append( - g.file_stats[entity.id]['ext'] - if entity.id in g.file_stats else 'N/A') + data.append(entity.get_file_size()) + data.append(entity.get_file_extension()) if entity.class_.view in ['actor', 'artifact', 'event', 'place']: data.append(entity.first) data.append(entity.last) @@ -466,9 +462,9 @@ def get_file_path( entity: Union[int, Entity], size: Optional[str] = None) -> Optional[Path]: id_ = entity if isinstance(entity, int) else entity.id - if id_ not in g.file_stats: + if id_ not in g.files: return None - ext = g.file_stats[id_]['ext'] + ext = g.files[id_].suffix if size: if ext in app.config['NONE_DISPLAY_EXT']: ext = app.config['PROCESSED_EXT'] # pragma: no cover diff --git a/openatlas/models/entity.py b/openatlas/models/entity.py index ea61cfd4b..286358b9b 100644 --- a/openatlas/models/entity.py +++ b/openatlas/models/entity.py @@ -12,7 +12,7 @@ from openatlas.database.entity import Entity as Db from openatlas.display.util import ( datetime64_to_timestamp, format_date_part, sanitize, - timestamp_to_datetime64) + timestamp_to_datetime64, convert_size) from openatlas.models.link import Link if TYPE_CHECKING: # pragma: no cover @@ -331,6 +331,13 @@ def get_structure_for_insert(self) -> dict[str, list[Entity]]: self.get_linked_entities_recursive('P46', inverse=True) + [self]} + def get_file_size(self) -> str: + return convert_size(g.files[self.id].stat().st_size) \ + if self.id in g.files else 'N/A' + + def get_file_extension(self) -> str: + return g.files[self.id].suffix if self.id in g.files else 'N/A' + @staticmethod def get_invalid_dates() -> list[Entity]: return [ @@ -372,8 +379,8 @@ def get_by_view( def get_display_files() -> list[Entity]: entities = [] for row in Db.get_by_class('file', types=True): - ext = g.file_stats[row['id']]['ext'] \ - if row['id'] in g.file_stats else 'N/A' + ext = g.files[row['id']].suffix \ + if row['id'] in g.files else 'N/A' if ext in app.config['DISPLAY_FILE_EXTENSIONS']: entities.append(Entity(row)) return entities diff --git a/openatlas/views/admin.py b/openatlas/views/admin.py index 39a4be31f..15d6b785b 100644 --- a/openatlas/views/admin.py +++ b/openatlas/views/admin.py @@ -519,6 +519,7 @@ def admin_orphans() -> str: for file in app.config['UPLOAD_DIR'].iterdir(): if file.name != '.gitignore' \ and os.path.isfile(file) \ + and file.stem.isdigit() \ and int(file.stem) not in entity_file_ids: confirm = _('Delete %(name)s?', name=file.name.replace("'", '')) tabs['orphaned_files'].table.rows.append([ @@ -606,18 +607,16 @@ def admin_logo(id_: Optional[int] = None) -> Union[str, Response]: table = Table([''] + g.table_headers['file'] + ['date']) for entity in Entity.get_display_files(): date = 'N/A' - if entity.id in g.file_stats: + if entity.id in g.files: date = format_date( datetime.datetime.utcfromtimestamp( - g.file_stats[entity.id]['date'])) + g.files[entity.id].stat().st_ctime)) table.rows.append([ link(_('set'), url_for('admin_logo', id_=entity.id)), entity.name, link(entity.standard_type), - g.file_stats[entity.id]['size'] - if entity.id in g.file_stats else 'N/A', - g.file_stats[entity.id]['ext'] - if entity.id in g.file_stats else 'N/A', + entity.get_file_size(), + entity.get_file_extension(), entity.description, date]) return render_template( diff --git a/openatlas/views/entity_index.py b/openatlas/views/entity_index.py index 842df7c9d..f61bca8f2 100644 --- a/openatlas/views/entity_index.py +++ b/openatlas/views/entity_index.py @@ -10,7 +10,7 @@ from openatlas.display.table import Table from openatlas.display.util import ( button, format_date, get_base_table_data, get_file_path, is_authorized, - link, manual, required_group) + link, manual, required_group, convert_size) from openatlas.models.entity import Entity from openatlas.models.gis import Gis @@ -50,10 +50,8 @@ def get_table(view: str) -> Table: format_date(entity.created), link(entity), link(entity.standard_type), - g.file_stats[entity.id]['size'] - if entity.id in g.file_stats else 'N/A', - g.file_stats[entity.id]['ext'] - if entity.id in g.file_stats else 'N/A', + entity.get_file_size(), + entity.get_file_extension(), entity.description] if g.settings['image_processing'] \ and current_user.settings['table_show_icons']: