Files
comic-manager/core/collision.py
T
2026-02-19 08:36:06 +01:00

61 lines
1.9 KiB
Python

# core/collision.py
import os
from core.paths import get_project_root
class CollisionPolicy:
ABORT = "abort" # comportamiento estricto actual
BACKUP = "backup" # mueve el existente a backup/ y sigue
RENAME = "rename" # añade sufijo _1, _2... hasta nombre libre
def safe_backup_name(path: str) -> str:
"""
Devuelve una ruta sin colisión dentro de backup/.
Añade sufijo _1, _2... si el nombre base ya existe.
"""
root = get_project_root()
backup_dir = os.path.join(root, "backup")
base = os.path.basename(path)
name, ext = os.path.splitext(base)
candidate = os.path.join(backup_dir, base)
counter = 1
while os.path.exists(candidate):
candidate = os.path.join(backup_dir, f"{name}_{counter}{ext}")
counter += 1
return candidate
def resolve_collision(target_path: str, policy: str = CollisionPolicy.ABORT) -> str:
"""
Comprueba si target_path existe y aplica la política:
ABORT → lanza FileExistsError
BACKUP → mueve el existente a backup/ y devuelve target_path
RENAME → devuelve una ruta alternativa libre (target_1.cbz, ...)
Devuelve la ruta segura donde escribir.
"""
if not os.path.exists(target_path):
return target_path
if policy == CollisionPolicy.ABORT:
raise FileExistsError(
f"El archivo destino ya existe y no se sobrescribirá: {target_path}"
)
if policy == CollisionPolicy.BACKUP:
from core.backup import move_to_backup
move_to_backup(target_path)
return target_path
if policy == CollisionPolicy.RENAME:
base, ext = os.path.splitext(target_path)
counter = 1
candidate = f"{base}_{counter}{ext}"
while os.path.exists(candidate):
counter += 1
candidate = f"{base}_{counter}{ext}"
return candidate
raise ValueError(f"Política de colisión desconocida: {policy}")