diff --git a/brancheneinstufung.py b/brancheneinstufung.py index 1667f4fb..f73e24fb 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -577,38 +577,67 @@ def normalize_company_name(name): # NEUE Funktion für Wiki-Updates basierend auf ChatGPT Vorschlägen (mit Status-Update in S) def process_wiki_updates_from_chatgpt(sheet_handler, data_processor): """ - Identifiziert Zeilen, bei denen Wiki-Konsistenz (S) NICHT 'OK' ist und ein - alternativer Artikel in T vorgeschlagen wurde (URL, != M). + Identifiziert Zeilen, bei denen Wiki-Konsistenz (S) NICHT 'OK'/'X (Updated)' ist + und ein alternativer Artikel in T vorgeschlagen wurde (URL, != M). Kopiert neue URL nach M, führt Reparse (N-R) & Re-Branch (W-Y) durch, löscht Timestamps (AN, AX, AO, AP) und markiert S als 'X (Updated)'. """ debug_print("Starte Modus: Wiki-Updates basierend auf ChatGPT-Vorschlägen...") - if not sheet_handler.load_data(): return + if not sheet_handler.load_data(): + debug_print("FEHLER: Konnte Sheet-Daten nicht laden für Wiki-Updates.") + return all_data = sheet_handler.get_all_data_with_headers() - if not all_data or len(all_data) <= 5: return + if not all_data or len(all_data) <= 5: + debug_print("FEHLER/WARNUNG: Keine Daten zum Verarbeiten in Wiki-Updates gefunden.") + return header_rows = 5 data_rows = all_data[header_rows:] - # Indizes holen (wie zuvor) - required_keys = ["Chat Wiki Konsistenzprüfung", "Chat Vorschlag Wiki Artikel", "Wiki URL", "Wiki Absatz", "Wiki Branche", "Wiki Umsatz", "Wiki Mitarbeiter", "Wiki Kategorien", "Chat Vorschlag Branche", "Chat Konsistenz Branche", "Chat Begründung Abweichung Branche", "Wikipedia Timestamp", "Wiki Verif. Timestamp", "Timestamp letzte Prüfung", "Version", "Website Zusammenfassung", "CRM Branche", "CRM Beschreibung"] - col_indices = {}; all_keys_found = True + # --- Indizes holen --- + required_keys = [ + "Chat Wiki Konsistenzprüfung", "Chat Vorschlag Wiki Artikel", "Wiki URL", + "Wiki Absatz", "Wiki Branche", "Wiki Umsatz", "Wiki Mitarbeiter", "Wiki Kategorien", + "Chat Vorschlag Branche", "Chat Konsistenz Branche", "Chat Begründung Abweichung Branche", + "Wikipedia Timestamp", "Wiki Verif. Timestamp", "Timestamp letzte Prüfung", "Version", + "Website Zusammenfassung", "CRM Branche", "CRM Beschreibung" + ] + col_indices = {} + all_keys_found = True + # Überprüfe jeden Schlüssel und logge genau, welcher fehlt for key in required_keys: idx = COLUMN_MAP.get(key) - if idx is None: debug_print(f"FEHLER: Schlüssel '{key}' fehlt!"); all_keys_found = False - col_indices[key] = idx - if not all_keys_found: return debug_print("Breche Wiki-Updates ab.") + if idx is None: + debug_print(f"FEHLER: Schlüssel '{key}' für Spaltenindex fehlt in COLUMN_MAP!") + all_keys_found = False + col_indices[key] = idx # Speichere auch None, um Fehler unten zu vermeiden - all_sheet_updates = []; processed_rows = 0 - wiki_scraper = data_processor.wiki_scraper + if not all_keys_found: + debug_print("Breche Wiki-Updates ab, da Spaltenindizes fehlen.") + return + # --- Variablen für Verarbeitung --- + all_sheet_updates = [] + processed_rows_count = 0 + skipped_rows_count = 0 + error_rows_count = 0 + wiki_scraper = data_processor.wiki_scraper # Nutze Instanz + + # --- Hauptschleife über Datenzeilen --- for idx, row in enumerate(data_rows): - row_num_in_sheet = idx + header_rows + 1 + row_num_in_sheet = idx + header_rows + 1 # 1-basierte Zeilennummer - # Werte sicher lesen - konsistenz_s = row[col_indices["Chat Wiki Konsistenzprüfung"]] if len(row) > col_indices["Chat Wiki Konsistenzprüfung"] else "" - vorschlag_t = row[col_indices["Chat Vorschlag Wiki Artikel"]] if len(row) > col_indices["Chat Vorschlag Wiki Artikel"] else "" - url_m = row[col_indices["Wiki URL"]] if len(row) > col_indices["Wiki URL"] else "" + # --- Werte sicher lesen --- + # Funktion zum sicheren Holen von Werten aus der Zeile + def get_value(key): + index = col_indices.get(key) + if index is not None and len(row) > index: + return row[index] + return "" # Leerer String als Standard + + konsistenz_s = get_value("Chat Wiki Konsistenzprüfung") + vorschlag_t = get_value("Chat Vorschlag Wiki Artikel") + url_m = get_value("Wiki URL") # --- Bedingung prüfen --- is_update_candidate = False @@ -616,84 +645,96 @@ def process_wiki_updates_from_chatgpt(sheet_handler, data_processor): konsistenz_s_upper = konsistenz_s.strip().upper() vorschlag_t_cleaned = vorschlag_t.strip() url_m_cleaned = url_m.strip() - t_is_url = vorschlag_t_cleaned.lower().startswith(("http://", "https://")) - t_differs_from_m = new_url != url_m_cleaned # new_url wird erst gesetzt, wenn t_is_url True ist - # --- NEUES DETAILLIERTES DEBUGGING (speziell für Zeile 28) --- - if row_num_in_sheet == 28: - debug_print(f"\n--- DEBUG Zeile 28 ---") - debug_print(f" Wert S (Roh): '{konsistenz_s}'") - debug_print(f" Wert S (Strip, Upper): '{konsistenz_s_upper}'") - debug_print(f" Bedingung (S != OK and S != ''): {konsistenz_s_upper != 'OK' and konsistenz_s_upper != ''}") - debug_print(f" Wert T (Roh): '{vorschlag_t}'") - debug_print(f" Wert T (Cleaned): '{vorschlag_t_cleaned}'") - debug_print(f" Bedingung (T ist URL): {t_is_url}") - debug_print(f" Wert M (Roh): '{url_m}'") - debug_print(f" Wert M (Cleaned): '{url_m_cleaned}'") - # Setze new_url hier nur für den Vergleichslog, wenn T eine URL ist - temp_new_url_for_log = vorschlag_t_cleaned if t_is_url else None - debug_print(f" Bedingung (T != M): {temp_new_url_for_log != url_m_cleaned if temp_new_url_for_log else 'N/A (T keine URL)'}") - debug_print(f"--- ENDE DEBUG Zeile 28 ---\n") - # --- ENDE DEBUGGING --- + # Bedingung 1: Status in S ist nicht OK und nicht bereits als "Updated" markiert + condition1_status_nok = konsistenz_s_upper not in ["OK", "X (UPDATED)", ""] - # Die eigentliche Bedingungsprüfung (Option B: Prüfe auf NICHT OK) - if konsistenz_s_upper != "OK" and konsistenz_s_upper != "": - if t_is_url: # Ist T eine URL? - new_url = vorschlag_t_cleaned # Setze new_url jetzt - if new_url != url_m_cleaned: # Ist T anders als M? - is_update_candidate = True + # Bedingung 2: Vorschlag T ist eine valide URL + condition2_t_is_url = vorschlag_t_cleaned.lower().startswith(("http://", "https://")) + # Bedingung 3: Vorgeschlagene URL T unterscheidet sich von aktueller URL M + condition3_t_differs_m = False + if condition2_t_is_url: # Prüfe nur, wenn T eine URL ist + new_url = vorschlag_t_cleaned # Setze new_url hier + if new_url != url_m_cleaned: + condition3_t_differs_m = True + + # Finale Entscheidung + is_update_candidate = condition1_status_nok and condition2_t_is_url and condition3_t_differs_m + + # Detailliertes Debugging für relevante Zeilen + if row_num_in_sheet in [28, 40, 42, 388, 416, 478, 523, 527, 545, 571, 630] or idx < 5: + debug_print(f"\n--- DEBUG Zeile {row_num_in_sheet} ---") + debug_print(f" S='{konsistenz_s}' -> Status NOK? {condition1_status_nok} (Wert: '{konsistenz_s_upper}')") + debug_print(f" T='{vorschlag_t}' -> Ist URL? {condition2_t_is_url} (Wert: '{vorschlag_t_cleaned}')") + debug_print(f" M='{url_m}' -> (Wert Cleaned: '{url_m_cleaned}')") + debug_print(f" Bedingung (T != M)?: {condition3_t_differs_m}") + debug_print(f" => Update-Kandidat? {is_update_candidate}") + debug_print(f"--- ENDE DEBUG Zeile {row_num_in_sheet} ---\n") + + # --- Verarbeitung des Kandidaten --- if is_update_candidate: - # ... (Restliche Verarbeitung der Zeile wie zuvor: Reparse, Re-Branch, Updates sammeln) ... - debug_print(f"Zeile {row_num_in_sheet}: Update-Kandidat gefunden. Status S='{konsistenz_s}', Neue URL: {new_url}") + debug_print(f"Zeile {row_num_in_sheet}: Verarbeite Update-Kandidat. Neue URL: {new_url}") try: - processed_rows += 1 + # --- Wiki Reparse --- debug_print(f" -> Reparsing Wiki-Daten für {new_url}...") - new_wiki_data = wiki_scraper.extract_company_data(new_url); time.sleep(0.5) - crm_branche = row[col_indices["CRM Branche"]] if len(row) > col_indices["CRM Branche"] else "" - crm_beschreibung = row[col_indices["CRM Beschreibung"]] if len(row) > col_indices["CRM Beschreibung"] else "" - website_summary = row[col_indices["Website Zusammenfassung"]] if len(row) > col_indices["Website Zusammenfassung"] else "" - debug_print(f" -> Neuberechnung der Branche...") - new_branch_result = evaluate_branche_chatgpt(crm_branche, crm_beschreibung, new_wiki_data.get('branche', 'k.A.'), new_wiki_data.get('categories', 'k.A.'), website_summary) + new_wiki_data = wiki_scraper.extract_company_data(new_url) + time.sleep(0.2) # Kleinere Pause nach Scrape - # Spaltenbuchstaben ermitteln... - url_m_letter=sheet_handler._get_col_letter(col_indices["Wiki URL"]+1); absatz_n_letter=sheet_handler._get_col_letter(col_indices["Wiki Absatz"]+1); branche_o_letter=sheet_handler._get_col_letter(col_indices["Wiki Branche"]+1); umsatz_p_letter=sheet_handler._get_col_letter(col_indices["Wiki Umsatz"]+1); ma_q_letter=sheet_handler._get_col_letter(col_indices["Wiki Mitarbeiter"]+1); kat_r_letter=sheet_handler._get_col_letter(col_indices["Wiki Kategorien"]+1); branch_w_letter=sheet_handler._get_col_letter(col_indices["Chat Vorschlag Branche"]+1); branch_x_letter=sheet_handler._get_col_letter(col_indices["Chat Konsistenz Branche"]+1); branch_y_letter=sheet_handler._get_col_letter(col_indices["Chat Begründung Abweichung Branche"]+1); ts_an_letter=sheet_handler._get_col_letter(col_indices["Wikipedia Timestamp"]+1); ts_ax_letter=sheet_handler._get_col_letter(col_indices["Wiki Verif. Timestamp"]+1); ts_ao_letter=sheet_handler._get_col_letter(col_indices["Timestamp letzte Prüfung"]+1); version_ap_letter=sheet_handler._get_col_letter(col_indices["Version"]+1); vorschlag_t_letter=sheet_handler._get_col_letter(col_indices["Chat Vorschlag Wiki Artikel"]+1); konsistenz_s_letter=sheet_handler._get_col_letter(col_indices["Chat Wiki Konsistenzprüfung"]+1) + # --- Branch Neuberechnung --- + crm_branche = get_value("CRM Branche") + crm_beschreibung = get_value("CRM Beschreibung") + website_summary = get_value("Website Zusammenfassung") + debug_print(f" -> Neuberechnung der Branche...") + new_branch_result = evaluate_branche_chatgpt( + crm_branche, crm_beschreibung, + new_wiki_data.get('branche', 'k.A.'), + new_wiki_data.get('categories', 'k.A.'), + website_summary + ) + time.sleep(0.2) # Kleine Pause nach ChatGPT + + # --- Updates sammeln --- + # Spaltenbuchstaben (vereinfacht für Lesbarkeit) + m_l=sheet_handler._get_col_letter(col_indices["Wiki URL"]+1); n_l=sheet_handler._get_col_letter(col_indices["Wiki Absatz"]+1); o_l=sheet_handler._get_col_letter(col_indices["Wiki Branche"]+1); p_l=sheet_handler._get_col_letter(col_indices["Wiki Umsatz"]+1); q_l=sheet_handler._get_col_letter(col_indices["Wiki Mitarbeiter"]+1); r_l=sheet_handler._get_col_letter(col_indices["Wiki Kategorien"]+1); w_l=sheet_handler._get_col_letter(col_indices["Chat Vorschlag Branche"]+1); x_l=sheet_handler._get_col_letter(col_indices["Chat Konsistenz Branche"]+1); y_l=sheet_handler._get_col_letter(col_indices["Chat Begründung Abweichung Branche"]+1); an_l=sheet_handler._get_col_letter(col_indices["Wikipedia Timestamp"]+1); ax_l=sheet_handler._get_col_letter(col_indices["Wiki Verif. Timestamp"]+1); ao_l=sheet_handler._get_col_letter(col_indices["Timestamp letzte Prüfung"]+1); ap_l=sheet_handler._get_col_letter(col_indices["Version"]+1); t_l=sheet_handler._get_col_letter(col_indices["Chat Vorschlag Wiki Artikel"]+1); s_l=sheet_handler._get_col_letter(col_indices["Chat Wiki Konsistenzprüfung"]+1) row_updates = [ - {'range':f'{url_m_letter}{row_num_in_sheet}','values':[[new_url]]}, - {'range':f'{absatz_n_letter}{row_num_in_sheet}','values':[[new_wiki_data.get('first_paragraph','k.A.')]]}, - {'range':f'{branche_o_letter}{row_num_in_sheet}','values':[[new_wiki_data.get('branche','k.A.')]]}, - {'range':f'{umsatz_p_letter}{row_num_in_sheet}','values':[[new_wiki_data.get('umsatz','k.A.')]]}, - {'range':f'{ma_q_letter}{row_num_in_sheet}','values':[[new_wiki_data.get('mitarbeiter','k.A.')]]}, - {'range':f'{kat_r_letter}{row_num_in_sheet}','values':[[new_wiki_data.get('categories','k.A.')]]}, - {'range':f'{branch_w_letter}{row_num_in_sheet}','values':[[new_branch_result.get("branch","Fehler")]]}, - {'range':f'{branch_x_letter}{row_num_in_sheet}','values':[[new_branch_result.get("consistency","Fehler")]]}, - {'range':f'{branch_y_letter}{row_num_in_sheet}','values':[[new_branch_result.get("justification","Fehler")]]}, - {'range':f'{ts_an_letter}{row_num_in_sheet}','values':[[""]]}, - {'range':f'{ts_ax_letter}{row_num_in_sheet}','values':[[""]]}, - {'range':f'{ts_ao_letter}{row_num_in_sheet}','values':[[""]]}, - {'range':f'{version_ap_letter}{row_num_in_sheet}','values':[[""]]}, - {'range':f'{vorschlag_t_letter}{row_num_in_sheet}','values':[["Korrektur übernommen"]]}, - {'range':f'{konsistenz_s_letter}{row_num_in_sheet}','values':[["X (Updated)"]]}, + {'range': f'{m_l}{row_num_in_sheet}', 'values': [[new_url]]}, + {'range': f'{n_l}{row_num_in_sheet}', 'values': [[new_wiki_data.get('first_paragraph', 'k.A.')]]}, + {'range': f'{o_l}{row_num_in_sheet}', 'values': [[new_wiki_data.get('branche', 'k.A.')]]}, + {'range': f'{p_l}{row_num_in_sheet}', 'values': [[new_wiki_data.get('umsatz', 'k.A.')]]}, + {'range': f'{q_l}{row_num_in_sheet}', 'values': [[new_wiki_data.get('mitarbeiter', 'k.A.')]]}, + {'range': f'{r_l}{row_num_in_sheet}', 'values': [[new_wiki_data.get('categories', 'k.A.')]]}, + {'range': f'{w_l}{row_num_in_sheet}', 'values': [[new_branch_result.get("branch", "Fehler")]]}, + {'range': f'{x_l}{row_num_in_sheet}', 'values': [[new_branch_result.get("consistency", "Fehler")]]}, + {'range': f'{y_l}{row_num_in_sheet}', 'values': [[new_branch_result.get("justification", "Fehler")]]}, + {'range': f'{an_l}{row_num_in_sheet}', 'values': [[""]]}, # Timestamps leeren + {'range': f'{ax_l}{row_num_in_sheet}', 'values': [[""]]}, + {'range': f'{ao_l}{row_num_in_sheet}', 'values': [[""]]}, + {'range': f'{ap_l}{row_num_in_sheet}', 'values': [[""]]}, # Version leeren + {'range': f'{t_l}{row_num_in_sheet}', 'values': [["Korrektur übernommen"]]}, + {'range': f'{s_l}{row_num_in_sheet}', 'values': [["X (Updated)"]]}, # Status aktualisieren ] all_sheet_updates.extend(row_updates) + processed_rows_count += 1 # Erfolgreich verarbeitet debug_print(f" -> Updates für Zeile {row_num_in_sheet} vorbereitet.") - time.sleep(Config.RETRY_DELAY) # Pause beibehalten except Exception as e_row: - debug_print(f"FEHLER Verarbeitung Zeile {row_num_in_sheet}: {e_row}") - import traceback; debug_print(traceback.format_exc()) + error_rows_count += 1 + debug_print(f"FEHLER bei Verarbeitung von Update-Kandidat Zeile {row_num_in_sheet}: {e_row}") + # Optional Traceback loggen: + # import traceback; debug_print(traceback.format_exc()) - # --- Batch Update --- + # --- Batch Update am Ende --- if all_sheet_updates: - debug_print(f"Sende Batch-Update für {processed_rows} korrigierte Wiki-Einträge ({len(all_sheet_updates)} Zellen)...") + debug_print(f"Sende Batch-Update für {processed_rows_count} korrigierte Wiki-Einträge ({len(all_sheet_updates)} Zellen)...") success = sheet_handler.batch_update_cells(all_sheet_updates) - if success: debug_print(f"Sheet-Update Wiki-Korrekturen erfolgreich.") - else: debug_print(f"FEHLER Sheet-Update Wiki-Korrekturen.") + if success: debug_print(f"Sheet-Update für Wiki-Korrekturen erfolgreich.") + else: debug_print(f"FEHLER beim Sheet-Update für Wiki-Korrekturen.") else: - debug_print("Keine Zeilen für Wiki-URL-Korrektur gefunden/verarbeitet.") + debug_print("Keine Zeilen gefunden, die eine Wiki-URL-Korrektur benötigen/erfüllen.") - debug_print(f"Wiki-Updates basierend auf ChatGPT abgeschlossen. {processed_rows} Zeilen aktualisiert.") + debug_print(f"Wiki-Updates basierend auf ChatGPT abgeschlossen. {processed_rows_count} Zeilen aktualisiert, {error_rows_count} Fehler bei Verarbeitung.") def extract_numeric_value(raw_value, is_umsatz=False): """Extrahiert und normalisiert Zahlenwerte (Umsatz in Mio, Mitarbeiter)."""