Files
ksef_app/app/services/backup_service.py
Mateusz Gruszczyński 35571df778 push
2026-03-13 11:03:13 +01:00

67 lines
2.7 KiB
Python

from __future__ import annotations
from datetime import datetime
from pathlib import Path
import shutil
from flask import current_app
class BackupService:
def create_backup(self):
target = Path(current_app.config['BACKUP_PATH']) / f'backup_{datetime.utcnow().strftime("%Y%m%d_%H%M%S")}'
target.mkdir(parents=True, exist_ok=True)
base_dir = Path(current_app.root_path).parent
for part in ['instance', 'storage/archive', 'storage/pdf']:
src = base_dir / part
if src.exists():
shutil.copytree(src, target / Path(part).name, dirs_exist_ok=True)
archive = shutil.make_archive(str(target), 'zip', root_dir=target)
return archive
def get_database_backup_meta(self) -> dict:
uri = current_app.config.get('SQLALCHEMY_DATABASE_URI', '')
backup_dir = Path(current_app.config['BACKUP_PATH'])
engine = 'unknown'
if '://' in uri:
engine = uri.split('://', 1)[0]
sqlite_supported = uri.startswith('sqlite:///') and not uri.endswith(':memory:')
sqlite_path = None
sqlite_exists = False
if sqlite_supported:
sqlite_path = Path(uri.replace('sqlite:///', '', 1))
sqlite_exists = sqlite_path.exists()
return {
'engine': engine,
'backup_dir': str(backup_dir),
'sqlite_supported': sqlite_supported,
'sqlite_path': str(sqlite_path) if sqlite_path else None,
'sqlite_exists': sqlite_exists,
'notes': [
'Kopia z panelu działa plikowo dla SQLite.',
'Dla PostgreSQL, MySQL i innych silników wymagany jest natywny dump bazy poza aplikacją.',
],
}
def create_database_backup(self) -> str:
target_dir = Path(current_app.config['BACKUP_PATH'])
target_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.utcnow().strftime('%Y%m%d_%H%M%S')
uri = current_app.config.get('SQLALCHEMY_DATABASE_URI', '')
if uri.startswith('sqlite:///') and not uri.endswith(':memory:'):
source = Path(uri.replace('sqlite:///', '', 1))
if not source.exists():
raise FileNotFoundError(f'Plik bazy nie istnieje: {source}')
target = target_dir / f'db_backup_{timestamp}.sqlite3'
shutil.copy2(source, target)
return str(target)
target = target_dir / f'db_backup_{timestamp}.txt'
target.write_text(
"""Automatyczna kopia DB dla bieżącego silnika nie jest obsługiwana plikowo.
W panelu admina kopia działa bezpośrednio tylko dla SQLite.
Wykonaj backup natywnym narzędziem bazy danych.
""",
encoding='utf-8',
)
return str(target)