fix: QC-Ratings aus 7 älteren Artikeln entfernt (CHECK 10)

This commit is contained in:
Hermes Agent
2026-06-23 23:47:51 +02:00
parent e73e0e88de
commit 4d90e4249d
656 changed files with 2602398 additions and 3 deletions
+147
View File
@@ -0,0 +1,147 @@
#!/usr/bin/env python3
"""Build Joomla article for children's games and POST to brettspiel-news.de."""
import json, base64, subprocess, sys, os
import urllib.request, urllib.error
# Load parsed deals
with open("/tmp/kinderspiele_data.json") as f:
data = json.load(f)
deals = data["deals"]
age_groups = data["age_groups"]
# Joomla config
JOOMLA_TOKEN = "sha256:794:cc64e486eddbb2e5a96a28be897034924f66f2722db0be3baab408e6b806e2b4"
API_BASE = "https://www.brettspiel-news.de/api/index.php/v1"
HEADERS = {
"Accept": "application/vnd.api+json",
"Content-Type": "application/json",
"X-Joomla-Token": JOOMLA_TOKEN,
}
def api_post(endpoint, payload):
url = f"{API_BASE}{endpoint}"
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(url, data=data, headers=HEADERS, method="POST")
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read())
except urllib.error.HTTPError as e:
body = e.read().decode()[:500]
print(f"HTTP {e.code}: {body}", file=sys.stderr)
raise
def api_patch(endpoint, payload):
url = f"{API_BASE}{endpoint}"
data = json.dumps(payload).encode("utf-8")
req = urllib.request.Request(url, data=data, headers=HEADERS, method="PATCH")
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read())
except urllib.error.HTTPError as e:
body = e.read().decode()[:500]
print(f"HTTP {e.code}: {body}", file=sys.stderr)
raise
# Step 1: Upload intro image to Joomla Media
print("Uploading intro image...")
with open("/tmp/monsterjaeger.jpg", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
media_result = api_post("/media/files", {
"path": "images/Spiele/2026/monsterjaeger_kinderspiele_2026-06-21.jpg",
"content": img_b64,
})
print(f"Media upload: {media_result.get('data', {}).get('id', 'OK')}")
# Step 2: Build article HTML
age_labels = {
"2+": "Für die Kleinsten (ab 23 Jahre)",
"3+": "Für die Kleinsten (ab 3 Jahre)",
"4+": "Ab 4 Jahre",
"5+": "Ab 5 Jahre",
"6+": "Ab 6 Jahre",
"7+": "Ab 7 Jahre",
"Allgemein": "Weitere Kinderspiele",
}
age_order = ["2+", "3+", "4+", "5+", "6+", "7+", "Allgemein"]
# Build deal blocks by age
sections = []
for age in age_order:
if age not in age_groups:
continue
games = age_groups[age]
label = age_labels.get(age, age)
blocks = []
for g in games:
blocks.append(f"""<div style="display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid #eee;">
<img src="{g['img']}" alt="" style="width: 100px; height: 100px; object-fit: contain;" loading="lazy" />
<div style="flex: 1;"><strong>{g['title']}</strong><br />
<span style="color: #b12704; font-size: 1.2rem; font-weight: bold;">{g['price']:.2f} €</span>
<span style="text-decoration: line-through; color: #999; margin-left: 0.5rem;">UVP {g['uvp']:.2f} €</span>
<span style="background: #b12704; color: #fff; padding: 2px 6px; border-radius: 3px; margin-left: 0.5rem; font-size: 0.85rem;">-{g['pct']}%</span>
<span style="color: #b12704; margin-left: 0.3rem;">({g['saved']:.2f} € gespart)</span><br />
<a href="https://www.amazon.de/dp/{g['asin']}?tag=60pro05-21" target="_blank" rel="noopener" style="color: #007185;">Zu Amazon →</a></div>
</div>""")
sections.append(f"<h2>{label}</h2>\n" + "\n".join(blocks))
total_count = len(deals)
group_count = len(age_groups)
# Summary stats
summary_lines = []
for age in age_order:
if age in age_groups:
summary_lines.append(f"{age_labels.get(age, age)}: {len(age_groups[age])} Spiele")
intro_html = f"""<p>Jeden Sonntag durchforsten wir Amazon nach den besten Kinderspiel-Angeboten heute mit {total_count} reduzierten Titeln für kleine Spieler.</p>
<p>Die Angebote sind nach Altersgruppen sortiert: von den ersten Brettspielen für die Kleinsten bis zu spannenden Familienspielen für Schulkinder. Alle Preise inklusive Mehrwertsteuer, Stand 21. Juni 2026.</p>
<p><strong>Unser Tipp:</strong> Monsterjäger von Schmidt Spiele ist heute mit 54 % Rabatt der absolute Preisknüller nur 11,31 € statt 24,49 €!</p>
<!--more-->"""
# Build full HTML
all_sections = "\n".join(sections)
body_html = intro_html + all_sections + f"""
<p style="margin-top: 2rem; color: #888; font-size: 0.9rem;">Preise und Verfugbarkeit konnen sich schnell andern. Uber die Links (Partner-Tag 60pro05-21) kauft ihr zum gleichen Preis Amazon zahlt eine kleine Provision.</p>
<p style="font-size: 0.8rem; color: #999; text-align: center; margin-top: 1rem;">Brettspiel-News.de · (C) liegt beim jeweiligen Rechteinhaber</p>"""
# Clean up extended chars for Joomla
body_html = body_html.replace("ö", "&ouml;").replace("ä", "&auml;").replace("ü", "&uuml;").replace("ß", "&szlig;")
print(f"\nArticle body: {len(body_html)} chars, {total_count} games, {group_count} groups")
# Step 3: POST article
print("\nCreating Joomla article...")
article = {
"title": "🧒 Sonntags-Kinderspiele: Die 20 besten Angebote für kleine Spieler",
"introtext": body_html,
"fulltext": body_html,
"catid": 61,
"state": 0,
"access": 6,
"created_by": 560,
"language": "de",
"featured": 1,
"metadesc": f"20 reduzierte Kinderspiele bei Amazon: Monsterj&auml;ger -54%, Pupsparade -42%, Sagaland -43% sortiert nach Altersgruppen. Alle Deals mit Direktlinks.",
"metakey": "Kinderspiele, Kinder Brettspiele, Angebote, Amazon Deals, Monsterj&auml;ger, Pupsparade, Sagaland, Kinderspiel des Jahres",
"metadata": {"author": "Daniel Krause", "robots": "index, follow"},
"images": {
"image_intro": "https://www.brettspiel-news.de/images/Spiele/2026/monsterjaeger_kinderspiele_2026-06-21.jpg#joomlaImage://local-images/Spiele/2026/monsterjaeger_kinderspiele_2026-06-21.jpg?width=&height="
},
}
result = api_post("/content/articles", article)
article_id = result["data"]["id"]
print(f"\n✅ Article created! ID: {article_id}")
print(f"URL: https://www.brettspiel-news.de/index.php?option=com_content&view=article&id={article_id}")
print(f"Article server: http://185.162.249.159:8890/?key=br3ttsp1el-n3ws-2026")
# Print summary
print(f"\n=== KINDERSPIELE TOP 20 ===")
print(f"Spiele: {total_count}")
print(f"Altersgruppen: {group_count}")
for line in summary_lines:
print(f" {line}")