From 55d6e704591e8e767aad2b0b8248e1c678aed2e4 Mon Sep 17 00:00:00 2001 From: Pablo Saiz Date: Thu, 21 Nov 2024 17:43:03 +0100 Subject: [PATCH] eos: serve eos files through the mount point --- cernopendata/api.py | 6 +- cernopendata/modules/records/utils.py | 86 ++++++++++----------------- 2 files changed, 32 insertions(+), 60 deletions(-) diff --git a/cernopendata/api.py b/cernopendata/api.py index 031a5f8..a6202c5 100644 --- a/cernopendata/api.py +++ b/cernopendata/api.py @@ -43,10 +43,8 @@ def __next__(self): def __getitem__(self, key): """Get a specific file.""" - obj = FileIndexMetadata.get(self.record, key) - if obj: - return self.file_cls(obj, self.filesmap.get(obj.key, {})) - raise KeyError(key) + obj = self.file_indices[key] + return FileIndexMetadata.get(None, obj["files"][0]["bucket"]) def flush(self): """Flush changes to record.""" diff --git a/cernopendata/modules/records/utils.py b/cernopendata/modules/records/utils.py index 072f71d..e8f0e6c 100644 --- a/cernopendata/modules/records/utils.py +++ b/cernopendata/modules/records/utils.py @@ -19,31 +19,25 @@ """Implementention of various utility functions.""" -import json -from re import sub -import six import itertools +import json +import re +from os.path import isfile +import flask from flask import abort, current_app, jsonify, render_template, request -from invenio_files_rest.views import ObjectResource -from invenio_records.api import Record -from invenio_records_files.utils import record_file_factory - from invenio_files_rest.models import FileInstance # from invenio_files_rest.models import FileInstance, ObjectVersion # from invenio_records.errors import MissingModelError +from invenio_files_rest.storage.pyfs import PyFSFileStorage +from invenio_files_rest.views import ObjectResource +from invenio_records.api import Record +from invenio_records_files.utils import record_file_factory from invenio_records_ui.utils import obj_or_import_string from invenio_xrootd import EOSFileStorage from werkzeug.utils import import_string -from invenio_search import current_search_client -from invenio_search.engine import dsl, search - -import sys -import flask -import re - def get_file_index(pid, record, file_index, **kwargs): """Return the list of entries.""" @@ -85,21 +79,15 @@ def file_download_ui(pid, record, _record_file_factory=None, **kwargs): _record_file_factory = _record_file_factory or record_file_factory # Extract file from record. filename = kwargs.get("filename") - if filename == "configFile.py": - rf = record.files.dumps() - for file in rf: - if file.get("key", "").endswith("configFile.py"): - filename = file.get("key") - break - fileobj = _record_file_factory(pid, record, filename) if not fileobj: - for index in record.file_indices: - for file in index["files"]: - if file["key"] == filename: - obj = ObjectResource.get_object( - file["bucket"], file["key"], file["version_id"] - ) + file_index = re.sub(r"_\d+$", "", filename) + for file in record.file_indices[file_index]._files: + if file["key"] == filename: + obj = ObjectResource.get_object( + file["bucket"], file["key"], file["version_id"] + ) + break if not obj: abort(404) else: @@ -107,44 +95,30 @@ def file_download_ui(pid, record, _record_file_factory=None, **kwargs): # Check permissions ObjectResource.check_object_permission(obj) + return _send_file(obj.file.uri) - return ObjectResource.send_object( - obj.bucket, - obj, - # expected_chksum=fileobj.get('checksum'), - logger_data={ - "bucket_id": obj.bucket_id, - "pid_type": pid.pid_type, - "pid_value": pid.pid_value, - }, - # create_dir=False - ) + +def _send_file(uri): + """Send a file to the client.""" + if isfile(uri.replace("root://eospublic.cern.ch/", "")): + storage = PyFSFileStorage(uri.replace("root://eospublic.cern.ch/", "file:///")) + else: + storage = EOSFileStorage(uri) + filename = uri.split("/")[-1:] + try: + return storage.send_file(filename[0]) + except Exception: + abort(404) def eos_file_download_ui(pid, record, _record_file_factory=None, **kwargs): """File download view for a given EOS uri.""" if current_app.config.get("CERNOPENDATA_DISABLE_DOWNLOADS", False): abort(503) - - path = kwargs.get("filepath", "") - - return eos_send_file_or_404(path) - - -def eos_send_file_or_404(file_path=""): - """File download for a given EOS uri.""" - storage = EOSFileStorage( - "root://eospublic.cern.ch//eos/opendata/" + file_path, - # create_dir=False + return _send_file( + "root://eospublic.cern.ch/eos/opendata/" + kwargs.get("filepath", "") ) - filename = file_path.split("/")[-1:] - - try: - return storage.send_file(filename[0]) - except Exception: - abort(404) - def get_paged_files(files, page, items_per_page=5): """Get files for current page."""