# -*- coding: utf-8 -*- """Offbox-rename gate (v0.123.0) — the Tier-3 feature is branded "Távoli mentés" everywhere customer-facing: the productized target is the Storage Box and the tier concept is "offsite", so "NAS-mentés"-style branding must not reappear in the offbox feature's customer strings. Python, not grep: Hungarian multibyte (the Windows-grep false-negative rule). Scope: ONLY the offbox feature's files — discovered by pattern since R-425, see scoped_files(). The "Hálózati tárhely" NAS network-storage feature is a DIFFERENT feature and keeps its device-truthful NAS wording (its files are not scanned). Allowed by construction (no banned token): the intro's "saját NAS vagy Felhom offsite tárhely" and the manual-target form's "NAS vagy SFTP-kiszolgáló" mentions, comments, code identifiers/routes. Run from controller/: python scripts/offbox_rename_gate.py """ import glob, io, json, os, re, sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import i18n_bundle # noqa: E402 # R-425 — THE SCOPE IS DISCOVERED, NOT LISTED. The gate used to scan a fixed three-entry FILES list, # correct when written, and narrower every time the feature grew a file: measured 2026-09-01, a # `NAS-mentés` in a new `backups_offbox_extra.html` passed. And since localisation the customer copy of # the listed template lives in the i18n bundle, which no entry named — so the gate had become largely # hollow, not only narrow. The scope is now, by pattern: # * every backup-surface template (`templates/**/backups*.html`, `recovery.html`), judged AS IT # RENDERS in Hungarian (bundle markers expanded), so copy that moved into hu.json is still seen; # * every off-site Go file (`internal/web/offbox*.go`, `internal/backup/offbox*.go`, not tests); # * every hu.json value whose KEY one of those Go files names (flash/note/err keys travel by key). # A new file matching the patterns is scanned the day it is added. Decoys: test_gate_decoys.py. _HERE = os.path.dirname(os.path.abspath(__file__)) _CTRL = os.path.dirname(_HERE) TEMPLATE_GLOBS = ["internal/web/templates/**/backups*.html", "internal/web/templates/**/recovery.html"] GO_GLOBS = ["internal/web/offbox*.go", "internal/backup/offbox*.go"] TEMPLATE_COMMENT = re.compile(r"\{\{/\*.*?\*/\}\}", re.S) KEY_LIT = re.compile(r'"([a-z][a-z0-9_]*(?:\.[a-z0-9_\-]+)+)"') def scoped_files(): out = [] for pats in (TEMPLATE_GLOBS, GO_GLOBS): for pat in pats: for f in glob.glob(os.path.join(_CTRL, pat), recursive=True): if not f.endswith("_test.go"): out.append(f) return sorted(set(out)) BANNED = [ "NAS-mentés", "NAS mentési", "NAS-visszaállítás", "a NAS-ra", "a NAS-ról", "NAS címe", "a NAS-on", "NAS ismert-host", ] def is_comment(line): s = line.strip() return s.startswith("//") or s.startswith("