This commit is contained in:
2025-04-16 14:02:01 +00:00
parent 3339376f3a
commit 924a0fe2ca

View File

@@ -2012,22 +2012,20 @@ def _process_batch(sheet, batches, row_numbers):
def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet):
"""
Batch-Prozess nur für Wikipedia-Verifizierung.
Prüft für jede Zeile im Bereich, ob Timestamp AN bereits gesetzt ist.
Batch-Prozess nur für Wikipedia-Verifizierung. Verarbeitet ALLE Zeilen im
angegebenen Bereich und setzt den AN-Timestamp.
"""
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()
if not all_data or len(all_data) <= 5: # Check ob Daten vorhanden sind
if not all_data or len(all_data) <= 5:
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"
ts_col_letter = sheet_handler._get_col_letter(timestamp_col_index + 1) if timestamp_col_index is not None else "AN_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.")
@@ -2037,7 +2035,7 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
current_batch = []
current_row_numbers = []
processed_count = 0
skipped_count = 0
# skipped_count nicht mehr benötigt
for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1):
row_index_in_list = i - 1
@@ -2047,27 +2045,9 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
row = all_data[row_index_in_list]
# --- 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 ---
# --- KEINE Timestamp-Prüfung mehr hier ---
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 ---
# (Restliche Logik zum Erstellen von entry_text wie zuvor)
# Erstelle Text für den Prompt (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.'
@@ -2089,11 +2069,13 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
# Wenn Batch voll oder letzte Zeile erreicht
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
# Rufe _process_batch auf, das S-Y schreibt
_process_batch(sheet_handler.sheet, current_batch, current_row_numbers)
# Setze den AN Timestamp für die bearbeiteten Zeilen *nach* dem Batch
wiki_ts_updates = []
current_wiki_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for row_num in current_row_numbers:
# Verwende Spaltenbuchstaben dynamisch
wiki_ts_updates.append({'range': f'{ts_col_letter}{row_num}', 'values': [[current_wiki_timestamp]]})
if wiki_ts_updates:
@@ -2103,14 +2085,12 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i
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
time.sleep(Config.RETRY_DELAY) # Pause nach API Calls und Sheet Update
current_batch = []
current_row_numbers = []
debug_print(f"Wikipedia-Verifizierungs-Batch abgeschlossen. {processed_count} Zeilen zur Verarbeitung an ChatGPT gesendet, {skipped_count} Zeilen übersprungen.")
debug_print(f"Wikipedia-Verifizierungs-Batch abgeschlossen. {processed_count} Zeilen verarbeitet.")
# Anpassung in _process_batch: Setzt jetzt *nicht* mehr AO/AP, sondern nur S-Y
def _process_batch(sheet, batches, row_numbers):
@@ -2208,15 +2188,24 @@ def _process_batch(sheet, batches, row_numbers):
# Komplette Funktion process_website_batch (prüft jetzt Timestamp AT mit erzwungenem Debugging)
def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet):
"""Batch-Prozess für Website-Scraping (Rohtext & Zusammenfassung)."""
"""
Batch-Prozess für Website-Scraping (Rohtext & Zusammenfassung).
Verarbeitet ALLE Zeilen im angegebenen Bereich und setzt AT + AP Timestamps.
"""
debug_print(f"Starte Website-Scraping (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...")
# Lade aktuelle Daten (optional, aber sicher)
if not sheet_handler.load_data():
debug_print("FEHLER beim Laden der Daten in process_website_batch.")
return
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_website_batch gefunden.")
return
sheet = sheet_handler.sheet
# Hole Indizes
timestamp_col_key = "Website Scrape Timestamp"
timestamp_col_index = COLUMN_MAP.get(timestamp_col_key)
website_col_index = COLUMN_MAP.get("CRM Website")
@@ -2225,7 +2214,7 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
version_col_index = COLUMN_MAP.get("Version")
if None in [timestamp_col_index, website_col_index, rohtext_col_index, summary_col_index, version_col_index]:
debug_print(f"FEHLER: Mindestens ein benötigter Spaltenindex für process_website_batch fehlt in COLUMN_MAP (benötigt: '{timestamp_col_key}', 'CRM Website', 'Website Rohtext', 'Website Zusammenfassung', 'Version').")
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)
@@ -2234,7 +2223,7 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
version_col_letter = sheet_handler._get_col_letter(version_col_index + 1)
processed_count = 0
skipped_count = 0
skipped_url_count = 0 # Zähle nur Zeilen ohne URL
for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1):
row_index_in_list = i - 1
@@ -2244,31 +2233,15 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
row = all_data[row_index_in_list]
# --- ERZWUNGENE 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]
# Konvertiere zu String VOR strip, um Fehler bei None etc. zu vermeiden
ts_at_is_set = bool(str(ts_value_at).strip())
# Gib für JEDE Zeile im Bereich die Prüfung aus
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()}', Überspringen? -> {ts_at_is_set}")
# --- Ende ERZWUNGENE DEBUGGING ---
# --- KEINE Timestamp-Prüfung mehr hier ---
if ts_at_is_set:
skipped_count += 1
# Logge nur noch selten, da wir die Prüfung oben schon loggen
# if skipped_count == 1 or skipped_count % 100 == 0:
# debug_print(f"Zeile {i}: Überspringe Website-Scraping (Timestamp {ts_col_letter} vorhanden). ({skipped_count} gesamt übersprungen)")
continue
# --- Ende Timestamp-Prüfung ---
# (Rest der Logik zum Scrapen und Updaten wie zuvor)
website_url = row[website_col_index] if len(row) > website_col_index else ""
if not website_url or website_url.strip().lower() == "k.a.":
skipped_count += 1
# debug_print(f"Zeile {i}: Kein gültiger Website-Eintrag, überspringe Website-Scraping.")
skipped_url_count += 1
continue
# debug_print(f"Zeile {i}: Verarbeite Website {website_url}...") # Weniger Lärm
raw_text = get_website_raw(website_url)
summary = summarize_website_content(raw_text)
processed_count += 1
@@ -2285,19 +2258,28 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index
if updates:
success = sheet_handler.batch_update_cells(updates)
if success:
debug_print(f"Zeile {i}: Website-Daten erfolgreich aktualisiert.") # Geänderte Log-Nachricht
if not success:
debug_print(f"FEHLER beim Schreiben der Website-Updates für Zeile {i}.")
# debug_print(f"Zeile {i}: Website-Daten erfolgreich aktualisiert.") # Weniger Lärm
pass
else:
debug_print(f"FEHLER beim Schreiben der Website-Updates für Zeile {i}.")
time.sleep(Config.RETRY_DELAY)
debug_print(f"Website-Scraping (Batch) abgeschlossen. {processed_count} Websites gescraped, {skipped_count} Zeilen übersprungen.")
debug_print(f"Website-Scraping (Batch) abgeschlossen. {processed_count} Websites gescraped, {skipped_url_count} Zeilen ohne URL übersprungen.")
# Komplette Funktion process_branch_batch (prüft jetzt Timestamp AO mit erzwungenem Debugging)
# Komplette Funktion process_branch_batch (OHNE interne Timestamp-Prüfung)
def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet):
"""Batch-Prozess für Brancheneinschätzung."""
"""
Batch-Prozess für Brancheneinschätzung. Verarbeitet ALLE Zeilen im
angegebenen Bereich und setzt AO + AP Timestamps.
"""
debug_print(f"Starte Brancheneinschätzung (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...")
# Lade aktuelle Daten
if not sheet_handler.load_data():
debug_print("FEHLER beim Laden der Daten in process_branch_batch.")
return
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.")
@@ -2305,7 +2287,7 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
sheet = sheet_handler.sheet
# Hole Indizes aus COLUMN_MAP
# Hole Indizes
timestamp_col_key = "Timestamp letzte Prüfung"
timestamp_col_index = COLUMN_MAP.get(timestamp_col_key)
branche_crm_idx = COLUMN_MAP.get("CRM Branche")
@@ -2332,7 +2314,7 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
branch_y_letter = sheet_handler._get_col_letter(branch_y_idx + 1)
processed_count = 0
skipped_count = 0
# skipped_count nicht mehr benötigt
if not ALLOWED_TARGET_BRANCHES:
load_target_schema()
@@ -2348,30 +2330,16 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
row = all_data[row_index_in_list]
# --- ERZWUNGENE 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())
# Gib für JEDE Zeile im Bereich die Prüfung aus
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()}', Überspringen? -> {ts_ao_is_set}")
# --- Ende ERZWUNGENE DEBUGGING ---
# --- KEINE Timestamp-Prüfung mehr hier ---
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). ({skipped_count} gesamt übersprungen)")
continue
# --- Ende Timestamp-Prüfung ---
# (Restliche Logik zum Datenholen und Bewerten wie zuvor)
# Daten holen
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...") # Weniger Lärm
result = evaluate_branche_chatgpt(crm_branche, beschreibung, wiki_branche, wiki_kategorien, website_summary)
processed_count += 1
@@ -2388,13 +2356,14 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
if updates:
success = sheet_handler.batch_update_cells(updates)
if success:
debug_print(f"Zeile {i}: Branch-Einschätzung erfolgreich aktualisiert.") # Geänderte Log-Nachricht
if not success:
# debug_print(f"Zeile {i}: Branch-Einschätzung erfolgreich aktualisiert.") # Weniger Lärm
pass
else:
debug_print(f"FEHLER beim Schreiben der Branch-Updates für Zeile {i}.")
time.sleep(Config.RETRY_DELAY)
debug_print(f"Brancheneinschätzung (Batch) abgeschlossen. {processed_count} Zeilen eingeschätzt, {skipped_count} Zeilen übersprungen.")
debug_print(f"Brancheneinschätzung (Batch) abgeschlossen. {processed_count} Zeilen eingeschätzt.")
def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet):
"""Batch-Prozess für Website-Scraping (Rohtext & Zusammenfassung)."""
@@ -2504,55 +2473,44 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_
# - sheet_handler ist eine initialisierte Instanz von GoogleSheetHandler (mit der korrekten get_start_row_index Methode).
# - Globale Konstante header_rows (oder besser, hol sie vom sheet_handler?)
# Komplette run_dispatcher Funktion (Start immer basierend auf AO)
def run_dispatcher(mode, sheet_handler, row_limit=None):
"""
Wählt den passenden Batch-Prozess basierend auf dem Modus.
Ermittelt die Startzeile dynamisch basierend auf dem Timestamp in der relevanten Spalte.
Die aufgerufenen Prozessfunktionen laden ihre Daten selbst oder verwenden den Handler.
Ermittelt die Startzeile IMMER basierend auf dem Timestamp letzte Prüfung (AO).
Die aufgerufenen Prozessfunktionen verarbeiten den vorgegebenen Bereich.
"""
debug_print(f"Starte Dispatcher im Modus '{mode}' mit row_limit={row_limit}.")
header_rows = 5 # Feste Annahme für Header
header_rows = 5
# --- Startzeilen-Ermittlung basierend auf Modus ---
start_col_key = "Timestamp letzte Prüfung" # Standard (Spalte AO)
# --- Startzeilen-Ermittlung IMMER basierend auf AO ---
start_col_key = "Timestamp letzte Prüfung" # Spalte AO
min_start_row = 7
if mode == "website": start_col_key = "Website Scrape Timestamp" # AT
elif mode == "wiki": start_col_key = "Wikipedia Timestamp" # AN
elif mode == "branch": start_col_key = "Timestamp letzte Prüfung" # AO
elif mode == "combined": start_col_key = "Timestamp letzte Prüfung" # AO (Combined startet, wo der letzte Schritt fehlt)
debug_print(f"Dispatcher: Ermittle Startzeile basierend auf Spalte '{start_col_key}'...")
# get_start_row_index wird aufgerufen, lädt die Daten neu
start_data_index = sheet_handler.get_start_row_index(check_column_key=start_col_key, min_sheet_row=min_start_row)
# Fehlerprüfung für get_start_row_index
if start_data_index == -1:
debug_print(f"FEHLER: Konnte Startzeile nicht ermitteln (Spaltenschlüssel '{start_col_key}' in COLUMN_MAP prüfen?). Dispatcher beendet.")
return
# Umrechnung des 0-basierten Daten-Index in die 1-basierte Sheet-Zeilennummer
start_row_index_in_sheet = start_data_index + header_rows + 1
total_sheet_rows = len(sheet_handler.sheet_values) # Greife auf Daten im Handler zu
# Hole Gesamtzahl der Zeilen (nach potentiellem Neuladen in get_start_row_index)
total_sheet_rows = len(sheet_handler.sheet_values)
# Prüfe, ob der Startpunkt überhaupt im Sheet liegt oder ob das Sheet leer ist
if start_data_index >= len(sheet_handler.get_data()): # Prüfe gegen Daten ohne Header
debug_print(f"Ermittelter Start-Daten-Index ({start_data_index}) liegt nach der letzten Datenzeile ({len(sheet_handler.get_data())-1}). Keine neuen Zeilen zu verarbeiten. Dispatcher beendet.")
if start_data_index >= len(sheet_handler.get_data()):
debug_print(f"Ermittelter Start-Daten-Index ({start_data_index}) liegt nach der letzten Datenzeile. Keine neuen Zeilen zu verarbeiten. Dispatcher beendet.")
return
elif start_row_index_in_sheet > total_sheet_rows:
# Dieser Fall sollte durch die Prüfung oben abgedeckt sein, aber zur Sicherheit
debug_print(f"Sheet hat keine Datenzeilen oder Startzeile ({start_row_index_in_sheet}) ist ungültig. Dispatcher beendet.")
return
# --- Endzeilen-Ermittlung ---
# --- Endzeilen-Ermittlung (wie gehabt) ---
if row_limit is not None and row_limit > 0:
# Berechne Endzeile basierend auf Startzeile und Limit
end_row_index_in_sheet = min(start_row_index_in_sheet + row_limit - 1, total_sheet_rows)
elif row_limit == 0:
debug_print("Zeilenlimit ist 0. Keine Verarbeitung.")
return
else: # Kein Limit oder negatives Limit -> bis zum Ende des Sheets
else:
end_row_index_in_sheet = total_sheet_rows
debug_print(f"Dispatcher: Verarbeitung geplant für Sheet-Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}.")
@@ -2562,22 +2520,27 @@ def run_dispatcher(mode, sheet_handler, row_limit=None):
return
# --- Modusauswahl und Aufruf der Verarbeitungsfunktionen ---
# Die Prozessfunktionen erhalten den Bereich und führen ihre Aufgabe aus,
# setzen aber nur noch ihren *eigenen* Timestamp (falls relevant) oder AO/AP.
# Sie überspringen NICHT mehr basierend auf Timestamps innerhalb ihrer Schleife.
try:
if mode == "wiki":
# Führt Wiki-Verifizierung für den Bereich aus und setzt AN
process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet)
elif mode == "website":
# Führt Website-Scraping für den Bereich aus und setzt AT + AP
process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet)
elif mode == "branch":
# Führt Branch-Einschätzung für den Bereich aus und setzt AO + AP
process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet)
elif mode == "combined":
debug_print("--- Start Combined Mode: Wiki ---")
process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AN
time.sleep(1) # Kurze Pause
process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Setzt AN
# Keine Pause nötig, da Datenaktualität nicht mehr das Hauptproblem war
debug_print("--- Start Combined Mode: Website ---")
process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AT
time.sleep(1) # Kurze Pause
process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Setzt AT + AP
debug_print("--- Start Combined Mode: Branch ---")
process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AO
process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Setzt AO + AP (überschreibt AP)
debug_print("--- Combined Mode abgeschlossen ---")
else:
debug_print(f"Ungültiger Modus '{mode}' wurde im Dispatcher übergeben.")