feat: add ZIP archive support and expand structure directory matching to include location codes

This commit is contained in:
kdeterme 2026-08-21 15:14:15 +02:00
parent 0ab5fee09b
commit 04eb087cf1

View file

@ -1,5 +1,7 @@
import os
import subprocess
import tempfile
import zipfile
from django.core.management.base import BaseCommand, CommandError
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
@ -16,7 +18,7 @@ User = get_user_model()
class Command(BaseCommand):
help = (
"Imports As-Built documents from a local directory or via rclone from OneDrive "
"Imports As-Built documents from a local directory, a ZIP archive, or via rclone "
"into the 'Electromechanics / As-Built' subfolder of specified structures."
)
@ -26,6 +28,11 @@ class Command(BaseCommand):
default="/tmp/as_built_sync",
help="Path to local directory containing files/folders to import (default: /tmp/as_built_sync).",
)
parser.add_argument(
"--source-zip",
default=None,
help="Path to a ZIP file downloaded from OneDrive to extract and import.",
)
parser.add_argument(
"--rclone-remote",
default=None,
@ -55,6 +62,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):
source_dir = options["source_dir"]
source_zip = options["source_zip"]
rclone_remote = options["rclone_remote"]
target_codes = options["structures"]
dry_run = options["dry_run"]
@ -64,8 +72,18 @@ class Command(BaseCommand):
if dry_run:
self.stdout.write(self.style.WARNING("DRY RUN — no changes will be committed."))
# Optionnel: Synchronisation via rclone si un remote est spécifié
if rclone_remote:
# Traitement d'une archive ZIP si spécifiée
if source_zip:
if not os.path.isfile(source_zip):
raise CommandError(f"ZIP file '{source_zip}' does not exist.")
self.stdout.write(self.style.NOTICE(f"Extracting ZIP archive '{source_zip}' into '{source_dir}'..."))
os.makedirs(source_dir, exist_ok=True)
with zipfile.ZipFile(source_zip, 'r') as zip_ref:
zip_ref.extractall(source_dir)
self.stdout.write(self.style.SUCCESS("ZIP extraction completed."))
# Synchronisation via rclone si un remote est spécifié
elif rclone_remote:
self.stdout.write(self.style.NOTICE(f"Syncing from rclone remote '{rclone_remote}' to '{source_dir}'..."))
os.makedirs(source_dir, exist_ok=True)
rclone_cmd = ["rclone", "copy", rclone_remote, source_dir]
@ -158,13 +176,23 @@ class Command(BaseCommand):
total_skipped = 0
for structure in structures:
# Check if there is a dedicated subfolder for this structure code or name in source_dir
# Check if there is a dedicated subfolder for this structure code, location codes or name in source_dir
struct_dir = None
possible_dirs = [
os.path.join(source_dir, structure.code),
os.path.join(source_dir, f"{structure.code}_{structure.name_fr}"),
os.path.join(source_dir, structure.name_fr or ""),
]
# Also check all associated location codes (e.g. WTB03)
loc_codes = list(structure.all_locations.values_list("code", flat=True))
for loc_code in loc_codes:
possible_dirs.append(os.path.join(source_dir, loc_code))
if os.path.isdir(source_dir):
for folder_item in os.listdir(source_dir):
if folder_item.upper().startswith(loc_code.upper()):
possible_dirs.append(os.path.join(source_dir, folder_item))
for p in possible_dirs:
if os.path.isdir(p):
struct_dir = p