From 6ade34970c0456a3d2e156d18cc7e58bddbf0f7c Mon Sep 17 00:00:00 2001 From: onysd Date: Tue, 4 Aug 2026 02:03:59 +0300 Subject: [PATCH] fix --- .env.example | 49 ++++++++++++++++------------ tui-panel/server-panel.py | 67 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 21 deletions(-) diff --git a/.env.example b/.env.example index 4451e87d..4c2b61e9 100644 --- a/.env.example +++ b/.env.example @@ -221,6 +221,24 @@ TELESRV_BUSINESS_AI_PROVIDER=echo # Master switch for in-app message/chat translation. TELESRV_TRANSLATION_ENABLED=true +## Moderation, Verification & Rating -- Toggles for the report-review queue, official/third-party verification, and the account-rating score. + +# Reports and moderation-case review are always on; this only gates the +# official platform-checkmark flow applicants file through @verifybot. Rate +# limits and cooldowns for it live in the Advanced section below. +TELESRV_VERIFICATION_ENABLED=true +# Plain user accounts as verification subjects. Off by default: the official +# process verifies a public presence (bot, public channel, public supergroup). +TELESRV_VERIFICATION_ALLOW_USER_TARGETS=false +# Third-party bot verification marks (an icon + description shown before a +# peer's name) -- a separate mechanism from the checkmark above, not the +# platform badge. Its tuning lives in the Advanced section below. +TELESRV_BOT_VERIFICATION_ENABLED=true +# Local composite account-rating score (stars/activity/moderation-based). +# Shown to every viewer via userFull.stars_rating, not admin-only. Scoring +# weights and recompute timing live in the Advanced section below. +TELESRV_RATING_ENABLED=true + # ============================================================================== # Advanced / internal tuning @@ -377,11 +395,10 @@ TELESRV_STARGIFT_RESELL_DELAY=0s TELESRV_STARGIFT_CRAFT_DELAY=0s TELESRV_STARGIFT_CRAFT_CHANCE_PERMILLE=250 -# Local admin-only composite account rating. It is not projected into Telegram's -# userFull.stars_rating fields. Disabling it refuses local rating writes. -TELESRV_RATING_ENABLED=true +# Tuning for the account-rating score; the on/off switch +# (TELESRV_RATING_ENABLED) is in the Moderation/Verification/Rating section above. # A local rating increase is parked for this long before it becomes the visible -# admin level; a decrease always applies immediately. 0 applies every change at once. +# level; a decrease always applies immediately. 0 applies every change at once. TELESRV_RATING_PENDING_DELAY=24h # Background recompute worker: the rating derives from signals owned by other # subsystems, so freshness is a worker property rather than a write-path one. @@ -410,15 +427,10 @@ TELESRV_RATING_ACTIVITY_CAP=5000 # segment. No external marketplace is contacted. TELESRV_COLLECTIBLE_USERNAME_URL_TEMPLATE= -# Official platform verification: applications filed through the built-in -# @verifybot and decided in the admin panel. An approval flips the platform -# verified flag on the target peer and nothing else; it is not the third-party -# bot verification icon. Disabling refuses every verification use case, while -# peers already carrying the badge keep it. -TELESRV_VERIFICATION_ENABLED=true -# Plain user accounts as verification subjects. Off by default: the official -# process verifies a public presence (bot, public channel, public supergroup). -TELESRV_VERIFICATION_ALLOW_USER_TARGETS=false +# Tuning for official platform verification (applications filed through +# @verifybot); the on/off switch (TELESRV_VERIFICATION_ENABLED) and the +# user-target toggle (TELESRV_VERIFICATION_ALLOW_USER_TARGETS) are in the +# Moderation/Verification/Rating section above. # How long an applicant must wait before filing the same target again after a # rejection, measured from the decision so a slow review never shortens it. # 0 disables the cooldown; must be 0..8760h. @@ -440,14 +452,9 @@ TELESRV_VERIFICATION_NOTIFY_BATCH=50 # is 50. TELESRV_VERIFICATION_MAX_ACTIVE_PER_USER=3 -# Third-party bot verification (core.telegram.org/api/bots/verification): a -# verifier bot marks peers with its OWN icon and description, which clients render -# before the name. This is NOT the platform checkmark above: the operator grants -# verifier status to a bot, and the two mechanisms never read each other's state. -# Disabling refuses every third-party mutation (grants, revocations, applications, -# icon catalogue edits) while the marks already granted keep rendering -- blanking -# one verifier's badges is what its per-verifier kill switch is for. -TELESRV_BOT_VERIFICATION_ENABLED=true +# Tuning for third-party bot verification; the on/off switch +# (TELESRV_BOT_VERIFICATION_ENABLED) is in the Moderation/Verification/Rating +# section above. # Peers one verifier bot may mark. Verifier status is granted per deployment rather # than earned per peer, so an unbounded verifier would be an unbounded badge # printer. 0 disables the service bound and leaves only the storage bound, which is diff --git a/tui-panel/server-panel.py b/tui-panel/server-panel.py index 1cf44abb..115575eb 100644 --- a/tui-panel/server-panel.py +++ b/tui-panel/server-panel.py @@ -486,6 +486,55 @@ def save_env(values: dict[str, str]) -> None: ENV_FILE.write_text("\n".join(out_lines) + "\n", encoding="utf-8") +def missing_env_fields() -> list[tuple[str, str]]: + """(key, default_value) pairs for every *active* (uncommented) field + .env.example defines that .env doesn't have at all -- e.g. after a git + pull brought in new TELESRV_* settings for features that didn't exist + when this install's .env was first created. + + Deliberately scans the whole file, not just parse_env_template()'s + panel-visible groups, so an Advanced-section field missing from .env + gets caught too. Deliberately skips template-commented (disabled by + default) fields -- those are meant to stay absent/off unless a self-hoster + opts in, and the server already falls back to the same default shown in + the comment when the key isn't set at all, so there's nothing to fix. + A key already present in .env is never touched, even if blank -- clearing + a field on purpose must never get silently reintroduced.""" + if not ENV_FILE.exists() or not ENV_EXAMPLE_FILE.exists(): + return [] + existing_keys: set[str] = set() + for line in ENV_FILE.read_text(encoding="utf-8", errors="replace").splitlines(): + m = _ACTIVE_FIELD_RE.match(line.strip()) + if m: + existing_keys.add(m.group(1)) + missing: list[tuple[str, str]] = [] + seen: set[str] = set() + for line in ENV_EXAMPLE_FILE.read_text(encoding="utf-8", errors="replace").splitlines(): + m = _ACTIVE_FIELD_RE.match(line.strip()) + if m and m.group(1) not in existing_keys and m.group(1) not in seen: + seen.add(m.group(1)) + missing.append((m.group(1), m.group(2))) + return missing + + +def append_missing_env_fields(missing: list[tuple[str, str]]) -> None: + """Appends (key, default_value) pairs to .env in one clearly-labeled, + timestamped block, so a self-hoster immediately sees what was added and + why. Purely additive -- never rewrites, reorders, or removes a single + existing line, unlike save_env()'s full rewrite-from-template.""" + if not missing: + return + block = [ + "", + f"# --- Added automatically by server-panel.py on " + f"{time.strftime('%Y-%m-%d %H:%M')}: new fields found in .env.example " + f"that this .env didn't have yet ---", + ] + block += [f"{key}={value}" for key, value in missing] + with ENV_FILE.open("a", encoding="utf-8") as f: + f.write("\n".join(block) + "\n") + + def admin_ui_info() -> tuple[str, str | None] | None: """Returns (url, password) for the admin UI, or None if it isn't configured at all. password is None when TELESRV_ADMIN_UI_PASSWORD is @@ -1155,6 +1204,7 @@ class MainScreen(Screen): def on_mount(self) -> None: self.query_one("#services-table", DataTable).add_columns("Service", "Type", "Status") + self._sync_missing_env_fields() self.refresh_status() self.refresh_stats() self.refresh_config_widgets() @@ -1164,6 +1214,23 @@ class MainScreen(Screen): if self._auto_start: self.action_start() + def _sync_missing_env_fields(self) -> None: + """Catches .env falling behind .env.example -- e.g. a git pull that + added new TELESRV_* settings for a feature this install predates. + Runs once per panel launch, before Start, so a missing field never + surprises the server at startup instead. A no-op on a fresh install + (Setup already writes every field at once) and a no-op once .env has + caught up.""" + missing = missing_env_fields() + if not missing: + return + append_missing_env_fields(missing) + keys = ", ".join(key for key, _ in missing) + self.notify( + f"Added {len(missing)} new field(s) to .env from .env.example: {keys}", + timeout=10, + ) + def refresh_status(self) -> None: status = MANAGER.status() table = self.query_one("#services-table", DataTable)