This commit is contained in:
2025-04-16 13:23:32 +00:00
parent ea5640828b
commit d152c2106c

View File

@@ -1847,11 +1847,18 @@ def evaluate_umsatz_chatgpt(company_name, wiki_umsatz):
def _process_batch(sheet, batches, row_numbers):
"""
Hilfsfunktion für process_verification_only: Verarbeitet einen Batch von Wikipedia-Verifizierungsanfragen.
Aktualisiert Spalten S-Y sowie Zeitstempel (AO) und Version (AP).
Aktualisiert NUR die Spalten S bis Y. Zeitstempel (AN, AO, AP) werden von
der aufrufenden Funktion oder anderen Prozessen gesetzt.
Args:
sheet (gspread.Worksheet): Das Worksheet-Objekt zum Schreiben.
batches (list): Liste der Prompt-Teile für den Batch.
row_numbers (list): Liste der zugehörigen Zeilennummern.
"""
if not batches:
return
# --- Prompt Erstellung (wie gehabt) ---
aggregated_prompt = (
"Du bist ein Experte in der Verifizierung von Wikipedia-Artikeln für Unternehmen. "
"Für jeden der folgenden Einträge prüfe, ob der vorhandene Wikipedia-Artikel (URL, Absatz, Kategorien) plausibel zum Firmennamen und zur Beschreibung passt. "
@@ -1861,32 +1868,27 @@ def _process_batch(sheet, batches, row_numbers):
"- 'OK' (wenn der Artikel gut passt)\n"
"- 'X | Alternativer Artikel: <URL> | Begründung: <Kurze Begründung>' (wenn der Artikel nicht passt, aber ein besserer gefunden wurde)\n"
"- 'X | Kein passender Artikel gefunden | Begründung: <Kurze Begründung>' (wenn der Artikel nicht passt und kein besserer gefunden wurde)\n"
"- 'Kein Wikipedia-Eintrag vorhanden.' (wenn initial keine URL angegeben wurde und keine Suche erfolgreich war - dieser Fall sollte selten sein, da die Suche vorher stattfindet)\n\n"
"- 'Kein Wikipedia-Eintrag vorhanden.' (wenn initial keine URL angegeben wurde und keine Suche erfolgreich war)\n\n"
"Einträge:\n"
"----------\n"
)
aggregated_prompt += "".join(batches) # Join ohne zusätzliches \n
aggregated_prompt += "----------\nBitte nur die 'Eintrag X: Antwort'-Zeilen ausgeben."
debug_print(f"Verarbeite Verifizierungs-Batch für Zeilen {row_numbers[0]} bis {row_numbers[-1]}.")
debug_print(f"Verarbeite Verifizierungs-Batch für Zeilen {row_numbers[0]} bis {row_numbers[-1]} (nur S-Y)...") # Hinweis angepasst
# Token Count für den Prompt
prompt_tokens = token_count(aggregated_prompt)
debug_print(f"Token-Zahl für Verifizierungs-Batch: {prompt_tokens}")
# Optional: Prüfung auf Token-Limit vor dem Senden
# if prompt_tokens > 3800: # Beispiel-Limit für gpt-3.5-turbo (4096 gesamt)
# debug_print(f"WARNUNG: Prompt für Batch {row_numbers[0]}-{row_numbers[-1]} überschreitet möglicherweise Token-Limit ({prompt_tokens}). Überspringe Batch.")
# # Hier könnte man den Batch aufteilen
# return
# --- ChatGPT Aufruf (wie gehabt) ---
chat_response = call_openai_chat(aggregated_prompt, temperature=0.0)
if not chat_response:
debug_print(f"Fehler: Keine Antwort von OpenAI für Verifizierungs-Batch {row_numbers[0]}-{row_numbers[-1]}.")
# Optional: Markiere Zeilen als fehlerhaft
return
# Parse die aggregierte Antwort
# --- Antwort parsen (wie gehabt) ---
answers = {}
lines = chat_response.strip().split('\n')
for line in lines:
@@ -1896,70 +1898,72 @@ def _process_batch(sheet, batches, row_numbers):
answer_text = match.group(2).strip()
if row_num in row_numbers:
answers[row_num] = answer_text
else:
debug_print(f"Warnung: Antwort für unerwartete Zeilennummer {row_num} im Batch erhalten: {answer_text}")
# else: # Weniger Lärm im Log
# debug_print(f"Warnung: Antwort für unerwartete Zeilennummer {row_num} im Batch erhalten: {answer_text}")
# Bereite Batch-Update für Google Sheet vor
# --- Batch-Update vorbereiten (NUR S bis Y) ---
updates = []
current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_version = Config.VERSION
# Timestamps und Version werden HIER NICHT mehr hinzugefügt
for row_num in row_numbers:
answer = answers.get(row_num, "k.A. (Keine Antwort im Batch)") # Fallback
debug_print(f"Zeile {row_num} Verifizierungsantwort: '{answer}'")
wiki_confirm = "" # Spalte S
alt_article = "" # Spalte T
wiki_explanation = "" # Spalte U
# Spalten V-Y bleiben vorerst leer oder werden hier gesetzt
v_val, w_val, x_val, y_val = "", "", "", "" # Beispiel
# Variablen für die Spalten S-Y initialisieren
wiki_confirm = "" # Spalte S
alt_article = "" # Spalte T
wiki_explanation = "" # Spalte U
v_val, w_val, x_val, y_val = "", "", "", "" # Spalten V-Y
# Logik zur Bestimmung der Werte für S, T, U basierend auf 'answer' (wie gehabt)
if answer.upper() == "OK":
wiki_confirm = "OK"
elif answer.upper() == "KEIN WIKIPEDIA-EINTRAG VORHANDEN.":
wiki_confirm = "X" # Markieren, da eigentlich einer da sein sollte
wiki_confirm = "X"
alt_article = "Kein Wikipedia-Eintrag vorhanden."
wiki_explanation = "Ursprünglich keine URL oder Suche erfolglos."
elif answer.startswith("X |"):
parts = answer.split("|", 2) # Splitte maximal 2 mal
parts = answer.split("|", 2)
wiki_confirm = "X"
if len(parts) > 1:
detail = parts[1].strip()
if detail.startswith("Alternativer Artikel:"):
alt_article = detail.split(":", 1)[1].strip()
elif detail == "Kein passender Artikel gefunden":
alt_article = "Kein passender Artikel gefunden"
else: # Fallback, falls Format unerwartet
alt_article = detail
alt_article = detail
else:
alt_article = detail
if len(parts) > 2:
reason_part = parts[2].strip()
if reason_part.startswith("Begründung:"):
wiki_explanation = reason_part.split(":", 1)[1].strip()
else: # Fallback
else:
wiki_explanation = reason_part
else: # Unerwartetes Format
wiki_confirm = "?"
wiki_explanation = f"Unerwartetes Format: {answer}"
# Füge Updates für diese Zeile zur Liste hinzu
# Füge Updates NUR für S-Y zur Liste hinzu
updates.append({'range': f'S{row_num}', 'values': [[wiki_confirm]]})
updates.append({'range': f'T{row_num}', 'values': [[alt_article]]})
updates.append({'range': f'U{row_num}', 'values': [[wiki_explanation]]})
# Setze V-Y zurück/leer
updates.append({'range': f'V{row_num}:Y{row_num}', 'values': [[v_val, w_val, x_val, y_val]]})
# Zeitstempel und Version
updates.append({'range': f'AO{row_num}', 'values': [[current_timestamp]]})
updates.append({'range': f'AP{row_num}', 'values': [[current_version]]})
# Führe das Batch-Update für alle Zeilen dieses Batches durch
# --- Führe das Batch-Update für S-Y durch ---
if updates:
GoogleSheetHandler().batch_update_cells(updates) # Nutze die zentrale Update-Funktion
debug_print(f"Verifizierungs-Batch {row_numbers[0]}-{row_numbers[-1]} erfolgreich in Google Sheet aktualisiert.")
try:
# Verwende das übergebene sheet-Objekt direkt
sheet.batch_update(updates, value_input_option='USER_ENTERED')
debug_print(f"Verifizierungs-Batch {row_numbers[0]}-{row_numbers[-1]} (S-Y) erfolgreich in Google Sheet aktualisiert.")
except Exception as e:
# Gib eine spezifischere Fehlermeldung aus
debug_print(f"FEHLER beim Batch-Update (S-Y) für Zeilen {row_numbers[0]}-{row_numbers[-1]}: {type(e).__name__} - {e}")
# Optional: Fehler weitergeben, wenn retry gewünscht wird (nicht empfohlen für Sheet-Updates hier)
# raise e
else:
debug_print(f"Keine Updates für Verifizierungs-Batch {row_numbers[0]}-{row_numbers[-1]} generiert.")
debug_print(f"Keine Updates (S-Y) für Verifizierungs-Batch {row_numbers[0]}-{row_numbers[-1]} generiert.")
# Kurze Pause nach jedem Batch-API-Call
time.sleep(Config.RETRY_DELAY)
# KEINE Pause hier mehr, wird in der aufrufenden Funktion gemacht
# time.sleep(Config.RETRY_DELAY)
def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet):
@@ -1969,8 +1973,21 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
"""
debug_print(f"Starte Wikipedia-Verifizierungsmodus (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...")
# Lade aktuelle Daten direkt hier
all_data = sheet_handler.get_all_data_with_headers()
timestamp_col_index = COLUMN_MAP["Wikipedia Timestamp"] # Prüfe Spalte AN
if not all_data or len(all_data) <= 5: # Check ob Daten vorhanden sind
debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_verification_only gefunden.")
return
# Hole Index für AN Timestamp
timestamp_col_key = "Wikipedia Timestamp"
timestamp_col_index = COLUMN_MAP.get(timestamp_col_key)
ts_col_letter = sheet_handler._get_col_letter(timestamp_col_index + 1) if timestamp_col_index is not None else "FEHLER"
if timestamp_col_index is None:
debug_print(f"FEHLER: Spaltenschlüssel '{timestamp_col_key}' nicht in COLUMN_MAP gefunden. Breche Wiki-Verifizierung ab.")
return
batch_size = Config.BATCH_SIZE
current_batch = []
@@ -1980,26 +1997,38 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1):
row_index_in_list = i - 1
if row_index_in_list >= len(all_data): # Sicherheitscheck
debug_print(f"Warnung: Zeilenindex {row_index_in_list} außerhalb des Datenbereichs ({len(all_data)} Zeilen).")
if row_index_in_list >= len(all_data):
debug_print(f"Warnung (Wiki): Zeilenindex {row_index_in_list} außerhalb des Datenbereichs ({len(all_data)} Zeilen).")
continue
row = all_data[row_index_in_list]
# --- NEU: Timestamp-Prüfung für jede Zeile ---
if len(row) > timestamp_col_index and row[timestamp_col_index].strip():
debug_print(f"Zeile {i}: Überspringe Wiki-Verifizierung (Timestamp AN bereits vorhanden: '{row[timestamp_col_index]}').")
# --- DEBUGGING Timestamp-Prüfung AN ---
ts_value_an = "INDEX_FEHLER"
ts_an_is_set = False
if len(row) > timestamp_col_index:
ts_value_an = row[timestamp_col_index]
ts_an_is_set = bool(str(ts_value_an).strip()) # Prüfe, ob Wert nach strip nicht leer ist
# Logge für die ersten 5 geprüften und letzte 5 geprüfte Zeilen im Range, oder wenn es sich ändert
log_debug = (i < start_row_index_in_sheet + 5 or i > end_row_index_in_sheet - 5 or i % 500 == 0)
if log_debug:
debug_print(f"Zeile {i} (Wiki Check): Prüfe Timestamp {ts_col_letter} (Index {timestamp_col_index}). Rohwert='{ts_value_an}', Strip='{str(ts_value_an).strip()}', Bedingung ist: {ts_an_is_set}")
# --- Ende DEBUGGING ---
if ts_an_is_set:
# Weniger Lärm im Log, nur zählen
skipped_count += 1
if skipped_count == 1 or skipped_count % 100 == 0: # Logge den ersten und jeden 100. übersprungenen
debug_print(f"Zeile {i}: Überspringe Wiki-Verifizierung (Timestamp {ts_col_letter} vorhanden: '{ts_value_an.strip()}'). ({skipped_count} gesamt übersprungen)")
continue
# --- Ende Timestamp-Prüfung ---
# Erstelle Text für den Prompt (wie zuvor)
# (Restliche Logik zum Erstellen von entry_text wie zuvor)
company_name = row[COLUMN_MAP["CRM Name"]] if len(row) > COLUMN_MAP["CRM Name"] else ''
crm_desc = row[COLUMN_MAP["CRM Beschreibung"]] if len(row) > COLUMN_MAP["CRM Beschreibung"] else ''
wiki_url = row[COLUMN_MAP["Wiki URL"]] if len(row) > COLUMN_MAP["Wiki URL"] and row[COLUMN_MAP["Wiki URL"]].strip() not in ['', 'k.A.'] else 'k.A.'
wiki_paragraph = row[COLUMN_MAP["Wiki Absatz"]] if len(row) > COLUMN_MAP["Wiki Absatz"] else 'k.A.'
wiki_categories = row[COLUMN_MAP["Wiki Kategorien"]] if len(row) > COLUMN_MAP["Wiki Kategorien"] else 'k.A.'
entry_text = (
f"Eintrag {i}:\n"
f" Firmenname: {company_name}\n"
@@ -2014,27 +2043,26 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
processed_count += 1
# Wenn Batch voll oder letzte Zeile erreicht
if len(current_batch) == batch_size or i == end_row_index_in_sheet:
if current_batch: # Nur wenn etwas im Batch ist
# _process_batch schreibt S-Y, AO, AP. AN wird *nicht* von _process_batch geschrieben!
# Wir müssen AN separat setzen oder _process_batch anpassen.
# Einfacher: Setzen AN hier *vor* dem Aufruf für die bearbeiteten Zeilen.
# Erstelle Updates für den AN-Timestamp
if len(current_batch) >= batch_size or i == end_row_index_in_sheet:
if current_batch:
# Setze zuerst den AN Timestamp für die bearbeiteten Zeilen
wiki_ts_updates = []
current_wiki_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for row_num in current_row_numbers:
wiki_ts_updates.append({'range': f'AN{row_num}', 'values': [[current_wiki_timestamp]]})
# Setze zuerst den AN Timestamp
if wiki_ts_updates:
sheet_handler.batch_update_cells(wiki_ts_updates)
debug_print(f"Wiki-Timestamp AN für Batch {current_row_numbers[0]}-{current_row_numbers[-1]} gesetzt.")
# Verwende Spaltenbuchstaben dynamisch
wiki_ts_updates.append({'range': f'{ts_col_letter}{row_num}', 'values': [[current_wiki_timestamp]]})
if wiki_ts_updates:
success_ts = sheet_handler.batch_update_cells(wiki_ts_updates)
if success_ts:
debug_print(f"Wiki-Timestamp {ts_col_letter} für Batch {current_row_numbers[0]}-{current_row_numbers[-1]} gesetzt.")
else:
debug_print(f"FEHLER beim Setzen des Wiki-Timestamps {ts_col_letter} für Batch.")
# Rufe dann _process_batch auf, das S-Y schreibt
_process_batch(sheet_handler.sheet, current_batch, current_row_numbers)
time.sleep(Config.RETRY_DELAY) # Pause nach API Calls
# Rufe dann _process_batch auf, das S-Y, AO, AP schreibt
_process_batch(sheet_handler.sheet, current_batch, current_row_numbers) # Nutzt noch alten Timestamp AO! Das müssen wir ändern.
# Reset für nächsten Batch
current_batch = []
current_row_numbers = []
@@ -2139,10 +2167,17 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
"""Batch-Prozess für Website-Scraping (Rohtext & Zusammenfassung)."""
debug_print(f"Starte Website-Scraping (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...")
# Lade aktuelle Daten direkt hier
all_data = sheet_handler.get_all_data_with_headers()
sheet = sheet_handler.sheet
# HIER KORRIGIERT: Sicherstellen, dass der Index für AT verwendet wird
timestamp_col_index = COLUMN_MAP.get("Website Scrape Timestamp")
if not all_data or len(all_data) <= 5:
debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_website_batch gefunden.")
return
sheet = sheet_handler.sheet # Zugriff auf gspread sheet Objekt
# Hole Indizes aus COLUMN_MAP
timestamp_col_key = "Website Scrape Timestamp"
timestamp_col_index = COLUMN_MAP.get(timestamp_col_key)
website_col_index = COLUMN_MAP.get("CRM Website")
rohtext_col_index = COLUMN_MAP.get("Website Rohtext")
summary_col_index = COLUMN_MAP.get("Website Zusammenfassung")
@@ -2153,27 +2188,44 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
debug_print("FEHLER: Mindestens ein benötigter Spaltenindex für process_website_batch fehlt in COLUMN_MAP.")
return
ts_col_letter = sheet_handler._get_col_letter(timestamp_col_index + 1)
rohtext_col_letter = sheet_handler._get_col_letter(rohtext_col_index + 1)
summary_col_letter = sheet_handler._get_col_letter(summary_col_index + 1)
version_col_letter = sheet_handler._get_col_letter(version_col_index + 1)
processed_count = 0
skipped_count = 0
for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1):
row_index_in_list = i - 1
if row_index_in_list >= len(all_data): continue
if row_index_in_list >= len(all_data):
debug_print(f"Warnung (Website): Zeilenindex {row_index_in_list} außerhalb des Datenbereichs ({len(all_data)} Zeilen).")
continue
row = all_data[row_index_in_list]
# --- KORRIGIERTE Timestamp-Prüfung für jede Zeile ---
if len(row) > timestamp_col_index and row[timestamp_col_index].strip():
# Optional: Weniger Lärm im Log, nur alle X Zeilen loggen
# if skipped_count % 100 == 0:
# debug_print(f"Zeile {i}: Überspringe Website-Scraping (Timestamp AT vorhanden: '{row[timestamp_col_index]}')...")
# --- DEBUGGING Timestamp-Prüfung AT ---
ts_value_at = "INDEX_FEHLER"
ts_at_is_set = False
if len(row) > timestamp_col_index:
ts_value_at = row[timestamp_col_index]
ts_at_is_set = bool(str(ts_value_at).strip())
log_debug = (i < start_row_index_in_sheet + 5 or i > end_row_index_in_sheet - 5 or i % 500 == 0)
if log_debug:
debug_print(f"Zeile {i} (Website Check): Prüfe Timestamp {ts_col_letter} (Index {timestamp_col_index}). Rohwert='{ts_value_at}', Strip='{str(ts_value_at).strip()}', Bedingung ist: {ts_at_is_set}")
# --- Ende DEBUGGING ---
if ts_at_is_set:
skipped_count += 1
if skipped_count == 1 or skipped_count % 100 == 0:
debug_print(f"Zeile {i}: Überspringe Website-Scraping (Timestamp {ts_col_letter} vorhanden: '{ts_value_at.strip()}'). ({skipped_count} gesamt übersprungen)")
continue
# --- Ende Timestamp-Prüfung ---
website_url = row[website_col_index] if len(row) > website_col_index else ""
if not website_url or website_url.strip().lower() == "k.a.":
# debug_print(f"Zeile {i}: Kein gültiger Website-Eintrag, überspringe Website-Scraping.")
skipped_count += 1
skipped_count += 1 # Zähle auch diese als übersprungen
continue
# debug_print(f"Zeile {i}: Verarbeite Website {website_url}...") # Weniger Lärm
@@ -2185,12 +2237,6 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_version = Config.VERSION
# Spaltenbuchstaben für die Ranges ermitteln
rohtext_col_letter = sheet_handler._get_col_letter(rohtext_col_index + 1)
summary_col_letter = sheet_handler._get_col_letter(summary_col_index + 1)
ts_col_letter = sheet_handler._get_col_letter(timestamp_col_index + 1)
version_col_letter = sheet_handler._get_col_letter(version_col_index + 1)
updates.append({'range': f'{rohtext_col_letter}{i}', 'values': [[raw_text]]})
updates.append({'range': f'{summary_col_letter}{i}', 'values': [[summary]]})
updates.append({'range': f'{ts_col_letter}{i}', 'values': [[current_timestamp]]}) # AT Timestamp
@@ -2200,13 +2246,11 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
if updates:
success = sheet_handler.batch_update_cells(updates)
if not success:
debug_print(f"FEHLER beim Schreiben der Updates für Zeile {i}.")
# Weniger Lärm im Log bei Erfolg:
# else: debug_print(f"Zeile {i}: Website-Daten aktualisiert...")
debug_print(f"FEHLER beim Schreiben der Website-Updates für Zeile {i}.")
# Weniger Lärm im Log bei Erfolg
# else: debug_print(f"Zeile {i}: Website-Daten aktualisiert.")
# Pause zwischen den Zeilen/Websites
time.sleep(Config.RETRY_DELAY)
time.sleep(Config.RETRY_DELAY) # Pause *nach* der Verarbeitung einer Zeile
debug_print(f"Website-Scraping (Batch) abgeschlossen. {processed_count} Websites gescraped, {skipped_count} Zeilen übersprungen.")
@@ -2215,39 +2259,86 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
"""Batch-Prozess für Brancheneinschätzung."""
debug_print(f"Starte Brancheneinschätzung (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...")
# Lade aktuelle Daten direkt hier
all_data = sheet_handler.get_all_data_with_headers()
if not all_data or len(all_data) <= 5:
debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_branch_batch gefunden.")
return
sheet = sheet_handler.sheet
timestamp_col_index = COLUMN_MAP["Timestamp letzte Prüfung"] # Prüfe Spalte AO
# Hole Indizes aus COLUMN_MAP
timestamp_col_key = "Timestamp letzte Prüfung"
timestamp_col_index = COLUMN_MAP.get(timestamp_col_key)
branche_crm_idx = COLUMN_MAP.get("CRM Branche")
beschreibung_idx = COLUMN_MAP.get("CRM Beschreibung")
branche_wiki_idx = COLUMN_MAP.get("Wiki Branche")
kategorien_wiki_idx = COLUMN_MAP.get("Wiki Kategorien")
summary_web_idx = COLUMN_MAP.get("Website Zusammenfassung")
version_col_index = COLUMN_MAP.get("Version")
# Indizes für Ergebnisspalten W, X, Y
branch_w_idx = COLUMN_MAP.get("Chat Vorschlag Branche")
branch_x_idx = COLUMN_MAP.get("Chat Konsistenz Branche")
branch_y_idx = COLUMN_MAP.get("Chat Begründung Abweichung Branche")
# Fehlerprüfung für Indizes
required_indices = [timestamp_col_index, branche_crm_idx, beschreibung_idx, branche_wiki_idx,
kategorien_wiki_idx, summary_web_idx, version_col_index, branch_w_idx,
branch_x_idx, branch_y_idx]
if None in required_indices:
debug_print("FEHLER: Mindestens ein benötigter Spaltenindex für process_branch_batch fehlt in COLUMN_MAP.")
return
ts_col_letter = sheet_handler._get_col_letter(timestamp_col_index + 1)
version_col_letter = sheet_handler._get_col_letter(version_col_index + 1)
branch_w_letter = sheet_handler._get_col_letter(branch_w_idx + 1)
branch_x_letter = sheet_handler._get_col_letter(branch_x_idx + 1)
branch_y_letter = sheet_handler._get_col_letter(branch_y_idx + 1)
processed_count = 0
skipped_count = 0
# Stelle sicher, dass das Branchenschema geladen ist
if not ALLOWED_TARGET_BRANCHES:
load_target_schema() # Versuch es zu laden
load_target_schema()
if not ALLOWED_TARGET_BRANCHES:
debug_print("FEHLER: Ziel-Branchenschema konnte nicht geladen werden. Breche Branch-Batch ab.")
return
for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1):
row_index_in_list = i - 1
if row_index_in_list >= len(all_data): continue
if row_index_in_list >= len(all_data):
debug_print(f"Warnung (Branch): Zeilenindex {row_index_in_list} außerhalb des Datenbereichs ({len(all_data)} Zeilen).")
continue
row = all_data[row_index_in_list]
# --- NEU: Timestamp-Prüfung für jede Zeile ---
if len(row) > timestamp_col_index and row[timestamp_col_index].strip():
debug_print(f"Zeile {i}: Überspringe Branchen-Einschätzung (Timestamp AO bereits vorhanden: '{row[timestamp_col_index]}').")
# --- DEBUGGING Timestamp-Prüfung AO ---
ts_value_ao = "INDEX_FEHLER"
ts_ao_is_set = False
if len(row) > timestamp_col_index:
ts_value_ao = row[timestamp_col_index]
ts_ao_is_set = bool(str(ts_value_ao).strip())
log_debug = (i < start_row_index_in_sheet + 5 or i > end_row_index_in_sheet - 5 or i % 500 == 0)
if log_debug:
debug_print(f"Zeile {i} (Branch Check): Prüfe Timestamp {ts_col_letter} (Index {timestamp_col_index}). Rohwert='{ts_value_ao}', Strip='{str(ts_value_ao).strip()}', Bedingung ist: {ts_ao_is_set}")
# --- Ende DEBUGGING ---
if ts_ao_is_set:
skipped_count += 1
if skipped_count == 1 or skipped_count % 100 == 0:
debug_print(f"Zeile {i}: Überspringe Branchen-Einschätzung (Timestamp {ts_col_letter} vorhanden: '{ts_value_ao.strip()}'). ({skipped_count} gesamt übersprungen)")
continue
# --- Ende Timestamp-Prüfung ---
# Hole benötigte Daten aus der Zeile (wie zuvor)
crm_branche = row[COLUMN_MAP["CRM Branche"]] if len(row) > COLUMN_MAP["CRM Branche"] else ""
beschreibung = row[COLUMN_MAP["CRM Beschreibung"]] if len(row) > COLUMN_MAP["CRM Beschreibung"] else ""
wiki_branche = row[COLUMN_MAP["Wiki Branche"]] if len(row) > COLUMN_MAP["Wiki Branche"] else ""
wiki_kategorien = row[COLUMN_MAP["Wiki Kategorien"]] if len(row) > COLUMN_MAP["Wiki Kategorien"] else ""
website_summary = row[COLUMN_MAP["Website Zusammenfassung"]] if len(row) > COLUMN_MAP["Website Zusammenfassung"] else ""
# Hole benötigte Daten aus der Zeile
crm_branche = row[branche_crm_idx] if len(row) > branche_crm_idx else ""
beschreibung = row[beschreibung_idx] if len(row) > beschreibung_idx else ""
wiki_branche = row[branche_wiki_idx] if len(row) > branche_wiki_idx else ""
wiki_kategorien = row[kategorien_wiki_idx] if len(row) > kategorien_wiki_idx else ""
website_summary = row[summary_web_idx] if len(row) > summary_web_idx else ""
debug_print(f"Zeile {i}: Starte Brancheneinschätzung...")
# debug_print(f"Zeile {i}: Starte Brancheneinschätzung...") # Weniger Lärm
result = evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary)
processed_count += 1
@@ -2255,19 +2346,23 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
current_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_version = Config.VERSION
updates.append({'range': f'W{i}', 'values': [[result.get("branch", "Fehler")]]}) # Spalte W
updates.append({'range': f'X{i}', 'values': [[result.get("consistency", "Fehler")]]}) # Spalte X
updates.append({'range': f'Y{i}', 'values': [[result.get("justification", "Fehler")]]})# Spalte Y
updates.append({'range': f'AO{i}', 'values': [[current_timestamp]]}) # Spalte AO (Timestamp letzte Prüfung)
updates.append({'range': f'AP{i}', 'values': [[current_version]]}) # Spalte AP (Version)
updates.append({'range': f'{branch_w_letter}{i}', 'values': [[result.get("branch", "Fehler")]]})
updates.append({'range': f'{branch_x_letter}{i}', 'values': [[result.get("consistency", "Fehler")]]})
updates.append({'range': f'{branch_y_letter}{i}', 'values': [[result.get("justification", "Fehler")]]})
updates.append({'range': f'{ts_col_letter}{i}', 'values': [[current_timestamp]]}) # AO Timestamp
updates.append({'range': f'{version_col_letter}{i}', 'values': [[current_version]]}) # AP Version
# Führe Batch-Update für diese eine Zeile durch
if updates:
sheet_handler.batch_update_cells(updates)
debug_print(f"Zeile {i}: Branch-Einschätzung aktualisiert: {result['branch']} ({result['consistency']}) | Zeitstempel AO: {current_timestamp}, Version: {current_version}")
success = sheet_handler.batch_update_cells(updates)
if success:
# Weniger Lärm im Log bei Erfolg
# debug_print(f"Zeile {i}: Branch-Einschätzung aktualisiert: {result['branch']} ({result['consistency']}) | Zeitstempel AO: {current_timestamp}, Version: {current_version}")
pass
else:
debug_print(f"FEHLER beim Schreiben der Branch-Updates für Zeile {i}.")
# Pause zwischen den API-Aufrufen
time.sleep(Config.RETRY_DELAY)
time.sleep(Config.RETRY_DELAY) # Pause *nach* der Verarbeitung
debug_print(f"Brancheneinschätzung (Batch) abgeschlossen. {processed_count} Zeilen eingeschätzt, {skipped_count} Zeilen übersprungen.")