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:
+68
-8
@@ -2828,21 +2828,81 @@ def _resize_image(data, output_path):
|
|||||||
img.save(output_path, "JPEG", quality=85, dpi=(72, 72))
|
img.save(output_path, "JPEG", quality=85, dpi=(72, 72))
|
||||||
|
|
||||||
|
|
||||||
def _publish_to_joomla(filepath, rubrik_id):
|
def _publish_to_joomla(filepath, rubrik_id, allow_live=False):
|
||||||
"""Artikel via Joomla-API veroffentlichen."""
|
"""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
|
import requests
|
||||||
with open(filepath, encoding="utf-8") as f:
|
with open(filepath, encoding="utf-8") as f:
|
||||||
html = f.read()
|
html = f.read()
|
||||||
|
|
||||||
|
# ── Metadaten extrahieren ──
|
||||||
title_match = re.search(r"<title>(.*?)</title>", html)
|
title_match = re.search(r"<title>(.*?)</title>", html)
|
||||||
title = title_match.group(1) if title_match else "Unbekannt"
|
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_match = re.search(r"<article>(.*?)</article>", html, re.DOTALL)
|
||||||
body = body_match.group(1).strip() if body_match else html
|
article_body = body_match.group(1).strip() if body_match else html
|
||||||
payload = {"data": {"type": "articles", "attributes": {
|
|
||||||
"title": title, "alias": title.lower().replace(" ", "-")[:100],
|
# ── Interne Marker entfernen (wie _handle_publish) ──
|
||||||
"articletext": body, "state": 1, "catid": rubrik_id, "language": "de-DE"
|
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:
|
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",
|
"Accept": "application/vnd.api+json", "Content-Type": "application/json",
|
||||||
"X-Joomla-Token": JOOMLA_TOKEN
|
"X-Joomla-Token": JOOMLA_TOKEN
|
||||||
}, timeout=30)
|
}, timeout=30)
|
||||||
|
|||||||
Reference in New Issue
Block a user