diff --git a/swh/deposit/api/deposit_status.py b/swh/deposit/api/deposit_status.py --- a/swh/deposit/api/deposit_status.py +++ b/swh/deposit/api/deposit_status.py @@ -100,10 +100,19 @@ 'status': deposit.status, 'status_detail': status_detail, 'swh_id': None, + 'swh_id_context': None, + 'swh_anchor_id': None, + 'swh_anchor_id_context': None, } if deposit.swh_id: context['swh_id'] = deposit.swh_id + if deposit.swh_id_context: + context['swh_id_context'] = deposit.swh_id_context + if deposit.swh_anchor_id: + context['swh_anchor_id'] = deposit.swh_anchor_id + if deposit.swh_anchor_id_context: + context['swh_anchor_id_context'] = deposit.swh_anchor_id_context return render(req, 'deposit/status.xml', context=context, diff --git a/swh/deposit/api/private/deposit_update_status.py b/swh/deposit/api/private/deposit_update_status.py --- a/swh/deposit/api/private/deposit_update_status.py +++ b/swh/deposit/api/private/deposit_update_status.py @@ -5,7 +5,9 @@ from rest_framework.parsers import JSONParser -from swh.model.identifiers import persistent_identifier, REVISION +from swh.model.identifiers import ( + persistent_identifier, REVISION, DIRECTORY +) from ..common import SWHPutDepositAPI, SWHPrivateAPIView from ...errors import make_error_dict, BAD_REQUEST @@ -66,9 +68,22 @@ """ deposit = Deposit.objects.get(pk=deposit_id) deposit.status = req.data['status'] # checks already done before - swh_id = req.data.get('revision_id') - if swh_id: - deposit.swh_id = persistent_identifier(REVISION, {'id': swh_id}) + + origin_url = req.data.get('origin_url') + + dir_id = req.data.get('directory_id') + if dir_id: + deposit.swh_id = persistent_identifier(DIRECTORY, dir_id) + deposit.swh_id_context = persistent_identifier( + DIRECTORY, dir_id, metadata={'origin': origin_url}) + + rev_id = req.data.get('revision_id') + if rev_id: + deposit.swh_anchor_id = persistent_identifier( + REVISION, rev_id) + deposit.swh_anchor_id_context = persistent_identifier( + REVISION, rev_id, metadata={'origin': origin_url}) + deposit.save() return {} diff --git a/swh/deposit/client/__init__.py b/swh/deposit/client/__init__.py --- a/swh/deposit/client/__init__.py +++ b/swh/deposit/client/__init__.py @@ -127,18 +127,21 @@ raise ValueError(msg) def status_update(self, update_status_url, status, - revision_id=None): + revision_id=None, directory_id=None): """Update the deposit's status. Args: update_status_url (str): the full deposit's archive status (str): The status to update the deposit with revision_id (str/None): the revision's identifier to update to + directory_id (str/None): the directory's identifier to update to """ payload = {'status': status} if revision_id: payload['revision_id'] = revision_id + if directory_id: + payload['directory_id'] = directory_id self.do('put', update_status_url, json=payload) @@ -348,11 +351,38 @@ else: deposit_swh_id = None + vals = tree.xpath( + '/x:entry/x:deposit_swh_id_context', + namespaces={'x': 'http://www.w3.org/2005/Atom'}) + if vals: + deposit_swh_id_context = vals[0].text + else: + deposit_swh_id_context = None + + vals = tree.xpath( + '/x:entry/x:deposit_swh_anchor_id', + namespaces={'x': 'http://www.w3.org/2005/Atom'}) + if vals: + deposit_swh_anchor_id = vals[0].text + else: + deposit_swh_anchor_id = None + + vals = tree.xpath( + '/x:entry/x:deposit_swh_anchor_id_context', + namespaces={'x': 'http://www.w3.org/2005/Atom'}) + if vals: + deposit_swh_anchor_id_context = vals[0].text + else: + deposit_swh_anchor_id_context = None + return { 'deposit_id': deposit_id, 'deposit_status': deposit_status, 'deposit_status_detail': deposit_status_detail, 'deposit_swh_id': deposit_swh_id, + 'deposit_swh_id_context': deposit_swh_id_context, + 'deposit_swh_anchor_id': deposit_swh_anchor_id, + 'deposit_swh_anchor_id_context': deposit_swh_anchor_id_context, } diff --git a/swh/deposit/loader/loader.py b/swh/deposit/loader/loader.py --- a/swh/deposit/loader/loader.py +++ b/swh/deposit/loader/loader.py @@ -109,15 +109,23 @@ self.client.status_update(self.deposit_update_url, status='failed') return - # first retrieve the new revision - [rev_id] = self.objects['revision'].keys() + + revisions = self.objects['revision'] + # Retrieve the revision + [rev_id] = revisions.keys() + rev = revisions[rev_id] if rev_id: - rev_id_hex = hashutil.hash_to_hex(rev_id) - # then update the deposit's status to success with its - # revision-id - self.client.status_update(self.deposit_update_url, - status='done', - revision_id=rev_id_hex) + rev_id = hashutil.hash_to_hex(rev_id) + dir_id = rev['directory'] + if dir_id: + dir_id = hashutil.hash_to_hex(dir_id) + + # update the deposit's status to success with its + # revision-id and directory-id + self.client.status_update(self.deposit_update_url, + status='done', + revision_id=rev_id, + directory_id=dir_id) except Exception: self.log.exception( 'Problem when trying to update the deposit\'s status') diff --git a/swh/deposit/migrations/0014_auto_20180720_1221.py b/swh/deposit/migrations/0014_auto_20180720_1221.py new file mode 100644 --- /dev/null +++ b/swh/deposit/migrations/0014_auto_20180720_1221.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.14 on 2018-07-20 12:21 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('deposit', '0013_depositrequest_raw_metadata'), + ] + + operations = [ + migrations.AddField( + model_name='deposit', + name='swh_anchor_id', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='deposit', + name='swh_anchor_id_context', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='deposit', + name='swh_id_context', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/swh/deposit/models.py b/swh/deposit/models.py --- a/swh/deposit/models.py +++ b/swh/deposit/models.py @@ -112,6 +112,9 @@ client = models.ForeignKey('DepositClient', models.DO_NOTHING) # SWH's loading result identifier swh_id = models.TextField(blank=True, null=True) + swh_id_context = models.TextField(blank=True, null=True) + swh_anchor_id = models.TextField(blank=True, null=True) + swh_anchor_id_context = models.TextField(blank=True, null=True) # Deposit's status regarding loading status = models.TextField( choices=DEPOSIT_STATUS, diff --git a/swh/deposit/templates/deposit/status.xml b/swh/deposit/templates/deposit/status.xml --- a/swh/deposit/templates/deposit/status.xml +++ b/swh/deposit/templates/deposit/status.xml @@ -5,4 +5,7 @@ {{ status }} {{ status_detail }} {% if swh_id is not None %}{{ swh_id }}{% endif %} + {% if swh_id_context is not None %}{{ swh_id_context }}{% endif %} + {% if swh_anchor_id is not None %}{{ swh_anchor_id }}{% endif %} + {% if swh_anchor_id_context is not None %}{{ swh_anchor_id_context }}{% endif %} diff --git a/swh/deposit/tests/api/test_deposit_status.py b/swh/deposit/tests/api/test_deposit_status.py --- a/swh/deposit/tests/api/test_deposit_status.py +++ b/swh/deposit/tests/api/test_deposit_status.py @@ -69,14 +69,22 @@ DEPOSIT_STATUS_DETAIL[DEPOSIT_STATUS_DEPOSITED]) @istest - def status_with_swh_id(self): + def status_with_swh_information(self): _status = DEPOSIT_STATUS_LOAD_SUCCESS - _swh_id = '548b3c0a2bb43e1fca191e24b5803ff6b3bc7c10' + _context = 'https://hal.archives-ouvertes.fr/hal-01727745' + _swh_id = 'swh:1:dir:42a13fc721c8716ff695d0d62fc851d641f3a12b' + _swh_id_context = '%s;%s' % (_swh_id, _context) + _swh_anchor_id = 'swh:rev:1:548b3c0a2bb43e1fca191e24b5803ff6b3bc7c10' + _swh_anchor_id_context = '%s;%s' % (_swh_anchor_id, _context) # given deposit_id = self.create_deposit_with_status( status=_status, - swh_id=_swh_id) + swh_id=_swh_id, + swh_id_context=_swh_id_context, + swh_anchor_id=_swh_anchor_id, + swh_anchor_id_context=_swh_anchor_id_context + ) url = reverse(STATE_IRI, args=[self.collection.name, deposit_id]) @@ -91,6 +99,10 @@ self.assertEqual(r['deposit_status_detail'], DEPOSIT_STATUS_DETAIL[DEPOSIT_STATUS_LOAD_SUCCESS]) self.assertEqual(r['deposit_swh_id'], _swh_id) + self.assertEqual(r['deposit_swh_id_context'], _swh_id_context) + self.assertEqual(r['deposit_swh_anchor_id'], _swh_anchor_id) + self.assertEqual(r['deposit_swh_anchor_id_context'], + _swh_anchor_id_context) @istest def status_on_unknown_deposit(self): diff --git a/swh/deposit/tests/api/test_deposit_update_status.py b/swh/deposit/tests/api/test_deposit_update_status.py --- a/swh/deposit/tests/api/test_deposit_update_status.py +++ b/swh/deposit/tests/api/test_deposit_update_status.py @@ -52,16 +52,23 @@ self.assertEquals(deposit.status, _status) @istest - def update_deposit_with_success_loading_and_swh_id(self): - """Existing status for update should return a 204 response + def update_deposit_status_with_info(self): + """Existing status for update with info should return a 204 response """ url = reverse(PRIVATE_PUT_DEPOSIT, args=[self.collection.name, self.deposit.id]) expected_status = DEPOSIT_STATUS_LOAD_SUCCESS + origin_url = 'something' + directory_id = '42a13fc721c8716ff695d0d62fc851d641f3a12b' revision_id = '47dc6b4636c7f6cba0df83e3d5490bf4334d987e' - expected_id = 'swh:1:rev:%s' % revision_id + expected_swh_id = 'swh:1:dir:%s' % directory_id + expected_swh_id_context = 'swh:1:dir:%s;origin=%s' % ( + directory_id, origin_url) + expected_swh_anchor_id = 'swh:1:rev:%s' % revision_id + expected_swh_anchor_id_context = 'swh:1:rev:%s;origin=%s' % ( + revision_id, origin_url) response = self.client.put( url, @@ -69,13 +76,19 @@ data=json.dumps({ 'status': expected_status, 'revision_id': revision_id, + 'directory_id': directory_id, + 'origin_url': origin_url, })) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) deposit = Deposit.objects.get(pk=self.deposit.id) self.assertEquals(deposit.status, expected_status) - self.assertEquals(deposit.swh_id, expected_id) + self.assertEquals(deposit.swh_id, expected_swh_id) + self.assertEquals(deposit.swh_id_context, expected_swh_id_context) + self.assertEquals(deposit.swh_anchor_id, expected_swh_anchor_id) + self.assertEquals(deposit.swh_anchor_id_context, + expected_swh_anchor_id_context) @istest def update_deposit_status_will_fail_with_unknown_status(self): diff --git a/swh/deposit/tests/common.py b/swh/deposit/tests/common.py --- a/swh/deposit/tests/common.py +++ b/swh/deposit/tests/common.py @@ -438,7 +438,12 @@ def create_deposit_with_status( self, status, - external_id='some-external-id-1', swh_id=None, status_detail=None): + external_id='some-external-id-1', + swh_id=None, + swh_id_context=None, + swh_anchor_id=None, + swh_anchor_id_context=None, + status_detail=None): # create an invalid deposit which we will update further down the line deposit_id = self.create_deposit_with_invalid_archive(external_id) @@ -451,8 +456,13 @@ deposit.status = status if swh_id: deposit.swh_id = swh_id + if swh_id_context: + deposit.swh_id_context = swh_id_context + if swh_anchor_id: + deposit.swh_anchor_id = swh_anchor_id + if swh_anchor_id_context: + deposit.swh_anchor_id_context = swh_anchor_id_context deposit.save() - return deposit_id def create_simple_deposit_partial(self, external_id='some-external-id'): diff --git a/swh/deposit/tests/loader/common.py b/swh/deposit/tests/loader/common.py --- a/swh/deposit/tests/loader/common.py +++ b/swh/deposit/tests/loader/common.py @@ -35,10 +35,13 @@ r = self.client.get(metadata_url) return json.loads(r.content.decode('utf-8')) - def status_update(self, update_status_url, status, revision_id=None): + def status_update(self, update_status_url, status, + revision_id=None, directory_id=None): payload = {'status': status} if revision_id: payload['revision_id'] = revision_id + if directory_id: + payload['directory_id'] = directory_id self.client.put(update_status_url, content_type='application/json', data=json.dumps(payload))