Use static terminal update announcements
This commit is contained in:
@@ -8,7 +8,6 @@ from fastapi.responses import PlainTextResponse
|
||||
from web.services.dashboard_init_api import build_dashboard_init_payload
|
||||
from web.services.system_api import (
|
||||
get_health_payload,
|
||||
get_public_update_announcement,
|
||||
get_prometheus_metrics_response,
|
||||
get_system_cache_status,
|
||||
get_system_status_payload,
|
||||
@@ -28,11 +27,6 @@ async def system_status():
|
||||
return await get_system_status_payload()
|
||||
|
||||
|
||||
@router.get("/api/system/update-announcement")
|
||||
async def system_update_announcement():
|
||||
return get_public_update_announcement()
|
||||
|
||||
|
||||
@router.get("/api/system/cache-status")
|
||||
async def system_cache_status(request: Request, cities: Optional[str] = None):
|
||||
return get_system_cache_status(request, cities=cities)
|
||||
|
||||
+1
-64
@@ -1206,24 +1206,6 @@ _EDITABLE_CONFIG_KEYS: dict[str, str] = {
|
||||
"POLYWEATHER_PAYMENT_POINTS_PER_USDC": "积分兑换汇率 (积分/USDC)",
|
||||
"POLYWEATHER_PAYMENT_POINTS_MAX_DISCOUNT_USDC": "积分最高抵扣金额 (USDC)",
|
||||
"POLYWEATHER_PAYMENT_DIRECT_RECEIVER_ADDRESS": "手动转账收款钱包地址",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_ENABLED": "终端顶部更新公告开关,true/false",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_ZH": "更新公告中文标题",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_ZH": "更新公告中文正文",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_EN": "Update announcement English title",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_EN": "Update announcement English body",
|
||||
}
|
||||
|
||||
_RUNTIME_CONFIG_KEYS = {
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_ENABLED",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_ZH",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_ZH",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_EN",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_EN",
|
||||
}
|
||||
|
||||
_MULTILINE_CONFIG_KEYS = {
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_ZH",
|
||||
"POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_EN",
|
||||
}
|
||||
|
||||
_SENSITIVE_CONFIG_KEYS: dict[str, dict[str, str]] = {
|
||||
@@ -1234,78 +1216,33 @@ _SENSITIVE_CONFIG_KEYS: dict[str, dict[str, str]] = {
|
||||
}
|
||||
|
||||
|
||||
def _runtime_config_payload(db: DBManager, key: str, description: str) -> dict[str, Any]:
|
||||
metadata = db.get_runtime_config_metadata(key)
|
||||
env_value = os.getenv(key)
|
||||
has_runtime_value = bool(metadata.get("configured"))
|
||||
return {
|
||||
"key": key,
|
||||
"value": str(metadata.get("value") if has_runtime_value else (env_value or "")),
|
||||
"description": description,
|
||||
"multiline": key in _MULTILINE_CONFIG_KEYS,
|
||||
"persistent": True,
|
||||
"updated_at": str(metadata.get("updated_at") or ""),
|
||||
"updated_by": str(metadata.get("updated_by") or ""),
|
||||
"source": "runtime_config" if has_runtime_value or env_value is None else "environment",
|
||||
}
|
||||
|
||||
|
||||
def get_ops_config(request: Request) -> dict[str, Any]:
|
||||
_require_ops(request)
|
||||
|
||||
db: DBManager | None = None
|
||||
configs: list[dict[str, Any]] = []
|
||||
for key, desc in _EDITABLE_CONFIG_KEYS.items():
|
||||
if key in _RUNTIME_CONFIG_KEYS:
|
||||
if db is None:
|
||||
db = DBManager()
|
||||
configs.append(_runtime_config_payload(db, key, desc))
|
||||
continue
|
||||
configs.append(
|
||||
{
|
||||
"key": key,
|
||||
"value": os.getenv(key) or "",
|
||||
"description": desc,
|
||||
"multiline": False,
|
||||
"persistent": False,
|
||||
"source": "environment",
|
||||
}
|
||||
)
|
||||
return {"configs": configs}
|
||||
|
||||
|
||||
def update_ops_config(request: Request, key: str, value: str) -> dict[str, Any]:
|
||||
admin = _require_ops(request) or {}
|
||||
_require_ops(request)
|
||||
|
||||
normalized_key = str(key or "").strip()
|
||||
if normalized_key not in _EDITABLE_CONFIG_KEYS:
|
||||
raise HTTPException(
|
||||
status_code=400, detail=f"config key '{normalized_key}' is not editable"
|
||||
)
|
||||
if normalized_key in _RUNTIME_CONFIG_KEYS:
|
||||
try:
|
||||
config = DBManager().set_runtime_config(
|
||||
normalized_key,
|
||||
str(value or ""),
|
||||
updated_by=str(admin.get("email") or ""),
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
return {
|
||||
**config,
|
||||
"description": _EDITABLE_CONFIG_KEYS[normalized_key],
|
||||
"multiline": normalized_key in _MULTILINE_CONFIG_KEYS,
|
||||
"persistent": True,
|
||||
"ok": True,
|
||||
}
|
||||
os.environ[normalized_key] = str(value)
|
||||
return {
|
||||
"key": normalized_key,
|
||||
"value": value,
|
||||
"description": _EDITABLE_CONFIG_KEYS[normalized_key],
|
||||
"multiline": False,
|
||||
"persistent": False,
|
||||
"source": "environment",
|
||||
"ok": True,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import time
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
@@ -11,66 +10,15 @@ from fastapi.concurrency import run_in_threadpool
|
||||
from fastapi.responses import PlainTextResponse
|
||||
from loguru import logger
|
||||
|
||||
from src.database.db_manager import DBManager
|
||||
from src.utils.metrics import export_prometheus_metrics
|
||||
from web.core import build_health_payload, build_system_status_payload
|
||||
import web.routes as legacy_routes
|
||||
|
||||
_ANNOUNCEMENT_ENABLED_KEY = "POLYWEATHER_UPDATE_ANNOUNCEMENT_ENABLED"
|
||||
_ANNOUNCEMENT_TEXT_KEYS = {
|
||||
"zh_title": "POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_ZH",
|
||||
"zh_body": "POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_ZH",
|
||||
"en_title": "POLYWEATHER_UPDATE_ANNOUNCEMENT_TITLE_EN",
|
||||
"en_body": "POLYWEATHER_UPDATE_ANNOUNCEMENT_BODY_EN",
|
||||
}
|
||||
|
||||
|
||||
def get_health_payload() -> Dict[str, Any]:
|
||||
return build_health_payload()
|
||||
|
||||
|
||||
def _runtime_or_env_value(db: DBManager, key: str) -> tuple[str, str]:
|
||||
metadata = db.get_runtime_config_metadata(key)
|
||||
if metadata.get("configured"):
|
||||
return str(metadata.get("value") or ""), str(metadata.get("updated_at") or "")
|
||||
return str(os.getenv(key) or ""), ""
|
||||
|
||||
|
||||
def _truthy_runtime_flag(value: str) -> bool:
|
||||
return str(value or "").strip().lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def get_public_update_announcement() -> Dict[str, Any]:
|
||||
db = DBManager()
|
||||
enabled_value, enabled_updated_at = _runtime_or_env_value(db, _ANNOUNCEMENT_ENABLED_KEY)
|
||||
values: dict[str, str] = {}
|
||||
updated_at_candidates = [enabled_updated_at]
|
||||
for name, key in _ANNOUNCEMENT_TEXT_KEYS.items():
|
||||
value, updated_at = _runtime_or_env_value(db, key)
|
||||
values[name] = value
|
||||
if updated_at:
|
||||
updated_at_candidates.append(updated_at)
|
||||
|
||||
has_content = any(
|
||||
values.get(name, "").strip()
|
||||
for name in ("zh_title", "zh_body", "en_title", "en_body")
|
||||
)
|
||||
enabled = _truthy_runtime_flag(enabled_value) and has_content
|
||||
updated_at = max((item for item in updated_at_candidates if item), default="")
|
||||
return {
|
||||
"enabled": enabled,
|
||||
"zh": {
|
||||
"title": values.get("zh_title", ""),
|
||||
"body": values.get("zh_body", ""),
|
||||
},
|
||||
"en": {
|
||||
"title": values.get("en_title", ""),
|
||||
"body": values.get("en_body", ""),
|
||||
},
|
||||
"updated_at": updated_at,
|
||||
}
|
||||
|
||||
|
||||
async def get_system_status_payload() -> Dict[str, Any]:
|
||||
payload = await run_in_threadpool(build_system_status_payload)
|
||||
payload["realtime"] = await run_in_threadpool(_realtime_status_payload)
|
||||
|
||||
Reference in New Issue
Block a user