Files
felhom.eu/documentation/audits/website-refresh-2026-10-08/tools/hu_build2.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

126 lines
15 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, second half: biztonsagimentes, gyik, kapcsolat, letoltes, 404 (Hungarian)."""
import html, json, re, sys
sys.path.insert(0, __file__.rsplit("/", 1)[0])
from common import *
APPS = 56
# ------------------------------------------------------------------ biztonsagimentes.html
s = head_text("biztonsagimentes.html")
s = sub1(s, "Professzionális mentési stratégiával gondoskodunk róla, hogy soha ne veszíts el semmit.",
"Professzionális mentési stratégiával gondoskodunk róla, hogy egy hiba vagy baleset után is legyen honnan visszahozni.")
s = sub1(s, "<p>Kritikus adatok (dokumentumok, fotók) általában elférnek néhány száz GB-on, ami havi pár száz forint.</p>",
"<p>A tárhely díja a mentett adatmennyiségtől függ. A Felhom dobozon ezt a megoldást használjuk.</p>")
s = sub1(s, "<p>A szerver automatikusan, ütemezetten készít mentéseket. Nem kell semmire sem emlékezned – a rendszer gondoskodik róla.</p>",
"<p>A szerver minden éjjel magától készít mentéseket, három szinten: <strong>a dobozon</strong>, egy <strong>második meghajtón</strong> (ha van), és <strong>titkosítva egy távoli tárhelyen</strong>. Nem kell semmire sem emlékezned – a rendszer gondoskodik róla.</p>")
s = sub1(s, "a teljes doboz biztonsági mentésbe tehető és szükség esetén egy új gépre is visszaállítható (titkosított offsite mentésből). Ez teszi lehetővé, hogy egy hardverhiba után gyorsan újrainduljon minden.</p>",
"a teljes doboz is biztonsági mentésbe kerül, és ebből visszaállítható. 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><strong>Személyre szabjuk:</strong> Minden ügyfélnél felmérjük a lehetőségeket (van-e haver szerver, iroda, felhő preferencia), és ennek megfelelően állítjuk be az offsite mentést.</p>",
"<p><strong>A távoli mentés helye:</strong> a Felhom dobozon a távoli másolat egy általunk biztosított tárhelyre kerül, titkosítva. A „haver rendszer” és az iroda általános lehetőségek a 3-2-1 szabályhoz — ezeket ma nem állítjuk be.</p>")
s = sub1(s, "Automatikus backup, offsite mentés, titkosított felhő tárolás. Adataid soha nem vesznek el.",
"Automatikus backup három szinten: a dobozon, egy második meghajtón és titkosítva egy távoli tárhelyen.")
s = sub1(s, "Professzionális szintű adatbiztonság otthon. Automatikus backup, offsite mentés — semmi nem vész el.",
"Professzionális szintű adatbiztonság otthon. Automatikus backup, és egy titkosított másolat távol is.")
s = set_alternates(s, "/biztonsagimentes", "/en/backups")
s = set_nav(s, "hu", "/biztonsagimentes", "/en/backups")
write("biztonsagimentes.html", s)
# ------------------------------------------------------------------ gyik.html (visible answers; JSON-LD rebuilt from them)
s = head_text("gyik.html")
R = [
("Nálunk több mint 45 alkalmazásból válogathatsz, és bármi egyedi igényt is megoldunk.</p>",
"Nálunk %d alkalmazásból válogathatsz, és ha valami hiányzik, megnézzük, felvehető-e.</p>" % APPS),
("<p>Több mint <strong>45 alkalmazást</strong> kínálunk — a teljes listát",
"<p><strong>%d alkalmazást</strong> kínálunk — a teljes listát" % APPS),
("<p>Ha valami nincs a listán, kérdezz — a legtöbb nyílt forráskódú alkalmazás telepíthető.</p>",
"<p>Ha valami nincs a listán, kérdezz — megnézzük, felvehető-e a katalógusba.</p>"),
("<p><strong>Igen, bármikor!</strong> A rendszer úgy van felépítve, hogy új alkalmazások könnyedén hozzáadhatók. Szólj, mit szeretnél, és mi telepítjük és bekonfiguráljuk neked.</p>",
"<p><strong>Igen, bármikor!</strong> A vezérlőpultból bármelyik alkalmazás telepíthető, pár kattintással. Ha elakadsz, szólj, és segítünk beállítani.</p>"),
("<p>Igen! Biztonságos távoli elérést biztosítunk, titkosított VPN kapcsolaton vagy reverse proxy-n keresztül. Ez azt jelenti,",
"<p>Igen! A doboz egy titkosított alagúton át, HTTPS-sel érhető el, külön alkalmazás nélkül. Ez azt jelenti,"),
("több rétegű biztonsági védelmet kapnak: tűzfal, automatikus SSL/TLS titkosítás (HTTPS), rendszeres szoftverfrissítések, és biztonságos hozzáférés-kezelés. A szervered a te otthonodon belül van — kívülről csak az általunk beállított, titkosított csatornákon keresztül érhető el.</p>",
"több rétegű védelmet kapnak: automatikus HTTPS titkosítás, rendszeres biztonsági frissítések, saját bejelentkezés minden alkalmazásban, és egyes alkalmazások előtt családi kapu. A szervered a te otthonodon belül van — otthon nem nyitunk portot, kívülről csak egy titkosított alagúton keresztül érhető el.</p>"),
("<p>Ha ez számodra nem elfogadható, van lehetőség <strong>„önálló\" modellre</strong>: ilyenkor a telepítés után a távoli hozzáférést eltávolítjuk, és a jövőbeli támogatás személyes jelenléttel történik. Ilyenkor a mentési kulcsokat kizárólag te ismered.</p>",
"<p>A távoli mentésed kulcsát viszont <strong>csak te ismered</strong>: a helyreállítási kód egyszer jelenik meg, a te képernyődön, és nálunk nem marad belőle másolat. A távoli mentést így mi sem tudjuk elolvasni.</p>"),
("nincs reklámcélú profilozás, és az adataid soha nem hagyják el a hálózatodat.</p>",
"nincs reklámcélú profilozás, és az adataid csak titkosítva hagyják el az otthonodat (a távoli mentés).</p>"),
("A rendszeres frissítések és a megfelelő tűzfal konfiguráció minimalizálja a kockázatot.</p>",
"A rendszeres frissítések, és hogy otthon nincs nyitott port, csökkentik a kockázatot.</p>"),
("<p>A mentések titkosítva vannak és külön helyen (offsite) is tárolódnak — tehát még egy zsarolóvírus támadás esetén is vissza tudjuk állítani az adataidat a legutolsó mentésből.</p>",
"<p>A mentéseidből egy titkosított másolat külön helyen (offsite) is tárolódik — így egy zsarolóvírus-támadás után is van egy távol tárolt másolat.</p>"),
("<p>A <strong>3-2-1 mentési szabályt</strong> követjük: 3 másolat az adatokról, 2 különböző tárolón, 1 távoli helyen. Ez iparági szabvány, amit a legnagyobb cégek is alkalmaznak.</p>",
"<p>A <strong>3-2-1 mentési szabályt</strong> követjük: 3 másolat az adatokról, 2 különböző tárolón, 1 távoli helyen. Ez iparági szabvány, amit a legnagyobb cégek is alkalmaznak. A dobozon ez három szint: egy mentés a dobozon, egy másodpéldány egy második meghajtón, és egy titkosított másolat egy távoli tárhelyen.</p>"),
("<p>Ezért vannak a mentések! A helyi és offsite biztonsági mentésekből az adatok visszaállíthatók egy új lemezre. A monitoring rendszerünk figyeli a lemezhasználatot, és előre figyelmeztet, ha probléma van.</p>",
"<p>Ezért vannak a mentések! A második meghajtón és a távoli tárhelyen lévő másolatokból az alkalmazásaid adatai visszahozhatók. A doboz figyeli a lemezek állapotát és a szabad helyet, és előre figyelmeztet, ha probléma van.</p>"),
("\n <p>Nagyobb rendszereknél RAID konfigurációt is alkalmazhatunk, ami azt jelenti, hogy egy lemez meghibásodása esetén a rendszer adatvesztés nélkül tovább működik.</p>", ""),
("<p>Az offsite (távoli) backup azt jelenti, hogy az adataidról egy másolat fizikailag más helyen is megvan — például egy ismerős szerverén, az irodádban, vagy titkosítva egy felhő tárhelyen. Ha otthon bármi katasztrófa történne (tűz, lopás, vízkár), az adataid akkor is biztonságban vannak.</p>",
"<p>Az offsite (távoli) backup azt jelenti, hogy az adataidról egy másolat fizikailag más helyen is megvan. A Felhom dobozon ez egy általunk biztosított tárhely, ahova a másolat titkosítva kerül. Ha otthon bármi katasztrófa történne (tűz, lopás, vízkár), a távoli másolat akkor is megmarad.</p>"),
("<p>Az alkalmazások konténerekben futnak, ami megkönnyíti a frissítést. Mi figyelemmel kísérjük az új verziókat, és ha szükséges, frissítjük az alkalmazásaidat — tesztelés után, hogy ne okozzon gondot.</p>",
"<p>Az alkalmazások konténerekben futnak, ami megkönnyíti a frissítést. Mi figyelemmel kísérjük az új verziókat, és egy új verzió csak akkor jut el hozzád, ha előbb kipróbáltuk. A doboz rendszere a biztonsági frissítéseket magától megkapja.</p>"),
("<p>Minden frissítés előtt automatikus mentés és rendszer-pillanatkép készül (a Proxmox alapnak köszönhetően), így ha bármi nem stimmel, gyorsan visszaállíthatjuk az előző állapotot.</p>",
"<p>Minden alkalmazásfrissí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>"),
("<p>A szerver és az összes adat a tiéd — mindig is az volt. Ha úgy döntesz, hogy nem kéred tovább a szolgáltatást, a rendszer tovább működik. Egyszerűen nem kapod a frissítéseket, a monitoring-ot, és a támogatást.</p>",
"<p>A szerver és az összes adat a tiéd — mindig is az volt. Ha úgy döntesz, hogy nem kéred tovább a szolgáltatást, a doboz az otthoni hálózaton tovább működik, de nem kapod a frissítéseket, a felügyeletet és a támogatást. A távoli elérés és a távoli mentés a szolgáltatás része: hogy mi lesz velük, azt a felmondáskor egyeztetjük.</p>"),
("<p>A szervered és az adataid a tiéd. Az összes alkalmazás nyílt forráskódú, ami azt jelenti, hogy bárki más is üzemeltetheti — nem függsz egyetlen szolgáltatótól sem.",
"<p>A szervered és az adataid a tiéd. Az alkalmazások szinte mind nyílt forráskódúak, ami azt jelenti, hogy bárki más is üzemeltetheti őket — nem függsz egyetlen szolgáltatótól sem."),
("Minden szoftver, amit telepítünk, <strong>100% ingyenes és nyílt forráskódú</strong> — nincs licencdíj, nincs előfizetés az alkalmazásokért.</p>",
"Az alkalmazások ingyenesen használhatók, és szinte mind <strong>nyílt forráskódú</strong> — nincs licencdíj az alkalmazásokért. (Néhánynak van fizetős extrája, például a Plex Pass; ez választható.)</p>"),
("<p>Ha offsite mentéshez titkosított felhő tárhelyet választasz, annak van havi költsége — de ez általában havi néhány száz forint, és vannak ingyenes alternatívák is (pl. „haver rendszer\").</p>",
"<p>A távoli mentés tárhelyének van havi költsége, ami a mentett adatmennyiségtől függ — ezt az ajánlatban előre leírjuk.</p>"),
("Az alkalmazásaid Docker konténerekben futnak egy elkülönített rendszerkörnyezetben, a Proxmox alapra telepítve. Így minden változtatás előtt pillanatképet készíthetünk, és az egész rendszered biztonságosan visszaállítható akár egy új gépre is.</p>",
"Az alkalmazásaid Docker konténerekben futnak egy elkülönített rendszerkörnyezetben, a Proxmox alapra telepítve. Így a teljes rendszerkörnyezet is menthető, és ebből visszaállítható.</p>"),
("<strong>Pillanatkép minden változtatás előtt</strong> — frissítés vagy beállítás előtt a rendszer „fényképet\" készít önmagáról, így bármi gond esetén pillanatok alatt visszaállunk az előző állapotra.</p>",
"<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.</p>"),
("<strong>Az egész rendszer menthető és visszaállítható</strong> — nem csak az adataid, hanem a teljes dobozod is mentésbe tehető, és szükség esetén egy új gépre költöztethető.</p>",
"<strong>Az egész rendszer menthető és visszaállítható</strong> — nem csak az adataid, hanem a teljes dobozod is mentésbe kerül.</p>"),
("<p>Igen, és ezt kifejezetten ajánljuk! A VPN (Virtual Private Network) titkosított alagutat hoz létre az eszközöd és az otthoni szervered között. Ez a legbiztonságosabb módja a távoli elérésnek — mintha a kanapédon ülnél, miközben egy kávézóból dolgozol.</p>\n <p>Modern VPN megoldásokat használunk, amelyek egyszerű mobil applikációval működnek — nem kell hozzá semmilyen technikai tudás.</p>",
"<p>Nem kell hozzá: a doboz alapból egy titkosított alagúton át, HTTPS-sel érhető el bárhonnan, külön alkalmazás nélkül.</p>\n <p>Háztartási VPN-elérést (amikor a telefonod vagy a laptopod úgy csatlakozik, mintha otthon lenne) ma nem állítunk be a dobozon. Ha erre van szükséged, kérdezz rá.</p>"),
]
R += [
("Mi ezzel szemben egy nyílt, Docker-alapú rendszert kínálunk, amelyre <strong>bármilyen</strong> nyílt forráskódú alkalmazás telepíthető — fotókezelőtől a média szerveren át a jelszókezelőig.</p>",
"Mi ezzel szemben egy nyílt, Docker-alapú rendszert kínálunk, amelyre a katalógus alkalmazásai pár kattintással telepíthetők — fotókezelőtől a média szerveren át a jelszókezelőig.</p>"),
("<p>Az adatok nem vesznek el áramkimaradás esetén — az adatbázisok és fájlrendszerek felkészültek erre. Ha a megbízhatóság kritikus,",
"<p>Áramszünet után a doboz magától helyreáll — ezt valódi áramszünettel is kipróbáltuk. Ha a megbízhatóság kritikus,"),
]
for old, new in R:
s = sub1(s, old, new)
def rebuild_faq_jsonld(page):
"""FAQPage JSON-LD = every visible question with its visible answer (text only, paragraphs joined)."""
items = re.findall(r'<button class="faq-question">\s*(.*?)\s*<svg class="faq-chevron".*?<div class="faq-answer-inner">(.*?)</div></div>', page, re.S)
ents = []
for q, a in items:
parts = re.findall(r"<(?:p|li)[^>]*>(.*?)</(?:p|li)>", a, re.S)
text = " ".join(re.sub(r"\s+", " ", html.unescape(re.sub(r"<[^>]+>", "", p))).strip() for p in parts)
ents.append({"@type": "Question", "name": html.unescape(q.strip()),
"acceptedAnswer": {"@type": "Answer", "text": text}})
body = json.dumps({"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": ents},
ensure_ascii=False, indent=2)
body = "\n".join(" " + l for l in body.split("\n"))
new, n = re.subn(r'<script type="application/ld\+json">.*?</script>',
lambda m: '<script type="application/ld+json">\n' + body + "\n </script>", page, count=1, flags=re.S)
assert n == 1
return new, len(ents)
s, nq = rebuild_faq_jsonld(s)
print("gyik: JSON-LD rebuilt from %d visible questions" % nq)
s = set_alternates(s, "/gyik", "/en/faq")
s = set_nav(s, "hu", "/gyik", "/en/faq")
write("gyik.html", s)
# ------------------------------------------------------------------ kapcsolat.html (no claim changed; nav + hreflang)
s = head_text("kapcsolat.html")
s = set_alternates(s, "/kapcsolat", "/en/contact")
s = set_nav(s, "hu", "/kapcsolat", "/en/contact")
write("kapcsolat.html", s)
# ------------------------------------------------------------------ letoltes.html: the R-559 header link gives way to the nav switch
s = head_text("letoltes.html")
s = sub1(s, '\n <p><a href="/en/download" lang="en" hreflang="en">English</a></p>', "")
s = set_alternates(s, "/letoltes", "/en/download")
s = set_nav(s, "hu", None, "/en/download")
write("letoltes.html", s)