/
qoopdata
/
IT-Planet_Pro_SberLinux
Обзор
Документация
Войти
/
qoopdata
/
IT-Planet_Pro_SberLinux
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
fs_abs/main.py
148 строк
5 KB
Kirill Bezuglyi
solutions
17 ноя 2024, 23:43
17 ноя 2024, 23:43
2b02cf3
Код
Авторство
О чём код?
import os import shutil import hashlib import time import json from datetime import datetime from apscheduler.schedulers.background import BackgroundScheduler import logging # Setup logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', filename='backup.log') # Configurations CONFIG_FILE = "backup_config.json" class BackupManager: def __init__(self, source_dir, backup_dir, method): self.source_dir = source_dir self.backup_dir = backup_dir self.method = method # 'incremental' or 'differential' self.hashes_file = os.path.join(backup_dir, "file_hashes.json") self.full_backup_marker = os.path.join(backup_dir, "last_full_backup.txt") self._load_file_hashes() def _load_file_hashes(self): if os.path.exists(self.hashes_file): with open(self.hashes_file, 'r') as f: self.file_hashes = json.load(f) else: self.file_hashes = {} def _save_file_hashes(self): with open(self.hashes_file, 'w') as f: json.dump(self.file_hashes, f) def _file_hash(self, filepath): hasher = hashlib.sha256() with open(filepath, 'rb') as f: while chunk := f.read(8192): hasher.update(chunk) return hasher.hexdigest() def _backup_path(self): timestamp = datetime.now().strftime("%Y%m%d%H%M%S") return os.path.join(self.backup_dir, f"backup_{timestamp}") def _is_file_changed(self, filepath): new_hash = self._file_hash(filepath) return self.file_hashes.get(filepath) != new_hash def _update_file_hash(self, filepath): self.file_hashes[filepath] = self._file_hash(filepath) def _mark_full_backup(self, path): with open(self.full_backup_marker, 'w') as f: f.write(path) def _get_last_full_backup(self): if os.path.exists(self.full_backup_marker): with open(self.full_backup_marker, 'r') as f: return f.read().strip() return None def _restore_directory(self, backup_dir, target_dir): if os.path.exists(target_dir): shutil.rmtree(target_dir) shutil.copytree(backup_dir, target_dir) def backup(self): try: os.makedirs(self.backup_dir, exist_ok=True) backup_path = self._backup_path() if self.method == 'incremental': files_to_backup = [ f for f in self._list_files(self.source_dir) if self._is_file_changed(f) ] elif self.method == 'differential': last_full = self._get_last_full_backup() files_to_backup = self._list_files(self.source_dir) if not last_full else [ f for f in self._list_files(self.source_dir) if self._is_file_changed(f) ] else: logging.error(f"Invalid method: {self.method}") return os.makedirs(backup_path, exist_ok=True) for file in files_to_backup: relative_path = os.path.relpath(file, self.source_dir) target_path = os.path.join(backup_path, relative_path) os.makedirs(os.path.dirname(target_path), exist_ok=True) shutil.copy2(file, target_path) self._update_file_hash(file) self._save_file_hashes() if self.method == 'differential': self._mark_full_backup(backup_path) logging.info(f"{self.method.capitalize()} backup completed: {backup_path}") except Exception as e: logging.error(f"Backup failed: {e}") def restore(self, backup_name, restore_dir): try: backup_path = os.path.join(self.backup_dir, backup_name) if not os.path.exists(backup_path): raise ValueError(f"Backup {backup_name} does not exist.") self._restore_directory(backup_path, restore_dir) logging.info(f"Restored backup {backup_name} to {restore_dir}") except Exception as e: logging.error(f"Restore failed: {e}") def _list_files(self, directory): return [os.path.join(root, f) for root, _, files in os.walk(directory) for f in files] def load_config(): if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, 'r') as f: return json.load(f) return {} def save_config(config): with open(CONFIG_FILE, 'w') as f: json.dump(config, f, indent=4) # Scheduling function def schedule_backup(config): scheduler = BackgroundScheduler() for task in config.get('tasks', []): scheduler.add_job( BackupManager(task['source_dir'], task['backup_dir'], task['method']).backup, 'interval', **task['schedule'] ) scheduler.start() logging.info("Scheduler started. Press Ctrl+C to stop.") try: while True: time.sleep(1) except KeyboardInterrupt: scheduler.shutdown() if __name__ == "__main__": config = load_config() schedule_backup(config)