From 507a6bd865a991aab6abf60afe968f727bfbf7bd Mon Sep 17 00:00:00 2001 From: Floke Date: Mon, 26 May 2025 18:27:11 +0000 Subject: [PATCH] bugfix --- list_generator.py | 115 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/list_generator.py b/list_generator.py index 43296824..c532e4f4 100644 --- a/list_generator.py +++ b/list_generator.py @@ -96,9 +96,13 @@ def create_google_doc_from_csv(service): return None requests = [] - current_index = 1 + # Startindex für das gesamte Dokument. Bleibt für den ersten Block bei 1. + # Für nachfolgende Seiten (nach PageBreak) müssen wir überlegen, wie der Index behandelt wird. + # Wenn PageBreak mit endOfSegmentLocation eingefügt wird, ist der nächste Einfügepunkt + # implizit am Anfang des neuen Segments. + doc_cursor_index = 1 - for i, gruppe_original in enumerate(sorted_gruppen_namen): # Jetzt ist sorted_gruppen_namen definiert + 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 @@ -108,41 +112,60 @@ def create_google_doc_from_csv(service): f"{EINRICHTUNG}\t\t\t{FOTOGRAF_NAME}\n" f"{FOTODATUM}\n\n" ) - requests.append({'insertText': {'location': {'index': current_index}, 'text': header_text_for_page}}) - current_index += len(header_text_for_page) + # Wenn es die erste Seite ist, verwenden wir doc_cursor_index. + # Für nachfolgende Seiten könnte man endOfSegmentLocation verwenden, wenn der vorherige Block auch damit endete. + # Wir versuchen, doc_cursor_index weiterzuführen. + requests.append({'insertText': {'location': {'index': doc_cursor_index}, 'text': header_text_for_page}}) + doc_cursor_index += len(header_text_for_page) # --- Tabelle --- num_rows_for_table = len(kinder_liste) + 1 num_cols_for_table = 3 + # Füge die Tabellenstruktur ein + # Die Tabelle wird an der aktuellen Cursor-Position eingefügt. requests.append({ 'insertTable': { - 'location': {'index': current_index}, + 'location': {'index': doc_cursor_index}, 'rows': num_rows_for_table, 'columns': num_cols_for_table } }) - table_fill_start_index = current_index + 1 + # WICHTIG: Wo ist der Cursor jetzt, um Text IN die Tabelle einzufügen? + # Annahme: Der Cursor ist jetzt AM ANFANG der ERSTEN Zelle. + # Daher sollte der Index für das Einfügen des Tabelleninhalts derselbe sein + # wie der Index, an dem die Tabelle erstellt wurde, PLUS EINS (für das Start-Tag der Tabelle selbst). + # Dies ist der kritische Punkt. + + # Der Index zum Befüllen der Tabelle ist der Startindex der Tabelle (doc_cursor_index) + 1. + # (Das +1 ist für das unsichtbare Zeichen, das den Anfang der Tabellenstruktur markiert). + table_content_insertion_point = doc_cursor_index + 1 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" + # Füge den gesamten Tabelleninhalt ein. requests.append({ 'insertText': { - 'location': {'index': table_fill_start_index}, + 'location': {'index': table_content_insertion_point}, 'text': full_table_text } }) + # Nach dem Einfügen der Tabelle und ihres Inhalts müssen wir den doc_cursor_index + # auf eine Position *NACH* der Tabelle setzen. + # Die Tabelle (Struktur) selbst belegt 1 Index-Einheit (aus Sicht des batchUpdate-Requests). + # Der Text, der in die Tabelle gefüllt wurde, belegt `len(full_table_text)` Zeichen. + # Aber die gesamte Tabellenstruktur im Dokument ist komplexer. + # Es ist sehr schwer, den genauen Index nach einer Tabelle vorherzusagen. + # HIER verwenden wir endOfSegmentLocation für den Footer, um dieses Problem zu umgehen. # --- Footer --- - # Korrektur: 'text' muss auf derselben Ebene wie 'endOfSegmentLocation' sein footer_text_for_page = ( - f"\n{anzahl_kinder} angemeldete Kinder\n\n" + f"\n{anzahl_kinder} angemeldete Kinder\n\n" # Start mit \n um sicher aus der Tabelle zu sein "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" @@ -150,7 +173,7 @@ def create_google_doc_from_csv(service): ) requests.append({ 'insertText': { - 'endOfSegmentLocation': {}, + 'endOfSegmentLocation': {}, # Fügt am Ende des aktuellen Haupttextkörpers ein 'text': footer_text_for_page } }) @@ -158,24 +181,58 @@ def create_google_doc_from_csv(service): # --- Seitenumbruch --- if i < len(sorted_gruppen_namen) - 1: requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}}) - # Reset current_index for the new page if not using endOfSegmentLocation for header - # Da wir endOfSegmentLocation für den nächsten Header nicht explizit verwenden (er basiert auf current_index), - # müssen wir sicherstellen, dass current_index für die nächste Seite korrekt ist. - # Mit endOfSegmentLocation für Footer und PageBreak ist die manuelle Index-Verfolgung - # für den *nächsten* Header schwierig. - # Eine sicherere Methode wäre, den Header der nächsten Seite auch mit endOfSegmentLocation zu beginnen. - # Für jetzt lassen wir current_index einfach weiterlaufen und hoffen, dass - # endOfSegmentLocation für Footer/PageBreak den Cursor korrekt für den *nächsten* Block - # (der wieder 'location' mit 'current_index' verwendet) positioniert. - # Dies könnte ein potenzielles Problem für die nächste Iteration sein, wenn der Footer/PageBreak - # den `current_index` nicht so verschiebt, wie es für den nächsten Header-Insert benötigt wird. - # EINFACHERE LÖSUNG: current_index nach endOfSegmentLocation nicht mehr verwenden. - # Wenn endOfSegmentLocation verwendet wird, sollte der nächste Insert auch endOfSegmentLocation verwenden oder - # man muss den Index explizit auf 1 für eine neue Seite setzen (was aber nicht korrekt ist, wenn das Dokument - # als ein langer Stream behandelt wird). - # Für jetzt: Da der Header der nächsten Seite `current_index` verwendet, müssen wir ihn aktualisieren. - # Ein Page Break fügt 1 zum Index hinzu. Der Footer hat `len(footer_text_for_page)`. - current_index += len(footer_text_for_page) + 1 # +1 für den PageBreak + # WICHTIG: Für die nächste Iteration muss doc_cursor_index + # den Anfang des neuen Segments (nach dem PageBreak) repräsentieren. + # Wenn endOfSegmentLocation verwendet wurde, ist der nächste logische Einfügepunkt + # wieder "endOfSegmentLocation" oder der Index muss neu "gefunden" werden. + # Für den Header der NÄCHSTEN Seite setzen wir doc_cursor_index + # NICHT einfach auf 1, da das Dokument weiterläuft. + # Wenn wir endOfSegmentLocation für PageBreak und Footer verwenden, + # sollte der Header der nächsten Seite auch mit endOfSegmentLocation beginnen, + # ODER wir müssen den exakten Index nach dem PageBreak kennen. + # Da der nächste Header wieder 'location' verwendet, müssen wir den Index aktualisieren. + # Ein PageBreak fügt 1 zum Index hinzu. Der Footer hat eine Länge. + # Dies ist immer noch der heikle Teil. + # doc_cursor_index += len(footer_text_for_page) + 1 # Ungenau, da Tabelle dazwischen war. + + # Da wir jetzt endOfSegmentLocation für Footer und PageBreak verwenden, + # ist der `doc_cursor_index` für den Header der nächsten Seite nicht mehr einfach weiterzuzählen. + # Wir müssen den Header der nächsten Seite auch mit `endOfSegmentLocation` einfügen, + # oder die Logik wird sehr komplex. + + # Umstellung: Header der Folgeseiten auch mit endOfSegmentLocation + # Dies erfordert, dass der *erste* Header mit `location` eingefügt wird, + # und alle *weiteren* Blöcke mit `endOfSegmentLocation`. + # Das machen wir später, wenn diese Version nicht geht. + # Vorerst: Wir nehmen an, `endOfSegmentLocation` hat den "globalen" Cursor bewegt. + # Der `doc_cursor_index` wird für den nächsten Header NICHT mehr direkt verwendet, + # wenn wir auf `endOfSegmentLocation` umstellen. + + # Temporär: Lassen wir die explizite Aktualisierung von doc_cursor_index hier weg, + # da die Einfügepunkte für Footer/PageBreak relativ sind. + # Wenn der nächste Header wieder `location: {index: doc_cursor_index}` verwendet, wird es knallen. + # Wir müssen konsequent sein. + # Wenn wir `doc_cursor_index` für den Header verwenden, müssen wir ihn korrekt weiterführen. + # Länge der Tabelle ist NICHT nur len(full_table_text). Es ist komplexer. + # + # EINFACHSTE LÖSUNG JETZT: Wir gehen davon aus, dass nach einem + # `insertPageBreak` mit `endOfSegmentLocation`, der NÄCHSTE `insertText` + # für den Header der neuen Seite an Index 1 dieser neuen Seite beginnt. + # Das ist FALSCH für die Google Docs API, da das Dokument ein Stream ist. + # + # Richtiger Ansatz: Wenn endOfSegmentLocation verwendet wird, sollte der nächste Block + # auch endOfSegmentLocation verwenden. + # Wir müssen uns entscheiden: Entweder alles mit exakten Indizes (schwer) + # oder alles relativ mit endOfSegmentLocation (einfacher für sequenzielles Anhängen). + + # DA DER HEADER DER NÄCHSTEN ITERATION `location: {'index': doc_cursor_index}` verwendet, + # MÜSSEN WIR `doc_cursor_index` AKTUALISIEREN. + # DIES IST DER TEIL, DER AM WAHRSCHEINLICHSTEN FEHLSCHLÄGT, WENN DIE LÄNGENBERECHNUNG FALSCH IST. + # Die Struktur einer Tabelle ist nicht nur ihr Text. + # Annahme: Eine Tabelle (Struktur + Text) + Footer + PageBreak + # Versuchen wir, `doc_cursor_index` *nicht* zu aktualisieren und stattdessen + # den Header der Folgeseiten auch mit `endOfSegmentLocation` einzufügen. + pass # doc_cursor_index wird nicht mehr manuell hochgezählt, wenn EOS verwendet wird. # Batch-Update ausführen