This commit is contained in:
2025-05-26 18:28:43 +00:00
parent 835f5645d6
commit 70c7b84403

View File

@@ -96,52 +96,34 @@ def create_google_doc_from_csv(service):
return None
requests = []
# 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):
kinder_liste = kinder_nach_gruppen[gruppe_original]
anzahl_kinder = len(kinder_liste)
gruppe_display_name = gruppe_original + GRUPPENNAME_SUFFIX
# ... (kinder_liste, anzahl_kinder, gruppe_display_name) ...
# --- Seiten-Header ---
header_text_for_page = (
f"{EINRICHTUNG}\t\t\t{FOTOGRAF_NAME}\n"
f"{FOTODATUM}\n\n"
)
# 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)
if i == 0: # Nur für die allererste Seite einen expliziten Index
requests.append({'insertText': {'location': {'index': 1}, 'text': header_text_for_page}})
else: # Für Folgeseiten nach einem PageBreak
requests.append({'insertText': {'endOfSegmentLocation': {}, 'text': 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.
# Tabelle wird nach dem Header eingefügt.
# Wenn Header mit EOS eingefügt wurde, wird Tabelle auch mit EOS eingefügt.
requests.append({
'insertTable': {
'location': {'index': doc_cursor_index},
'endOfSegmentLocation': {}, # Fügt Tabelle am aktuellen Ende an
'rows': num_rows_for_table,
'columns': num_cols_for_table
}
})
# 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:
@@ -149,23 +131,17 @@ def create_google_doc_from_csv(service):
full_table_text = "\n".join(table_text_content) + "\n"
# Füge den gesamten Tabelleninhalt ein.
# Dies sollte in die zuletzt mit EOS erstellte Tabelle gehen.
requests.append({
'insertText': {
'location': {'index': table_content_insertion_point},
'endOfSegmentLocation': {},
'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_text_for_page = (
f"\n{anzahl_kinder} angemeldete Kinder\n\n" # Start mit \n um sicher aus der Tabelle zu sein
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"
@@ -173,7 +149,7 @@ def create_google_doc_from_csv(service):
)
requests.append({
'insertText': {
'endOfSegmentLocation': {}, # Fügt am Ende des aktuellen Haupttextkörpers ein
'endOfSegmentLocation': {},
'text': footer_text_for_page
}
})
@@ -181,65 +157,16 @@ def create_google_doc_from_csv(service):
# --- Seitenumbruch ---
if i < len(sorted_gruppen_namen) - 1:
requests.append({'insertPageBreak': {'endOfSegmentLocation': {}}})
# 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
if requests:
try:
print("Sende Batch Update an Google Docs API...")
print("Anzahl der Requests:", len(requests))
# Debug: Gib die ersten paar Requests aus, um zu sehen, ob sie logisch aussehen
# for req_idx, req_content in enumerate(requests[:6]):
# print(f"Request [{req_idx}]: {req_content}")
service.documents().batchUpdate(
documentId=document_id, body={'requests': requests}
).execute()
@@ -254,6 +181,10 @@ def create_google_doc_from_csv(service):
error_details = f"Fehler beim Dekodieren der Fehlerdetails: {e_decode}"
print(f"Details zum Fehler ({err.resp.status} {err._get_reason()}): {error_details}")
# Wenn es immer noch schiefgeht, alle Requests ausgeben:
# print("Alle gesendeten Requests:")
# for req_idx, req_content in enumerate(requests):
# print(f"Request [{req_idx}]: {req_content}")
return document_id