cmgstv/encoder
0
1import gradio as gr2import subprocess3import tempfile4import shutil5import os6import sys7import json8from pathlib import Path9 10# Caminho do "soffice" (LibreOffice) — no container será simplesmente "soffice"11DEFAULT_SOFFICE = "soffice"12 13SCRIPT = "atas_encoder_decoder.py"14 15def run_encode(docx_file, count, prefix, export_pdf, soffice_path):16 if docx_file is None:17 return None, "Envie um arquivo .docx."18 try:19 tmpdir = Path(tempfile.mkdtemp(prefix="atas_"))20 in_path = tmpdir / "input.docx"21 out_dir = tmpdir / "out"22 out_dir.mkdir(parents=True, exist_ok=True)23 with open(in_path, "wb") as f:24 f.write(docx_file.read())25 26 cmd = [27 sys.executable, SCRIPT, "encode",28 "--input", str(in_path),29 "--outdir", str(out_dir),30 "--count", str(int(count)),31 "--prefix", prefix if prefix else "ata_ID_"32 ]33 if export_pdf:34 cmd.append("--pdf")35 # Se o usuário quiser informar path específico do soffice:36 soff = (soffice_path or "").strip()37 if soff:38 cmd.extend(["--soffice-bin", soff])39 else:40 cmd.extend(["--soffice-bin", DEFAULT_SOFFICE])41 42 # Roda o encoder43 p = subprocess.run(cmd, capture_output=True, text=True)44 if p.returncode != 0:45 return None, f"Erro no encoder:\n{p.stderr or p.stdout}"46 47 # Compacta a pasta out/ em ZIP para baixar tudo de uma vez48 zip_path = tmpdir / "versoes.zip"49 shutil.make_archive(str(zip_path.with_suffix("")), "zip", out_dir)50 # Procura mapping.csv51 mapping = out_dir / "mapping.csv"52 mapping_msg = "mapping.csv gerado."53 if not mapping.exists():54 mapping_msg = "ATENÇÃO: mapping.csv não encontrado (verifique logs)."55 56 # Devolve ZIP e uma mensagem curta57 return str(zip_path), f"OK ✅ {mapping_msg}"58 except Exception as e:59 return None, f"Falhou: {e}"60 61def run_decode(texto, vazamento_txt):62 try:63 # Aceita texto colado OU arquivo .txt64 if (not texto or not texto.strip()) and vazamento_txt is None:65 return "Envie um texto ou um arquivo .txt."66 67 tmpdir = Path(tempfile.mkdtemp(prefix="atas_decode_"))68 cmd = [sys.executable, SCRIPT, "decode", "--top", "10"]69 70 if vazamento_txt is not None:71 in_path = tmpdir / "vazamento.txt"72 with open(in_path, "wb") as f:73 f.write(vazamento_txt.read())74 cmd.extend(["--text-file", str(in_path)])75 else:76 cmd.extend(["--text", texto.strip()])77 78 p = subprocess.run(cmd, capture_output=True, text=True)79 if p.returncode != 0:80 return f"Erro no decoder:\n{p.stderr or p.stdout}"81 82 # Mostra saída como está (o seu script já ranqueia/formatta)83 saida = p.stdout.strip() or "(sem saída)"84 return saida85 except Exception as e:86 return f"Falhou: {e}"87 88with gr.Blocks(title="Atas Encoder/Decoder") as demo:89 gr.Markdown("# Atas Encoder/Decoder\nInterface web para gerar versões e detectar máscaras.")90 91 with gr.Tab("Gerar versões (Encoder)"):92 docx_file = gr.File(label="Ata DOCX", file_types=[".docx"])93 count = gr.Number(label="Quantidade de versões", value=5, precision=0)94 prefix = gr.Textbox(label="Prefixo do arquivo", value="ata_ID_")95 export_pdf = gr.Checkbox(label="Exportar PDF via LibreOffice", value=True)96 soffice_path = gr.Textbox(label="Caminho do 'soffice' (opcional)", placeholder="Deixe em branco para padrão")97 btn_encode = gr.Button("Gerar versões")98 zip_out = gr.File(label="Baixar versões (ZIP)")99 msg = gr.Textbox(label="Mensagens", interactive=False)100 101 btn_encode.click(102 fn=run_encode,103 inputs=[docx_file, count, prefix, export_pdf, soffice_path],104 outputs=[zip_out, msg],105 )106 107 with gr.Tab("Detectar versão (Decoder)"):108 texto = gr.Textbox(label="Texto vazado", lines=8, placeholder="Cole aqui o trecho...")109 vazamento_txt = gr.File(label="...ou envie um .txt", file_types=[".txt"])110 btn_decode = gr.Button("Analisar")111 resultado = gr.Textbox(label="Resultado", lines=16)112 btn_decode.click(113 fn=run_decode,114 inputs=[texto, vazamento_txt],115 outputs=[resultado],116 )117 118if __name__ == "__main__":119 port = int(os.getenv("PORT", os.getenv("GRADIO_SERVER_PORT", "7860")))120 demo.queue().launch(121 server_name="0.0.0.0",122 server_port=port,123 share=True, # evita o "localhost not accessible" em Spaces124 show_api=False # evita o bug do schema (/info)125 )126 127 