mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-19 02:21:32 +08:00
Merge pull request #17997 from davelopez/23.2_invenio_plugin_fixes
[23.2] Invenio plugin fixes
This commit is contained in:
@@ -199,10 +199,14 @@
|
||||
doc: Make sure to define this generic drs file source if you have defined any other drs file sources, or stock drs download capability will be disabled.
|
||||
|
||||
- type: inveniordm
|
||||
id: invenio
|
||||
doc: Invenio RDM turn-key research data management repository
|
||||
label: Invenio RDM Demo Repository
|
||||
id: invenio_sandbox
|
||||
doc: This is the Sandbox instance of Invenio. It is used for testing purposes only, content is NOT preserved. DOIs created in this instance are not real and will not resolve.
|
||||
label: Invenio RDM Sandbox Repository (TESTING ONLY)
|
||||
url: https://inveniordm.web.cern.ch/
|
||||
token: ${user.user_vault.read_secret('preferences/invenio_sandbox/token')}
|
||||
# token: ${user.preferences['invenio_sandbox|token']} # Alternatively use this for retrieving the token from user preferences instead of the Vault
|
||||
public_name: ${user.preferences['invenio_sandbox|public_name']}
|
||||
writable: true
|
||||
|
||||
- type: onedata
|
||||
id: onedata1
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import logging
|
||||
from typing import (
|
||||
cast,
|
||||
List,
|
||||
NamedTuple,
|
||||
Optional,
|
||||
@@ -26,6 +25,7 @@ OptionalUserContext = Optional[ProvidesUserFileSourcesUserContext]
|
||||
class RDMFilesSourceProperties(FilesSourceProperties):
|
||||
url: str
|
||||
token: str
|
||||
public_name: str
|
||||
|
||||
|
||||
class RecordFilename(NamedTuple):
|
||||
@@ -80,7 +80,9 @@ class RDMRepositoryInteractor:
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def create_draft_record(self, title: str, user_context: OptionalUserContext = None):
|
||||
def create_draft_record(
|
||||
self, title: str, public_name: Optional[str] = None, user_context: OptionalUserContext = None
|
||||
):
|
||||
"""Creates a draft record (directory) in the repository with basic metadata.
|
||||
|
||||
The metadata is usually just the title of the record and the user that created it.
|
||||
@@ -138,11 +140,10 @@ class RDMFilesSource(BaseFilesSource):
|
||||
|
||||
def __init__(self, **kwd: Unpack[FilesSourceProperties]):
|
||||
props = self._parse_common_config_opts(kwd)
|
||||
base_url = props.get("url", None)
|
||||
base_url = props.get("url")
|
||||
if not base_url:
|
||||
raise Exception("URL for RDM repository must be provided in configuration")
|
||||
self._repository_url = base_url
|
||||
self._token = props.get("token", None)
|
||||
self._props = props
|
||||
self._repository_interactor = self.get_repository_interactor(base_url)
|
||||
|
||||
@@ -150,10 +151,6 @@ class RDMFilesSource(BaseFilesSource):
|
||||
def repository(self) -> RDMRepositoryInteractor:
|
||||
return self._repository_interactor
|
||||
|
||||
@property
|
||||
def token(self) -> Optional[str]:
|
||||
return self._token if self._token and not self._token.startswith("$") else None
|
||||
|
||||
def get_repository_interactor(self, repository_url: str) -> RDMRepositoryInteractor:
|
||||
"""Returns an interactor compatible with the given repository URL.
|
||||
|
||||
@@ -190,25 +187,23 @@ class RDMFilesSource(BaseFilesSource):
|
||||
def get_record_id_from_path(self, source_path: str) -> str:
|
||||
return self.parse_path(source_path, record_id_only=True).record_id
|
||||
|
||||
def _serialization_props(self, user_context: OptionalUserContext = None) -> RDMFilesSourceProperties:
|
||||
def _serialization_props(self, user_context: OptionalUserContext = None):
|
||||
effective_props = {}
|
||||
for key, val in self._props.items():
|
||||
effective_props[key] = self._evaluate_prop(val, user_context=user_context)
|
||||
effective_props["url"] = self._repository_url
|
||||
effective_props["token"] = self.safe_get_authorization_token(user_context)
|
||||
return cast(RDMFilesSourceProperties, effective_props)
|
||||
return effective_props
|
||||
|
||||
def get_authorization_token(self, user_context: OptionalUserContext) -> str:
|
||||
token = self.token
|
||||
if not token and user_context:
|
||||
vault = user_context.user_vault if user_context else None
|
||||
token = vault.read_secret(f"preferences/{self.id}/token") if vault else None
|
||||
if token is None:
|
||||
raise AuthenticationRequired(f"No authorization token provided in user's settings for '{self.label}'")
|
||||
token = None
|
||||
if user_context:
|
||||
effective_props = self._serialization_props(user_context)
|
||||
token = effective_props.get("token")
|
||||
if not token:
|
||||
raise AuthenticationRequired(
|
||||
f"Please provide a personal access token in your user's preferences for '{self.label}'"
|
||||
)
|
||||
return token
|
||||
|
||||
def safe_get_authorization_token(self, user_context: OptionalUserContext) -> Optional[str]:
|
||||
try:
|
||||
return self.get_authorization_token(user_context)
|
||||
except AuthenticationRequired:
|
||||
return None
|
||||
def get_public_name(self, user_context: OptionalUserContext) -> Optional[str]:
|
||||
effective_props = self._serialization_props(user_context)
|
||||
return effective_props.get("public_name")
|
||||
|
||||
@@ -135,7 +135,8 @@ class InvenioRDMFilesSource(RDMFilesSource):
|
||||
user_context: OptionalUserContext = None,
|
||||
opts: Optional[FilesSourceOptions] = None,
|
||||
) -> Entry:
|
||||
record = self.repository.create_draft_record(entry_data["name"], user_context=user_context)
|
||||
public_name = self.get_public_name(user_context)
|
||||
record = self.repository.create_draft_record(entry_data["name"], public_name, user_context=user_context)
|
||||
return {
|
||||
"uri": self.repository.to_plugin_uri(record["id"]),
|
||||
"name": record["metadata"]["title"],
|
||||
@@ -198,9 +199,11 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
|
||||
response_data = self._get_response(user_context, request_url)
|
||||
return self._get_record_files_from_response(record_id, response_data)
|
||||
|
||||
def create_draft_record(self, title: str, user_context: OptionalUserContext = None) -> RemoteDirectory:
|
||||
def create_draft_record(
|
||||
self, title: str, public_name: Optional[str] = None, user_context: OptionalUserContext = None
|
||||
) -> RemoteDirectory:
|
||||
today = datetime.date.today().isoformat()
|
||||
creator = self._get_creator_from_user_context(user_context)
|
||||
creator = self._get_creator_from_public_name(public_name)
|
||||
create_record_request = {
|
||||
"files": {"enabled": True},
|
||||
"metadata": {
|
||||
@@ -360,10 +363,9 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
|
||||
)
|
||||
return rval
|
||||
|
||||
def _get_creator_from_user_context(self, user_context: OptionalUserContext):
|
||||
public_name = self.get_user_preference_by_key("public_name", user_context)
|
||||
family_name = "Galaxy User"
|
||||
def _get_creator_from_public_name(self, public_name: Optional[str] = None) -> Creator:
|
||||
given_name = "Anonymous"
|
||||
family_name = "Galaxy User"
|
||||
if public_name:
|
||||
tokens = public_name.split(", ")
|
||||
if len(tokens) == 2:
|
||||
@@ -371,12 +373,16 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
|
||||
given_name = tokens[1]
|
||||
else:
|
||||
given_name = public_name
|
||||
return {"person_or_org": {"family_name": family_name, "given_name": given_name, "type": "personal"}}
|
||||
|
||||
def get_user_preference_by_key(self, key: str, user_context: OptionalUserContext):
|
||||
preferences = user_context.preferences if user_context else None
|
||||
value = preferences.get(f"{self.plugin.id}|{key}", None) if preferences else None
|
||||
return value
|
||||
return {
|
||||
"person_or_org": {
|
||||
"name": f"{given_name} {family_name}",
|
||||
"family_name": family_name,
|
||||
"given_name": given_name,
|
||||
"type": "personal",
|
||||
"identifiers": [],
|
||||
},
|
||||
"affiliations": [],
|
||||
}
|
||||
|
||||
def _get_response(
|
||||
self, user_context: OptionalUserContext, request_url: str, params: Optional[Dict[str, Any]] = None
|
||||
|
||||
Reference in New Issue
Block a user