diff --git a/loko/assets/management/commands/import_as_built_documents.py b/loko/assets/management/commands/import_as_built_documents.py index 5a5e608..43bab33 100644 --- a/loko/assets/management/commands/import_as_built_documents.py +++ b/loko/assets/management/commands/import_as_built_documents.py @@ -1,4 +1,5 @@ import os +import subprocess from django.core.management.base import BaseCommand, CommandError from django.contrib.contenttypes.models import ContentType from django.contrib.auth import get_user_model @@ -15,15 +16,20 @@ User = get_user_model() class Command(BaseCommand): help = ( - "Imports As-Built documents from a local directory into the " - "'Electromechanics / As-Built' subfolder of specified structures." + "Imports As-Built documents from a local directory or via rclone from OneDrive " + "into the 'Electromechanics / As-Built' subfolder of specified structures." ) def add_arguments(self, parser): parser.add_argument( "--source-dir", - required=True, - help="Path to the directory containing files/folders to import.", + default="/tmp/as_built_sync", + help="Path to local directory containing files/folders to import (default: /tmp/as_built_sync).", + ) + parser.add_argument( + "--rclone-remote", + default=None, + help="Optional rclone remote path (e.g. 'onedrive:DPO_TUNNEL_EM_AS-BUILT') to sync before import.", ) parser.add_argument( "--structures", @@ -49,17 +55,32 @@ class Command(BaseCommand): def handle(self, *args, **options): source_dir = options["source_dir"] + rclone_remote = options["rclone_remote"] target_codes = options["structures"] dry_run = options["dry_run"] username = options["user"] tag_name = options["tag"] - if not os.path.isdir(source_dir): - raise CommandError(f"Source directory '{source_dir}' does not exist or is not a directory.") - 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: + 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] + rclone_conf = os.path.join(os.getcwd(), "rclone.conf") + if os.path.exists(rclone_conf): + rclone_cmd.extend(["--config", rclone_conf]) + + res = subprocess.run(rclone_cmd, capture_output=True, text=True) + if res.returncode != 0: + raise CommandError(f"rclone sync failed:\n{res.stderr}") + self.stdout.write(self.style.SUCCESS("rclone sync completed successfully.")) + + if not os.path.isdir(source_dir): + raise CommandError(f"Source directory '{source_dir}' does not exist or is not a directory.") + # Creator user lookup creator_user = None if username: @@ -134,6 +155,7 @@ class Command(BaseCommand): structures = Structure.objects.all() total_imported = 0 + total_skipped = 0 for structure in structures: # Check if there is a dedicated subfolder for this structure code or name in source_dir @@ -173,12 +195,24 @@ class Command(BaseCommand): continue self.stdout.write(f" Target subfolder: Electromechanics / As-Built (ID: {as_built_folder.pk or 'dry-run'})") - self.stdout.write(f" Found {len(files_to_import)} file(s) to import.") + self.stdout.write(f" Found {len(files_to_import)} file(s) to process.") for file_path in files_to_import: rel_name = os.path.basename(file_path) doc_title = os.path.splitext(rel_name)[0] + # Deduplication check + if as_built_folder.pk: + existing_doc = ManagedDocument.objects.filter( + folders=as_built_folder, + title=doc_title, + is_archived=False + ).first() + if existing_doc: + self.stdout.write(f" Document '{rel_name}' already exists in As-Built folder (Doc ID: {existing_doc.pk}). Skipped.") + total_skipped += 1 + continue + if dry_run: self.stdout.write(f" [Dry-run] Would import '{rel_name}' into structure {structure.code}") total_imported += 1 @@ -216,4 +250,4 @@ class Command(BaseCommand): self.stdout.write(self.style.SUCCESS(f" Imported '{rel_name}' (Doc ID: {doc.pk})")) total_imported += 1 - self.stdout.write(self.style.SUCCESS(f"\nDone! Total documents imported: {total_imported}")) + self.stdout.write(self.style.SUCCESS(f"\nDone! Imported: {total_imported}, Skipped (already imported): {total_skipped}"))