chore: fix formatting checks

This commit is contained in:
3252a8
2026-05-24 18:51:37 +03:00
parent 6f4074e8d6
commit 2b3078fcce
20 changed files with 41 additions and 59 deletions
@@ -79,9 +79,10 @@ async def admin_settings_patch_route(request: web.Request) -> web.Response:
return _error(400, "invalid_updates") return _error(400, "invalid_updates")
if not isinstance(deletes, list): if not isinstance(deletes, list):
return _error(400, "invalid_deletes") return _error(400, "invalid_deletes")
if "SUBSCRIPTION_PAGE_CONFIG_JSON" in updates and not str( if (
updates.get("SUBSCRIPTION_PAGE_CONFIG_JSON") or "" "SUBSCRIPTION_PAGE_CONFIG_JSON" in updates
).strip(): and not str(updates.get("SUBSCRIPTION_PAGE_CONFIG_JSON") or "").strip()
):
updates = dict(updates) updates = dict(updates)
updates.pop("SUBSCRIPTION_PAGE_CONFIG_JSON", None) updates.pop("SUBSCRIPTION_PAGE_CONFIG_JSON", None)
deletes = [*deletes, "SUBSCRIPTION_PAGE_CONFIG_JSON"] deletes = [*deletes, "SUBSCRIPTION_PAGE_CONFIG_JSON"]
+3 -5
View File
@@ -66,11 +66,9 @@ def _bump_theme_asset_versions(
previous_theme = previous_by_key.get(key) previous_theme = previous_by_key.get(key)
previous_version = int(getattr(previous_theme, "assets_version", 0) or 0) previous_version = int(getattr(previous_theme, "assets_version", 0) or 0)
current_version = int(theme.get("assets_version") or 1) current_version = int(theme.get("assets_version") or 1)
theme_changed = ( theme_changed = previous_theme is None or _theme_payload_for_version_compare(
previous_theme is None theme
or _theme_payload_for_version_compare(theme) ) != _theme_payload_for_version_compare(previous_theme)
!= _theme_payload_for_version_compare(previous_theme)
)
if theme_changed or (default_changed and key == config.default_theme): if theme_changed or (default_changed and key == config.default_theme):
theme["assets_version"] = max(previous_version + 1, current_version, 1) theme["assets_version"] = max(previous_version + 1, current_version, 1)
elif previous_version > current_version: elif previous_version > current_version:
@@ -211,7 +211,7 @@ SETTINGS_MANIFEST: List[SettingField] = [
"Optional admin JSON override. It is applied only when the JSON override " "Optional admin JSON override. It is applied only when the JSON override "
"switch is enabled." "switch is enabled."
), ),
placeholder="{\n \"version\": \"1\"\n}", placeholder='{\n "version": "1"\n}',
), ),
# ─── Subscription periods & pricing ──────────────────────────── # ─── Subscription periods & pricing ────────────────────────────
SettingField("MONTH_1_ENABLED", "bool", "pricing", "Тариф 1 месяц"), SettingField("MONTH_1_ENABLED", "bool", "pricing", "Тариф 1 месяц"),
+1 -3
View File
@@ -95,9 +95,7 @@ async def theme_css_asset_route(request: web.Request) -> web.Response:
raise web.HTTPNotFound(text="theme_css_not_found") from None raise web.HTTPNotFound(text="theme_css_not_found") from None
query = getattr(request, "query", {}) or {} query = getattr(request, "query", {}) or {}
cache_control = ( cache_control = "public, max-age=31536000, immutable" if query.get("v") else "no-cache"
"public, max-age=31536000, immutable" if query.get("v") else "no-cache"
)
try: try:
stat = path.stat() stat = path.stat()
if stat.st_size > WEBAPP_THEME_CSS_MAX_BYTES: if stat.st_size > WEBAPP_THEME_CSS_MAX_BYTES:
+2 -6
View File
@@ -66,9 +66,7 @@ def invalidate_local_webapp_user_payload(
user_id: int, user_id: int,
) -> None: ) -> None:
key = str(int(user_id)) key = str(int(user_id))
for (settings_id, cache_namespace, _ttl), cache in tuple( for (settings_id, cache_namespace, _ttl), cache in tuple(_WEBAPP_USER_PAYLOAD_CACHES.items()):
_WEBAPP_USER_PAYLOAD_CACHES.items()
):
if settings_id == id(settings) and cache_namespace == namespace: if settings_id == id(settings) and cache_namespace == namespace:
cache.invalidate(key) cache.invalidate(key)
@@ -86,9 +84,7 @@ def invalidate_all_local_webapp_user_payloads(
else: else:
namespaces = None namespaces = None
for (settings_id, cache_namespace, _ttl), cache in tuple( for (settings_id, cache_namespace, _ttl), cache in tuple(_WEBAPP_USER_PAYLOAD_CACHES.items()):
_WEBAPP_USER_PAYLOAD_CACHES.items()
):
if settings_id != id(settings): if settings_id != id(settings):
continue continue
if namespaces is not None and cache_namespace not in namespaces: if namespaces is not None and cache_namespace not in namespaces:
+1 -2
View File
@@ -86,8 +86,7 @@ async def _load_devices_payload(
"max_devices": max_devices, "max_devices": max_devices,
"max_devices_label": _format_devices_limit(max_devices), "max_devices_label": _format_devices_limit(max_devices),
"devices": [ "devices": [
_serialize_device(device, index) _serialize_device(device, index) for index, device in enumerate(devices, start=1)
for index, device in enumerate(devices, start=1)
], ],
}, },
} }
+1 -3
View File
@@ -258,9 +258,7 @@ def _public_install_url(request: web.Request, share_token: str) -> str:
base = configured_base.rstrip("/") base = configured_base.rstrip("/")
else: else:
host = ( host = (
request.headers.get("X-Forwarded-Host") request.headers.get("X-Forwarded-Host") or request.headers.get("Host") or request.host
or request.headers.get("Host")
or request.host
) )
proto = request.headers.get("X-Forwarded-Proto") or request.scheme or "https" proto = request.headers.get("X-Forwarded-Proto") or request.scheme or "https"
base = f"{proto}://{host}" base = f"{proto}://{host}"
+1 -3
View File
@@ -340,9 +340,7 @@ def _build_install_share_link(
base = configured_base.rstrip("/") base = configured_base.rstrip("/")
else: else:
host = ( host = (
request.headers.get("X-Forwarded-Host") request.headers.get("X-Forwarded-Host") or request.headers.get("Host") or request.host
or request.headers.get("Host")
or request.host
) )
proto = request.headers.get("X-Forwarded-Proto") or request.scheme or "https" proto = request.headers.get("X-Forwarded-Proto") or request.scheme or "https"
base = f"{proto}://{host}" base = f"{proto}://{host}"
+1 -3
View File
@@ -952,9 +952,7 @@ async def _perform_sync_impl(
duplicate_panel_user=panel_user_dict, duplicate_panel_user=panel_user_dict,
settings=settings, settings=settings,
subscriptions_by_panel_uuid=subscriptions_by_panel_uuid, subscriptions_by_panel_uuid=subscriptions_by_panel_uuid,
active_subscriptions_by_user_panel=( active_subscriptions_by_user_panel=(active_subscriptions_by_user_panel),
active_subscriptions_by_user_panel
),
) )
subscriptions_created += int(merge_result["subscriptions_created"]) subscriptions_created += int(merge_result["subscriptions_created"])
subscriptions_updated += int(merge_result["subscriptions_updated"]) subscriptions_updated += int(merge_result["subscriptions_updated"])
+3
View File
@@ -156,6 +156,7 @@ async def on_startup_configured(dispatcher: Dispatcher):
raise SystemExit("WEBHOOK_BASE_URL is required. Polling mode is disabled.") raise SystemExit("WEBHOOK_BASE_URL is required. Polling mode is disabled.")
if settings.SUBSCRIPTION_MINI_APP_URL: if settings.SUBSCRIPTION_MINI_APP_URL:
async def _configure_mini_app_menu() -> None: async def _configure_mini_app_menu() -> None:
menu_text = i18n_instance.gettext( menu_text = i18n_instance.gettext(
settings.DEFAULT_LANGUAGE, settings.DEFAULT_LANGUAGE,
@@ -169,6 +170,7 @@ async def on_startup_configured(dispatcher: Dispatcher):
) )
await bot.set_chat_menu_button(menu_button=MenuButtonDefault()) await bot.set_chat_menu_button(menu_button=MenuButtonDefault())
logging.info("STARTUP: Mini app domain registered and default menu button restored.") logging.info("STARTUP: Mini app domain registered and default menu button restored.")
await _run_telegram_startup_step( await _run_telegram_startup_step(
"registering mini app menu button", "registering mini app menu button",
_configure_mini_app_menu, _configure_mini_app_menu,
@@ -186,6 +188,7 @@ async def on_startup_configured(dispatcher: Dispatcher):
) )
await bot.set_my_commands(bot_commands) await bot.set_my_commands(bot_commands)
logging.info("STARTUP: bot command descriptions set.") logging.info("STARTUP: bot command descriptions set.")
await _run_telegram_startup_step( await _run_telegram_startup_step(
"setting bot commands", "setting bot commands",
_configure_bot_commands, _configure_bot_commands,
+2 -5
View File
@@ -288,9 +288,7 @@ class WataService(HttpClientMixin):
return web.Response(status=400, text="bad_request") return web.Response(status=400, text="bad_request")
transaction_id = str(payload.get("transactionId") or "").strip() transaction_id = str(payload.get("transactionId") or "").strip()
payment_link_id = str( payment_link_id = str(payload.get("paymentLinkId") or payload.get("id") or "").strip()
payload.get("paymentLinkId") or payload.get("id") or ""
).strip()
status = str(payload.get("transactionStatus") or "").strip().lower() status = str(payload.get("transactionStatus") or "").strip().lower()
order_id_raw = payload.get("orderId") order_id_raw = payload.get("orderId")
amount_raw = payload.get("amount") amount_raw = payload.get("amount")
@@ -339,8 +337,7 @@ class WataService(HttpClientMixin):
except Exception: except Exception:
await session.rollback() await session.rollback()
logging.exception( logging.exception(
"Wata webhook: failed to persist transaction id %s " "Wata webhook: failed to persist transaction id %s for payment %s.",
"for payment %s.",
transaction_id, transaction_id,
payment.payment_id, payment.payment_id,
) )
+1 -3
View File
@@ -452,9 +452,7 @@ def _resolve_yookassa_activation_amounts(
else: else:
months_for_activation = int(traffic_amount_gb) months_for_activation = int(traffic_amount_gb)
traffic_gb_for_activation = ( traffic_gb_for_activation = traffic_amount_gb if is_traffic_sale_base(sale_mode_base) else None
traffic_amount_gb if is_traffic_sale_base(sale_mode_base) else None
)
return ( return (
subscription_months, subscription_months,
traffic_amount_gb, traffic_amount_gb,
+1 -2
View File
@@ -321,8 +321,7 @@ class TariffTrafficWorker:
sub.skip_notifications = True sub.skip_notifications = True
sub.status_from_panel = "PANEL_USER_NOT_FOUND" sub.status_from_panel = "PANEL_USER_NOT_FOUND"
logging.warning( logging.warning(
"TariffTrafficWorker: deactivated subscription %s because panel user %s " "TariffTrafficWorker: deactivated subscription %s because panel user %s is missing",
"is missing",
sub.subscription_id, sub.subscription_id,
current_uuid, current_uuid,
) )
+6 -3
View File
@@ -98,9 +98,12 @@ async def ensure_install_share_token(
await session.flush() await session.flush()
if result.rowcount: if result.rowcount:
await session.refresh(subscription) await session.refresh(subscription)
return normalize_install_share_token( return (
getattr(subscription, "install_share_token", None) normalize_install_share_token(
) or token getattr(subscription, "install_share_token", None)
)
or token
)
await session.refresh(subscription) await session.refresh(subscription)
raw_existing = str(getattr(subscription, "install_share_token", "") or "").strip() raw_existing = str(getattr(subscription, "install_share_token", "") or "").strip()
+1 -3
View File
@@ -53,9 +53,7 @@ class AdminWebappRuntimeTests(unittest.IsolatedAsyncioTestCase):
"invalidate_all_webapp_user_payloads", "invalidate_all_webapp_user_payloads",
AsyncMock(), AsyncMock(),
), ),
patch( patch("bot.app.web.admin_api_impl.themes.prune_unused_appearance_assets") as prune_mock,
"bot.app.web.admin_api_impl.themes.prune_unused_appearance_assets"
) as prune_mock,
): ):
await webapp_runtime.refresh_webapp_runtime_after_settings_change( await webapp_runtime.refresh_webapp_runtime_after_settings_change(
request, request,
+1 -2
View File
@@ -35,8 +35,7 @@ def test_telegram_startup_network_error_retries_until_success_without_traceback(
assert calls == ["try", "try", "try"] assert calls == ["try", "try", "try"]
assert "Telegram network error while registering mini app menu button" in caplog.text assert "Telegram network error while registering mini app menu button" in caplog.text
assert ( assert (
"Telegram step succeeded while registering mini app menu button on attempt 3" "Telegram step succeeded while registering mini app menu button on attempt 3" in caplog.text
in caplog.text
) )
assert "api.telegram.org" in caplog.text assert "api.telegram.org" in caplog.text
assert "Temporary failure in name resolution" in caplog.text assert "Temporary failure in name resolution" in caplog.text
+1 -3
View File
@@ -761,9 +761,7 @@ class AdminSettingsSecurityTests(unittest.IsolatedAsyncioTestCase):
payload = json.loads(response.text) payload = json.loads(response.text)
fields = { fields = {
field["key"]: field field["key"]: field for section in payload["sections"] for field in section["fields"]
for section in payload["sections"]
for field in section["fields"]
} }
self.assertEqual( self.assertEqual(
+4 -6
View File
@@ -163,9 +163,7 @@ def test_unsafe_svg_is_rejected():
def test_unsafe_external_link_is_rejected(): def test_unsafe_external_link_is_rejected():
config = _config() config = _config()
config["platforms"]["ios"]["apps"][0]["blocks"][0]["buttons"][0][ config["platforms"]["ios"]["apps"][0]["blocks"][0]["buttons"][0]["link"] = "javascript:alert(1)"
"link"
] = "javascript:alert(1)"
with pytest.raises(SubscriptionGuidesConfigError, match="unsafe URL scheme"): with pytest.raises(SubscriptionGuidesConfigError, match="unsafe URL scheme"):
validate_subscription_guides_config(config) validate_subscription_guides_config(config)
@@ -173,9 +171,9 @@ def test_unsafe_external_link_is_rejected():
def test_external_custom_scheme_is_allowed_for_multiapp_compatibility(): def test_external_custom_scheme_is_allowed_for_multiapp_compatibility():
config = _config() config = _config()
config["platforms"]["ios"]["apps"][0]["blocks"][0]["buttons"][0][ config["platforms"]["ios"]["apps"][0]["blocks"][0]["buttons"][0]["link"] = (
"link" "streisand://import/demo"
] = "streisand://import/demo" )
validated = validate_subscription_guides_config(config) validated = validate_subscription_guides_config(config)
+2 -2
View File
@@ -68,7 +68,7 @@ class SubscriptionGuidesRouteTests(unittest.IsolatedAsyncioTestCase):
"uuid": default_uuid, "uuid": default_uuid,
"config": json.loads(default_subscription_guides_config_text()), "config": json.loads(default_subscription_guides_config_text()),
} }
) ),
) )
request = self._request(self._settings(), panel_service) request = self._request(self._settings(), panel_service)
@@ -113,7 +113,7 @@ class SubscriptionGuidesRouteTests(unittest.IsolatedAsyncioTestCase):
"uuid": default_uuid, "uuid": default_uuid,
"config": json.loads(default_subscription_guides_config_text()), "config": json.loads(default_subscription_guides_config_text()),
} }
) ),
) )
request = self._request( request = self._request(
self._settings(SUBSCRIPTION_PAGE_CONFIG_JSON=json.dumps(admin_config)), self._settings(SUBSCRIPTION_PAGE_CONFIG_JSON=json.dumps(admin_config)),
+4 -1
View File
@@ -396,7 +396,10 @@ class WebappThemesConfigTests(unittest.TestCase):
self.assertIn("New webapp surfaces: support, purchase info, password login", css) self.assertIn("New webapp surfaces: support, purchase info, password login", css)
self.assertIn("Install guide theme surfaces", css) self.assertIn("Install guide theme surfaces", css)
self.assertIn( self.assertIn(
".theme-key-windows95 .support-list-card {\n grid-template-rows: auto auto minmax(0, 1fr);", (
".theme-key-windows95 .support-list-card {\n"
" grid-template-rows: auto auto minmax(0, 1fr);"
),
css, css,
) )
self.assertIn(".theme-key-windows95 .traffic-top strong", css) self.assertIn(".theme-key-windows95 .traffic-top strong", css)