#!/usr/bin/env python3 """Parse the cached topic pages into posts.jsonl (in the cache folder, never in git). Read-only research (forum-research-2026-10-12). Stdlib only. Per post: num, date, reply_to, author_id, off, text. - author_id = first 12 hex of sha256(salt + username). The salt is made once and kept in the cache folder; it is never committed. - text = the post's OWN words. The quoted parent sits in
and is skipped whole; only
outside it is kept. - off = the site marked the post off-topic (
  • ). A post with no parent has data-rplid="" (an earlier pattern that required digits silently dropped every such post). - Posts before WINDOW_START are dropped; a post number seen twice (a redirected page) is kept once. Then it runs the parser controls (spec 7 B) and prints them. Exit 1 if a control fails. Usage: python3 parse.py """ import glob import hashlib import html import json import os import random import re import secrets import sys from html.parser import HTMLParser CACHE = os.path.expanduser("~/research-cache/prohardver-hazi-szerver") PAGES = os.path.join(CACHE, "pages") OUT = os.path.join(CACHE, "posts.jsonl") SALT_FILE = os.path.join(CACHE, "salt.txt") WINDOW_START = "2023-10-12 00:00:00" LI_RE = re.compile(r'
  • ') TIME_RE = re.compile(r'', re.S) TAG_RE = re.compile(r"<[^>]+>") # The site shows this year's dates without a year ("aug. 9., 12:34:56"), and "ma"/"tegnap" for # today/yesterday. FETCH_DAY is the day the pages were fetched (fetch.log). FETCH_DAY = (2026, 10, 12) HU_MONTHS = {"jan.": 1, "febr.": 2, "márc.": 3, "ápr.": 4, "máj.": 5, "jún.": 6, "júl.": 7, "aug.": 8, "szept.": 9, "okt.": 10, "nov.": 11, "dec.": 12} def norm_date(raw): """Return 'YYYY-MM-DD HH:MM:SS' or '' if the shape is unknown. Edited posts carry a pencil inside