summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2025-06-18 11:27:30 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2025-06-18 11:27:30 +0200
commitc228fdc8c6e498dc306f45f28c3475d8ca42f4a1 (patch)
tree5d03be9c09bb8130d59512d579cfcea132f9cd7d /ishtar_common
parent93e14d0aeeb101d3595a21315b07871dda9c9db3 (diff)
downloadIshtar-c228fdc8c6e498dc306f45f28c3475d8ca42f4a1.tar.bz2
Ishtar-c228fdc8c6e498dc306f45f28c3475d8ca42f4a1.zip
✨ Media exporter: manage cascade update
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/models_imports.py48
1 files changed, 40 insertions, 8 deletions
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"