2a06bcaee0
- artikel_*.html: 24 Dateien von <style>-Blöcken befreit (body, max-width zerstören Joomla) - journalistic-article-writing SKILL.md: falsche 'AUSNAHME 09.07.' entfernt - Ursache: Skill-Kommentar erlaubte Sub-Agenten <style> 'für Vorschau' — kein Gatekeeper existiert
110 lines
4.3 KiB
Python
110 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
||
"""Generate the KW28 Fantasywelt article HTML from parsed JSON data."""
|
||
|
||
import json
|
||
import html as html_mod
|
||
|
||
with open('/home/hermes/workspace/fantasywelt_data/kw28_parsed.json', 'r') as f:
|
||
data = json.load(f)
|
||
|
||
neuheiten = data['neuheiten']
|
||
wieder_da = data['wieder_da']
|
||
vorbestellungen = data['vorbestellungen']
|
||
|
||
AFFILIATE = 'ig1UxQ0L2cNMNslzFhyr'
|
||
|
||
def escape_html(text):
|
||
"""Escape text for HTML, but preserve existing entities."""
|
||
return html_mod.escape(text, quote=False)
|
||
|
||
def build_table(items, max_items=None):
|
||
"""Build an HTML table from items."""
|
||
if max_items:
|
||
items = items[:max_items]
|
||
|
||
rows = []
|
||
for item in items:
|
||
name = escape_html(item['name'])
|
||
url = item['url']
|
||
price = item['price_display']
|
||
ersch = item['ersch_date']
|
||
ausverkauft = item['ausverkauft']
|
||
|
||
if ausverkauft:
|
||
price_cell = f'<span style="color:#c0392b;font-weight:600">{price} (ausverkauft)</span>'
|
||
else:
|
||
price_cell = f'<span>{price}</span>'
|
||
|
||
rows.append(f'<tr><td><a href="{url}" target="_blank">{name}</a></td><td>{price_cell}</td><td>{ersch}</td></tr>')
|
||
|
||
table = f'''<table>
|
||
<thead><tr><th>Spiel</th><th>Preis</th><th>Erschienen</th></tr></thead>
|
||
<tbody>
|
||
{chr(10).join(rows)}
|
||
</tbody>
|
||
</table>'''
|
||
return table
|
||
|
||
# Build the article
|
||
article = f'''<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="description" content="Fantasywelt Neuheiten KW28: {len(neuheiten)} brandneue Brettspiele + {len(wieder_da)} wieder auf Lager. Alle Preise mit Affiliate-Links.">
|
||
<meta name="keywords" content="Fantasywelt, Neuheiten, Brettspiele, KW28, Affiliate, FantasyWelt">
|
||
<meta name="bsn-tags" content="Branche, Strategie">
|
||
<title>Die Spiele sind nun bei FantasyWelt erstmals auf Lager oder wieder verfügbar (KW28)</title>
|
||
</head>
|
||
<body>
|
||
|
||
<p class="meta">8. Juli 2026</p>
|
||
<!-- bsn-meta:8. Juli 2026 -->
|
||
|
||
<p class="dachzeile">{len(neuheiten)} brandneue Brettspiele und {len(wieder_da)} Rückkehrer: Das ist neu bei Fantasywelt in der KW28.</p>
|
||
|
||
<article>
|
||
|
||
<h2>Die Spiele sind nun bei FantasyWelt erstmals auf Lager oder wieder verfügbar (KW28)</h2>
|
||
|
||
<p>Die Kalenderwoche 28 bringt frischen Wind in die Fantasywelt-Regale: {len(neuheiten)} brandneue Titel sind erstmals im Shop gelistet, {len(wieder_da)} weitere Spiele sind nach einer Durststrecke wieder auf Lager. Dazu kommen {len(vorbestellungen)} neue Vorbestellungen. Wir haben alle Neuheiten und Rückkehrer für euch zusammengestellt — mit Preisen, Sprache und Verfügbarkeit.</p>
|
||
|
||
<div class="infobox" style="background:#f0f4f8;border:1px solid #d0d8e0;padding:0.8rem 1.2rem;margin:1rem 0;font-size:0.9rem;border-radius:4px;">
|
||
<p><strong>ℹ️ Hinweis:</strong> Die Verfügbarkeitsangaben entsprechen dem Stand vom 8. Juli 2026. Besonders Trading-Card-Game(TCG)-Produkte sind oft innerhalb weniger Stunden ausverkauft. „Auf Lager" bedeutet: zum Zeitpunkt der Abfrage verfügbar. Bei ausverkauften Titeln lohnt sich der Klick trotzdem — oft gibt es eine Vormerkfunktion.</p>
|
||
</div>
|
||
|
||
<hr id="system-readmore" />
|
||
|
||
<h2>Neu im Shop ({len(neuheiten)})</h2>
|
||
|
||
{build_table(neuheiten)}
|
||
|
||
<h2>Wieder auf Lager ({len(wieder_da)})</h2>
|
||
<p><em>Auswahl der wichtigsten Titel. Die vollständige Liste umfasst {len(wieder_da)} Spiele.</em></p>
|
||
|
||
{build_table(wieder_da)}
|
||
|
||
<h2>Neue Vorbestellungen ({len(vorbestellungen)})</h2>
|
||
|
||
{build_table(vorbestellungen)}
|
||
|
||
<p><span style="font-size:1.17em;font-weight:bold;display:block;margin:1em 0;"><strong>Quellen</strong></span></p>
|
||
<ul>
|
||
<li><a href="https://www.fantasywelt.de?bsn={AFFILIATE}" target="_blank">FantasyWelt.de — Neuheiten</a></li>
|
||
</ul>
|
||
|
||
<p class="bsn-recherche"><em>Recherchestand: 8. Juli 2026. Preise und Verfügbarkeiten können sich ändern. Dieser Artikel enthält Affiliate-Links — bei einem Kauf erhalten wir eine Provision. Alle Angaben ohne Gewähr.</em></p>
|
||
|
||
</article>
|
||
</body>
|
||
</html>'''
|
||
|
||
with open('/home/hermes/workspace/artikel_fantasywelt_kw28.html', 'w') as f:
|
||
f.write(article)
|
||
|
||
print(f"Article written to artikel_fantasywelt_kw28.html")
|
||
print(f" Neuheiten: {len(neuheiten)}")
|
||
print(f" Wieder da: {len(wieder_da)}")
|
||
print(f" Vorbestellungen: {len(vorbestellungen)}")
|
||
print(f" Total items in tables: {len(neuheiten) + len(wieder_da) + len(vorbestellungen)}")
|