diff --git a/oarepo_doi/actions/doi.py b/oarepo_doi/actions/doi.py index 49d225a..620a84f 100644 --- a/oarepo_doi/actions/doi.py +++ b/oarepo_doi/actions/doi.py @@ -1,8 +1,10 @@ -from invenio_requests.customizations import actions from flask import current_app -from oarepo_doi.api import create_doi, edit_doi +from oarepo_doi.api import create_doi +from oarepo_requests.actions.generic import OARepoAcceptAction, OARepoSubmitAction +from invenio_base.utils import obj_or_import_string -class CreateDoiAction(actions.CreateAction): + +class CreateDoiAction(OARepoAcceptAction): log_event = True def __init__(self, *args, **kwargs): @@ -11,6 +13,7 @@ def __init__(self, *args, **kwargs): self.mode = current_app.config.get("DATACITE_MODE") self.url = current_app.config.get("DATACITE_URL") self.mapping = current_app.config.get("DATACITE_MAPPING") + self.specified_doi = current_app.config.get("DATACITE_SPECIFIED_ID") self.username = None self.password = None @@ -26,49 +29,33 @@ def credentials(self, community): self.password = community_credentials["password"] self.prefix = community_credentials["prefix"] + def execute(self, identity, uow, *args, **kwargs): topic = self.request.topic.resolve() - self.credentials(topic['parent']['communities']['default']) + self.credentials(topic.parent['communities']['default']) if topic.is_draft: - create_doi(self, topic, topic["metadata"], None) + create_doi(self, topic, topic, None) else: - create_doi(self, topic, topic["metadata"], "publish") + create_doi(self, topic, topic, "publish") super().execute(identity, uow) - -class EditDoiAction(actions.AcceptAction): +class ValidateDataForDoiAction(OARepoSubmitAction): log_event = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.mode = current_app.config.get("DATACITE_MODE") - self.url = current_app.config.get("DATACITE_URL") self.mapping = current_app.config.get("DATACITE_MAPPING") - self.username = None - self.password = None - self.prefix = None - - def credentials(self, community): - credentials_def = current_app.config.get("DATACITE_CREDENTIALS") - - community_credentials = getattr(credentials_def, community, None) - if community_credentials is None and "DATACITE_CREDENTIALS_DEFAULT" in current_app.config: - community_credentials = current_app.config.get("DATACITE_CREDENTIALS_DEFAULT") - self.username = community_credentials["username"] - self.password = community_credentials["password"] - self.prefix = community_credentials["prefix"] def execute(self, identity, uow, *args, **kwargs): topic = self.request.topic.resolve() - self.credentials(topic['parent']['communities']['default']) - if topic.is_draft: - edit_doi(self, topic, None) - else: - edit_doi(self, topic, "publish") + mapping = obj_or_import_string(self.mapping[topic.schema])() + errors = mapping.metadata_check(topic) + if len(errors) > 0: + return super().execute(identity, uow) \ No newline at end of file diff --git a/oarepo_doi/api.py b/oarepo_doi/api.py index d939856..6ce2346 100644 --- a/oarepo_doi/api.py +++ b/oarepo_doi/api.py @@ -2,22 +2,38 @@ import json from invenio_base.utils import obj_or_import_string from flask import current_app - +from oarepo_runtime.datastreams.utils import get_record_service_for_record +from invenio_access.permissions import system_identity def create_doi(service, record, data, event = None ): """ if event = None, doi will be created as a draft.""" mapping = obj_or_import_string(service.mapping[record.schema])() - errors = mapping.metadata_check(data) + errors = mapping.metadata_check(record) + record_service = get_record_service_for_record(record) + record["links"] = record_service.links_item_tpl.expand(system_identity, record) + if len(errors) > 0 and event: return #todo: dois can not be published with missing mandatory values - request_metadata = mapping.create_datacite_payload(data) + request_metadata = { + "data": { + "type": "dois", + "attributes": { + } + } + } + + payload = mapping.create_datacite_payload(data) + request_metadata["data"]["attributes"] = payload + if service.specified_doi: + doi = f"{service.prefix}/{record['id']}" + request_metadata["data"]["attributes"]["doi"] = doi if event: request_metadata["data"]["attributes"]["event"] = event - request_metadata["data"]["attributes"]["prefix"] = service.prefix + request_metadata["data"]["attributes"]["prefix"] = str(service.prefix) request = requests.post(url=service.url, json=request_metadata, headers={'Content-type': 'application/vnd.api+json'}, auth=(service.username, service.password) @@ -37,8 +53,11 @@ def edit_doi(service, record, event = None): mapping = obj_or_import_string(service.mapping[record.schema])() errors = mapping.metadata_check(record) + record_service = get_record_service_for_record(record) + record["links"] = record_service.links_item_tpl.expand(system_identity, record) if len(errors) > 0 and event: return #todo: dois can not be published with missing mandatory values + doi_value = mapping.get_doi(record) if doi_value: if not service.url.endswith('/'): @@ -56,4 +75,3 @@ def edit_doi(service, record, event = None): if request.status_code != 200: raise requests.ConnectionError("Expected status code 200, but got {}".format(request.status_code)) - diff --git a/oarepo_doi/ext.py b/oarepo_doi/ext.py index 9d9a263..26670ce 100644 --- a/oarepo_doi/ext.py +++ b/oarepo_doi/ext.py @@ -18,3 +18,5 @@ def init_config(self, app): app.config["DATACITE_URL"] = 'https://api.datacite.org/dois' if "DATACITE_MODE" not in app.config: app.config["DATACITE_MODE"] = "ON_EVENT" + if "DATACITE_SPECIFIED_ID" not in app.config: + app.config["DATACITE_SPECIFIED_ID"] = False diff --git a/oarepo_doi/services/components/__init__.py b/oarepo_doi/services/components/__init__.py index 59a6d50..0e0c9b2 100644 --- a/oarepo_doi/services/components/__init__.py +++ b/oarepo_doi/services/components/__init__.py @@ -15,6 +15,7 @@ def __init__(self, *args, **kwargs): self.mode = current_app.config.get("DATACITE_MODE") self.url = current_app.config.get("DATACITE_URL") self.mapping = current_app.config.get("DATACITE_MAPPING") + self.specified_doi = current_app.config.get("DATACITE_SPECIFIED_ID") self.username = None self.password = None @@ -39,12 +40,12 @@ def create(self, identity, data=None, record=None, **kwargs): create_doi(self, record,data, None) def update_draft(self, identity, data=None, record=None, **kwargs): - if self.mode == "AUTOMATIC_DRAFT": + if self.mode == "AUTOMATIC_DRAFT" or self.mode == "ON_EVENT": self.credentials(data['parent']['communities']['default']) edit_doi(self, record) def update(self, identity, data=None, record=None, **kwargs): - if self.mode == "AUTOMATIC_DRAFT" or self.mode == "AUTOMATIC": + if self.mode == "AUTOMATIC_DRAFT" or self.mode == "AUTOMATIC" or self.mode == "ON_EVENT": self.credentials(data['parent']['communities']['default']) edit_doi(self, record) diff --git a/oarepo_doi/types/doi.py b/oarepo_doi/types/doi.py index e9df5d0..6be2e2f 100644 --- a/oarepo_doi/types/doi.py +++ b/oarepo_doi/types/doi.py @@ -1,29 +1,17 @@ from invenio_requests.customizations import RequestType from oarepo_runtime.i18n import lazy_gettext as _ -from ..actions.doi import CreateDoiAction, EditDoiAction +from ..actions.doi import CreateDoiAction, ValidateDataForDoiAction from oarepo_requests.types.ref_types import ModelRefTypes -from oarepo_requests.types.generic import NonDuplicableOARepoRequestType -class CreateDoiRequestType(NonDuplicableOARepoRequestType): - type_id = "create_doi" - name = _("create_doi") +class CreateDoiRequestType(RequestType): + type_id = "assign_doi" + name = _("assign_doi") available_actions = { **RequestType.available_actions, "accept": CreateDoiAction, + "submit": ValidateDataForDoiAction, } receiver_can_be_none = True allowed_topic_ref_types = ModelRefTypes(published=True, draft=True) - -class EditDoiRequestType(NonDuplicableOARepoRequestType): - type_id = "edit_doi" - name = _("edit_doi") - - available_actions = { - **RequestType.available_actions, - "accept": EditDoiAction, - } - - receiver_can_be_none = True - allowed_topic_ref_types = ModelRefTypes(published=True, draft=True) \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index a8885e2..3a73dcd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = oarepo-doi -version = 1.0.2 +version = 1.0.3 description = authors = Alzbeta Pokorna readme = README.md @@ -35,4 +35,3 @@ invenio_base.api_apps = oarepodoi = oarepo_doi.ext:OARepoDOI invenio_requests.types = create-doi-request = oarepo_doi.types.doi:CreateDoiRequestType - edit-doi-request = oarepo_doi.types.doi:EditDoiRequestType \ No newline at end of file