feat(workflow): simplify article flow and add automated rewrite step
This commit is contained in:
parent
8d7375c99f
commit
35ccceb260
11 changed files with 332 additions and 107 deletions
83
backend/app/rewrite.py
Normal file
83
backend/app/rewrite.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from typing import Any
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from .config import get_settings
|
||||
|
||||
|
||||
def _sanitize_source_text(text: str) -> str:
|
||||
raw = (text or "").strip()
|
||||
if not raw:
|
||||
return ""
|
||||
|
||||
lines = [ln.strip() for ln in raw.splitlines() if ln.strip()]
|
||||
if len(lines) > 3:
|
||||
lines = lines[3:]
|
||||
|
||||
joined = "\n".join(lines)
|
||||
# Remove press contact block at end from "Pressekontakt" onward.
|
||||
joined = re.sub(
|
||||
r"\n?\s*Pressekontakt[\s\S]*$",
|
||||
"",
|
||||
joined,
|
||||
flags=re.IGNORECASE,
|
||||
).strip()
|
||||
return joined
|
||||
|
||||
|
||||
def rewrite_article_text(article: dict[str, Any]) -> str:
|
||||
settings = get_settings()
|
||||
api_key = settings.openai_api_key
|
||||
if not api_key:
|
||||
raise RuntimeError("OPENAI_API_KEY fehlt")
|
||||
|
||||
source_text = _sanitize_source_text(article.get("content_raw") or "")
|
||||
if not source_text:
|
||||
source_text = (article.get("summary") or "").strip()
|
||||
if not source_text:
|
||||
raise RuntimeError("Kein Quelltext für Rewrite verfügbar")
|
||||
|
||||
title = (article.get("title") or "").strip()
|
||||
prompt = (
|
||||
"Schreibe den folgenden News-Text neu auf Deutsch in persönlicher Du-Form. "
|
||||
"Stil: ausführlich, gut lesbar, ohne Einleitung mit Datum/Uhrzeit/Firma/Ort, "
|
||||
"ohne Pressekontakt, ohne Quellenblock. "
|
||||
"Nutze klare Absätze und Zwischenüberschriften in HTML (<h2>, <p>, <ul><li> falls passend). "
|
||||
"Inhaltlich korrekt bleiben, nichts erfinden.\n\n"
|
||||
f"Titel: {title}\n\n"
|
||||
f"Originaltext:\n{source_text}"
|
||||
)
|
||||
|
||||
payload = {
|
||||
"model": settings.openai_model,
|
||||
"temperature": 0.4,
|
||||
"messages": [
|
||||
{"role": "system", "content": "Du bist ein deutscher News-Redakteur."},
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
}
|
||||
req = Request(
|
||||
url="https://api.openai.com/v1/chat/completions",
|
||||
method="POST",
|
||||
data=json.dumps(payload).encode("utf-8"),
|
||||
headers={
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
},
|
||||
)
|
||||
with urlopen(req, timeout=60) as resp:
|
||||
raw = resp.read().decode("utf-8", errors="replace")
|
||||
data = json.loads(raw)
|
||||
choices = data.get("choices")
|
||||
if not isinstance(choices, list) or not choices:
|
||||
raise RuntimeError(f"Ungültige OpenAI-Antwort: {data}")
|
||||
message = choices[0].get("message", {})
|
||||
content = message.get("content")
|
||||
if not isinstance(content, str) or not content.strip():
|
||||
raise RuntimeError("OpenAI lieferte keinen Rewrite-Text")
|
||||
return content.strip()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue