summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_operations/tests.py49
-rw-r--r--ishtar_common/models_imports.py48
2 files changed, 86 insertions, 11 deletions
diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py
index 688af87ad..b8db7e2c7 100644
--- a/archaeological_operations/tests.py
+++ b/archaeological_operations/tests.py
@@ -4128,14 +4128,14 @@ class OperationExportMediaTest(TestCase, TestPermissionQuery, OperationInitTest)
c.login(username=self.username, password=self.password)
response = c.get(self.export_url)
- self._test_files(response, [('image_00001.png', True)])
+ self._test_files(response, [('operation_image_00001.png', True)])
self.exporter.files_to_export = 'A'
self.exporter.save()
response = c.get(self.export_url)
self._test_files(
response,
- [('image_00001.png', True), ('file_00001.txt', False), ]
+ [('operation_image_00001.png', True), ('operation_file_00001.txt', False), ]
)
self.exporter.thumbnail_for_images = True
@@ -4143,7 +4143,50 @@ class OperationExportMediaTest(TestCase, TestPermissionQuery, OperationInitTest)
response = c.get(self.export_url)
self._test_files(
response,
- [('image_00001.jpg', True), ('file_00001.txt', False), ]
+ [('operation_image_00001.jpg', True), ('operation_file_00001.txt', False), ]
+ )
+
+ def _add_find(self):
+ cr_data = {
+ "label": "Context record",
+ "operation": self.operation,
+ "history_modifier": self.user,
+ }
+ ContextRecord = apps.get_model(
+ "archaeological_context_records", "ContextRecord"
+ )
+ cr = ContextRecord.objects.create(**cr_data)
+
+ BaseFind = apps.get_model("archaeological_finds", "BaseFind")
+ Find = apps.get_model("archaeological_finds", "Find")
+
+ bf_data = {
+ "label": "Base find",
+ "history_modifier": self.get_default_user(),
+ "context_record": cr,
+ }
+ base_find = BaseFind.objects.create(**bf_data)
+ find = Find.objects.create(
+ history_modifier=self.get_default_user(), label="Find me"
+ )
+ find.base_finds.add(base_find)
+ return cr, find
+
+ def test_cascade_update(self):
+ self.exporter.cascade = True
+ self.exporter.save()
+ cr, find = self._add_find()
+ cr.documents.add(self.documents[0])
+ find.documents.add(self.documents[0])
+ c = Client()
+ c.login(username=self.username, password=self.password)
+
+ response = c.get(self.export_url)
+ self._test_files(
+ response,
+ [('operation_image_00001.png', True),
+ ('contextrecord_image_00001.png', True),
+ ('find_image_00001.png', True),]
)
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index 175d2f25b..0157b33ee 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -3115,6 +3115,19 @@ class MediaExporter(models.Model):
return True
return False
+ def _get_down_objects(self, obj_list):
+ if not obj_list:
+ return []
+ down = []
+ for o in obj_list:
+ if o.SLUG == "basefind":
+ attrs = ["find"]
+ else:
+ attrs = getattr(o, "DOWN_MODEL_UPDATE", [])
+ for attr in attrs:
+ down += list(getattr(o, attr).all())
+ return down
+
def export(self, obj, tmpdir=None):
if not tmpdir:
tmpdir = tempfile.mkdtemp()
@@ -3138,7 +3151,26 @@ class MediaExporter(models.Model):
media_attrs.append("associated_file")
archive_path = os.path.join(tmpdir, "archive")
os.mkdir(archive_path)
- for idx, document in enumerate(obj.documents.filter(q).all()):
+ items = [obj]
+ if self.cascade:
+ down = self._get_down_objects([obj])
+ items += down
+ while down:
+ down = self._get_down_objects(down)
+ items += down
+ counters = {}
+ for item in items:
+ if not hasattr(item, "documents"):
+ continue
+ self._copy_media(item, q, media_attrs, counters, archive_path)
+ now = datetime.datetime.now()
+ archive_name = os.path.join(tmpdir, f"media-{now.strftime('%Y-%m-%d-%H%M%S')}")
+ shutil.make_archive(archive_name, "zip", archive_path)
+ return archive_name + ".zip"
+
+ def _copy_media(self, item, q, media_attrs, counters, archive_path):
+ item_type = item.SLUG
+ for idx, document in enumerate(item.documents.filter(q).all()):
for media_attr in media_attrs:
media = getattr(document, media_attr)
if not media or not media.path or not os.path.exists(media.path):
@@ -3150,12 +3182,12 @@ class MediaExporter(models.Model):
name = base_name
else:
if media_attr == "associated_file":
- name = "file"
+ name = f"{item_type}_file"
else:
- name = "image"
- name += f"_{idx + 1:05d}.{ext}"
+ name = f"{item_type}_image"
+ key = (item_type, media_attr)
+ if key not in counters:
+ counters[key] = 0
+ counters[key] += 1
+ name += f"_{idx + counters[key]:05d}.{ext}"
shutil.copy(media.path, os.path.join(archive_path, name))
- now = datetime.datetime.now()
- archive_name = os.path.join(tmpdir, f"media-{now.strftime('%Y-%m-%d-%H%M%S')}")
- shutil.make_archive(archive_name, "zip", archive_path)
- return archive_name + ".zip"