bugfix
This commit is contained in:
@@ -96,9 +96,13 @@ def create_google_doc_from_csv(service):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
requests = []
|
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]
|
kinder_liste = kinder_nach_gruppen[gruppe_original]
|
||||||
anzahl_kinder = len(kinder_liste)
|
anzahl_kinder = len(kinder_liste)
|
||||||
gruppe_display_name = gruppe_original + GRUPPENNAME_SUFFIX
|
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"{EINRICHTUNG}\t\t\t{FOTOGRAF_NAME}\n"
|
||||||
f"{FOTODATUM}\n\n"
|
f"{FOTODATUM}\n\n"
|
||||||
)
|
)
|
||||||
requests.append({'insertText': {'location': {'index': current_index}, 'text': header_text_for_page}})
|
# Wenn es die erste Seite ist, verwenden wir doc_cursor_index.
|
||||||
current_index += len(header_text_for_page)
|
# 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 ---
|
# --- Tabelle ---
|
||||||
num_rows_for_table = len(kinder_liste) + 1
|
num_rows_for_table = len(kinder_liste) + 1
|
||||||
num_cols_for_table = 3
|
num_cols_for_table = 3
|
||||||
|
|
||||||
|
# Füge die Tabellenstruktur ein
|
||||||
|
# Die Tabelle wird an der aktuellen Cursor-Position eingefügt.
|
||||||
requests.append({
|
requests.append({
|
||||||
'insertTable': {
|
'insertTable': {
|
||||||
'location': {'index': current_index},
|
'location': {'index': doc_cursor_index},
|
||||||
'rows': num_rows_for_table,
|
'rows': num_rows_for_table,
|
||||||
'columns': num_cols_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 = []
|
||||||
table_text_content.append("Nachname\tVorname\tGruppe")
|
table_text_content.append("Nachname\tVorname\tGruppe")
|
||||||
for kind in kinder_liste:
|
for kind in kinder_liste:
|
||||||
table_text_content.append(f"{kind['Nachname']}\t{kind['Vorname']}\t{gruppe_display_name}")
|
table_text_content.append(f"{kind['Nachname']}\t{kind['Vorname']}\t{gruppe_display_name}")
|
||||||
|
|
||||||
full_table_text = "\n".join(table_text_content) + "\n"
|
full_table_text = "\n".join(table_text_content) + "\n"
|
||||||
|
|
||||||
|
# Füge den gesamten Tabelleninhalt ein.
|
||||||
requests.append({
|
requests.append({
|
||||||
'insertText': {
|
'insertText': {
|
||||||
'location': {'index': table_fill_start_index},
|
'location': {'index': table_content_insertion_point},
|
||||||
'text': full_table_text
|
'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 ---
|
# --- Footer ---
|
||||||
# Korrektur: 'text' muss auf derselben Ebene wie 'endOfSegmentLocation' sein
|
|
||||||
footer_text_for_page = (
|
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"
|
"Dies ist die Liste der bereits angemeldeten Kinder. Bitte die Eltern der noch fehlenden\n"
|
||||||
"Kinder an die Anmeldung erinnern.\n\n"
|
"Kinder an die Anmeldung erinnern.\n\n"
|
||||||
f"Stand {stand_zeit}\n\n"
|
f"Stand {stand_zeit}\n\n"
|
||||||
@@ -150,7 +173,7 @@ def create_google_doc_from_csv(service):
|
|||||||
)
|
)
|
||||||
requests.append({
|
requests.append({
|
||||||
'insertText': {
|
'insertText': {
|
||||||
'endOfSegmentLocation': {},
|
'endOfSegmentLocation': {}, # Fügt am Ende des aktuellen Haupttextkörpers ein
|
||||||
'text': footer_text_for_page
|
'text': footer_text_for_page
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -158,24 +181,58 @@ def create_google_doc_from_csv(service):
|
|||||||
# --- Seitenumbruch ---
|
# --- Seitenumbruch ---
|
||||||
if i < len(sorted_gruppen_namen) - 1:
|
if i < len(sorted_gruppen_namen) - 1:
|
||||||
requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}})
|
requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}})
|
||||||
# Reset current_index for the new page if not using endOfSegmentLocation for header
|
# WICHTIG: Für die nächste Iteration muss doc_cursor_index
|
||||||
# Da wir endOfSegmentLocation für den nächsten Header nicht explizit verwenden (er basiert auf current_index),
|
# den Anfang des neuen Segments (nach dem PageBreak) repräsentieren.
|
||||||
# müssen wir sicherstellen, dass current_index für die nächste Seite korrekt ist.
|
# Wenn endOfSegmentLocation verwendet wurde, ist der nächste logische Einfügepunkt
|
||||||
# Mit endOfSegmentLocation für Footer und PageBreak ist die manuelle Index-Verfolgung
|
# wieder "endOfSegmentLocation" oder der Index muss neu "gefunden" werden.
|
||||||
# für den *nächsten* Header schwierig.
|
# Für den Header der NÄCHSTEN Seite setzen wir doc_cursor_index
|
||||||
# Eine sicherere Methode wäre, den Header der nächsten Seite auch mit endOfSegmentLocation zu beginnen.
|
# NICHT einfach auf 1, da das Dokument weiterläuft.
|
||||||
# Für jetzt lassen wir current_index einfach weiterlaufen und hoffen, dass
|
# Wenn wir endOfSegmentLocation für PageBreak und Footer verwenden,
|
||||||
# endOfSegmentLocation für Footer/PageBreak den Cursor korrekt für den *nächsten* Block
|
# sollte der Header der nächsten Seite auch mit endOfSegmentLocation beginnen,
|
||||||
# (der wieder 'location' mit 'current_index' verwendet) positioniert.
|
# ODER wir müssen den exakten Index nach dem PageBreak kennen.
|
||||||
# Dies könnte ein potenzielles Problem für die nächste Iteration sein, wenn der Footer/PageBreak
|
# Da der nächste Header wieder 'location' verwendet, müssen wir den Index aktualisieren.
|
||||||
# den `current_index` nicht so verschiebt, wie es für den nächsten Header-Insert benötigt wird.
|
# Ein PageBreak fügt 1 zum Index hinzu. Der Footer hat eine Länge.
|
||||||
# EINFACHERE LÖSUNG: current_index nach endOfSegmentLocation nicht mehr verwenden.
|
# Dies ist immer noch der heikle Teil.
|
||||||
# Wenn endOfSegmentLocation verwendet wird, sollte der nächste Insert auch endOfSegmentLocation verwenden oder
|
# doc_cursor_index += len(footer_text_for_page) + 1 # Ungenau, da Tabelle dazwischen war.
|
||||||
# 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).
|
# Da wir jetzt endOfSegmentLocation für Footer und PageBreak verwenden,
|
||||||
# Für jetzt: Da der Header der nächsten Seite `current_index` verwendet, müssen wir ihn aktualisieren.
|
# ist der `doc_cursor_index` für den Header der nächsten Seite nicht mehr einfach weiterzuzählen.
|
||||||
# Ein Page Break fügt 1 zum Index hinzu. Der Footer hat `len(footer_text_for_page)`.
|
# Wir müssen den Header der nächsten Seite auch mit `endOfSegmentLocation` einfügen,
|
||||||
current_index += len(footer_text_for_page) + 1 # +1 für den PageBreak
|
# 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
|
# Batch-Update ausführen
|
||||||
|
|||||||
Reference in New Issue
Block a user