#!/usr/bin/env python3 """Mailchimp-Newsletter (Wayback-Kopie) -> DokuWiki-Rohtext (Englisch) + Bildliste. Aufruf: html2wiki.py Schreibt /en_.txt (Seitenrumpf ohne Rahmen) und /images_.json """ import json import os import re import sys import urllib.parse from bs4 import BeautifulSoup, NavigableString, Tag SKIP_IMG = re.compile(r'(social|google|tumblr|like_|cdn-images|facebook|twitter)', re.I) WAYBACK = re.compile(r'^https?://web\.archive\.org/web/\d+[a-z_]*/', re.I) MEDIA_NS = 'news:newsletter:{nr}:' def clean_name(fname): """Wayback-Anhang entfernen, DokuWiki-taugliche Kleinschreibung.""" base, ext = os.path.splitext(fname) base = re.sub(r'_[A-Za-z0-9]{4}$', '', base) # _0oNk usw. base = re.sub(r'[^A-Za-z0-9]+', '_', base).strip('_').lower() ext = ext.lower().replace('jpeg', 'jpg') return base + ext def wrap(text, mk): """Formatierung je Absatz/Zeile, Leerraum außerhalb der Marker.""" parts = re.split(r'(\n+)', text) res = [] for p in parts: if not p.strip() or p.startswith('\n'): res.append(p) continue lead = p[:len(p) - len(p.lstrip())] trail = p[len(p.rstrip()):] res.append(lead + mk + p.strip() + mk + trail) return ''.join(res) def esc(text): """Sternchen-Folgen (z. B. Teaser 'the *****') vor DokuWiki schützen.""" return re.sub(r'(?.*?', '', html, flags=re.S) soup = BeautifulSoup(html, 'html.parser') body = soup.find(id='templateBody') or soup.body header = soup.find(id='templateHeader') c = Conv(path, nr) if header: for im in header.find_all('img'): c.add_img(im) c.walk(body) c.flush() # Ende abschneiden: "Follow Elite: Dangerous" und alles danach blocks = [] for b in c.out: if b[0] == 'h' and re.match(r'follow elite', b[1], re.I): break blocks.append(b) ns = MEDIA_NS.format(nr=nr) lines = [] # Kopfbild (mail_head / erstes Bild im Kopf) nicht in den Text, es ist das Box-Bild if blocks and blocks[0][0] == 'img': blocks = blocks[1:] grouped = [] for b in blocks: if b[0] == 'img' and b[2] < 500 and grouped and grouped[-1][0] == 'imgs': grouped[-1][1].append(b) elif b[0] == 'img' and b[2] < 500: grouped.append(('imgs', [b])) else: grouped.append(b) blocks = grouped for b in blocks: if b[0] == 'imgs': lines.append(' '.join('{{%s%s?%d|}}' % (ns, i[1], i[2]) for i in b[1]) + '\n') continue if b[0] == 'p': lines.append(b[1] + '\n') elif b[0] == 'h': lines.append('===== %s =====\n' % b[1]) elif b[0] == 'img': lines.append('{{%s%s?%d|}}\n' % (ns, b[1], min(b[2], 560))) elif b[0] in ('ul', 'ol'): mark = '*' if b[0] == 'ul' else '-' lines.append('\n'.join(' %s %s' % (mark, i) for i in b[1]) + '\n') os.makedirs(outdir, exist_ok=True) open(os.path.join(outdir, 'en_%s.txt' % nr), 'w').write('\n'.join(lines)) json.dump(c.images, open(os.path.join(outdir, 'images_%s.json' % nr), 'w'), indent=1) if __name__ == '__main__': main()