fix: Kingdom Rush #15540 online mit Bild + Workflow gehärtet
- verify_article.sh: +4 CSS-Compliance-Checks (vorbestell-box, bsn-facts, veraltete Boxen, Inline-Styles) - fix_article_format.py: Auto-Fixer für Inline-Style-Stripping - journalistic-article-writing SKILL.md: QC-Pipeline + Template mit vorbestell-box - artikel_kingdom_rush_deal_20260710.html: PATCH 200 auf Joomla + Bild
This commit is contained in:
+63
-63
@@ -1,67 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fix article HTML format for Article-Server compatibility.
|
||||
Ensures: <p class="meta"> date, <meta name="description">, <meta name="keywords">
|
||||
Run: python3 fix_article_format.py /home/hermes/workspace/artikel.html
|
||||
"""
|
||||
import sys, re, os
|
||||
from datetime import datetime
|
||||
fix_article_format.py — Stripped Inline-Styles von BSN-Standard-Klassen.
|
||||
Entfernt veraltete Box-Formate aus Artikel-HTML.
|
||||
Usage: python3 fix_article_format.py <artikel.html>
|
||||
"""
|
||||
import re, sys
|
||||
|
||||
def fix_article(filepath):
|
||||
with open(filepath, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
changed = False
|
||||
|
||||
# 1. Fix <div class="meta"> → <p class="meta">
|
||||
if re.search(r'<div class="meta">([^<]+)</div>', content):
|
||||
content = re.sub(r'<div class="meta">([^<]+)</div>', r'<p class="meta">\1</p>', content)
|
||||
changed = True
|
||||
print(f" ✓ <div class=\"meta\"> → <p class=\"meta\">")
|
||||
|
||||
# 2. Add <p class="meta"> if missing (using dateline or default)
|
||||
if '<p class="meta">' not in content:
|
||||
date_str = datetime.now().strftime("%d. %B %Y")
|
||||
# Try to extract date from dateline
|
||||
dl = re.search(r'<p class="dateline">([^<]+)</p>', content)
|
||||
if dl:
|
||||
date_str = dl.group(1).split('·')[0].strip()
|
||||
# Insert after <body> or after <h1>
|
||||
meta_line = f'<p class="meta">{date_str} · Lesezeit: ca. 5 Minuten</p>\n'
|
||||
if '<h1>' in content:
|
||||
content = re.sub(r'(</h1>\n)', r'\1' + meta_line, content, count=1)
|
||||
else:
|
||||
content = re.sub(r'(<body>\n)', r'\1' + meta_line, content, count=1)
|
||||
changed = True
|
||||
print(f" ✓ <p class=\"meta\"> hinzugefügt: {date_str}")
|
||||
|
||||
# 3. Add <meta name="description"> if missing
|
||||
if '<meta name="description" content="' not in content:
|
||||
title_m = re.search(r'<title>(.*?)</title>', content)
|
||||
if title_m:
|
||||
title = title_m.group(1).strip()
|
||||
desc = title[:160] + ('…' if len(title) > 160 else '')
|
||||
desc_tag = f'<meta name="description" content="{desc}">\n'
|
||||
content = re.sub(r'(<title>.*?</title>\n)', r'\1' + desc_tag, content, count=1)
|
||||
changed = True
|
||||
print(f" ✓ <meta name=\"description\"> hinzugefügt")
|
||||
|
||||
# 4. Add <meta name="keywords"> if missing
|
||||
if '<meta name="keywords" content="' not in content:
|
||||
kw_tag = '<meta name="keywords" content="Brettspiel, News, brettspiel-news.de">\n'
|
||||
content = re.sub(r'(<meta name="description".*?>\n)', r'\1' + kw_tag, content, count=1)
|
||||
changed = True
|
||||
print(f" ✓ <meta name=\"keywords\"> hinzugefügt")
|
||||
|
||||
if changed:
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(content)
|
||||
return True
|
||||
return False
|
||||
if len(sys.argv) < 2:
|
||||
print(f"Usage: {sys.argv[0]} <artikel.html>")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
for f in sys.argv[1:]:
|
||||
print(f"{os.path.basename(f)}:")
|
||||
if fix_article(f):
|
||||
print(f" ✅ Gefixt")
|
||||
else:
|
||||
print(f" ✓ Bereits korrekt")
|
||||
filepath = sys.argv[1]
|
||||
with open(filepath) as f:
|
||||
html = f.read()
|
||||
|
||||
original = html
|
||||
fixes = 0
|
||||
|
||||
# 1. Strip style="" from vorbestell-box elements
|
||||
html, n = re.subn(
|
||||
r'(<div[^>]*class="[^"]*vorbestell-box[^"]*")[^>]*>',
|
||||
r'\1>',
|
||||
html
|
||||
)
|
||||
fixes += n
|
||||
|
||||
# 2. Strip style="" from bsn-facts elements
|
||||
html, n = re.subn(
|
||||
r'(<div[^>]*class="[^"]*bsn-facts[^"]*")[^>]*>',
|
||||
r'\1>',
|
||||
html
|
||||
)
|
||||
fixes += n
|
||||
|
||||
# 3. Remove <div class="affiliate-box">...</div> blocks entirely
|
||||
html, n = re.subn(
|
||||
r'<div class="affiliate-box"[^>]*>.*?</div>\s*',
|
||||
'',
|
||||
html,
|
||||
flags=re.DOTALL
|
||||
)
|
||||
fixes += n
|
||||
|
||||
# 4. Strip style="background:..." / style="border:..." from <div>s
|
||||
# (but ONLY if they also have a class= — pure style-only divs stay)
|
||||
html, n = re.subn(
|
||||
r'(<div[^>]*class="[^"]*"[^>]*)\s+style="[^"]*(?:background|border)[^"]*"',
|
||||
r'\1',
|
||||
html
|
||||
)
|
||||
fixes += n
|
||||
|
||||
# 5. Strip style="" from <p> inside old-format deal boxes
|
||||
html, n = re.subn(
|
||||
r'<p style="[^"]*(?:margin|font-weight|font-size|color:#888)[^"]*"[^>]*>',
|
||||
r'<p>',
|
||||
html
|
||||
)
|
||||
fixes += n
|
||||
|
||||
if html != original:
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(html)
|
||||
print(f"✅ {fixes} Fixes angewandt auf {filepath}")
|
||||
else:
|
||||
print(f"ℹ️ Keine Fixes nötig für {filepath}")
|
||||
|
||||
Reference in New Issue
Block a user