Files
felhom.eu/documentation/audits/website-refresh-2026-10-08/tools/hu_build.py
T
admin 67b3fd23d1
gates / gates (push) Failing after 13m1s
website refresh: true numbers (56 apps), claims checked against the capability map, ten missing apps, an English twin of every public page (public, choice B), 404 page; site gates 13-18 + 11 decoys; R-902 opened
Part A: claim table documentation/audits/website-refresh-2026-10-08/claims.md; "100% open source" corrected
from the licence read; unbacked claims cut (firewall, RAID, snapshots, new-machine restore, self-managed
mode, household VPN, "never lost"). Part B: dawarich, docmost, grimmory, homebox, karakeep, mealie, metube,
radicale, recipe-importer, sparkyfitness cards; plant-it and wger cut (not offered). Part C: /en/ twins,
nav language switch, hreflang both ways, sitemap with xhtml:link, og-image-en.png. Part D: site_gates.py
twins/lang/same-apps/no-Hungarian/FAQ-JSON-LD/tail. Operator ruling 9 + choice B in 10-localisation.md §11,
§10.7. Register: R-902 (contact mailer source in no repo); R-813, R-784, R-559 annotated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-08 08:29:17 +02:00

122 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""Part A — the Hungarian pages: every claim the claim table marks FIX or CUT, plus the nav switch and hreflang.
Starts from HEAD each run (idempotent). Every replacement asserts it matched exactly once."""
import html, json, re, sys
sys.path.insert(0, __file__.rsplit("/", 1)[0])
from common import *
APPS = 56 # measured 2026-10-08: 58 catalog templates minus plant-it (abandoned) and wger (hidden)
# ------------------------------------------------------------------ index.html
s = head_text("index.html")
s = sub1(s, "53 telepíthető nyílt forráskódú alkalmazás, kétszintű automatikus mentés, magyar nyelvű vezérlőpult.",
"%d telepíthető alkalmazás, háromszintű automatikus mentés, magyar vagy angol nyelvű vezérlőpult." % APPS)
s = sub1(s, '"knowsLanguage": "hu",', '"knowsLanguage": ["hu", "en"],')
s = sub1(s, """Kétszintű automatikus mentés</h3>
<p>Minden éjjel készül egy helyi másodpéldány egy második meghajtóra, és egy titkosított másolat egy távoli tárhelyre. A megosztott mappáid is benne vannak mindkettőben.</p>""",
"""Háromszintű automatikus mentés</h3>
<p>Minden éjjel készül egy mentés a dobozon, egy másodpéldány egy második meghajtóra (ha van), és egy titkosított másolat egy távoli tárhelyre. A megosztott mappáid a második meghajtón és a távoli másolatban is benne vannak.</p>""")
s = sub1(s, """53 telepíthető alkalmazás</h3>
<p>Egy magyar nyelvű vezérlőpultból telepíthetők, pár kattintással — parancssor nélkül. Mind nyílt forráskódú, és mind a te gépeden fut.</p>""",
"""%d telepíthető alkalmazás</h3>
<p>A vezérlőpultból telepíthetők, pár kattintással — parancssor nélkül. Szinte mind nyílt forráskódú (a kivételeket az alkalmazások oldalán jelöljük), és mind a te gépeden fut.</p>""" % APPS)
s = sub1(s, """Távoli felügyelet, automatikus frissítés</h3>
<p>Figyeljük a doboz állapotát, és a vezérlőpult magától frissül a legutóbbi kiadásra — neked nem kell csinálnod semmit. Ha valami elromlik, mi látjuk.</p>
</div>""",
"""Távoli felügyelet, automatikus frissítés</h3>
<p>Figyeljük a doboz állapotát. A vezérlőpult magától frissül a legutóbbi kiadásra, és a doboz rendszere is megkapja a biztonsági frissítéseket — neked nem kell csinálnod semmit. Ha valami elromlik, mi látjuk.</p>
</div>
<div class="why-card">
<h3><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-rotate-cw"/></svg> Óvatos alkalmazásfrissítés</h3>
<p>Egy alkalmazás új verziója csak akkor jut el hozzád, ha előbb kipróbáltuk. Frissítés előtt friss mentés készül, és ha az új verzió nem indul el rendesen, a doboz magától visszaállítja az előzőt, az adataiddal együtt.</p>
</div>
<div class="why-card">
<h3><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-globe"/></svg> Magyarul vagy angolul</h3>
<p>A vezérlőpult magyarul és angolul is használható. A nyelvet a háztartás választja, és a dobozról érkező e-mailek is ezt a nyelvet követik.</p>
</div>""")
s = sub1(s, "<p>Egy törölt fájl visszahozható a mentésből. Hardverhiba esetén az egész rendszer visszaállítható egy új gépre, a titkosított távoli mentésből.</p>",
"<p>Egy törölt fájl visszahozható a mentésből. Ha maga a doboz megy tönkre, az újratelepített rendszerre a titkosított távoli mentésből visszahozhatók az alkalmazásaid adatai — a helyreállítási kóddal.</p>")
s = sub1(s, "<p>Az adataid a te otthonodban maradnak. Senki más nem fér hozzájuk - sem a Google, sem a Microsoft, sem senki más.</p>",
"<p>Az adataid a te otthonodban maradnak, nem a Google vagy a Microsoft szerverein. A távoli mentésbe csak titkosítva kerülnek.</p>")
s = sub1(s, """Egyszeri befektetés</h3>
<p>Nincs havi előfizetés, nincs rejtett költség. A szerver a tiéd, örökre. Csak az áramért fizetsz.</p>""",
"""Egyszeri befektetés</h3>
<p>A gép a tiéd, örökre. Nincs tárhely-előfizetés, ami évről évre drágul: az áramot fizeted, és ha kéred, az üzemeltetést.</p>""")
s = sub1(s, "<p>Soha többé nem veszíted el az adataidat - rendszeres, automatikus mentések.</p>",
"<p>Rendszeres, automatikus mentések három szinten: a dobozon, egy második meghajtón és titkosítva egy távoli tárhelyen.</p>")
s = sub1(s, "<p>Paperless-ngx, BookStack, Outline</p>", "<p>Paperless-ngx, Docmost, BookStack, Outline</p>")
s = sub1(s, "<p>Tandoor, Plant-it, wger, Actual Budget</p>", "<p>Tandoor, Mealie, Homebox, Actual Budget</p>")
s = sub1(s, "<p>AdventureLog, Wanderer, Cal.com</p>", "<p>AdventureLog, Wanderer, Dawarich, Cal.com</p>")
s = sub1(s, "<strong>53</strong> alkalmazás — mind <strong>100% nyílt forráskódú</strong>",
"<strong>%d</strong> alkalmazás — szinte mind <strong>nyílt forráskódú</strong>" % APPS)
s = sub1(s, "<p>Magyar nyelvű kezelőfelület</p>", "<p>Magyar vagy angol kezelőfelület</p>")
s = sub1(s, """<h3>Kétszintű mentés</h3>
<p>Helyi másodpéldány + titkosított távoli</p>""",
"""<h3>Háromszintű mentés</h3>
<p>A dobozon, második meghajtón, titkosítva távol</p>""")
s = sub1(s, "<p>SSL, tűzfal, VPN védelem</p>", "<p>HTTPS, titkosított alagút, nyitott port nélkül</p>")
s = sub1(s, "<p>SSD + HDD, RAID védelem</p>", "<p>SSD + HDD, második meghajtó a mentéseknek</p>")
s = sub1(s, "<p>A 3-2-1 mentési szabályt követve professzionális szintű adatbiztonságot építünk fel – semmi sem vész el, még katasztrófa esetén sem.</p>",
"<p>A 3-2-1 mentési szabályt követve professzionális szintű adatbiztonságot építünk fel – egy katasztrófa után is marad egy titkosított másolat, távol az otthonodtól.</p>")
s = sub1(s, "A <strong>TV-re streamelés hamarosan</strong> jön, egyelőre böngészőből és mobil appból megy a médiatár.",
"A <strong>TV-re streamelés (DLNA)</strong> még nincs: egyelőre böngészőből és mobil appból megy a médiatár.")
s = set_alternates(s, "/", "/en/")
s = set_nav(s, "hu", None, "/en/")
write("index.html", s)
# ------------------------------------------------------------------ technologiak.html
s = head_text("technologiak.html")
s = s[: s.index("</html>") + len("</html>")] # a stray file-dump summary sat after </html>, visible on the page
s = sub1(s, "Docker konténerek, magyar nyelvű vezérlőpult, Proxmox virtualizáció. SSL, tűzfal, VPN — professzionális biztonság.",
"Docker konténerek, magyar vagy angol nyelvű vezérlőpult, Proxmox virtualizáció. HTTPS és titkosított alagút — nyitott port nélkül.")
s = sub1(s, "reverse proxy, SSL, tűzfal, VPN, otthoni szerver technológia", "reverse proxy, HTTPS, titkosított alagút, otthoni szerver technológia")
s = sub1(s, "Docker, magyar nyelvű vezérlőpult, Proxmox — ipari szintű megoldások otthoni környezetben.",
"Docker, magyar vagy angol nyelvű vezérlőpult, Proxmox — ipari szintű megoldások otthoni környezetben.")
s = sub1(s, "Docker, magyar nyelvű vezérlőpult, Proxmox — ipari megoldások, otthoni környezetben.",
"Docker, magyar vagy angol nyelvű vezérlőpult, Proxmox — ipari megoldások, otthoni környezetben.")
s = sub1(s, '"description": "Docker konténerek, magyar nyelvű vezérlőpult és Proxmox virtualizáció otthoni szerverre.",',
'"description": "Docker konténerek, magyar vagy angol nyelvű vezérlőpult és Proxmox virtualizáció otthoni szerverre.",')
s = sub1(s, '<div class="subtitle">Docker / Podman</div>', '<div class="subtitle">Docker</div>')
s = sub1(s, "<p>Minden Felhom doboz magyar nyelvű kezelőfelülete</p>", "<p>Minden Felhom doboz kezelőfelülete, magyarul vagy angolul</p>")
s = sub1(s, "ez a magyar nyelvű kezelőfelület, amely a Proxmox alapra épülő rendszeredet vezérli.",
"ez a magyar vagy angol nyelvű kezelőfelület, amely a Proxmox alapra épülő rendszeredet vezérli.")
s = sub1(s, "<li>Magyar nyelvű webes felület – nincs szükség parancssor ismeretre</li>",
"<li>Magyar vagy angol webes felület – a háztartás választ, és nincs szükség parancssor ismeretre</li>")
s = sub1(s, "<li>Alkalmazás katalógus – 53 app telepíthető pár kattintással</li>",
"<li>Alkalmazás katalógus – %d app telepíthető pár kattintással</li>" % APPS)
s = sub1(s, "<li>Alkalmazás frissítések – egy kattintással, naplózással</li>",
"<li>Alkalmazás frissítések – csak kipróbált verzió, előtte friss mentés, és ha az új verzió nem indul, a doboz magától visszaáll az előzőre</li>")
s = sub1(s, '<div class="layer-tech">Magyar kezelőfelület · Nextcloud, Jellyfin, Immich…</div>',
'<div class="layer-tech">Magyar vagy angol kezelőfelület · Nextcloud, Jellyfin, Immich…</div>')
s = sub1(s, '<div class="layer-tech">Virtualizációs alap · pillanatkép, mentés, visszaállítás</div>',
'<div class="layer-tech">Virtualizációs alap · a teljes doboz mentése, visszaállítás</div>')
s = sub1(s, "<li><strong>Pillanatkép minden változtatás előtt</strong> – frissítés vagy beállítás előtt a rendszer pillanatképet készít, így bármi gond esetén pillanatok alatt visszaállunk az előző állapotra</li>",
"<li><strong>Mentés frissítés előtt</strong> – egy alkalmazás frissítése előtt friss mentés készül, és ha az új verzió nem indul el, a doboz magától visszaállítja az előzőt</li>")
s = sub1(s, "<li><strong>Az egész rendszer menthető</strong> – nem csak az adataid, hanem a teljes dobozod biztonsági mentésbe tehető, és szükség esetén egy új gépre is visszaállítható</li>",
"<li><strong>Az egész rendszer menthető</strong> – nem csak az adataid, hanem a teljes dobozod is biztonsági mentésbe kerül, és ebből visszaállítható</li>")
s = re.sub(r"\n\s*<div class=\"[^\"]*\">\s*\n\s*<p><strong>És ha többre van szükséged…</strong>.*?</p>\s*\n\s*</div>", "", s, count=0, flags=re.S) \
if False else sub1(s, "<p><strong>És ha többre van szükséged…</strong> ugyanez az alap teszi lehetővé a haladó igényeket is: Windows-os szoftver vagy hálózati szolgáltatás (pl. pfSense/OPNsense) külön virtuális gépben, tesztkörnyezetek, vagy egy app extra erős elkülönítése — kérésre.</p>",
"<p><strong>Egy alap, egy feladat:</strong> a Felhom dobozon a Proxmox egyetlen elkülönített rendszerkörnyezetet futtat — azt, amelyben az alkalmazásaid dolgoznak.</p>")
s = sub1(s, '<div class="node-tech">Traefik / Nginx</div>', '<div class="node-tech">Traefik</div>')
s = sub1(s, """ <li><strong>Traefik</strong> – automatikus SSL, dinamikus konfiguráció</li>
<li><strong>Nginx Proxy Manager</strong> – egyszerű webes felület</li>
<li><strong>Caddy</strong> – minimalista, automatikus HTTPS</li>""",
""" <li><strong>Traefik</strong> – minden alkalmazás a saját aldomainjén, HTTPS-sel</li>
<li><strong>Titkosított alagút</strong> – a doboz maga épít kapcsolatot kifelé, így otthon nem kell portot nyitni</li>""")
s = sub1(s, """ <li><strong>UFW tűzfal</strong> – csak a szükséges portok nyitva</li>
<li><strong>Fail2ban</strong> – brute-force támadások blokkolása</li>
<li><strong>Geo-blocking</strong> – kérések szűrése földrajzi hely alapján</li>
<li><strong>WireGuard VPN</strong> – biztonságos, titkosított távoli elérés</li>""",
""" <li><strong>Nincs nyitott port</strong> – kívülről csak a titkosított alagúton át érhető el a doboz</li>
<li><strong>Saját bejelentkezés</strong> – minden alkalmazásnak saját fiókjai vannak, a vezérlőpultnak jelszava</li>
<li><strong>Családi kapu</strong> – egyes alkalmazások elé a családtagok saját belépése kerül, idegen el sem jut az alkalmazásig</li>
<li><strong>Biztonsági frissítések</strong> – a doboz rendszere magától megkapja őket</li>""")
s = sub1(s, "Tűzfal és védelem</h3>", "Védelem</h3>")
s = sub1(s, "Kétszintű mentés – így védjük az adataidat</h3>", "Háromszintű mentés – így védjük az adataidat</h3>")
s = sub1(s, "<p>A Felhom dobozon minden éjjel készül egy <strong>helyi másodpéldány</strong> egy második meghajtóra, és egy <strong>titkosított másolat egy távoli tárhelyre</strong>. A két szint együtt véd: a helyi gyors, a távoli túléli azt is, ha a doboznak fizikailag baja esik.</p>",
"<p>A Felhom dobozon minden éjjel készül egy <strong>mentés a dobozon</strong>, egy <strong>másodpéldány egy második meghajtóra</strong>, és egy <strong>titkosított másolat egy távoli tárhelyre</strong>. A szintek együtt védenek: a helyi gyors, a távoli túléli azt is, ha a doboznak fizikailag baja esik.</p>")
s = set_alternates(s, "/technologiak", "/en/technology")
s = set_nav(s, "hu", "/technologiak", "/en/technology")
write("technologiak.html", s)