Skip to content

Commit 7a97a85

Browse files
committed
OpenConceptLab/ocl_issues#22 | Retired concepts and/or mappings are now excluded from exports
1 parent e6f4de2 commit 7a97a85

File tree

7 files changed

+31
-18
lines changed

7 files changed

+31
-18
lines changed

core/collections/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
CollectionVersionSummaryDetailSerializer, CollectionReferenceDetailSerializer)
3232
from core.collections.utils import is_version_specified
3333
from core.common.constants import (
34-
HEAD, RELEASED_PARAM, PROCESSING_PARAM, OK_MESSAGE, NOT_FOUND, MUST_SPECIFY_EXTRA_PARAM_IN_BODY
34+
HEAD, INCLUDE_RETIRED_PARAM, RELEASED_PARAM, PROCESSING_PARAM, OK_MESSAGE, NOT_FOUND, MUST_SPECIFY_EXTRA_PARAM_IN_BODY
3535
)
3636
from core.common.mixins import (
3737
ConceptDictionaryCreateMixin, ListWithHeadersMixin, ConceptDictionaryUpdateMixin,
@@ -594,7 +594,8 @@ class CollectionVersionExportView(ConceptContainerExportMixin, CollectionVersion
594594
def handle_export_version(self):
595595
version = self.get_object()
596596
try:
597-
export_collection.delay(version.id)
597+
include_retired = parse_boolean_query_param(self.request, INCLUDE_RETIRED_PARAM)
598+
export_collection.delay(version.id, include_retired)
598599
return status.HTTP_202_ACCEPTED
599600
except AlreadyQueued:
600601
return status.HTTP_409_CONFLICT

core/common/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,11 @@ def is_exporting(self):
722722
def export_path(self):
723723
last_update = self.last_child_update.strftime('%Y%m%d%H%M%S')
724724
return self.generic_export_path(suffix="{}.zip".format(last_update))
725+
726+
@cached_property
727+
def exclude_retired_export_path(self):
728+
last_update = self.last_child_update.strftime('%Y%m%d%H%M%S')
729+
return self.generic_export_path(suffix="{}_unretired.zip".format(last_update))
725730

726731
def generic_export_path(self, suffix='*'):
727732
path = "{}/{}_{}.".format(self.parent_resource, self.mnemonic, self.version)

core/common/tasks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def delete_organization(org_id):
4343

4444

4545
@app.task(base=QueueOnce, bind=True)
46-
def export_source(self, version_id):
46+
def export_source(self, version_id, include_retired=True):
4747
from core.sources.models import Source
4848
logger.info('Finding source version...')
4949

@@ -58,14 +58,14 @@ def export_source(self, version_id):
5858
version.add_processing(self.request.id)
5959
try:
6060
logger.info('Found source version %s. Beginning export...', version.version)
61-
write_export_file(version, 'source', 'core.sources.serializers.SourceVersionExportSerializer', logger)
61+
write_export_file(version, include_retired, 'source', 'core.sources.serializers.SourceVersionExportSerializer', logger)
6262
logger.info('Export complete!')
6363
finally:
6464
version.remove_processing(self.request.id)
6565

6666

6767
@app.task(base=QueueOnce, bind=True)
68-
def export_collection(self, version_id):
68+
def export_collection(self, version_id, include_retired=True):
6969
from core.collections.models import Collection
7070
logger.info('Finding collection version...')
7171

@@ -81,7 +81,7 @@ def export_collection(self, version_id):
8181
try:
8282
logger.info('Found collection version %s. Beginning export...', version.version)
8383
write_export_file(
84-
version, 'collection', 'core.collections.serializers.CollectionVersionExportSerializer', logger
84+
version, include_retired, 'collection', 'core.collections.serializers.CollectionVersionExportSerializer', logger
8585
)
8686
logger.info('Export complete!')
8787
finally:

core/common/utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def get_class(kls):
191191

192192

193193
def write_export_file(
194-
version, resource_type, resource_serializer_type, logger
194+
version, include_retired, resource_type, resource_serializer_type, logger
195195
): # pylint: disable=too-many-statements,too-many-locals,too-many-branches
196196
from core.concepts.models import Concept
197197
from core.mappings.models import Mapping
@@ -207,6 +207,12 @@ def write_export_file(
207207
logger.info('Done serializing attributes.')
208208

209209
batch_size = 100
210+
concepts_qs = version.concepts
211+
mappings_qs = version.mappings
212+
if not include_retired:
213+
concepts_qs = concepts_qs.filter(retired=False)
214+
mappings_qs = mappings_qs.filter(retired=False)
215+
210216
is_collection = resource_type == 'collection'
211217

212218
if is_collection:
@@ -329,7 +335,7 @@ def write_export_file(
329335
logger.info(file_path)
330336
logger.info('Done compressing. Uploading...')
331337

332-
s3_key = version.export_path
338+
s3_key = version.export_path if include_retired else version.exclude_retired_export_path
333339
S3.upload_file(
334340
key=s3_key, file_path=file_path, binary=True, metadata=dict(ContentType='application/zip'),
335341
headers={'content-type': 'application/zip'}

core/integration_tests/tests_collections.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -875,29 +875,29 @@ def test_post_303(self, s3_exists_mock):
875875
def test_post_202(self, s3_exists_mock, export_collection_mock):
876876
s3_exists_mock.return_value = False
877877
response = self.client.post(
878-
'/collections/coll/v1/export/',
878+
'/collections/coll/v1/export/?includeRetired=False',
879879
HTTP_AUTHORIZATION='Token ' + self.token,
880880
format='json'
881881
)
882882

883883
self.assertEqual(response.status_code, 202)
884884
s3_exists_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))
885-
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id)
885+
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id, False)
886886

887887
@patch('core.collections.views.export_collection')
888888
@patch('core.common.services.S3.exists')
889889
def test_post_409(self, s3_exists_mock, export_collection_mock):
890890
s3_exists_mock.return_value = False
891891
export_collection_mock.delay.side_effect = AlreadyQueued('already-queued')
892892
response = self.client.post(
893-
'/collections/coll/v1/export/',
893+
'/collections/coll/v1/export/?includeRetired=False',
894894
HTTP_AUTHORIZATION='Token ' + self.token,
895895
format='json'
896896
)
897897

898898
self.assertEqual(response.status_code, 409)
899899
s3_exists_mock.assert_called_once_with("username/coll_v1.{}.zip".format(self.v1_updated_at))
900-
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id)
900+
export_collection_mock.delay.assert_called_once_with(self.collection_v1.id, False)
901901

