commit 1166a140be602b676ef20f0e1674d2616073df58 Author: vaporvee Date: Tue Jun 17 22:29:43 2025 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..843ec65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +.venv +auswertung.csv +*.pdf diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e8ddd7 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# pdf-gpt diff --git a/main.py b/main.py new file mode 100644 index 0000000..bee4f9d --- /dev/null +++ b/main.py @@ -0,0 +1,90 @@ +import os +import time +import csv +import base64 +from io import BytesIO +from dotenv import load_dotenv +from pdf2image import convert_from_path +from PIL import Image +from openai import OpenAI + +load_dotenv() +client = OpenAI(api_key=os.getenv("OPEN_AI_KEY")) + + +def convert_pdf_to_images(pdf_path, dpi=144): + print(f"Konvertiere PDF '{pdf_path}' in Bilder...") + if not os.path.exists(pdf_path): + raise FileNotFoundError(f"Die PDF-Datei '{pdf_path}' wurde nicht gefunden.") + if not pdf_path.lower().endswith('.pdf'): + raise ValueError("Die angegebene Datei ist keine PDF-Datei.") + if not os.path.isfile(pdf_path): + raise ValueError(f"Die angegebene Datei '{pdf_path}' ist kein gültiger Pfad.") + + return convert_from_path(pdf_path, dpi=dpi) + + +def image_to_base64(img: Image.Image) -> str: + buf = BytesIO() + img.save(buf, format="PNG") + return base64.b64encode(buf.getvalue()).decode("utf-8") + + +def analyze_image(img_b64: str, prompt: str) -> str: + print("Sende Bild zur Analyse...") + if not img_b64: + raise ValueError("Das Bild ist leer oder ungültig.") + resp = client.chat.completions.create( + model="gpt-4.1-mini", + messages=[ + { + "role": "user", + "content": [ + {"type": "text", "text": prompt}, + { + "type": "image_url", + "image_url": {"url": f"data:image/png;base64,{img_b64}"}, + }, + ], + } + ], + max_tokens=1000, + ) + print(resp) + return resp.choices[0].message.content + + +def analyze_pdf(pdf_path: str, prompt: str, csv_path="auswertung.csv", delay=2): + imgs = convert_pdf_to_images(pdf_path) + with open(csv_path, "w", newline="", encoding="utf-8") as f: + w = csv.writer(f) + w.writerow(["Seite", "Ergebnis"]) + pdf_start = int(os.getenv("PDF_START", 1)) + pdf_end = int(os.getenv("PDF_END", len(imgs))) + print(f"Analysiere Seiten {pdf_start} bis {pdf_end} von {len(imgs)} Seiten...") + if pdf_start < 1 or pdf_end > len(imgs): + print("Ungültiger Seitenbereich. Bitte überprüfe die Umgebungsvariablen PDF_START und PDF_END.") + return + for i in range(pdf_start - 1, min(pdf_end + 1, len(imgs))): + img = imgs[i] + try: + b64 = image_to_base64(img) + res = analyze_image(b64, prompt) + if res: + print(f"Seite {i+1}: Ergebnis gefunden") + w.writerow([i+1, res]) + else: + print(f"Seite {i+1}: Kein Ergebnis") + except Exception as e: + w.writerow([i+1, f"Fehler: {e}"]) + time.sleep(delay) + + +if __name__ == "__main__": + print("Starte PDF-Analyse...") + pdf_path = os.getenv("PDF_PATH", "example.pdf") + if not os.path.exists(pdf_path): + print(f"PDF-Datei '{pdf_path}' nicht gefunden.") + exit(1) + prompt = open("prompt.txt", encoding="utf-8").read().strip() + analyze_pdf(pdf_path, prompt) diff --git a/prompt.txt b/prompt.txt new file mode 100644 index 0000000..17e6be3 --- /dev/null +++ b/prompt.txt @@ -0,0 +1,15 @@ +Extrahiere aus diesem PDF-Dokument sämtliche Klemmenbezeichnungen (z. B. X1, X2, X101 etc.) und Gerätebezeichnungen (z. B. F1, Q2, K3, A1 etc.). + +Gib die Ergebnisse bitte nur im CSV-Format zurück mit den Spalten: Typ, Bezeichnung, Fundstelle. + +Beispiel: +Klemme,X1,Seite 3, Klemmplan oben +Gerät,Q2,Seite 5, Stromlaufplan rechts + +Hinweise: +- Klemmen beginnen mit „X“ gefolgt von Zahlen (z. B. X1, X10, X101). +- Geräte beginnen mit Q, F, K, A, M, T oder R gefolgt von Zahlen (z. B. K3, F1, Q5). +- Erstelle keine Überschriften oder Kommentare. +- Ignoriere doppelte Einträge. +- Wenn auf der Seite keine passenden Bezeichnungen sind, gib keine Ausgabe zurück. +- Gib nur die reinen Datenzeilen zurück, keine Tabellenrahmen oder sonstige Formatierungen. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7595174 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +openai +python-dotenv +pdf2image +Pillow