Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/api/private/deposit_update_status.py
# Copyright (C) 2017-2019 The Software Heritage developers | # Copyright (C) 2017-2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
from rest_framework.parsers import JSONParser | from rest_framework.parsers import JSONParser | ||||
from swh.model.identifiers import persistent_identifier, REVISION, DIRECTORY | from swh.model.identifiers import DIRECTORY, persistent_identifier, REVISION, SNAPSHOT | ||||
from . import SWHPrivateAPIView | from . import SWHPrivateAPIView | ||||
from ..common import SWHPutDepositAPI | from ..common import SWHPutDepositAPI | ||||
from ...errors import make_error_dict, BAD_REQUEST | from ...errors import make_error_dict, BAD_REQUEST | ||||
from ...models import Deposit, DEPOSIT_STATUS_DETAIL | from ...models import Deposit, DEPOSIT_STATUS_DETAIL | ||||
from ...models import DEPOSIT_STATUS_LOAD_SUCCESS | from ...models import DEPOSIT_STATUS_LOAD_SUCCESS | ||||
MANDATORY_KEYS = ["origin_url", "revision_id", "directory_id", "snapshot_id"] | |||||
class SWHUpdateStatusDeposit(SWHPrivateAPIView, SWHPutDepositAPI): | class SWHUpdateStatusDeposit(SWHPrivateAPIView, SWHPutDepositAPI): | ||||
"""Deposit request class to update the deposit's status. | """Deposit request class to update the deposit's status. | ||||
HTTP verbs supported: PUT | HTTP verbs supported: PUT | ||||
""" | """ | ||||
parser_classes = (JSONParser,) | parser_classes = (JSONParser,) | ||||
def additional_checks(self, request, headers, collection_name, deposit_id=None): | def additional_checks(self, request, headers, collection_name, deposit_id=None): | ||||
"""Enrich existing checks to the default ones. | """Enrich existing checks to the default ones. | ||||
New checks: | New checks: | ||||
- Ensure the status is provided | - Ensure the status is provided | ||||
- Ensure it exists | - Ensure it exists | ||||
- no missing information on load success update | |||||
""" | """ | ||||
data = request.data | data = request.data | ||||
status = data.get("status") | status = data.get("status") | ||||
if not status: | if not status: | ||||
msg = "The status key is mandatory with possible values %s" % list( | msg = "The status key is mandatory with possible values %s" % list( | ||||
DEPOSIT_STATUS_DETAIL.keys() | DEPOSIT_STATUS_DETAIL.keys() | ||||
) | ) | ||||
return make_error_dict(BAD_REQUEST, msg) | return make_error_dict(BAD_REQUEST, msg) | ||||
if status not in DEPOSIT_STATUS_DETAIL: | if status not in DEPOSIT_STATUS_DETAIL: | ||||
msg = "Possible status in %s" % list(DEPOSIT_STATUS_DETAIL.keys()) | msg = "Possible status in %s" % list(DEPOSIT_STATUS_DETAIL.keys()) | ||||
return make_error_dict(BAD_REQUEST, msg) | return make_error_dict(BAD_REQUEST, msg) | ||||
if status == DEPOSIT_STATUS_LOAD_SUCCESS: | if status == DEPOSIT_STATUS_LOAD_SUCCESS: | ||||
swh_id = data.get("revision_id") | missing_keys = [] | ||||
if not swh_id: | for key in MANDATORY_KEYS: | ||||
msg = "Updating status to %s requires a revision_id key" % (status,) | value = data.get(key) | ||||
if value is None: | |||||
missing_keys.append(key) | |||||
if missing_keys: | |||||
msg = ( | |||||
f"Updating deposit status to {status}" | |||||
anlambert: you can remove the `+` here | |||||
f" requires information {','.join(missing_keys)}" | |||||
) | |||||
return make_error_dict(BAD_REQUEST, msg) | return make_error_dict(BAD_REQUEST, msg) | ||||
return {} | return {} | ||||
def process_put(self, request, headers, collection_name, deposit_id): | def process_put(self, request, headers, collection_name, deposit_id): | ||||
"""Update the deposit's status | """Update the deposit with status and SWHIDs | ||||
Not Done Inline Actionss/new ids/SWHIDs/ anlambert: s/new ids/SWHIDs/ | |||||
Returns: | Returns: | ||||
204 No content | 204 No content | ||||
400 Bad request if checks fail | |||||
""" | """ | ||||
data = request.data | |||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = Deposit.objects.get(pk=deposit_id) | ||||
deposit.status = request.data["status"] # checks already done before | |||||
origin_url = request.data.get("origin_url") | status = data["status"] | ||||
deposit.status = status | |||||
if status == DEPOSIT_STATUS_LOAD_SUCCESS: | |||||
origin_url = data["origin_url"] | |||||
directory_id = data["directory_id"] | |||||
revision_id = data["revision_id"] | |||||
dir_id = persistent_identifier(DIRECTORY, directory_id) | |||||
snp_id = persistent_identifier(SNAPSHOT, data["snapshot_id"]) | |||||
rev_id = persistent_identifier(REVISION, revision_id) | |||||
dir_id = request.data.get("directory_id") | deposit.swh_id = dir_id | ||||
if dir_id: | # new id with contextual information | ||||
deposit.swh_id = persistent_identifier(DIRECTORY, dir_id) | |||||
deposit.swh_id_context = persistent_identifier( | deposit.swh_id_context = persistent_identifier( | ||||
DIRECTORY, dir_id, metadata={"origin": origin_url} | DIRECTORY, | ||||
directory_id, | |||||
metadata={ | |||||
"origin": origin_url, | |||||
"visit": snp_id, | |||||
"anchor": rev_id, | |||||
"path": "/", | |||||
}, | |||||
) | ) | ||||
rev_id = request.data.get("revision_id") | # backward compatibility for now | ||||
if rev_id: | deposit.swh_anchor_id = rev_id | ||||
deposit.swh_anchor_id = persistent_identifier(REVISION, rev_id) | |||||
deposit.swh_anchor_id_context = persistent_identifier( | deposit.swh_anchor_id_context = persistent_identifier( | ||||
REVISION, rev_id, metadata={"origin": origin_url} | REVISION, revision_id, metadata={"origin": origin_url} | ||||
) | ) | ||||
else: # rejected | |||||
deposit.status = status | |||||
Done Inline ActionsWe keep those 2 for now. ardumont: We keep those 2 for now.
That allows to uncouple the migration of the previous deposit to the… | |||||
Done Inline Actions(The code moved so this comment is unreadable now...) I meant, we keep the deposit.swh_anchor_id and ardumont: (The code moved so this comment is unreadable now...)
I meant, we keep the `deposit. | |||||
deposit.save() | deposit.save() | ||||
return {} | return {} |
you can remove the + here