import streamlit as st import PyPDF2 import os import io import re # Per l'uso delle espressioni regolari import uuid # Per la generazione di UUID from datetime import datetime # Per ottenere il timestamp # Funzione per estrarre testo dal PDF def extract_text_from_pdf(pdf_file): """ Estrae il testo dalla prima pagina di un PDF. """ try: # Crea un oggetto BytesIO dal file caricato per permettere a PyPDF2 di leggerlo # Questo è importante perché Streamlit passa un UploadedFile che potrebbe non essere seekable o leggibile direttamente # da PyPDF2 senza essere avvolto in un buffer di byte. pdf_reader = PyPDF2.PdfReader(io.BytesIO(pdf_file.read())) if pdf_reader.pages: first_page = pdf_reader.pages[0] text = first_page.extract_text() return text else: return "" except Exception as e: st.error(f"Errore durante l'estrazione del testo dal PDF: {e}") return "" # Funzione principale dell'app Streamlit def app(): st.set_page_config(layout="centered", page_title="Rinominatore PDF Intelligente") st.title("📄 Rinominatore di PDF Intelligente") st.markdown(""" Carica uno o più file PDF. Il programma tenterà di leggere il contenuto della prima pagina per suggerire un nuovo nome per ciascun file. Il naming seguirà il formato: `1006373999_DDT[NUMERO_DOCUMENTO]_TIMESTAMP_UUID.pdf`. """) # Permette il caricamento di più file PDF uploaded_files = st.file_uploader("Carica i tuoi file PDF", type="pdf", accept_multiple_files=True) if uploaded_files: st.success(f"{len(uploaded_files)} file caricati con successo!") st.subheader("Suggerisci Nomi e Scarica PDF Rinominati:") for i, uploaded_file in enumerate(uploaded_files): st.markdown(f"---") st.markdown(f"**Elaborazione file: {uploaded_file.name}**") # Sposta il puntatore del file all'inizio per ogni elaborazione uploaded_file.seek(0) # Estrai il testo dalla prima pagina del PDF extracted_text = extract_text_from_pdf(uploaded_file) sequence_number = "" if extracted_text: st.text_area(f"Anteprima testo estratto da '{uploaded_file.name}':", extracted_text[:500], height=100, key=f"text_area_{i}") # Cerca il numero di sequenza con espressione regolare "DOCUM. NR. DEL PAG. XXXXXXXXXXX" match = re.search(r"DOCUM\. NR\. DEL PAG\.\s*(\d+)", extracted_text) if match: sequence_number = match.group(1) st.info(f"Numero DDT rilevato: **{sequence_number}**") else: st.warning("Numero DDT (es. 'DOCUM. NR. DEL PAG. 12345') non trovato in questo PDF. Il nome suggerito userà un placeholder per la sequenza.") sequence_number = "" # Assicura che sia una stringa vuota se non trovato else: st.warning(f"Impossibile estrarre testo da '{uploaded_file.name}'. Il nome suggerito sarà basato sul nome originale.") sequence_number = "" # Assicura che sia una stringa vuota se non c'è testo # Componenti per il nuovo nome del file codice_ddt_fixed = "1006373999" # TIMESTAMP: AAAAMMGGhhmmssSSS (fino ai millisecondi) current_timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3] # UUID: generatore univoco di 5 caratteri unique_uuid_5_chars = uuid.uuid4().hex[:5] # Costruisci il nome suggerito con '_DDT' prima della sequenza if sequence_number: suggested_name_base = f"{codice_ddt_fixed}_DDT{sequence_number}_{current_timestamp}_{unique_uuid_5_chars}" else: # Fallback se il numero di sequenza non è trovato base_original_name = os.path.splitext(uploaded_file.name)[0] # Pulisci il nome originale da caratteri non validi per i nomi file clean_original_name = "".join(c if c.isalnum() or c in ('_', '-') else '_' for c in base_original_name) # Limita la lunghezza del fallback del nome originale per evitare nomi troppo lunghi suggested_name_base = f"{codice_ddt_fixed}_DDT_NOSEQ_{clean_original_name[:10]}_{current_timestamp}_{unique_uuid_5_chars}" new_filename_input = st.text_input( f"Nuovo nome suggerito per '{uploaded_file.name}' (senza estensione .pdf):", value=suggested_name_base, key=f"filename_input_{i}" # Chiave unica per ogni widget ) final_new_filename = f"{new_filename_input.strip()}.pdf" # Prepara il contenuto del PDF originale per il download con il nuovo nome # Sposta il puntatore del file caricato all'inizio prima di leggerlo di nuovo uploaded_file.seek(0) pdf_bytes = uploaded_file.read() st.download_button( label=f"Scarica {final_new_filename}", data=pdf_bytes, file_name=final_new_filename, mime="application/pdf", key=f"download_btn_{i}" # Chiave unica per ogni pulsante ) # Messaggio di successo più conciso e immediatamente sotto il pulsante di download st.success(f"PDF pronto come '{final_new_filename}'!") else: st.info("Carica uno o più file PDF per iniziare il processo di rinominazione.") # Punto di ingresso dell'applicazione Streamlit if __name__ == "__main__": app()