Update src/streamlit_app.py
Browse files- src/streamlit_app.py +18 -71
src/streamlit_app.py
CHANGED
|
@@ -2,22 +2,17 @@ import re
|
|
| 2 |
from datetime import datetime
|
| 3 |
from typing import List
|
| 4 |
|
| 5 |
-
import
|
| 6 |
from pypdf import PdfReader
|
| 7 |
-
|
| 8 |
from reportlab.lib.pagesizes import A4
|
| 9 |
from reportlab.pdfgen import canvas
|
| 10 |
from reportlab.lib.units import mm
|
| 11 |
|
| 12 |
-
|
| 13 |
KEY_RE = re.compile(r"\b\d{44}\b")
|
| 14 |
|
| 15 |
-
|
| 16 |
def extract_keys_from_pdf(pdf_path: str) -> List[str]:
|
| 17 |
reader = PdfReader(pdf_path)
|
| 18 |
-
found
|
| 19 |
-
seen = set()
|
| 20 |
-
|
| 21 |
for page in reader.pages:
|
| 22 |
text = page.extract_text() or ""
|
| 23 |
for k in KEY_RE.findall(text):
|
|
@@ -26,42 +21,33 @@ def extract_keys_from_pdf(pdf_path: str) -> List[str]:
|
|
| 26 |
found.append(k)
|
| 27 |
return found
|
| 28 |
|
| 29 |
-
|
| 30 |
def safe_date_default() -> str:
|
| 31 |
return datetime.now().strftime("%d/%m/%Y")
|
| 32 |
|
| 33 |
-
|
| 34 |
def render_print_pdf(out_path: str, data_coleta: str, hora_coleta: str, keys: List[str]):
|
| 35 |
c = canvas.Canvas(out_path, pagesize=A4)
|
| 36 |
w, h = A4
|
| 37 |
-
|
| 38 |
left = 20 * mm
|
| 39 |
top = h - 20 * mm
|
| 40 |
line_h = 6.2 * mm
|
| 41 |
|
| 42 |
-
def draw(text: str, y: float,
|
| 43 |
c.setFont("Helvetica-Bold" if bold else "Helvetica", size)
|
| 44 |
c.drawString(left, y, text)
|
| 45 |
return y - line_h
|
| 46 |
|
| 47 |
y = top
|
| 48 |
-
|
| 49 |
-
# Cabeçalho
|
| 50 |
y = draw("CLIENTE:", y)
|
| 51 |
y -= line_h * 1.3
|
| 52 |
-
|
| 53 |
y = draw("DATA DA COLETA:", y)
|
| 54 |
y = draw(data_coleta, y)
|
| 55 |
y -= line_h * 0.6
|
| 56 |
-
|
| 57 |
y = draw("HORA DA COLETA:", y)
|
| 58 |
y = draw("_____ : _____", y)
|
| 59 |
y -= line_h * 0.9
|
| 60 |
|
| 61 |
-
# ===== ALTERAÇÃO AQUI =====
|
| 62 |
y = draw("CHAVES DE ACESSO:", y)
|
| 63 |
y -= line_h * 0.2
|
| 64 |
-
# =========================
|
| 65 |
|
| 66 |
c.setFont("Helvetica", 10.8)
|
| 67 |
for k in keys:
|
|
@@ -75,7 +61,6 @@ def render_print_pdf(out_path: str, data_coleta: str, hora_coleta: str, keys: Li
|
|
| 75 |
y -= line_h * 0.8
|
| 76 |
y = draw(f"TOTAL DA REMESSA: {len(keys)} VOLUMES", y)
|
| 77 |
|
| 78 |
-
# Assinaturas
|
| 79 |
if y < 55 * mm:
|
| 80 |
c.showPage()
|
| 81 |
|
|
@@ -85,62 +70,24 @@ def render_print_pdf(out_path: str, data_coleta: str, hora_coleta: str, keys: Li
|
|
| 85 |
c.drawString(left + 140 * mm, y_sig + 12, "ASSINATURA DO MOTORISTA")
|
| 86 |
c.line(left + 55 * mm, y_sig + 10, left + 118 * mm, y_sig + 10)
|
| 87 |
c.line(left + 130 * mm, y_sig + 10, left + 193 * mm, y_sig + 10)
|
| 88 |
-
|
| 89 |
c.save()
|
| 90 |
|
|
|
|
| 91 |
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
f.write("\n")
|
| 96 |
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
if pdf_file is None:
|
| 100 |
-
raise gr.Error("Envie um PDF.")
|
| 101 |
-
|
| 102 |
-
keys = extract_keys_from_pdf(pdf_file)
|
| 103 |
if not keys:
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
out_pdf,
|
| 112 |
-
data_coleta=data_coleta or safe_date_default(),
|
| 113 |
-
hora_coleta=hora_coleta or "_____ : _____",
|
| 114 |
-
keys=keys,
|
| 115 |
-
)
|
| 116 |
-
build_txt(out_txt, keys)
|
| 117 |
-
|
| 118 |
-
preview = (
|
| 119 |
-
f"Total extraído: {len(keys)}\n\n"
|
| 120 |
-
"Primeiras chaves:\n" + "\n".join(keys[:10])
|
| 121 |
-
)
|
| 122 |
-
return preview, out_pdf, out_txt
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
with gr.Blocks(title="Extrator de Chaves NF-e") as demo:
|
| 126 |
-
gr.Markdown("### Envie um PDF e gere um arquivo pronto para imprimir.")
|
| 127 |
-
|
| 128 |
-
with gr.Row():
|
| 129 |
-
pdf = gr.File(label="PDF", file_types=[".pdf"])
|
| 130 |
-
preview = gr.Textbox(label="Prévia", lines=12)
|
| 131 |
-
|
| 132 |
-
with gr.Row():
|
| 133 |
-
data_coleta = gr.Textbox(label="Data da coleta", value=safe_date_default())
|
| 134 |
-
hora_coleta = gr.Textbox(label="Hora da coleta", value="_____ : _____")
|
| 135 |
-
|
| 136 |
-
btn = gr.Button("Gerar arquivos")
|
| 137 |
-
out_pdf = gr.File(label="PDF pronto para imprimir")
|
| 138 |
-
out_txt = gr.File(label="TXT (opcional)")
|
| 139 |
-
|
| 140 |
-
btn.click(
|
| 141 |
-
fn=run,
|
| 142 |
-
inputs=[pdf, data_coleta, hora_coleta],
|
| 143 |
-
outputs=[preview, out_pdf, out_txt],
|
| 144 |
-
)
|
| 145 |
-
|
| 146 |
-
demo.launch()
|
|
|
|
| 2 |
from datetime import datetime
|
| 3 |
from typing import List
|
| 4 |
|
| 5 |
+
import streamlit as st
|
| 6 |
from pypdf import PdfReader
|
|
|
|
| 7 |
from reportlab.lib.pagesizes import A4
|
| 8 |
from reportlab.pdfgen import canvas
|
| 9 |
from reportlab.lib.units import mm
|
| 10 |
|
|
|
|
| 11 |
KEY_RE = re.compile(r"\b\d{44}\b")
|
| 12 |
|
|
|
|
| 13 |
def extract_keys_from_pdf(pdf_path: str) -> List[str]:
|
| 14 |
reader = PdfReader(pdf_path)
|
| 15 |
+
found, seen = [], set()
|
|
|
|
|
|
|
| 16 |
for page in reader.pages:
|
| 17 |
text = page.extract_text() or ""
|
| 18 |
for k in KEY_RE.findall(text):
|
|
|
|
| 21 |
found.append(k)
|
| 22 |
return found
|
| 23 |
|
|
|
|
| 24 |
def safe_date_default() -> str:
|
| 25 |
return datetime.now().strftime("%d/%m/%Y")
|
| 26 |
|
|
|
|
| 27 |
def render_print_pdf(out_path: str, data_coleta: str, hora_coleta: str, keys: List[str]):
|
| 28 |
c = canvas.Canvas(out_path, pagesize=A4)
|
| 29 |
w, h = A4
|
|
|
|
| 30 |
left = 20 * mm
|
| 31 |
top = h - 20 * mm
|
| 32 |
line_h = 6.2 * mm
|
| 33 |
|
| 34 |
+
def draw(text: str, y: float, size=11, bold=False) -> float:
|
| 35 |
c.setFont("Helvetica-Bold" if bold else "Helvetica", size)
|
| 36 |
c.drawString(left, y, text)
|
| 37 |
return y - line_h
|
| 38 |
|
| 39 |
y = top
|
|
|
|
|
|
|
| 40 |
y = draw("CLIENTE:", y)
|
| 41 |
y -= line_h * 1.3
|
|
|
|
| 42 |
y = draw("DATA DA COLETA:", y)
|
| 43 |
y = draw(data_coleta, y)
|
| 44 |
y -= line_h * 0.6
|
|
|
|
| 45 |
y = draw("HORA DA COLETA:", y)
|
| 46 |
y = draw("_____ : _____", y)
|
| 47 |
y -= line_h * 0.9
|
| 48 |
|
|
|
|
| 49 |
y = draw("CHAVES DE ACESSO:", y)
|
| 50 |
y -= line_h * 0.2
|
|
|
|
| 51 |
|
| 52 |
c.setFont("Helvetica", 10.8)
|
| 53 |
for k in keys:
|
|
|
|
| 61 |
y -= line_h * 0.8
|
| 62 |
y = draw(f"TOTAL DA REMESSA: {len(keys)} VOLUMES", y)
|
| 63 |
|
|
|
|
| 64 |
if y < 55 * mm:
|
| 65 |
c.showPage()
|
| 66 |
|
|
|
|
| 70 |
c.drawString(left + 140 * mm, y_sig + 12, "ASSINATURA DO MOTORISTA")
|
| 71 |
c.line(left + 55 * mm, y_sig + 10, left + 118 * mm, y_sig + 10)
|
| 72 |
c.line(left + 130 * mm, y_sig + 10, left + 193 * mm, y_sig + 10)
|
|
|
|
| 73 |
c.save()
|
| 74 |
|
| 75 |
+
st.title("Extrator de Chaves NF-e (PDF → PDF para imprimir)")
|
| 76 |
|
| 77 |
+
pdf = st.file_uploader("Envie o PDF", type=["pdf"])
|
| 78 |
+
data_coleta = st.text_input("Data da coleta", value=safe_date_default())
|
| 79 |
+
hora_coleta = st.text_input("Hora da coleta", value="_____ : _____")
|
|
|
|
| 80 |
|
| 81 |
+
if pdf and st.button("Gerar PDF"):
|
| 82 |
+
with open("entrada.pdf", "wb") as f:
|
| 83 |
+
f.write(pdf.read())
|
| 84 |
|
| 85 |
+
keys = extract_keys_from_pdf("entrada.pdf")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
if not keys:
|
| 87 |
+
st.error("Não encontrei chaves de 44 dígitos no PDF.")
|
| 88 |
+
else:
|
| 89 |
+
out_pdf = f"chaves_prontas_{datetime.now().strftime('%Y%m%d-%H%M%S')}.pdf"
|
| 90 |
+
render_print_pdf(out_pdf, data_coleta, hora_coleta, keys)
|
| 91 |
+
st.success(f"{len(keys)} chaves encontradas.")
|
| 92 |
+
with open(out_pdf, "rb") as f:
|
| 93 |
+
st.download_button("Baixar PDF pronto para imprimir", f, file_name=out_pdf, mime="application/pdf")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|