#!/usr/bin/env python3 """ Script per convertire dati da export G.A.I.A (Excel) a formato Google Contacts (CSV). Legge un file Excel contenente dati di contatti e li converte in formato CSV compatibile con Google Contacts. Estrae le colonne: - Cognome - Nome - Email - Numeri di telefono I dati vengono: 1. Stampati a video in formato CSV per verifica manuale 2. Esportati in un file GoogleContacts.csv nel formato richiesto da Google Autore: Luigi D'Acunto Data: 27 gennaio 2026 """ import sys import pandas as pd import argparse from pathlib import Path # Header del file CSV per Google Contacts GOOGLE_CONTACTS_HEADER = ( "Last Name,First Name,Phonetic First Name,Phonetic Middle Name," "Phonetic Last Name,Name Prefix,Name Suffix,Nickname,File As," "Organization Name,Organization Title,Organization Department," "Birthday,Notes,Photo,Labels,E-mail 1 - Label,E-mail 1 - Value," "Phone 1 - Label,Phone 1 - Value,Phone 2 - Label,Phone 2 - Value" ) # Colonne da cercare nel file Excel COLONNE_RICHIESTE = ['Cognome', 'Nome', 'Email', 'Numeri di telefono'] def normalizza_numero_telefono(numero): """ Normalizza il numero di telefono aggiungendo il prefisso +39 se non presente. Args: numero: Numero di telefono da normalizzare Returns: str: Numero di telefono normalizzato con prefisso +39 """ if pd.isna(numero): return '' # Converti a stringa e rimuovi spazi num_str = str(numero).strip() # Se vuoto, ritorna stringa vuota if not num_str: return '' # Rimuovi tutti gli spazi dal numero num_str = num_str.replace(' ', '') # Se non inizia con +39, aggiungi il prefisso if not num_str.startswith('+39'): # Rimuovi il 0 iniziale se presente (formato italiano locale) if num_str.startswith('0'): num_str = num_str[1:] # Aggiungi il prefisso num_str = f'+39{num_str}' return num_str def formato_google_contacts(cognome, nome, email, telefono, etichetta): """ Formatta una riga di dati nel formato richiesto da Google Contacts. Args: cognome: Cognome del contatto nome: Nome del contatto email: Email del contatto telefono: Numero di telefono del contatto etichetta: Etichetta/categoria per il contatto Returns: str: Riga formattata nel formato Google Contacts """ # Normalizza il numero di telefono telefono_formattato = normalizza_numero_telefono(telefono) # Costruisci la riga nel formato richiesto # Last Name,First Name,Phonetic First Name,Phonetic Middle Name,Phonetic Last Name, # Name Prefix,Name Suffix,Nickname,File As,Organization Name,Organization Title, # Organization Department,Birthday,Notes,Photo, # Labels,E-mail 1 - Label,E-mail 1 - Value,Phone 1 - Label,Phone 1 - Value,Phone 2 - Label,Phone 2 - Value riga = f'{cognome},{nome},,,,,,,,,,,,,,{etichetta} ::: * myContacts,* Other,{email},Mobile,{telefono_formattato},,' return riga def leggi_excel_e_processa(excel_file, etichetta=None): """ Legge un file Excel, stampa i dati a video e crea un file CSV per Google Contacts. Args: excel_file: Path del file Excel da leggere etichetta: Etichetta/categoria da aggiungere ai contatti (opzionale) """ try: # Leggi il file Excel df = pd.read_excel(excel_file) # Verifica che tutte le colonne richieste siano presenti colonne_presenti = [] colonne_mancanti = [] for col in COLONNE_RICHIESTE: if col in df.columns: colonne_presenti.append(col) else: colonne_mancanti.append(col) if colonne_mancanti: print(f"ERRORE: Colonne mancanti nel file Excel: {', '.join(colonne_mancanti)}", file=sys.stderr) print(f"Colonne disponibili nel file: {', '.join(df.columns.tolist())}", file=sys.stderr) return # Se l'etichetta non è stata passata come parametro, chiedi all'utente in modo interattivo if not etichetta: print("\n" + "="*60) print("INSERIMENTO ETICHETTA/CATEGORIA") print("="*60) etichetta = input("Inserisci l'etichetta/categoria da aggiungere ai contatti: ").strip() if not etichetta: print("ERRORE: L'etichetta non può essere vuota!", file=sys.stderr) sys.exit(1) print(f"Etichetta utilizzata: '{etichetta}\n") # Seleziona solo le colonne richieste df_selezionato = df[colonne_presenti] # === PARTE 1: Stampa a video per verifica manuale === print("\n" + "="*60) print("VERIFICA DATI ESTRATTI DA EXCEL") print("="*60 + "\n") # Stampa l'header CSV print(','.join(colonne_presenti)) # Stampa ogni riga in formato CSV for _, row in df_selezionato.iterrows(): valori = [] for val in row: if pd.isna(val): valori.append('') else: val_str = str(val).replace('"', '""') if ',' in val_str or '"' in val_str or '\n' in val_str: valori.append(f'"{val_str}"') else: valori.append(val_str) print(','.join(valori)) # === PARTE 2: Creazione del file per Google Contacts === print("\n" + "="*60) print("GENERAZIONE FILE PER GOOGLE CONTACTS") print("="*60 + "\n") # Crea il nome del file includendo l'etichetta etichetta_filename = etichetta.replace(' ', '_').replace('/', '_').replace('\\', '_') output_file = f'GoogleContacts_{etichetta_filename}.csv' try: with open(output_file, 'w', encoding='utf-8', newline='') as f: # Scrivi l'header f.write(GOOGLE_CONTACTS_HEADER + '\n') # Scrivi ogni riga nel formato Google Contacts righe_scritte = 0 for _, row in df_selezionato.iterrows(): cognome = str(row['Cognome']).strip() if not pd.isna(row['Cognome']) else '' nome = str(row['Nome']).strip() if not pd.isna(row['Nome']) else '' email = str(row['Email']).strip() if not pd.isna(row['Email']) else '' telefono = str(row['Numeri di telefono']).strip() if not pd.isna(row['Numeri di telefono']) else '' riga_google = formato_google_contacts(cognome, nome, email, telefono, etichetta) f.write(riga_google + '\n') righe_scritte += 1 print(f"✓ File '{output_file}' creato con successo!") print(f" - Righe scritte: {righe_scritte}") print(f" - Etichetta utilizzata: '{etichetta}'") print(f" - Formato: Google Contacts CSV") except Exception as e: print(f"ERRORE durante la scrittura del file CSV: {str(e)}", file=sys.stderr) sys.exit(1) print(f"\n--- Elaborazione completata: {len(df_selezionato)} contatti processati ---", file=sys.stderr) except FileNotFoundError: print(f"ERRORE: File '{excel_file}' non trovato.", file=sys.stderr) sys.exit(1) except Exception as e: print(f"ERRORE durante la lettura del file: {str(e)}", file=sys.stderr) sys.exit(1) def main(): parser = argparse.ArgumentParser( description='Converte dati da export G.A.I.A (Excel) a formato Google Contacts (CSV)', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Esempi di utilizzo: python %(prog)s data/export.xlsx # Modalità interattiva python %(prog)s data/export.xlsx --label "Riunione" # Con etichetta specificata """ ) parser.add_argument( 'excel_file', help='Path del file Excel da leggere' ) parser.add_argument( '--label', dest='etichetta', help='Etichetta/categoria da aggiungere ai contatti (opzionale, se non fornita verrà richiesta interattivamente)', default=None ) args = parser.parse_args() leggi_excel_e_processa(args.excel_file, args.etichetta) if __name__ == '__main__': main()