From 078500d86fdc56cb6afb353d0417abc75a7883c0 Mon Sep 17 00:00:00 2001 From: Floke Date: Tue, 27 May 2025 05:41:54 +0000 Subject: [PATCH] bugfix --- list_generator.py | 96 ++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/list_generator.py b/list_generator.py index 114fffba..01a71094 100644 --- a/list_generator.py +++ b/list_generator.py @@ -41,25 +41,43 @@ def get_services_with_service_account(): except Exception as e: print(f"Fehler Drive Service: {e}") return docs_service, drive_service -def generate_tables_with_gdoctableapp(docs_api_service, document_id_to_fill): # docs_api_service ist hier unser "docsService" - # ... (CSV-Lesen und Datenaufbereitung in kinder_nach_gruppen bleibt gleich) ... - # sorted_gruppen_namen, stand_zeit bleiben +def generate_tables_with_gdoctableapp(docs_api_service, document_id_to_fill): + 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=';') + 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: continue + kinder_nach_gruppen[gruppe_original].append({'Nachname': nachname, 'Vorname': vorname}) + except Exception as e: print(f"FEHLER CSV-Lesen: {e}"); return False + if not kinder_nach_gruppen: print("Keine CSV-Daten."); return False + + for gk_key in kinder_nach_gruppen: + kinder_nach_gruppen[gk_key].sort(key=lambda x: (x['Nachname'].lower(), x['Vorname'].lower())) + + # ***** KORREKTUR HIER: Definition von sorted_gruppen_namen und stand_zeit ***** + sorted_gruppen_namen = sorted(kinder_nach_gruppen.keys()) + stand_zeit = datetime.now().strftime("%d.%m.%Y %H:%M Uhr") + # ***** ENDE KORREKTUR ***** - # Initialisiere gdoctableapp try: resource_for_lib = { - "docsService": docs_api_service, # Unser Service-Objekt + "docsService": docs_api_service, "documentId": document_id_to_fill } - gtable_manager = gdoctableapp(resource_for_lib) # Instanz der Klasse erstellen + gtable_manager = gdoctableapp(resource_for_lib) except Exception as e_dta_init: print(f"Fehler bei der Initialisierung von gdoctableapp: {e_dta_init}") return False - additional_requests = [] # Für Text außerhalb von Tabellen und Seitenumbrüche + additional_requests_fallback = [] # Nur für Fallback-Text bei Lib-Fehler + # Jetzt ist sorted_gruppen_namen definiert for i, gruppe_original in enumerate(sorted_gruppen_namen): - # ... (kinder_liste, anzahl_kinder, gruppe_display_name wie zuvor) ... + kinder_liste = kinder_nach_gruppen[gruppe_original] + anzahl_kinder = len(kinder_liste) + gruppe_display_name = gruppe_original + GRUPPENNAME_SUFFIX table_values = [] table_values.append(["Nachname", "Vorname", "Gruppe"]) @@ -68,10 +86,6 @@ def generate_tables_with_gdoctableapp(docs_api_service, document_id_to_fill): # try: print(f"Versuche Tabelle für Gruppe '{gruppe_original}' mit gdoctableapp einzufügen...") - - # Tabelle einfügen. index=None hängt sie ans Ende des Dokuments an (relativ zum aktuellen Inhalt). - # Da wir die "einmalige Info" zuerst schreiben, wird die erste Tabelle danach angehängt. - # Folgende Tabellen werden nach dem PageBreak angehängt. res_table_obj = gtable_manager.add_table(values=table_values, index=None) if res_table_obj and "table_object" in res_table_obj and "created_table" in res_table_obj["table_object"]: @@ -79,60 +93,38 @@ def generate_tables_with_gdoctableapp(docs_api_service, document_id_to_fill): # table_start_idx = created_table_info.get("startIndex") if table_start_idx is not None: - # Definiere den Bereich für die Kopfzeile - # table_range für update_text_style_to_range braucht tableStartIndex (groß S, kleines i) - header_range_for_style = { - "tableStartIndex": table_start_idx, # Korrekter Schlüsselname - "rowIndex": 0, - "columnIndex": 0, - "rowSpan": 1, - "colSpan": 3 - } - text_style_bold = {"bold": True} - fields_bold = "bold" - # Die Methode update_text_style_to_range ist in gdoctableapp, nicht DocsTableApp + header_range_for_style = { "tableStartIndex": table_start_idx, "rowIndex": 0, "columnIndex": 0, "rowSpan": 1, "colSpan": 3 } + text_style_bold = {"bold": True}; fields_bold = "bold" gtable_manager.update_text_style_to_range(text_style_bold, fields_bold, table_range=header_range_for_style) print(f" Kopfzeile für Tabelle '{gruppe_original}' versucht fett zu formatieren.") - else: - print(f" Konnte startIndex für Tabelle '{gruppe_original}' nicht erhalten, Kopfzeile nicht formatiert.") - else: - print(f" Unerwartete Antwort von add_table, Kopfzeile nicht formatiert: {res_table_obj}") + else: print(f" Konnte startIndex für Tabelle '{gruppe_original}' nicht erhalten für Formatierung.") + else: print(f" Unerwartete Antwort von add_table für Formatierung: {res_table_obj}") - # Text unter der Tabelle - footer_lines_for_group = [""] # Leerzeile nach Tabelle - footer_lines_for_group.append(f"{anzahl_kinder} angemeldete Kinder") - # ... (Rest des Footers für die Gruppe) ... - footer_lines_for_group.append(""); footer_lines_for_group.append("Dies ist die Liste der bereits angemeldeten Kinder. Bitte die Eltern der noch fehlenden"); footer_lines_for_group.append("Kinder an die Anmeldung erinnern."); footer_lines_for_group.append(""); footer_lines_for_group.append(f"Stand {stand_zeit}"); footer_lines_for_group.append("") + footer_lines_for_group = ["", f"{anzahl_kinder} angemeldete Kinder", "", "Dies ist die Liste der bereits angemeldeten Kinder. Bitte die Eltern der noch fehlenden", "Kinder an die Anmeldung erinnern.", "", f"Stand {stand_zeit}", ""] full_footer_text_for_group = "\n".join(footer_lines_for_group) + "\n" - - # Wichtig: Die Bibliothek gdoctableapp sendet ihre BatchUpdates selbst. - # Wir müssen den Text danach mit einem neuen BatchUpdate oder einer Methode der Lib einfügen. - # `gtable_manager.add_text(text, index=None)` könnte hier verwendet werden. - if full_footer_text_for_group.strip(): # Nur einfügen, wenn Text vorhanden ist - gtable_manager.add_text(text=full_footer_text_for_group, index=None) # index=None hängt an + if full_footer_text_for_group.strip(): + gtable_manager.add_text(text=full_footer_text_for_group, index=None) except Exception as e_table: - print(f"Fehler bei Tabelle für Gruppe '{gruppe_original}': {e_table}") - # Fallback (fügen wir als separaten Request hinzu, falls die Lib-Operationen fehlschlagen) - additional_requests.append({'insertText': {'endOfSegmentLocation': {}, 'text': f"\nFEHLER BEI TABELLE {gruppe_original}\n"}}) + print(f"Fehler bei Tabelle/Footer für Gruppe '{gruppe_original}': {e_table}") + fallback_text = f"\nFEHLER BEI TABELLENERSTELLUNG FÜR GRUPPE {gruppe_original}\n" + # Im Fehlerfall fügen wir den Fallback-Text über einen separaten Batch-Request hinzu, + # um die Hauptlogik der Bibliothek nicht zu stören. + additional_requests_fallback.append({'insertText': {'endOfSegmentLocation': {}, 'text': fallback_text}}) + if i < len(sorted_gruppen_namen) - 1: - # PageBreak muss auch über die Lib oder einen separaten Batch erfolgen - # Die Lib hat `gtable_manager.add_page_break(index=None)` try: - gtable_manager.add_page_break(index=None) # index=None hängt an + gtable_manager.add_page_break(index=None) except Exception as e_pb: print(f"Fehler beim Einfügen des PageBreak nach {gruppe_original}: {e_pb}") - additional_requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}}) # Fallback + additional_requests_fallback.append({'insertPageBreak': {'endOfSegmentLocation': {}}}) - # Wenn es `additional_requests` gab (z.B. für Fehler-Fallbacks) - if additional_requests and docs_api_service: + if additional_requests_fallback and docs_api_service: try: print(f"Sende zusätzliche Fallback-Requests für Doc ID '{document_id_to_fill}'...") - docs_api_service.documents().batchUpdate(documentId=document_id_to_fill, body={'requests': additional_requests}).execute() - except HttpError as err: - print(f"Fehler bei zusätzlichen Requests: {err}") - return False + docs_api_service.documents().batchUpdate(documentId=document_id_to_fill, body={'requests': additional_requests_fallback}).execute() + except HttpError as err: print(f"Fehler bei zusätzlichen Fallback-Requests: {err}") return True