v1.3.5 FSM & Servicetechniker-Explanation, Sheet-Update-Check Auto Log
Der Dekorator retry_on_failure wurde oben im Code definiert. Wikipedia-Artikelvorschlag aus Spalte K wird bevorzugt genutzt. Nach dem Schreiben der Wiki-Daten wird geprüft, ob das Update abgeschlossen ist, mit einer 3‑Sekunden-Pause. Der FSM-Eignungsparser wurde flexibler angepasst, sodass auch freie Antworten erkannt werden. Bei Abweichungen in der Servicetechniker-Schätzung wird jetzt zusätzlich eine detaillierte Erklärung von ChatGPT angefordert. Die Spalten AF und AG werden mit "XX" befüllt. Alle Debug-Ausgaben werden automatisch in einer Log-Datei im Ordner "Log" gespeichert, deren Name Datum, Uhrzeit und Versionsnummer enthält.
This commit is contained in:
@@ -14,7 +14,7 @@ import csv
|
|||||||
|
|
||||||
# ==================== KONFIGURATION ====================
|
# ==================== KONFIGURATION ====================
|
||||||
class Config:
|
class Config:
|
||||||
VERSION = "v1.3.5" # v1.3.5: FSM-Prüfung mit flexiblem Parser, Servicetechniker-Explanation, Log-Datei, Warten bis Sheet-Update.
|
VERSION = "v1.3.5" # v1.3.5: FSM-Eignungsprüfung & Servicetechniker-Explanation, Sheet-Update-Check, automatische Log-Datei.
|
||||||
LANG = "de"
|
LANG = "de"
|
||||||
CREDENTIALS_FILE = "service_account.json"
|
CREDENTIALS_FILE = "service_account.json"
|
||||||
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
||||||
@@ -26,7 +26,19 @@ class Config:
|
|||||||
WIKIPEDIA_SEARCH_RESULTS = 5
|
WIKIPEDIA_SEARCH_RESULTS = 5
|
||||||
HTML_PARSER = "html.parser"
|
HTML_PARSER = "html.parser"
|
||||||
|
|
||||||
# Log-Datei vorbereiten
|
# ==================== RETRY-DECORATOR ====================
|
||||||
|
def retry_on_failure(func):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
for attempt in range(Config.MAX_RETRIES):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Fehler bei {func.__name__} (Versuch {attempt+1}): {str(e)[:100]}")
|
||||||
|
time.sleep(Config.RETRY_DELAY)
|
||||||
|
return None
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
# ==================== LOGGING & HELPER FUNCTIONS ====================
|
||||||
if not os.path.exists("Log"):
|
if not os.path.exists("Log"):
|
||||||
os.makedirs("Log")
|
os.makedirs("Log")
|
||||||
LOG_FILE = os.path.join("Log", f"{datetime.now().strftime('%d-%m-%Y_%H-%M')}_{Config.VERSION.replace('.', '')}.txt")
|
LOG_FILE = os.path.join("Log", f"{datetime.now().strftime('%d-%m-%Y_%H-%M')}_{Config.VERSION.replace('.', '')}.txt")
|
||||||
@@ -209,7 +221,6 @@ def evaluate_fsm_suitability(company_name, company_data):
|
|||||||
)
|
)
|
||||||
result = response.choices[0].message.content.strip()
|
result = response.choices[0].message.content.strip()
|
||||||
debug_print(f"FSM-Eignungsantwort ChatGPT: '{result}'")
|
debug_print(f"FSM-Eignungsantwort ChatGPT: '{result}'")
|
||||||
# Flexibler Parser: Falls keine Zeilen mit ":" vorhanden sind, nimm den ersten Satz.
|
|
||||||
suitability = "k.A."
|
suitability = "k.A."
|
||||||
justification = ""
|
justification = ""
|
||||||
lines = result.split("\n")
|
lines = result.split("\n")
|
||||||
@@ -618,7 +629,6 @@ class WikipediaScraper:
|
|||||||
}
|
}
|
||||||
@retry_on_failure
|
@retry_on_failure
|
||||||
def search_company_article(self, company_name, website):
|
def search_company_article(self, company_name, website):
|
||||||
# Zuerst prüfen: Gibt es in Spalte K bereits einen Wikipedia-Vorschlag?
|
|
||||||
search_terms = self._generate_search_terms(company_name, website)
|
search_terms = self._generate_search_terms(company_name, website)
|
||||||
for term in search_terms:
|
for term in search_terms:
|
||||||
try:
|
try:
|
||||||
@@ -701,11 +711,10 @@ class DataProcessor:
|
|||||||
company_data.get('categories', 'k.A.')
|
company_data.get('categories', 'k.A.')
|
||||||
]
|
]
|
||||||
self.sheet_handler.sheet.update(values=[wiki_values], range_name=wiki_update_range)
|
self.sheet_handler.sheet.update(values=[wiki_values], range_name=wiki_update_range)
|
||||||
# Warten, bis das Update im Sheet übernommen wurde (prüfe Zelle K{row_num})
|
|
||||||
wait_for_sheet_update(self.sheet_handler.sheet, f"K{row_num}", wiki_values[0])
|
wait_for_sheet_update(self.sheet_handler.sheet, f"K{row_num}", wiki_values[0])
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
# Umsatz-Schätzung (Spalte AF soll "XX" erhalten)
|
# Umsatz-Schätzung: Spalte AF soll "XX" erhalten
|
||||||
self.sheet_handler.sheet.update(values=[["XX"]], range_name=chatgpt_range)
|
self.sheet_handler.sheet.update(values=[["XX"]], range_name=chatgpt_range)
|
||||||
|
|
||||||
# Umsatz-Abgleich (Spalte AG)
|
# Umsatz-Abgleich (Spalte AG)
|
||||||
@@ -743,14 +752,13 @@ class DataProcessor:
|
|||||||
internal_value = row_data[7] if len(row_data) > 7 else "k.A."
|
internal_value = row_data[7] if len(row_data) > 7 else "k.A."
|
||||||
internal_category = map_internal_technicians(internal_value) if internal_value != "k.A." else "k.A."
|
internal_category = map_internal_technicians(internal_value) if internal_value != "k.A." else "k.A."
|
||||||
if internal_category != "k.A." and st_estimate != internal_category:
|
if internal_category != "k.A." and st_estimate != internal_category:
|
||||||
# Hole detaillierte Erklärung von ChatGPT, warum die Schätzung so ist.
|
|
||||||
explanation = evaluate_servicetechnicians_explanation(company_name, st_estimate, company_data)
|
explanation = evaluate_servicetechnicians_explanation(company_name, st_estimate, company_data)
|
||||||
discrepancy = explanation
|
discrepancy = explanation
|
||||||
else:
|
else:
|
||||||
discrepancy = "ok"
|
discrepancy = "ok"
|
||||||
self.sheet_handler.sheet.update(values=[[discrepancy]], range_name=f"AE{row_num}")
|
self.sheet_handler.sheet.update(values=[[discrepancy]], range_name=f"AE{row_num}")
|
||||||
|
|
||||||
# Spalten AF und AG sollen "XX" enthalten
|
# Spalten AF und AG: "XX"
|
||||||
self.sheet_handler.sheet.update(values=[["XX"]], range_name="AF" + str(row_num))
|
self.sheet_handler.sheet.update(values=[["XX"]], range_name="AF" + str(row_num))
|
||||||
self.sheet_handler.sheet.update(values=[["XX"]], range_name="AG" + str(row_num))
|
self.sheet_handler.sheet.update(values=[["XX"]], range_name="AG" + str(row_num))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user