z230
This commit is contained in:
42
indexer/backup.py
Normal file
42
indexer/backup.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
|
||||
def blob_path(backup_root: str, content_hash: bytes) -> str:
|
||||
"""Vrátí cestu k blob souboru: BACKUP/ab/cd/abcdef...blob"""
|
||||
hex_hash = content_hash.hex()
|
||||
return os.path.join(backup_root, hex_hash[:2], hex_hash[2:4], hex_hash + ".blob")
|
||||
|
||||
|
||||
def ensure_backed_up(files_with_hash: list, backup_root: str) -> int:
|
||||
"""
|
||||
Zkopíruje soubory do content-addressable storage.
|
||||
files_with_hash: [(full_path, content_hash_bytes), ...]
|
||||
Přeskočí soubory, jejichž blob už existuje (deduplikace).
|
||||
Returns: počet nově zálohovaných souborů.
|
||||
"""
|
||||
backed_up = 0
|
||||
for full_path, content_hash in files_with_hash:
|
||||
target = blob_path(backup_root, content_hash)
|
||||
if os.path.exists(target):
|
||||
continue
|
||||
|
||||
target_dir = os.path.dirname(target)
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
|
||||
try:
|
||||
# Atomický zápis: temp soubor + přejmenování
|
||||
fd, tmp_path = tempfile.mkstemp(dir=target_dir, suffix=".tmp")
|
||||
os.close(fd)
|
||||
shutil.copy2(full_path, tmp_path)
|
||||
os.replace(tmp_path, target)
|
||||
backed_up += 1
|
||||
except (FileNotFoundError, PermissionError, OSError) as e:
|
||||
print(f" WARN: backup failed for {full_path}: {e}")
|
||||
# Uklidíme temp soubor pokud existuje
|
||||
if os.path.exists(tmp_path):
|
||||
os.remove(tmp_path)
|
||||
continue
|
||||
|
||||
return backed_up
|
||||
Reference in New Issue
Block a user