diff --git a/brancheneinstufung.py b/brancheneinstufung.py index cea97e63..ee4536ad 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -2013,16 +2013,18 @@ 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, + Lädt Daten neu, prüft für jede Zeile im Bereich, ob Timestamp AN bereits gesetzt ist, und überspringt diese ggf. Setzt AN für bearbeitete Zeilen. """ 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, um sicherzustellen, dass der Check aktuell ist + # --- NEU: Daten explizit neu laden --- if not sheet_handler.load_data(): debug_print("FEHLER beim Laden der Daten in process_verification_only.") return all_data = sheet_handler.get_all_data_with_headers() + # --- Ende Daten neu laden --- + if not all_data or len(all_data) <= 5: debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_verification_only gefunden.") return @@ -2040,7 +2042,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 # Zähler für übersprungene Zeilen wieder hinzufügen + skipped_count = 0 for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1): row_index_in_list = i - 1 @@ -2050,42 +2052,48 @@ def process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_i row = all_data[row_index_in_list] - # --- WIEDER AKTIVIERT: Timestamp-Prüfung für jede Zeile (AN) --- + # --- Timestamp-Prüfung für jede Zeile (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()) - # Debug Log (kann drin bleiben oder reduziert werden) + # Debug Log (kann reduziert werden) 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()}', Überspringen? -> {ts_an_is_set}") + 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()}', Überspringen? -> {ts_an_is_set}") if ts_an_is_set: skipped_count += 1 - # Optional: Weniger Logging für Übersprungene - # if skipped_count == 1 or skipped_count % 100 == 0: - # debug_print(f"Zeile {i}: Überspringe Wiki-Verifizierung (Timestamp {ts_col_letter} vorhanden).") continue # --- Ende Timestamp-Prüfung --- - # (Restliche Logik zum Erstellen von entry_text wie zuvor) - company_name = row[COLUMN_MAP["CRM Name"]] if len(row) > COLUMN_MAP["CRM Name"] else '' - # ... (andere Daten holen) ... + # (Restliche Logik zum Erstellen von entry_text) + company_name = row[COLUMN_MAP.get("CRM Name", 1)] if len(row) > COLUMN_MAP.get("CRM Name", 1) else '' # Füge Fallback hinzu + crm_desc = row[COLUMN_MAP.get("CRM Beschreibung", 5)] if len(row) > COLUMN_MAP.get("CRM Beschreibung", 5) else '' + wiki_url_idx = COLUMN_MAP.get("Wiki URL") + wiki_url = row[wiki_url_idx] if wiki_url_idx is not None and len(row) > wiki_url_idx and row[wiki_url_idx].strip() not in ['', 'k.A.'] else 'k.A.' + wiki_para_idx = COLUMN_MAP.get("Wiki Absatz") + wiki_paragraph = row[wiki_para_idx] if wiki_para_idx is not None and len(row) > wiki_para_idx else 'k.A.' + wiki_cat_idx = COLUMN_MAP.get("Wiki Kategorien") + wiki_categories = row[wiki_cat_idx] if wiki_cat_idx is not None and len(row) > wiki_cat_idx else 'k.A.' + entry_text = ( f"Eintrag {i}:\n" - f" Firmenname: {company_name}...\n" - # ... (Rest des entry_text) ... + f" Firmenname: {company_name}\n" + f" CRM-Beschreibung: {crm_desc[:200]}...\n" + f" Wikipedia-URL: {wiki_url}\n" + f" Wiki-Absatz: {wiki_paragraph[:200]}...\n" + f" Wiki-Kategorien: {wiki_categories[:200]}...\n" f"----\n" ) current_batch.append(entry_text) current_row_numbers.append(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: - # Rufe _process_batch auf, das S-Y schreibt + # Rufe _process_batch auf (schreibt S-Y) _process_batch(sheet_handler.sheet, current_batch, current_row_numbers) # Setze den AN Timestamp für die bearbeiteten Zeilen @@ -2204,20 +2212,21 @@ def _process_batch(sheet, batches, row_numbers): # time.sleep(Config.RETRY_DELAY) # Entfernt # Komplette Funktion process_website_batch (prüft jetzt Timestamp AT mit erzwungenem Debugging) -# Komplette Funktion process_website_batch (MIT Prüfung auf AT) def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet): """ - Batch-Prozess für Website-Scraping. Prüft für jede Zeile im Bereich, - ob Timestamp AT bereits gesetzt ist und überspringt diese ggf. + Batch-Prozess für Website-Scraping. Lädt Daten neu, prüft für jede Zeile + im Bereich, ob Timestamp AT bereits gesetzt ist und überspringt diese ggf. Setzt AT + AP für bearbeitete Zeilen. """ 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 + # --- NEU: Daten explizit neu laden --- 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() + # --- Ende Daten neu laden --- + if not all_data or len(all_data) <= 5: debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_website_batch gefunden.") return @@ -2227,22 +2236,22 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index # 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") - rohtext_col_index = COLUMN_MAP.get("Website Rohtext") - summary_col_index = COLUMN_MAP.get("Website Zusammenfassung") - version_col_index = COLUMN_MAP.get("Version") + website_col_idx = COLUMN_MAP.get("CRM Website") # Korrigiert zu idx + rohtext_col_idx = COLUMN_MAP.get("Website Rohtext") + summary_col_idx = COLUMN_MAP.get("Website Zusammenfassung") + version_col_idx = COLUMN_MAP.get("Version") - if None in [timestamp_col_index, website_col_index, rohtext_col_index, summary_col_index, version_col_index]: + if None in [timestamp_col_index, website_col_idx, rohtext_col_idx, summary_col_idx, version_col_idx]: debug_print(f"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) + rohtext_col_letter = sheet_handler._get_col_letter(rohtext_col_idx + 1) + summary_col_letter = sheet_handler._get_col_letter(summary_col_idx + 1) + version_col_letter = sheet_handler._get_col_letter(version_col_idx + 1) processed_count = 0 - skipped_count = 0 # Zähler wieder aktiv + skipped_count = 0 skipped_url_count = 0 for i in range(start_row_index_in_sheet, end_row_index_in_sheet + 1): @@ -2259,21 +2268,17 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index if len(row) > timestamp_col_index: ts_value_at = row[timestamp_col_index] ts_at_is_set = bool(str(ts_value_at).strip()) - # Debug Log (kann reduziert werden, wenn es funktioniert) + # Debug Log 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()}', Überspringen? -> {ts_at_is_set}") if ts_at_is_set: skipped_count += 1 - # Optional: Weniger Logging - # if skipped_count == 1 or skipped_count % 100 == 0: - # debug_print(f"Zeile {i}: Überspringe Website-Scraping (Timestamp {ts_col_letter} vorhanden).") 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 "" + website_url = row[website_col_idx] if len(row) > website_col_idx else "" if not website_url or website_url.strip().lower() == "k.a.": skipped_url_count += 1 continue @@ -2305,17 +2310,19 @@ def process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index # Komplette Funktion process_branch_batch (prüft jetzt Timestamp AO mit erzwungenem Debugging) def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet): """ - Batch-Prozess für Brancheneinschätzung. Prüft für jede Zeile im Bereich, - ob Timestamp AO bereits gesetzt ist und überspringt diese ggf. + Batch-Prozess für Brancheneinschätzung. Lädt Daten neu, prüft für jede Zeile + im Bereich, ob Timestamp AO bereits gesetzt ist und überspringt diese ggf. Setzt AO + AP für bearbeitete Zeilen. """ debug_print(f"Starte Brancheneinschätzung (Batch) für Zeilen {start_row_index_in_sheet} bis {end_row_index_in_sheet}...") - # Lade aktuelle Daten + # --- NEU: Daten explizit neu laden --- 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() + # --- Ende Daten neu laden --- + if not all_data or len(all_data) <= 5: debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in process_branch_batch gefunden.") return @@ -2325,7 +2332,7 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_ # Hole Indizes timestamp_col_key = "Timestamp letzte Prüfung" timestamp_col_index = COLUMN_MAP.get(timestamp_col_key) - # ... (andere Indizes wie zuvor) ... + # ... (andere Indizes) ... branche_crm_idx = COLUMN_MAP.get("CRM Branche") beschreibung_idx = COLUMN_MAP.get("CRM Beschreibung") branche_wiki_idx = COLUMN_MAP.get("Wiki Branche") @@ -2336,6 +2343,7 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_ branch_x_idx = COLUMN_MAP.get("Chat Konsistenz Branche") branch_y_idx = COLUMN_MAP.get("Chat Begründung Abweichung Branche") + 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] @@ -2350,9 +2358,8 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_ 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 # Zähler wieder aktiv + skipped_count = 0 if not ALLOWED_TARGET_BRANCHES: load_target_schema() @@ -2374,20 +2381,17 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_ if len(row) > timestamp_col_index: ts_value_ao = row[timestamp_col_index] ts_ao_is_set = bool(str(ts_value_ao).strip()) - # Debug Log (kann reduziert werden) + # Debug Log 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()}', Überspringen? -> {ts_ao_is_set}") if ts_ao_is_set: skipped_count += 1 - # Optional: Weniger Logging - # if skipped_count == 1 or skipped_count % 100 == 0: - # debug_print(f"Zeile {i}: Überspringe Branchen-Einschätzung (Timestamp {ts_col_letter} vorhanden).") continue # --- Ende Timestamp-Prüfung --- - # (Restliche Logik zum Datenholen, Bewerten und Updaten wie zuvor) + # (Restliche Logik zum Datenholen, Bewerten und Updaten) crm_branche = row[branche_crm_idx] if len(row) > branche_crm_idx else "" # ... (andere Daten holen) ... website_summary = row[summary_web_idx] if len(row) > summary_web_idx else "" @@ -2525,19 +2529,32 @@ def process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_ # - Globale Konstante header_rows (oder besser, hol sie vom sheet_handler?) # Komplette run_dispatcher Funktion (Start immer basierend auf AO) +# Komplette run_dispatcher Funktion (Korrigierte start_col_key Auswahl) def run_dispatcher(mode, sheet_handler, row_limit=None): """ Wählt den passenden Batch-Prozess basierend auf dem Modus. - Ermittelt die Startzeile IMMER basierend auf dem Timestamp letzte Prüfung (AO). - Die aufgerufenen Prozessfunktionen verarbeiten den vorgegebenen Bereich. + Ermittelt die Startzeile dynamisch basierend auf dem Timestamp in der relevanten Spalte. + Die aufgerufenen Prozessfunktionen laden ihre Daten selbst. """ debug_print(f"Starte Dispatcher im Modus '{mode}' mit row_limit={row_limit}.") header_rows = 5 - # --- Startzeilen-Ermittlung IMMER basierend auf AO --- - start_col_key = "Timestamp letzte Prüfung" # Spalte AO + # --- Startzeilen-Ermittlung basierend auf Modus --- + # Definiere, welche Spalte für welchen Modus den Startpunkt bestimmt + start_col_key = "Timestamp letzte Prüfung" # Standard (Spalte AO) min_start_row = 7 + # --- KORRIGIERT: Korrekte Schlüsselzuweisung für jeden Modus --- + if mode == "website": + start_col_key = "Website Scrape Timestamp" # Spalte AT + elif mode == "wiki": + start_col_key = "Wikipedia Timestamp" # Spalte AN + elif mode == "branch": + start_col_key = "Timestamp letzte Prüfung" # Spalte AO + elif mode == "combined": + start_col_key = "Timestamp letzte Prüfung" # Spalte AO (Combined startet, wo der letzte Schritt fehlt) + # --- Ende Korrektur --- + debug_print(f"Dispatcher: Ermittle Startzeile basierend auf Spalte '{start_col_key}'...") start_data_index = sheet_handler.get_start_row_index(check_column_key=start_col_key, min_sheet_row=min_start_row) @@ -2546,7 +2563,9 @@ def run_dispatcher(mode, sheet_handler, row_limit=None): return 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 (wird im Handler aktualisiert) + total_sheet_rows = len(sheet_handler.sheet_values) 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.") @@ -2555,7 +2574,7 @@ def run_dispatcher(mode, sheet_handler, row_limit=None): debug_print(f"Sheet hat keine Datenzeilen oder Startzeile ({start_row_index_in_sheet}) ist ungültig. Dispatcher beendet.") return - # --- Endzeilen-Ermittlung (wie gehabt) --- + # --- Endzeilen-Ermittlung --- if row_limit is not None and row_limit > 0: end_row_index_in_sheet = min(start_row_index_in_sheet + row_limit - 1, total_sheet_rows) elif row_limit == 0: @@ -2570,28 +2589,24 @@ def run_dispatcher(mode, sheet_handler, row_limit=None): debug_print("Berechnete Startzeile liegt nach der Endzeile. Keine Verarbeitung.") 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. + # --- Modusauswahl und Aufruf --- 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) # Setzt AN - # Keine Pause nötig, da Datenaktualität nicht mehr das Hauptproblem war + process_verification_only(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AN, setzt AN + # Kurze Pause einfügen, um Google Sheets Zeit für die Aktualisierung zu geben (optional aber sicherer) + time.sleep(3) debug_print("--- Start Combined Mode: Website ---") - process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Setzt AT + AP + process_website_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AT, setzt AT+AP + time.sleep(3) # Kurze Pause debug_print("--- Start Combined Mode: Branch ---") - process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Setzt AO + AP (überschreibt AP) + process_branch_batch(sheet_handler, start_row_index_in_sheet, end_row_index_in_sheet) # Lädt Daten, prüft AO, setzt AO+AP debug_print("--- Combined Mode abgeschlossen ---") else: debug_print(f"Ungültiger Modus '{mode}' wurde im Dispatcher übergeben.")