Add missing fcntl import and fix EOF newline

This commit is contained in:
thePR0M3TH3AN
2025-06-29 12:17:48 -04:00
parent 6ee6b6d395
commit a989bd197e

View File

@@ -16,6 +16,7 @@ import os
import shutil import shutil
import time import time
import traceback import traceback
import fcntl
from pathlib import Path from pathlib import Path
from colorama import Fore from colorama import Fore
from termcolor import colored from termcolor import colored
@@ -26,6 +27,7 @@ from constants import APP_DIR
# Instantiate the logger # Instantiate the logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class BackupManager: class BackupManager:
""" """
BackupManager Class BackupManager Class
@@ -35,7 +37,7 @@ class BackupManager:
timestamped filenames to facilitate easy identification and retrieval. timestamped filenames to facilitate easy identification and retrieval.
""" """
BACKUP_FILENAME_TEMPLATE = 'passwords_db_backup_{timestamp}.json.enc' BACKUP_FILENAME_TEMPLATE = "passwords_db_backup_{timestamp}.json.enc"
def __init__(self, fingerprint_dir: Path): def __init__(self, fingerprint_dir: Path):
""" """
@@ -45,17 +47,24 @@ class BackupManager:
fingerprint_dir (Path): The directory corresponding to the fingerprint. fingerprint_dir (Path): The directory corresponding to the fingerprint.
""" """
self.fingerprint_dir = fingerprint_dir self.fingerprint_dir = fingerprint_dir
self.backup_dir = self.fingerprint_dir / 'backups' self.backup_dir = self.fingerprint_dir / "backups"
self.backup_dir.mkdir(parents=True, exist_ok=True) self.backup_dir.mkdir(parents=True, exist_ok=True)
self.index_file = self.fingerprint_dir / 'seedpass_passwords_db.json.enc' self.index_file = self.fingerprint_dir / "seedpass_passwords_db.json.enc"
logger.debug(f"BackupManager initialized with backup directory at {self.backup_dir}") logger.debug(
f"BackupManager initialized with backup directory at {self.backup_dir}"
)
def create_backup(self) -> None: def create_backup(self) -> None:
try: try:
index_file = self.index_file index_file = self.index_file
if not index_file.exists(): if not index_file.exists():
logger.warning("Index file does not exist. No backup created.") logger.warning("Index file does not exist. No backup created.")
print(colored("Warning: Index file does not exist. No backup created.", 'yellow')) print(
colored(
"Warning: Index file does not exist. No backup created.",
"yellow",
)
)
return return
timestamp = int(time.time()) timestamp = int(time.time())
@@ -64,56 +73,67 @@ class BackupManager:
shutil.copy2(index_file, backup_file) shutil.copy2(index_file, backup_file)
logger.info(f"Backup created successfully at '{backup_file}'.") logger.info(f"Backup created successfully at '{backup_file}'.")
print(colored(f"Backup created successfully at '{backup_file}'.", 'green')) print(colored(f"Backup created successfully at '{backup_file}'.", "green"))
except Exception as e: except Exception as e:
logger.error(f"Failed to create backup: {e}") logger.error(f"Failed to create backup: {e}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
print(colored(f"Error: Failed to create backup: {e}", 'red')) print(colored(f"Error: Failed to create backup: {e}", "red"))
def restore_latest_backup(self) -> None: def restore_latest_backup(self) -> None:
try: try:
backup_files = sorted( backup_files = sorted(
self.backup_dir.glob('passwords_db_backup_*.json.enc'), self.backup_dir.glob("passwords_db_backup_*.json.enc"),
key=lambda x: x.stat().st_mtime, key=lambda x: x.stat().st_mtime,
reverse=True reverse=True,
) )
if not backup_files: if not backup_files:
logger.error("No backup files found to restore.") logger.error("No backup files found to restore.")
print(colored("Error: No backup files found to restore.", 'red')) print(colored("Error: No backup files found to restore.", "red"))
return return
latest_backup = backup_files[0] latest_backup = backup_files[0]
index_file = self.index_file index_file = self.index_file
shutil.copy2(latest_backup, index_file) shutil.copy2(latest_backup, index_file)
logger.info(f"Restored the index file from backup '{latest_backup}'.") logger.info(f"Restored the index file from backup '{latest_backup}'.")
print(colored(f"Restored the index file from backup '{latest_backup}'.", 'green')) print(
colored(
f"Restored the index file from backup '{latest_backup}'.", "green"
)
)
except Exception as e: except Exception as e:
logger.error(f"Failed to restore from backup '{latest_backup}': {e}") logger.error(f"Failed to restore from backup '{latest_backup}': {e}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
print(colored(f"Error: Failed to restore from backup '{latest_backup}': {e}", 'red')) print(
colored(
f"Error: Failed to restore from backup '{latest_backup}': {e}",
"red",
)
)
def list_backups(self) -> None: def list_backups(self) -> None:
try: try:
backup_files = sorted( backup_files = sorted(
self.backup_dir.glob('passwords_db_backup_*.json.enc'), self.backup_dir.glob("passwords_db_backup_*.json.enc"),
key=lambda x: x.stat().st_mtime, key=lambda x: x.stat().st_mtime,
reverse=True reverse=True,
) )
if not backup_files: if not backup_files:
logger.info("No backup files available.") logger.info("No backup files available.")
print(colored("No backup files available.", 'yellow')) print(colored("No backup files available.", "yellow"))
return return
print(colored("Available Backups:", 'cyan')) print(colored("Available Backups:", "cyan"))
for backup in backup_files: for backup in backup_files:
creation_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(backup.stat().st_mtime)) creation_time = time.strftime(
print(colored(f"- {backup.name} (Created on: {creation_time})", 'cyan')) "%Y-%m-%d %H:%M:%S", time.localtime(backup.stat().st_mtime)
)
print(colored(f"- {backup.name} (Created on: {creation_time})", "cyan"))
except Exception as e: except Exception as e:
logger.error(f"Failed to list backups: {e}") logger.error(f"Failed to list backups: {e}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
print(colored(f"Error: Failed to list backups: {e}", 'red')) print(colored(f"Error: Failed to list backups: {e}", "red"))
def restore_backup_by_timestamp(self, timestamp: int) -> None: def restore_backup_by_timestamp(self, timestamp: int) -> None:
backup_filename = self.BACKUP_FILENAME_TEMPLATE.format(timestamp=timestamp) backup_filename = self.BACKUP_FILENAME_TEMPLATE.format(timestamp=timestamp)
@@ -121,15 +141,23 @@ class BackupManager:
if not backup_file.exists(): if not backup_file.exists():
logger.error(f"No backup found with timestamp {timestamp}.") logger.error(f"No backup found with timestamp {timestamp}.")
print(colored(f"Error: No backup found with timestamp {timestamp}.", 'red')) print(colored(f"Error: No backup found with timestamp {timestamp}.", "red"))
return return
try: try:
with lock_file(backup_file, lock_type=fcntl.LOCK_SH): with lock_file(backup_file, lock_type=fcntl.LOCK_SH):
shutil.copy2(backup_file, self.index_file) shutil.copy2(backup_file, self.index_file)
logger.info(f"Restored the index file from backup '{backup_file}'.") logger.info(f"Restored the index file from backup '{backup_file}'.")
print(colored(f"Restored the index file from backup '{backup_file}'.", 'green')) print(
colored(
f"Restored the index file from backup '{backup_file}'.", "green"
)
)
except Exception as e: except Exception as e:
logger.error(f"Failed to restore from backup '{backup_file}': {e}") logger.error(f"Failed to restore from backup '{backup_file}': {e}")
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
print(colored(f"Error: Failed to restore from backup '{backup_file}': {e}", 'red')) print(
colored(
f"Error: Failed to restore from backup '{backup_file}': {e}", "red"
)
)