fix: _publish_to_joomla nutzt flaches API-Format (wie _handle_publish)

- JSON:API-Wrapper entfernt (Joomla 5/6 akzeptiert den nicht bei POST)
- articletext → introtext + fulltext (Read-More-Split)
- Metadaten (metadesc, metakey) werden extrahiert
- Kategorie/State/Featured-Logik identisch zu _handle_publish
- Behebt den 400-Fehler 'Field required: Title / Category'
This commit is contained in:
Hermes Agent
2026-07-13 23:48:43 +02:00
parent db707f650a
commit 42746581b1
+68 -8
View File
@@ -2828,21 +2828,81 @@ def _resize_image(data, output_path):
img.save(output_path, "JPEG", quality=85, dpi=(72, 72))
def _publish_to_joomla(filepath, rubrik_id):
"""Artikel via Joomla-API veroffentlichen."""
def _publish_to_joomla(filepath, rubrik_id, allow_live=False):
"""Artikel via Joomla-API veroffentlichen.
Nutzt das gleiche flache Payload-Format wie _handle_publish()
(Joomla 5/6 API akzeptiert NICHT den JSON:API-Wrapper bei POST).
"""
import requests
with open(filepath, encoding="utf-8") as f:
html = f.read()
# ── Metadaten extrahieren ──
title_match = re.search(r"<title>(.*?)</title>", html)
title = title_match.group(1) if title_match else "Unbekannt"
alias = re.sub(r'[^a-z0-9]+', '-', title.lower().strip())[:100]
body_match = re.search(r"<article>(.*?)</article>", html, re.DOTALL)
body = body_match.group(1).strip() if body_match else html
payload = {"data": {"type": "articles", "attributes": {
"title": title, "alias": title.lower().replace(" ", "-")[:100],
"articletext": body, "state": 1, "catid": rubrik_id, "language": "de-DE"
}}}
article_body = body_match.group(1).strip() if body_match else html
# ── Interne Marker entfernen (wie _handle_publish) ──
article_body = re.sub(r'<h1[^>]*>.*?</h1>\s*', '', article_body, flags=re.DOTALL)
article_body = re.sub(r'<p\s+class="meta"[^>]*>.*?</p>\s*', '', article_body, flags=re.DOTALL)
# ── Read-More-Split für introtext/fulltext ──
introtext = ""
fulltext = article_body.strip()
sr_match = re.search(r'<hr\s+id="system-readmore"\s*/?>', article_body, re.IGNORECASE)
if sr_match:
split_idx = sr_match.start()
introtext = article_body[:split_idx].strip()
fulltext = article_body[split_idx:].strip()
fulltext = re.sub(r'^<hr\s+id="system-readmore"\s*/?>\s*', '', fulltext)
# ── Meta-Description & Keywords ──
meta_desc_match = re.search(r'<meta\s+name="description"\s+content="([^"]+)"', html, re.IGNORECASE)
meta_key_match = re.search(r'<meta\s+name="keywords"\s+content="([^"]+)"', html, re.IGNORECASE)
# ── Kategorie/State/Featured (gleiche Logik wie _handle_publish) ──
catid = rubrik_id or 61 # Default: Korrektur
state = 0 if catid == 61 else 1
access = 6 if catid == 61 else 1
featured = 0
featured_up = None
featured_down = None
if allow_live and catid != 61:
from datetime import datetime as dt, timedelta
now = dt.now()
featured = 1
featured_up = now.strftime("%Y-%m-%d %H:%M:%S")
featured_down = (now + timedelta(days=3)).strftime("%Y-%m-%d %H:%M:%S")
# ── Flaches Payload (Joomla 5/6 API-Format) ──
article_payload = {
"title": title,
"alias": alias,
"introtext": introtext,
"fulltext": fulltext,
"catid": catid,
"language": "*",
"state": state,
"access": access,
"featured": featured,
"created_by": 560,
}
if meta_desc_match and meta_desc_match.group(1).strip():
article_payload["metadesc"] = meta_desc_match.group(1).strip()
if meta_key_match and meta_key_match.group(1).strip():
article_payload["metakey"] = meta_key_match.group(1).strip()
if featured_up:
article_payload["featured_up"] = featured_up
if featured_down:
article_payload["featured_down"] = featured_down
try:
r = requests.post(JOOMLA_API_URL, json=payload, headers={
r = requests.post(JOOMLA_API_URL, json=article_payload, headers={
"Accept": "application/vnd.api+json", "Content-Type": "application/json",
"X-Joomla-Token": JOOMLA_TOKEN
}, timeout=30)