diff --git a/backup_manager.py b/backup_manager.py index 757fa69..8bb5f66 100644 --- a/backup_manager.py +++ b/backup_manager.py @@ -252,6 +252,15 @@ class BackupStrategy(ABC): else: self.log("Pembersihan selesai. Tidak ada file lama ditemukan.") + def _get_dated_dest_dir(self, base_dest): + """Creates and returns YYYY/MM/DD subfolder path inside base_dest.""" + now = datetime.datetime.now() + # Create structure: base/YYYY/MM/DD + dated_path = os.path.join(base_dest, now.strftime("%Y"), now.strftime("%m"), now.strftime("%d")) + if not os.path.exists(dated_path): + os.makedirs(dated_path, exist_ok=True) + return dated_path + @abstractmethod def run_backup(self, config): pass @@ -266,10 +275,10 @@ class FileBackup(BackupStrategy): if not os.path.exists(source): raise FileNotFoundError("Sumber tidak ditemukan: {}".format(source)) - if not os.path.exists(dest): - os.makedirs(dest, exist_ok=True) + # Use dated directory + target_dest = self._get_dated_dest_dir(dest) - self.log("Memulai Backup File: {} -> {}".format(source, dest)) + self.log("Memulai Backup File: {} -> {}".format(source, target_dest)) name = os.path.basename(source.rstrip(os.sep)) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") @@ -277,7 +286,7 @@ class FileBackup(BackupStrategy): if archive: # ZIP MODE zip_filename = "{}_{}.zip".format(name, timestamp) - zip_path = os.path.join(dest, zip_filename) + zip_path = os.path.join(target_dest, zip_filename) self.log("Membuat arsip: {}".format(zip_path)) # Count total files for progress @@ -308,7 +317,7 @@ class FileBackup(BackupStrategy): else: # COPY MODE - dest_path = os.path.join(dest, "{}_{}".format(name, timestamp)) + dest_path = os.path.join(target_dest, "{}_{}".format(name, timestamp)) self.log("Menyalin ke: {}".format(dest_path)) if os.path.isfile(source): @@ -392,8 +401,10 @@ class MySQLBackup(BackupStrategy): "Letakkan di folder 'sql_tools' di samping ProBackup.exe\n" "atau pastikan sql_tools ada di dalam bundle.") - if not os.path.exists(dest): - os.makedirs(dest, exist_ok=True) + "atau pastikan sql_tools ada di dalam bundle.") + + # Use dated directory + target_dest = self._get_dated_dest_dir(dest) # Log tool location for debugging self.log("Menggunakan mysqldump: {}".format(mysqldump_path)) @@ -402,11 +413,11 @@ class MySQLBackup(BackupStrategy): if all_databases: self.log("Menghubungkan ke MySQL: {}:{} (SEMUA DATABASE)".format(host, port)) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") - dump_file_path = os.path.join(dest, "all_databases_{}.sql".format(timestamp)) + dump_file_path = os.path.join(target_dest, "all_databases_{}.sql".format(timestamp)) else: self.log("Menghubungkan ke MySQL: {}:{} / {}".format(host, port, database)) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") - dump_file_path = os.path.join(dest, "{}_{}.sql".format(database, timestamp)) + dump_file_path = os.path.join(target_dest, "{}_{}.sql".format(database, timestamp)) # Get skip_ssl setting (default True for backward compatibility) skip_ssl = config.get('skip_ssl', True) @@ -529,8 +540,8 @@ class PostgresBackup(BackupStrategy): dest = config.get('dest') all_databases = config.get('all_databases', False) - if not os.path.exists(dest): - os.makedirs(dest, exist_ok=True) + # Use dated directory + target_dest = self._get_dated_dest_dir(dest) # Detect Server Version self.log("Mendeteksi versi server Postgres di {}:{}...".format(host, port)) @@ -557,7 +568,7 @@ class PostgresBackup(BackupStrategy): self.log("Menghubungkan ke Postgres: {}:{} (SEMUA DATABASE)".format(host, port)) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") - dump_file_path = os.path.join(dest, "all_databases_{}.sql".format(timestamp)) + dump_file_path = os.path.join(target_dest, "all_databases_{}.sql".format(timestamp)) else: # Use pg_dump for single database pg_tool_path = find_sql_tool('pg_dump.exe', 'postgres', server_version) @@ -571,7 +582,7 @@ class PostgresBackup(BackupStrategy): self.log("Menghubungkan ke Postgres: {}:{} / {}".format(host, port, database)) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") - dump_file_path = os.path.join(dest, "{}_{}.sql".format(database, timestamp)) + dump_file_path = os.path.join(target_dest, "{}_{}.sql".format(database, timestamp)) # Prepare Environment for Password env = os.environ.copy()