Skip to content

Commit 7b35349

Browse files
authored
Merge pull request #20685 from davelopez/25.0_fix_invenio_download_published_with_draft
[25.0] Fix Invenio file downloads for published records with draft
2 parents 4ad5399 + 983267d commit 7b35349

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

lib/galaxy/files/sources/invenio.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
Unpack,
1919
)
2020

21-
from galaxy.exceptions import AuthenticationRequired
21+
from galaxy.exceptions import (
22+
AuthenticationRequired,
23+
MessageException,
24+
)
2225
from galaxy.files import OptionalUserContext
2326
from galaxy.files.sources import (
2427
AnyRemoteEntry,
@@ -397,17 +400,15 @@ def _get_download_file_url(self, record_id: str, filename: str, user_context: Op
397400
398401
This method is used to download files from both published and draft records that are accessible by the user.
399402
"""
400-
is_draft_record = self._is_draft_record(record_id, user_context)
401-
file_details_url = f"{self.records_url}/{record_id}/files/{quote(filename)}"
402-
download_file_content_url = f"{file_details_url}/content"
403-
if is_draft_record:
404-
file_details_url = self._to_draft_url(file_details_url)
405-
download_file_content_url = self._to_draft_url(download_file_content_url)
406-
# Downloading through the API is only supported for local files and depends on how
407-
# the InvenioRDM instance file storage is configured.
408-
# So this is the most reliable way to download files for now it.
409-
download_file_content_url = f"{file_details_url.replace('/api', '')}?download=1"
410-
return download_file_content_url
403+
file_details_url = self._get_file_details_url(record_id, filename)
404+
if self._is_published_record(record_id, user_context):
405+
return self._file_url_to_download_url(file_details_url)
406+
if self._is_draft_record(record_id, user_context):
407+
draft_download_url = f"{self._to_draft_url(file_details_url)}/content"
408+
return draft_download_url
409+
raise MessageException(
410+
f"Cannot download file '{filename}' from record '{record_id}'. The record is not accessible or does not exist."
411+
)
411412

412413
def _is_api_url(self, url: str) -> bool:
413414
return "/api/" in url
@@ -418,11 +419,29 @@ def _to_draft_url(self, url: str) -> str:
418419
def _is_draft_record(self, record_id: str, user_context: OptionalUserContext = None):
419420
request_url = self._get_draft_record_url(record_id)
420421
headers = self._get_request_headers(user_context)
421-
response = requests.get(request_url, headers=headers)
422+
response = requests.head(request_url, headers=headers)
423+
return response.status_code == 200
424+
425+
def _is_published_record(self, record_id: str, user_context: OptionalUserContext = None):
426+
request_url = self._get_record_url(record_id)
427+
headers = self._get_request_headers(user_context)
428+
response = requests.head(request_url, headers=headers)
422429
return response.status_code == 200
423430

431+
def _get_record_url(self, record_id: str):
432+
return f"{self.records_url}/{record_id}"
433+
424434
def _get_draft_record_url(self, record_id: str):
425-
return f"{self.records_url}/{record_id}/draft"
435+
return f"{self._get_record_url(record_id)}/draft"
436+
437+
def _get_file_details_url(self, record_id: str, filename: str):
438+
return f"{self._get_record_url(record_id)}/files/{quote(filename)}"
439+
440+
def _file_url_to_download_url(self, file_url: str) -> str:
441+
# Downloading through the API is only supported for local files and depends on how
442+
# the InvenioRDM instance file storage is configured.
443+
# So this is the most reliable way to download files for now.
444+
return f"{file_url.replace('/api', '')}?download=1"
426445

427446
def _get_draft_record(self, record_id: str, user_context: OptionalUserContext = None):
428447
request_url = self._get_draft_record_url(record_id)

0 commit comments

Comments
 (0)