diff --git a/brancheneinstufung.py b/brancheneinstufung.py index d4b41f11..3e64cf2a 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -574,11 +574,13 @@ def normalize_company_name(name): return normalized.lower() # NEUE Funktion für Wiki-Updates basierend auf ChatGPT Vorschlägen +# 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 ChatGPT einen alternativen Wiki-Artikel vorgeschlagen hat (S='X', T=URL), kopiert die neue URL nach M, führt ein Reparse der Wiki-Daten (N-R) durch, - berechnet die Branche neu (W-Y) und löscht relevante Timestamps (AN, AX, AO, AP). + berechnet die Branche neu (W-Y), löscht relevante Timestamps (AN, AX, AO, AP) + und markiert die Zeile in Spalte S als "X (Updated)". """ debug_print("Starte Modus: Wiki-Updates basierend auf ChatGPT-Vorschlägen...") @@ -586,138 +588,132 @@ def process_wiki_updates_from_chatgpt(sheet_handler, data_processor): all_data = sheet_handler.get_all_data_with_headers() if not all_data or len(all_data) <= 5: return header_rows = 5 - data_rows = all_data[header_rows:] # Arbeite mit Daten ohne Header + data_rows = all_data[header_rows:] - # Indizes holen (Beispielhaft, passe Schlüssel an deine COLUMN_MAP an) - wiki_konsistenz_idx = COLUMN_MAP.get("Chat Wiki Konsistenzprüfung") # S - vorschlag_t_idx = COLUMN_MAP.get("Chat Vorschlag Wiki Artikel") # T - wiki_url_m_idx = COLUMN_MAP.get("Wiki URL") # M - # Indizes für Wiki-Daten N-R - absatz_n_idx = COLUMN_MAP.get("Wiki Absatz") - branche_o_idx = COLUMN_MAP.get("Wiki Branche") - umsatz_p_idx = COLUMN_MAP.get("Wiki Umsatz") - ma_q_idx = COLUMN_MAP.get("Wiki Mitarbeiter") - kat_r_idx = COLUMN_MAP.get("Wiki Kategorien") - # Indizes für Branch W-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") - # Indizes für Timestamps und Version - ts_an_idx = COLUMN_MAP.get("Wikipedia Timestamp") - ts_ax_idx = COLUMN_MAP.get("Wiki Verif. Timestamp") - ts_ao_idx = COLUMN_MAP.get("Timestamp letzte Prüfung") - version_ap_idx = COLUMN_MAP.get("Version") - # Index für Website Summary AS (wird für Branch-Neuberechnung gebraucht) - summary_as_idx = COLUMN_MAP.get("Website Zusammenfassung") - # Index für CRM Branche/Beschreibung (für Branch-Neuberechnung) - crm_branch_idx = COLUMN_MAP.get("CRM Branche") - crm_desc_idx = COLUMN_MAP.get("CRM Beschreibung") - - - # Prüfe, ob alle Indizes gefunden wurden - required_indices = [ - wiki_konsistenz_idx, vorschlag_t_idx, wiki_url_m_idx, absatz_n_idx, branche_o_idx, - umsatz_p_idx, ma_q_idx, kat_r_idx, branch_w_idx, branch_x_idx, branch_y_idx, - ts_an_idx, ts_ax_idx, ts_ao_idx, version_ap_idx, summary_as_idx, - crm_branch_idx, crm_desc_idx + # --- Indizes holen --- + # Stelle sicher, dass ALLE benötigten Schlüssel in COLUMN_MAP existieren + 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" ] - if None in required_indices: - missing = [k for k, v in COLUMN_MAP.items() if v in required_indices and v is None] # Finde fehlende Keys - debug_print(f"FEHLER: Mindestens ein benötigter Spaltenindex für Wiki-Updates fehlt in COLUMN_MAP. Fehlende Keys (Beispiel): {missing}") + col_indices = {} + all_keys_found = True + for key in required_keys: + idx = COLUMN_MAP.get(key) + if idx is None: + debug_print(f"FEHLER: Schlüssel '{key}' fehlt in COLUMN_MAP!") + all_keys_found = False + col_indices[key] = idx + + if not all_keys_found: + debug_print("Breche Wiki-Updates ab, da Spaltenindizes fehlen.") return all_sheet_updates = [] processed_rows = 0 - wiki_scraper = data_processor.wiki_scraper # Nutze den Scraper aus dem DataProcessor + wiki_scraper = data_processor.wiki_scraper # Gehe durch alle *Daten*-Zeilen for idx, row in enumerate(data_rows): - row_num_in_sheet = idx + header_rows + 1 # 1-basierte Zeilennummer + row_num_in_sheet = idx + header_rows + 1 # Lese Werte sicher aus - konsistenz_s = row[wiki_konsistenz_idx] if len(row) > wiki_konsistenz_idx else "" - vorschlag_t = row[vorschlag_t_idx] if len(row) > vorschlag_t_idx else "" - url_m = row[wiki_url_m_idx] if len(row) > wiki_url_m_idx else "" + 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 "" # Bedingung prüfen: S='X' und T ist eine URL und T != M is_update_candidate = False new_url = "" if konsistenz_s.strip().upper() == "X": - # Prüfe, ob T eine valide URL ist (einfache Prüfung) - if vorschlag_t.strip().lower().startswith(("http://", "https://")): - new_url = vorschlag_t.strip() - # Prüfe, ob die neue URL anders ist als die alte + vorschlag_t_cleaned = vorschlag_t.strip() + if vorschlag_t_cleaned.lower().startswith(("http://", "https://")): + new_url = vorschlag_t_cleaned if new_url != url_m.strip(): is_update_candidate = True + # Optional: Prüfen ob T vielleicht "Kein passender Artikel" etc. enthält und nicht updaten? + # elif "kein" in vorschlag_t_cleaned.lower() and "artikel" in vorschlag_t_cleaned.lower(): + # pass # Explizit nicht als Kandidat werten if is_update_candidate: debug_print(f"Zeile {row_num_in_sheet}: Update-Kandidat gefunden. Neue URL: {new_url}") - processed_rows += 1 - # --- Schritt 3a: Wiki Reparse --- - debug_print(f" -> Reparsing Wiki-Daten für {new_url}...") - new_wiki_data = wiki_scraper.extract_company_data(new_url) + try: # Füge Try-Block um die Verarbeitung einer Zeile hinzu + processed_rows += 1 - # --- Schritt 3b: Branch Neuberechnung --- - # Hole benötigte Daten für Branch-Eval - crm_branche = row[crm_branch_idx] if len(row) > crm_branch_idx else "" - crm_beschreibung = row[crm_desc_idx] if len(row) > crm_desc_idx else "" - website_summary = row[summary_as_idx] if len(row) > summary_as_idx else "" - debug_print(f" -> Neuberechnung der Branche...") - new_branch_result = evaluate_branche_chatgpt( - crm_branche, - crm_beschreibung, - new_wiki_data.get('branche', 'k.A.'), # Neue Wiki-Branche - new_wiki_data.get('categories', 'k.A.'), # Neue Wiki-Kategorien - website_summary # Vorhandene Website-Zusammenfassung - ) + # --- Schritt 3a: Wiki Reparse --- + debug_print(f" -> Reparsing Wiki-Daten für {new_url}...") + new_wiki_data = wiki_scraper.extract_company_data(new_url) + # Kleine Pause nach Wiki-Scrape + time.sleep(0.5) - # --- Schritt 4: Updates sammeln --- - # Spaltenbuchstaben ermitteln - url_m_letter = sheet_handler._get_col_letter(wiki_url_m_idx + 1) - absatz_n_letter = sheet_handler._get_col_letter(absatz_n_idx + 1) - branche_o_letter = sheet_handler._get_col_letter(branche_o_idx + 1) - umsatz_p_letter = sheet_handler._get_col_letter(umsatz_p_idx + 1) - ma_q_letter = sheet_handler._get_col_letter(ma_q_idx + 1) - kat_r_letter = sheet_handler._get_col_letter(kat_r_idx + 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) - ts_an_letter = sheet_handler._get_col_letter(ts_an_idx + 1) - ts_ax_letter = sheet_handler._get_col_letter(ts_ax_idx + 1) - ts_ao_letter = sheet_handler._get_col_letter(ts_ao_idx + 1) - version_ap_letter = sheet_handler._get_col_letter(version_ap_idx + 1) - # Optional: Spalte T leeren/markieren - vorschlag_t_letter = sheet_handler._get_col_letter(vorschlag_t_idx + 1) + # --- Schritt 3b: Branch Neuberechnung --- + 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 + ) + # --- Schritt 4: Updates sammeln --- + # 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) # NEU - row_updates = [ - # Wiki-Daten aktualisieren - {'range': f'{url_m_letter}{row_num_in_sheet}', 'values': [[new_url]]}, # Neue URL nach M - {'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.')]]}, - # Branch-Daten aktualisieren - {'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")]]}, - # Timestamps und Version leeren, um erneute Prüfung zu triggern - {'range': f'{ts_an_letter}{row_num_in_sheet}', 'values': [[""]]}, # Wiki Extraktion TS - {'range': f'{ts_ax_letter}{row_num_in_sheet}', 'values': [[""]]}, # Wiki Verif. TS - {'range': f'{ts_ao_letter}{row_num_in_sheet}', 'values': [[""]]}, # Letzte Prüfung TS - {'range': f'{version_ap_letter}{row_num_in_sheet}', 'values': [[""]]}, # Version - # Optional: Spalte T leeren oder markieren - {'range': f'{vorschlag_t_letter}{row_num_in_sheet}', 'values': [["Korrektur übernommen"]]}, - ] - all_sheet_updates.extend(row_updates) + 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"]]}, + # --- NEU: Spalte S aktualisieren --- + {'range': f'{konsistenz_s_letter}{row_num_in_sheet}', 'values': [["X (Updated)"]]}, + ] + all_sheet_updates.extend(row_updates) + debug_print(f" -> Updates für Zeile {row_num_in_sheet} vorbereitet.") + + # Kurze Pause nach jeder Zeile, um APIs nicht zu überlasten + time.sleep(Config.RETRY_DELAY) # Behalte Pause bei, da ChatGPT hier läuft + + except Exception as e_row: + # Fehler bei der Verarbeitung einer einzelnen Zeile loggen, aber weitermachen + debug_print(f"FEHLER bei Verarbeitung von Update-Kandidat Zeile {row_num_in_sheet}: {e_row}") + import traceback + debug_print(traceback.format_exc()) - # Kurze Pause nach jeder Zeile, um APIs nicht zu überlasten - time.sleep(Config.RETRY_DELAY) # Pause nach Wiki Reparse + Branch Neuberechnung # --- Schritt 5: Batch Update --- if all_sheet_updates: + # Sende alle Updates auf einmal am Ende debug_print(f"Sende Batch-Update für {processed_rows} korrigierte Wiki-Einträge ({len(all_sheet_updates)} Zellen)...") success = sheet_handler.batch_update_cells(all_sheet_updates) if success: