""" Comando de limpeza das duplicatas do banco de análises. Remove as evidências visuais e cenas duplicadas por execuções antigas do Scanner, que acrescentavam em vez de substituir. Faz backup do banco antes de apagar qualquer linha, e aceita ``--simular`` para apenas contar. Uso: python code/engine/limpar_duplicatas.py [--banco CAMINHO] [--simular] """ from __future__ import annotations import argparse import shutil import sys from datetime import datetime from pathlib import Path CAMINHO_DO_CODIGO = Path(__file__).resolve().parent.parent if str(CAMINHO_DO_CODIGO) not in sys.path: sys.path.insert(0, str(CAMINHO_DO_CODIGO)) from engine.persistencia.conexao import abrir_banco # noqa: E402 from engine.persistencia.esquema import reconstruir_indice_de_busca # noqa: E402 from engine.persistencia.limpeza import LimpadorDeDuplicatas # noqa: E402 BANCO_PADRAO = CAMINHO_DO_CODIGO.parent / ".jhonny" / "analises.db" def criar_backup(banco: Path) -> Path: """ Copia o banco para um arquivo datado ao lado do original. Parâmetros: banco: Caminho do banco a copiar. Retorna: O caminho do backup criado. """ carimbo = datetime.now().strftime("%Y%m%d-%H%M%S") destino = banco.with_name(f"{banco.name}.backup-{carimbo}") shutil.copy2(banco, destino) return destino def executar(banco: Path, simular: bool) -> int: """ Conta e, quando autorizado, remove as duplicatas do banco. Parâmetros: banco: Caminho do banco de análises. simular: Quando verdadeiro, apenas conta e não apaga nada. Retorna: Código de saída do processo: 0 em sucesso, 1 quando o banco não existe. """ if not banco.is_file(): print(f"Banco não encontrado: {banco}", file=sys.stderr) return 1 conexao = abrir_banco(banco) limpador = LimpadorDeDuplicatas(conexao) duplicatas = limpador.contar_duplicatas() print(f"Duplicatas encontradas: {duplicatas.evidencias_visuais} evidência(s) visual(is), " f"{duplicatas.cenas} cena(s).") if duplicatas.total == 0: print("Nada a remover.") return 0 if simular: print("Simulação: nenhuma linha foi apagada.") return 0 backup = criar_backup(banco) print(f"Backup criado em {backup}") removidas = limpador.limpar() print(f"Removidas: {removidas.evidencias_visuais} evidência(s) visual(is), " f"{removidas.cenas} cena(s).") print(f"Índice de busca reconstruído com {reconstruir_indice_de_busca(conexao)} fala(s).") return 0 def principal() -> int: """Lê os argumentos da linha de comando e executa a limpeza.""" parser = argparse.ArgumentParser(description="Remove duplicatas do banco de análises.") parser.add_argument("--banco", type=Path, default=BANCO_PADRAO, help="Caminho do analises.db.") parser.add_argument("--simular", action="store_true", help="Apenas conta as duplicatas, sem apagar.") argumentos = parser.parse_args() return executar(argumentos.banco, argumentos.simular) if __name__ == "__main__": raise SystemExit(principal())