diff --git a/list_generator.py b/list_generator.py index b75eb1ce..58970ce3 100644 --- a/list_generator.py +++ b/list_generator.py @@ -9,8 +9,8 @@ from googleapiclient.errors import HttpError # --- Konfiguration --- CSV_FILENAME = 'Namensliste.csv' -GOOGLE_DOC_TITLE = f"Gruppenlisten Kinderhaus St. Martin Neuching (Service Acc) - {datetime.now().strftime('%Y-%m-%d_%H-%M')}" # Zeit hinzugefügt für Eindeutigkeit -TARGET_FOLDER_ID = "18DNQaH9zbcBzwhckJI-4Uah-WXTXg6bg" # <<-- IHRE ORDNER-ID +GOOGLE_DOC_TITLE = f"Gruppenlisten Kinderhaus St. Martin Neuching (Service Acc) - {datetime.now().strftime('%Y-%m-%d_%H-%M')}" +TARGET_FOLDER_ID = "18DNQaH9zbcBzwhckJI-4Uah-WXTXg6bg" EINRICHTUNG = "Kinderhaus St. Martin Neuching" FOTODATUM = "02. - 05.06.2025" @@ -21,378 +21,50 @@ FOTOGRAF_ADRESSE = "Gartenstr. 10 85445 Oberding" FOTOGRAF_WEB = "www.kinderfotos-erding.de" FOTOGRAF_TEL = "08122-8470867" -SCOPES = ['https://www.googleapis.com/auth/documents'] -# Optional, wenn Probleme auftreten, oder für mehr Dateioperationen: -# SCOPES.append('https://www.googleapis.com/auth/drive.file') +SCOPES = [ + 'https://www.googleapis.com/auth/documents', + 'https://www.googleapis.com/auth/drive.file' # Notwendig für Erstellung im Ordner + # Alternativ: 'https://www.googleapis.com/auth/drive' für vollen Drive-Zugriff +] SERVICE_ACCOUNT_FILE = 'service_account.json' # --- Ende Konfiguration --- -def get_docs_service_with_service_account(): - """Erstellt den API-Dienst mit einem Service Account und gibt Service und Credentials zurück.""" +def get_services_with_service_account(): # Umbenannt für Klarheit + """Erstellt Docs und Drive API-Dienste mit einem Service Account.""" creds = None + docs_service = None + drive_service = None try: creds = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES) except Exception as e: print(f"Fehler beim Laden der Service Account Credentials aus '{SERVICE_ACCOUNT_FILE}': {e}") - return None, None # Gibt Tuple zurück + return None, None try: - # Build für Docs Service docs_service = build('docs', 'v1', credentials=creds) - # Optional: Build für Drive Service, wenn benötigt für komplexere Ordneroperationen - # drive_service = build('drive', 'v3', credentials=creds) - return docs_service, creds # Gibt Tuple zurück - except HttpError as err: - print(f"Ein Fehler beim Erstellen des/der API Service(s) mit Service Account ist aufgetreten: {err}") - return None, None - except Exception as e: - print(f"Ein unerwarteter Fehler beim Erstellen des/der API Service(s): {e}") - return None, None - -def create_google_doc_from_csv(docs_service, folder_id): # Nimmt docs_service und folder_id entgegen - """Liest CSV, verarbeitet Daten und erstellt/befüllt das Google Doc im angegebenen Ordner.""" - kinder_nach_gruppen = collections.defaultdict(list) + print("Google Docs API Service erfolgreich erstellt.") + except Exception as e_docs: + print(f"Konnte Google Docs API Service nicht erstellen: {e_docs}") try: - with open(CSV_FILENAME, mode='r', encoding='utf-8-sig', newline='') as csvfile: - reader = csv.DictReader(csvfile, delimiter=';') - for row in reader: - vorname = row.get('Vorname', '').strip() - nachname = row.get('Nachname', '').strip() - gruppe_original = row.get('Gruppe', '').strip() - - if not vorname or not nachname or not gruppe_original: - print(f"Warnung: Zeile übersprungen wegen fehlender Daten: {row}") - continue - kinder_nach_gruppen[gruppe_original].append({ - 'Nachname': nachname, - 'Vorname': vorname - }) - except FileNotFoundError: - print(f"FEHLER: Die Datei '{CSV_FILENAME}' wurde nicht gefunden.") - return None - except Exception as e: - print(f"FEHLER beim Lesen der CSV-Datei: {e}") - return None - - if not kinder_nach_gruppen: - print("Keine Daten aus der CSV-Datei geladen.") - return None - - for gruppe_key in kinder_nach_gruppen: - kinder_nach_gruppen[gruppe_key].sort(key=lambda x: (x['Nachname'].lower(), x['Vorname'].lower())) - - sorted_gruppen_namen = sorted(kinder_nach_gruppen.keys()) - stand_zeit = datetime.now().strftime("%d.%m.%Y %H:%M Uhr") - - # Dokument-Metadaten für die Erstellung vorbereiten - file_metadata = { - 'name': GOOGLE_DOC_TITLE, - 'mimeType': 'application/vnd.google-apps.document' - } - if folder_id: - file_metadata['parents'] = [folder_id] - - try: - # Wichtig: Wir verwenden den Drive Service, um die Datei mit parentId zu erstellen. - # Der Docs Service kann keine parentId direkt beim .create() angeben. - # Daher brauchen wir den Drive Service doch. - - # Drive Service wird hier benötigt, um im spezifischen Ordner zu erstellen. - # Wir müssen sicherstellen, dass der Drive Service im get_docs_service_with_service_account - # auch mit den richtigen Scopes gebaut wird, falls wir ihn dort nicht auch zurückgeben. - # Einfacher: Wir nehmen an, `docs_service` ist der `build('docs', ...)` - # und wir brauchen einen separaten `drive_service`. - # Die Credentials `service_creds` aus `main` werden hierfür benötigt. - # Das bedeutet, `service_creds` muss an diese Funktion übergeben werden. - - # NEIN, Korrektur: googleapiclient.discovery.build('docs', 'v1').documents().create() - # unterstützt KEIN 'parents'. Das ist eine Drive API Eigenschaft. - # Um ein Doc in einem bestimmten Ordner zu erstellen, MUSS man die Drive API verwenden, - # um die Datei zu erstellen und dann die Doc ID verwenden, um sie mit der Docs API zu bearbeiten. - - # --- ALTERNATIVE (und korrekte) ERSTELLUNG MIT DRIVE API --- - # Diese Funktion braucht also auch die `service_creds` - # def create_google_doc_from_csv(docs_service, service_creds, folder_id): - # temp_drive_service = build('drive', 'v3', credentials=service_creds) - # created_file = temp_drive_service.files().create(body=file_metadata, fields='id').execute() - # document_id = created_file.get('id') - # print(f"Google Doc erstellt mit Drive API in Ordner '{folder_id}', ID: {document_id}") - # print(f"Link: https://docs.google.com/document/d/{document_id}/edit") - # --- ENDE ALTERNATIVE --- - - # --- VEREINFACHUNG: Erstellen mit Docs API, dann Verschieben mit Drive API (wenn nötig) --- - # Oder, wenn wir nur den Docs API Scope haben wollen: - # Zuerst mit Docs API erstellen, DANN mit Drive API verschieben (erfordert Drive Scope) - - # Für jetzt: Wir erstellen es mit Docs API (landet im Root des Service Accounts) - # und verlassen uns darauf, dass der Nutzer es manuell verschiebt oder - # der Service Account bereits Root-Zugriff auf den geteilten Ordner hat. - # Das ist nicht ideal. - - # RICHTIGER ANSATZ für Erstellung im Ordner: - # Siehe die `main` Funktion für die Drive Service Erstellung. - # Diese Funktion benötigt dann `drive_service` anstelle von `docs_service` für den .create() Teil. - # Oder sie erstellt das Doc mit Docs API und gibt die ID zurück, und `main` verschiebt es. - - # DERZEITIGER KOMPROMISS: - # Wir erstellen das Doc mit Docs API (landet im Root des Servicekontos). - # Der Nutzer muss es manuell in den geteilten Ordner verschieben. - # ODER wir implementieren das Verschieben. - - doc_body_for_create = {'title': GOOGLE_DOC_TITLE} - # Wenn wir die Datei mit Drive API erstellen, um sie in einen Ordner zu legen, - # dann bearbeiten wir sie mit der Docs API. - # Wenn wir sie nur mit Docs API erstellen, können wir keinen Ordner angeben. - - # => Für die Erstellung im Ordner brauchen wir den Drive Service. - # Nehmen wir an, `main` übergibt uns `drive_service` und `docs_service`. - - # Diese Funktion sollte so aussehen: - # def create_google_doc_from_csv(docs_api_service, drive_api_service, folder_id_to_use): - - # Da wir jetzt nur `docs_service` haben: - doc = docs_service.documents().create(body=doc_body_for_create).execute() - document_id = doc.get('documentId') - print(f"Google Doc erstellt (im Root des Service Accounts) mit ID: {document_id}") - print(f"Link: https://docs.google.com/document/d/{document_id}/edit") - print(f"BITTE manuell in den Ordner {folder_id} verschieben, oder Skript anpassen, um Drive API zum Erstellen/Verschieben zu nutzen.") - - except HttpError as err: - print(f"Fehler beim Erstellen des Google Dokuments: {err}") - return None - except Exception as e_create: - print(f"Allgemeiner Fehler beim Erstellen des Dokuments: {e_create}") - return None - - requests = [] - for i, gruppe_original in enumerate(sorted_gruppen_namen): - kinder_liste = kinder_nach_gruppen[gruppe_original] - anzahl_kinder = len(kinder_liste) - gruppe_display_name = gruppe_original + GRUPPENNAME_SUFFIX - - header_text_for_page = ( - f"{EINRICHTUNG}\t\t\t{FOTOGRAF_NAME}\n" - f"{FOTODATUM}\n\n" - ) - if i == 0: - requests.append({'insertText': {'location': {'index': 1}, 'text': header_text_for_page}}) - else: - requests.append({'insertText': {'endOfSegmentLocation': {}, 'text': header_text_for_page}}) - - num_rows_for_table = len(kinder_liste) + 1 - num_cols_for_table = 3 - - requests.append({ - 'insertTable': { - 'endOfSegmentLocation': {}, - 'rows': num_rows_for_table, - 'columns': num_cols_for_table - } - }) - - table_text_content = [] - table_text_content.append("Nachname\tVorname\tGruppe") - for kind in kinder_liste: - table_text_content.append(f"{kind['Nachname']}\t{kind['Vorname']}\t{gruppe_display_name}") - full_table_text = "\n".join(table_text_content) + "\n" - - requests.append({ - 'insertText': { - 'endOfSegmentLocation': {}, - 'text': full_table_text - } - }) - - footer_text_for_page = ( - f"\n{anzahl_kinder} angemeldete Kinder\n\n" - "Dies ist die Liste der bereits angemeldeten Kinder. Bitte die Eltern der noch fehlenden\n" - "Kinder an die Anmeldung erinnern.\n\n" - f"Stand {stand_zeit}\n\n" - f"{FOTOGRAF_NAME}\n{FOTOGRAF_ADRESSE}\n{FOTOGRAF_WEB}\n{FOTOGRAF_TEL}\n" - ) - requests.append({ - 'insertText': { - 'endOfSegmentLocation': {}, - 'text': footer_text_for_page - } - }) - - if i < len(sorted_gruppen_namen) - 1: - requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}}) - - if requests: - try: - print("Sende Batch Update an Google Docs API...") - print("Anzahl der Requests:", len(requests)) - docs_service.documents().batchUpdate( # Verwende docs_service hier - documentId=document_id, body={'requests': requests} - ).execute() - print("Dokument erfolgreich befüllt.") - except HttpError as err: - print(f"Fehler beim Befüllen des Google Dokuments: {err}") - error_details = "Keine Fehlerdetails im Content." - if err.content: - try: error_details = err.content.decode('utf-8') - except: pass # Ignoriere Dekodierungsfehler - print(f"Details zum Fehler ({err.resp.status} {err._get_reason()}): {error_details}") - return document_id - - -if __name__ == '__main__': - print(f"Info: Verwendetes Fotodatum: {FOTODATUM}") - print(f"Info: Gruppennamen werden mit Suffix '{GRUPPENNAME_SUFFIX}' versehen.") - print(f"Info: Zieldokumente sollen in Ordner-ID '{TARGET_FOLDER_ID}' landen (ggf. manuell oder per Drive API).") - - # Service Account Authentifizierung - service_tuple = get_docs_service_with_service_account() - - if service_tuple and service_tuple[0] and service_tuple[1]: # Prüfe ob docs_service und creds da sind - docs_api_service, service_creds = service_tuple - - # --- Um ein Dokument direkt im Ordner zu erstellen, benötigen wir die Drive API --- - # Zusätzlichen Scope für Drive hinzufügen, falls nicht schon geschehen: - current_scopes = SCOPES - if 'https://www.googleapis.com/auth/drive.file' not in current_scopes and \ - 'https://www.googleapis.com/auth/drive' not in current_scopes: - # Dies ist nur ein Hinweis, der Scope muss in der `SCOPES`-Liste oben definiert sein - # und die Credentials neu generiert (oder token.json gelöscht, falls OAuth verwendet würde) - print("WARNUNG: Um im Ordner zu erstellen, wird 'drive.file' oder 'drive' Scope benötigt.") - print(" Stellen Sie sicher, dass der Scope in der SCOPES-Liste ist und die API aktiviert ist.") - - drive_api_service = None - try: - # Baue den Drive Service mit denselben Credentials - drive_api_service = build('drive', 'v3', credentials=service_creds) + # Prüfen, ob Drive Scope vorhanden ist, bevor Drive Service gebaut wird + has_drive_scope = any(s in SCOPES for s in ['https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive']) + if has_drive_scope: + drive_service = build('drive', 'v3', credentials=creds) print("Google Drive API Service erfolgreich erstellt.") - except Exception as e_drive_build: - print(f"Konnte Google Drive API Service nicht erstellen: {e_drive_build}") - print("Das Dokument wird im Root-Verzeichnis des Servicekontos erstellt.") - - document_id_to_process = None - - if drive_api_service: - file_metadata = { - 'name': GOOGLE_DOC_TITLE, - 'mimeType': 'application/vnd.google-apps.document', - 'parents': [TARGET_FOLDER_ID] - } - try: - created_file = drive_api_service.files().create(body=file_metadata, fields='id').execute() - document_id_to_process = created_file.get('id') - print(f"Google Doc via Drive API in Ordner '{TARGET_FOLDER_ID}' erstellt, ID: {document_id_to_process}") - print(f"Link: https://docs.google.com/document/d/{document_id_to_process}/edit") - except HttpError as err_drive_create: - print(f"Fehler beim Erstellen des Dokuments mit Drive API im Ordner: {err_drive_create}") - print("Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") - except Exception as e_drive_create_general: - print(f"Allg. Fehler beim Erstellen des Dokuments mit Drive API: {e_drive_create_general}") - print("Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") - - - if not document_id_to_process: # Fallback, wenn Drive API Erstellung fehlschlug - try: - doc_body_for_create = {'title': GOOGLE_DOC_TITLE} - doc = docs_api_service.documents().create(body=doc_body_for_create).execute() - document_id_to_process = doc.get('documentId') - print(f"Google Doc via Docs API (im Root des Servicekontos) erstellt, ID: {document_id_to_process}") - print(f"Link: https://docs.google.com/document/d/{document_id_to_process}/edit") - print(f"BITTE manuell in den Ordner {TARGET_FOLDER_ID} verschieben.") - except Exception as e_docs_create: - print(f"Konnte Dokument auch nicht mit Docs API erstellen: {e_docs_create}") + else: + print("WARNUNG: Kein Drive Scope in SCOPES definiert. Drive Service wird nicht erstellt.") + print(" Dokumente können nicht in spezifischen Ordnern erstellt werden.") + except Exception as e_drive: + print(f"Konnte Google Drive API Service nicht erstellen: {e_drive}") - if document_id_to_process: - # Befülle das Dokument (egal wie es erstellt wurde) mit der Docs API - # Wir übergeben hier nur den docs_api_service, da die create_google_doc_from_csv - # Funktion in ihrer jetzigen Form nur diesen zum *Befüllen* braucht. - # Das Erstellen ist jetzt ausgelagert. - # Wir müssen die Funktion `create_google_doc_from_csv` anpassen, damit sie die Doc-ID übernimmt. + return docs_service, drive_service # Gibt beide Services zurück - # --- ANPASSUNG NOTWENDIG --- - # Die Funktion `create_google_doc_from_csv` erstellt das Dokument selbst. - # Wir müssen das trennen: 1. Dokument erstellen (in main), 2. Dokument befüllen (Funktion). - - # Temporär: Wir rufen die Funktion auf, sie wird versuchen, es neu zu erstellen. - # Das ist nicht, was wir wollen. - # Wir brauchen eine Funktion `fill_google_doc(docs_service, document_id)` - - # => Umstrukturierung für Klarheit: - # 1. `get_services()` - # 2. `ensure_document_exists_in_folder(drive_service, folder_id, title)` -> gibt document_id zurück - # 3. `populate_document_with_csv_data(docs_service, document_id, csv_data_dict)` - - print(f"\nVersuche Dokument ID '{document_id_to_process}' zu befüllen...") - # Hier rufen wir eine modifizierte Funktion auf, die die Daten in ein *existierendes* Dokument schreibt - # oder wir passen die Logik in create_google_doc_from_csv an, um die doc_id zu verwenden. - - # Für jetzt, da create_google_doc_from_csv das Dokument selbst erstellt, - # kommentieren wir den Befüllungsteil hier aus, da die Funktion oben - # bereits die Erstellung und Befüllung macht (aber nicht mit der übergebenen ID). - # Dies muss refaktorisiert werden. - - # Das aktuelle `create_google_doc_from_csv` macht zu viel. - # Wir führen es aus und es wird ein *weiteres* Dokument im Root des SA erstellen und befüllen. - # Das ist nicht ideal. - - # KORREKTER FLUSS WÄRE: - # 1. document_id_in_folder = create_doc_in_folder_with_drive_api(...) - # 2. populate_doc_with_docs_api(docs_api_service, document_id_in_folder, data_from_csv) - - # DA DIE AKTUELLE `create_google_doc_from_csv` das Erstellen UND Befüllen macht, - # und wir wollen, dass es im Ordner landet: - # WIR MÜSSEN `create_google_doc_from_csv` so anpassen, dass sie - # `drive_api_service` und `TARGET_FOLDER_ID` verwendet, um das Dokument zu erstellen. - - # --- Überarbeitete `create_google_doc_from_csv` (siehe unten) --- - # --- und neuer Aufruf hier --- - - # Der Aufruf der alten `create_google_doc_from_csv` wird jetzt das Dokument - # im Root des Service Accounts erstellen und befüllen, ignoriert unsere Drive API Erstellung. - # Das ist redundant. - # Wir müssen EINE Methode zur Erstellung wählen. - - # METHODE: Drive API zum Erstellen im Ordner, Docs API zum Befüllen. - if document_id_to_process: # Wenn die Erstellung im Ordner (oder Fallback) erfolgreich war - # Jetzt brauchen wir eine Funktion, die nur das Befüllen macht: - # populate_doc_with_data(docs_api_service, document_id_to_process, kinder_nach_gruppen, stand_zeit) - # Der Code zum Befüllen ist bereits in `create_google_doc_from_csv`. - # Wir müssen ihn extrahieren. - - # Für diesen Testlauf: Wenn ein Dokument mit Drive erstellt wurde, ist es leer. - # Wir rufen jetzt die `create_google_doc_from_csv` auf, die dann ein *zweites* - # Dokument (im Root) erstellt und dieses befüllt. - # Um das zu vermeiden, müsste `create_google_doc_from_csv` die `document_id_to_process` - # verwenden und *nicht* neu erstellen. - - # Schnelle Lösung für diesen Durchgang: - # Wir machen die Erstellung UND Befüllung in einer Funktion, die Drive API verwendet. - # Siehe überarbeitete Funktion unten. - final_doc_id = create_and_fill_doc_in_folder( - docs_api_service, - drive_api_service, # Kann None sein, wenn Drive Service nicht gebaut werden konnte - TARGET_FOLDER_ID, - GOOGLE_DOC_TITLE - ) - if final_doc_id: - print(f"\n--- ERFOLG ---") - print(f"Dokument-ID: {final_doc_id}") - print(f"Link: https://docs.google.com/document/d/{final_doc_id}/edit") - print("Das Dokument sollte sich im angegebenen Ordner befinden und befüllt sein.") - else: - print("\n--- FEHLGESCHLAGEN ---") - print("Konnte Dokument nicht erstellen oder befüllen.") - - # Der alte Hinweis ist immer noch relevant, falls Drive API Erstellung fehlschlägt - # und das Dokument im Root landet. - # print("\n--- WICHTIG (falls im Root erstellt) ---") - # ... - else: - print("Konnte API Services nicht initialisieren.") - -# Neue Funktion, die Erstellung (idealerweise im Ordner) und Befüllung kombiniert -def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_title): +def create_and_fill_doc(docs_service, drive_service, folder_id, doc_title): # Umbenannt für Konsistenz + """Erstellt ein Dokument (idealerweise im Ordner) und befüllt es mit CSV-Daten.""" document_id = None + # 1. Dokument erstellen if drive_service and folder_id: file_metadata = { @@ -406,32 +78,37 @@ def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_ti print(f"Google Doc via Drive API in Ordner '{folder_id}' erstellt, ID: {document_id}") except HttpError as err_drive_create: print(f"Fehler beim Erstellen des Dokuments mit Drive API im Ordner: {err_drive_create}") - print("Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") + if err_drive_create.resp.status == 403: + print(" -> Dies deutet oft auf fehlende Scopes ('drive.file' oder 'drive') hin oder darauf, dass die Drive API nicht im Projekt aktiviert ist.") + print(" Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") except Exception as e_drive_create_general: print(f"Allg. Fehler beim Erstellen des Dokuments mit Drive API: {e_drive_create_general}") - print("Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") + print(" Versuche, Dokument im Root des Servicekontos mit Docs API zu erstellen...") - if not document_id: # Fallback, wenn Drive API Erstellung fehlschlug oder drive_service nicht da war + if not document_id: + if not docs_service: + print("FEHLER: Docs API Service nicht verfügbar, kann kein Dokument erstellen.") + return None try: doc_body_for_create = {'title': doc_title} doc = docs_service.documents().create(body=doc_body_for_create).execute() document_id = doc.get('documentId') print(f"Google Doc via Docs API (im Root des Servicekontos) erstellt, ID: {document_id}") - if folder_id: # Hinweis geben, wenn ein Ordner gewünscht war - print(f"BITTE manuell in den Ordner '{folder_id}' verschieben.") + if folder_id: + print(f" BITTE manuell in den Ordner '{folder_id}' verschieben.") except Exception as e_docs_create: print(f"Konnte Dokument auch nicht mit Docs API erstellen: {e_docs_create}") - return None # Wenn auch das fehlschlägt, abbrechen + return None if not document_id: + print("Konnte keine Dokumenten-ID für die Befüllung erhalten.") return None - # 2. Daten aus CSV lesen (oder als Parameter übergeben, hier für Einfachheit neu gelesen) + # 2. Daten aus CSV lesen kinder_nach_gruppen = collections.defaultdict(list) try: with open(CSV_FILENAME, mode='r', encoding='utf-8-sig', newline='') as csvfile: reader = csv.DictReader(csvfile, delimiter=';') - # ... (Rest des CSV-Lesens wie in create_google_doc_from_csv) ... for row in reader: vorname = row.get('Vorname', '').strip() nachname = row.get('Nachname', '').strip() @@ -440,7 +117,7 @@ def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_ti kinder_nach_gruppen[gruppe_original].append({'Nachname': nachname, 'Vorname': vorname}) except Exception as e: print(f"FEHLER beim Lesen der CSV-Datei für Befüllung: {e}") - return document_id # Gibt zumindest die ID des leeren Dokuments zurück + return document_id if not kinder_nach_gruppen: print("Keine Daten aus der CSV-Datei für Befüllung geladen.") @@ -451,9 +128,8 @@ def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_ti sorted_gruppen_namen = sorted(kinder_nach_gruppen.keys()) stand_zeit = datetime.now().strftime("%d.%m.%Y %H:%M Uhr") - # 3. Dokument befüllen (Code aus create_google_doc_from_csv) + # 3. Dokument befüllen requests = [] - # ... (kompletter Schleifen- und Request-Aufbau-Code von oben hier einfügen) ... for i, gruppe_original in enumerate(sorted_gruppen_namen): kinder_liste = kinder_nach_gruppen[gruppe_original] anzahl_kinder = len(kinder_liste) @@ -483,6 +159,9 @@ def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_ti requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}}) if requests: + if not docs_service: + print("FEHLER: Docs API Service nicht verfügbar, kann Dokument nicht befüllen.") + return document_id # Gibt ID des (wahrscheinlich leeren) Dokuments zurück try: print(f"Sende Batch Update für Dokument ID '{document_id}'...") docs_service.documents().batchUpdate( @@ -490,17 +169,39 @@ def create_and_fill_doc_in_folder(docs_service, drive_service, folder_id, doc_ti ).execute() print("Dokument erfolgreich befüllt.") except HttpError as err: - # ... (Fehlerbehandlung wie gehabt) ... print(f"Fehler beim Befüllen des Dokuments ID '{document_id}': {err}") error_details = "Keine Fehlerdetails im Content." if err.content: try: error_details = err.content.decode('utf-8') except: pass print(f"Details zum Fehler ({err.resp.status} {err._get_reason()}): {error_details}") - return document_id # Gibt ID des (evtl. teilweise befüllten) Dokuments zurück + return document_id return document_id -# Die alte create_google_doc_from_csv Funktion wird nicht mehr direkt aus main aufgerufen, -# da create_and_fill_doc_in_folder ihre Logik übernimmt und verbessert. -# Sie kann als Referenz oder für Tests noch im Code bleiben. \ No newline at end of file +# --- Main execution block --- +if __name__ == "__main__": + print(f"Info: Verwendetes Fotodatum: {FOTODATUM}") + print(f"Info: Gruppennamen werden mit Suffix '{GRUPPENNAME_SUFFIX}' versehen.") + print(f"Info: Zieldokumente sollen in Ordner-ID '{TARGET_FOLDER_ID}' landen.") + + docs_api_service, drive_api_service = get_services_with_service_account() + + if docs_api_service: # Mindestens Docs Service muss vorhanden sein + final_doc_id = create_and_fill_doc( # Name der Funktion hier korrigiert + docs_api_service, + drive_api_service, + TARGET_FOLDER_ID, + GOOGLE_DOC_TITLE + ) + if final_doc_id: + print(f"\n--- SKRIPT BEENDET ---") + print(f"Dokument-ID: {final_doc_id}") + print(f"Link: https://docs.google.com/document/d/{final_doc_id}/edit") + if not drive_api_service or not TARGET_FOLDER_ID: # Hinweis, falls nicht im Ordner erstellt + print("Das Dokument wurde im Root-Verzeichnis des Servicekontos erstellt.") + else: + print("\n--- FEHLGESCHLAGEN ---") + print("Konnte Dokument nicht erstellen oder befüllen.") + else: + print("Konnte Google Docs API Service nicht initialisieren. Skript wird beendet.") \ No newline at end of file