From 69e5990db0f85a3101b60141a2c38b34afb3184f Mon Sep 17 00:00:00 2001 From: wwartana Date: Fri, 30 Jan 2026 14:25:34 +0800 Subject: [PATCH] feat: Scope backup cleanup to specific job directories for safety and pass the job name from configuration. --- backup_manager.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/backup_manager.py b/backup_manager.py index fe6fd9a..1c65706 100644 --- a/backup_manager.py +++ b/backup_manager.py @@ -219,21 +219,30 @@ class BackupStrategy(ABC): def is_cancelled(self): return self._cancel_flag - def cleanup_old_backups(self, dest, retention_days): + def cleanup_old_backups(self, dest, retention_days, job_name=None): if retention_days <= 0: return - self.log("Menjalankan pembersihan (Retensi: {} hari)...".format(retention_days)) + # SAFETY FIX: Scope cleanup to the specific Job Name folder + if job_name: + safe_job_name = "".join(c for c in job_name if c.isalnum() or c in (' ', '.', '_', '-')).strip() + scan_root = os.path.join(dest, safe_job_name) + else: + # If no job name provided, DO NOT scan the root dest to prevent deleting user files + # self.log("Warning: Nama pekerjaan tidak ada. Skip pembersihan demi keamanan.") + return + + if not os.path.exists(scan_root): + return + + self.log("Menjalankan pembersihan di {} (Retensi: {} hari)...".format(scan_root, retention_days)) now = time.time() cutoff = now - (retention_days * 86400) - if not os.path.exists(dest): - return - count = 0 try: # Recursive scan for YYYY/MM/DD structure - for root, dirs, files in os.walk(dest): + for root, dirs, files in os.walk(scan_root): for filename in files: filepath = os.path.join(root, filename) try: @@ -247,7 +256,7 @@ class BackupStrategy(ABC): self.log("Gagal menghapus {}: {}".format(filename, e)) # Optional: Remove empty folders after cleanup - for root, dirs, files in os.walk(dest, topdown=False): + for root, dirs, files in os.walk(scan_root, topdown=False): for name in dirs: d_path = os.path.join(root, name) try: @@ -376,14 +385,11 @@ class FileBackup(BackupStrategy): dst_file = os.path.join(current_dest_dir, file) shutil.copy2(src_file, dst_file) - processed_files += 1 - if total_files > 0: - self.progress(int(processed_files / total_files * 100)) - - self.log("Penyalinan berhasil diselesaikan.") - - # Cleanup - self.cleanup_old_backups(dest, config.get('retention_days', 0)) + # Retention + retention_days = config.get('retention_days', 0) + if retention_days > 0: + job_name = config.get('name') + self.cleanup_old_backups(dest, retention_days, job_name) self.progress(100)