902902

903903
class CollectionVersionListViewTest(OCLAPITestCase):

core/integration_tests/tests_sources.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -705,29 +705,29 @@ def test_post_303(self, s3_exists_mock):
705705
def test_post_202(self, s3_exists_mock, export_source_mock):
706706
s3_exists_mock.return_value = False
707707
response = self.client.post(
708-
'/sources/source1/v1/export/',
708+
'/sources/source1/v1/export/?includeRetired=False',
709709
HTTP_AUTHORIZATION='Token ' + self.token,
710710
format='json'
711711
)
712712

713713
self.assertEqual(response.status_code, 202)
714714
s3_exists_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))
715-
export_source_mock.delay.assert_called_once_with(self.source_v1.id)
715+
export_source_mock.delay.assert_called_once_with(self.source_v1.id, False)
716716

717717
@patch('core.sources.views.export_source')
718718
@patch('core.common.services.S3.exists')
719719
def test_post_409(self, s3_exists_mock, export_source_mock):
720720
s3_exists_mock.return_value = False
721721
export_source_mock.delay.side_effect = AlreadyQueued('already-queued')
722722
response = self.client.post(
723-
'/sources/source1/v1/export/',
723+
'/sources/source1/v1/export/?includeRetired=False',
724724
HTTP_AUTHORIZATION='Token ' + self.token,
725725
format='json'
726726
)
727727

728728
self.assertEqual(response.status_code, 409)
729729
s3_exists_mock.assert_called_once_with("username/source1_v1.{}.zip".format(self.v1_updated_at))
730-
export_source_mock.delay.assert_called_once_with(self.source_v1.id)
730+
export_source_mock.delay.assert_called_once_with(self.source_v1.id, False)
731731

732732

733733
class ExportSourceTaskTest(OCLAPITestCase):

core/sources/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from rest_framework.response import Response
1515

1616
from core.client_configs.views import ResourceClientConfigsView
17-
from core.common.constants import HEAD, RELEASED_PARAM, PROCESSING_PARAM, NOT_FOUND, MUST_SPECIFY_EXTRA_PARAM_IN_BODY
17+
from core.common.constants import HEAD, INCLUDE_RETIRED_PARAM, RELEASED_PARAM, PROCESSING_PARAM, NOT_FOUND, MUST_SPECIFY_EXTRA_PARAM_IN_BODY
1818
from core.common.mixins import ListWithHeadersMixin, ConceptDictionaryCreateMixin, ConceptDictionaryUpdateMixin, \
1919
ConceptContainerExportMixin, ConceptContainerProcessingMixin
2020
from core.common.permissions import CanViewConceptDictionary, CanEditConceptDictionary, HasAccessToVersionedObject, \
@@ -365,7 +365,8 @@ class SourceVersionExportView(ConceptContainerExportMixin, SourceVersionBaseView
365365
def handle_export_version(self):
366366
version = self.get_object()
367367
try:
368-
export_source.delay(version.id)
368+
include_retired = parse_boolean_query_param(self.request, INCLUDE_RETIRED_PARAM)
369+
export_source.delay(version.id, include_retired)
369370
return status.HTTP_202_ACCEPTED
370371
except AlreadyQueued:
371372
return status.HTTP_409_CONFLICT

0 commit comments

Comments
 (0)