Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/api/edit.py
# Copyright (C) 2017-2020 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 typing import Any, Dict, Optional, Tuple | from typing import Any, Dict | ||||
from rest_framework import status | |||||
from rest_framework.request import Request | from rest_framework.request import Request | ||||
from swh.deposit.models import Deposit | from swh.deposit.models import Deposit | ||||
from swh.model.identifiers import parse_swhid | from swh.model.identifiers import parse_swhid | ||||
from ..config import ( | from ..config import DEPOSIT_STATUS_LOAD_SUCCESS | ||||
DEPOSIT_STATUS_LOAD_SUCCESS, | |||||
EDIT_SE_IRI, | |||||
EM_IRI, | |||||
) | |||||
from ..errors import BAD_REQUEST, BadRequestError, ParserError, make_error_dict | from ..errors import BAD_REQUEST, BadRequestError, ParserError, make_error_dict | ||||
from ..parsers import SWHAtomEntryParser, SWHMultiPartParser | from ..parsers import SWHAtomEntryParser, SWHMultiPartParser | ||||
from .common import APIDelete, APIPost, APIPut | from .common import APIDelete, APIPut | ||||
class EditAPI(APIPost, APIPut, APIDelete): | class EditAPI(APIPut, APIDelete): | ||||
"""Deposit request class defining api endpoints for sword deposit. | """Deposit request class defining api endpoints for sword deposit. | ||||
What's known as 'Edit-IRI' and 'SE-IRI' in the sword specification. | What's known as 'Edit-IRI' in the sword specification. | ||||
HTTP verbs supported: POST (SE IRI), PUT (Edit IRI), DELETE | HTTP verbs supported: PUT, DELETE | ||||
""" | """ | ||||
parser_classes = (SWHMultiPartParser, SWHAtomEntryParser) | parser_classes = (SWHMultiPartParser, SWHAtomEntryParser) | ||||
def restrict_access( | def restrict_access( | ||||
self, request: Request, headers: Dict, deposit: Deposit | self, request: Request, headers: Dict, deposit: Deposit | ||||
) -> Dict[str, Any]: | ) -> Dict[str, Any]: | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | ) -> Dict[str, Any]: | ||||
return { | return { | ||||
"deposit_id": deposit.id, | "deposit_id": deposit.id, | ||||
"deposit_date": deposit_request.date, | "deposit_date": deposit_request.date, | ||||
"status": deposit.status, | "status": deposit.status, | ||||
"archive": None, | "archive": None, | ||||
} | } | ||||
def process_post( | |||||
self, | |||||
request, | |||||
headers: Dict, | |||||
collection_name: str, | |||||
deposit_id: Optional[int] = None, | |||||
) -> Tuple[int, str, Dict]: | |||||
"""Add new metadata/archive to existing deposit. | |||||
This allows the following scenarios to occur: | |||||
- multipart: Add new metadata and archive to a deposit in status partial with | |||||
the provided ones. | |||||
- empty atom: Allows to finalize a deposit in status partial (transition to | |||||
deposited). | |||||
source: | |||||
- http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#protocoloperations_addingcontent_metadata | |||||
- http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#protocoloperations_addingcontent_multipart | |||||
- http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#continueddeposit_complete | |||||
Returns: | |||||
In optimal case for a multipart and atom-entry update, a | |||||
201 Created response. The body response will hold a | |||||
deposit. And the response headers will contain an entry | |||||
'Location' with the EM-IRI. | |||||
For the empty post case, this returns a 200. | |||||
""" # noqa | |||||
assert deposit_id is not None | |||||
if request.content_type.startswith("multipart/"): | |||||
data = self._multipart_upload( | |||||
request, headers, collection_name, deposit_id=deposit_id | |||||
) | |||||
return (status.HTTP_201_CREATED, EM_IRI, data) | |||||
content_length = headers["content-length"] or 0 | |||||
if content_length == 0 and headers["in-progress"] is False: | |||||
# check for final empty post | |||||
data = self._empty_post(request, headers, collection_name, deposit_id) | |||||
return (status.HTTP_200_OK, EDIT_SE_IRI, data) | |||||
data = self._atom_entry( | |||||
request, headers, collection_name, deposit_id=deposit_id | |||||
) | |||||
return (status.HTTP_201_CREATED, EM_IRI, data) | |||||
def process_delete(self, req, collection_name: str, deposit_id: int) -> Dict: | def process_delete(self, req, collection_name: str, deposit_id: int) -> Dict: | ||||
"""Delete the container (deposit). | """Delete the container (deposit). | ||||
source: http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#protocoloperations_deleteconteiner # noqa | source: http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html#protocoloperations_deleteconteiner # noqa | ||||
""" | """ | ||||
return self._delete_deposit(collection_name, deposit_id) | return self._delete_deposit(collection_name, deposit_id) |