fix: tariff server binding, VLESS links from API, zero traffic logic

This commit is contained in:
Capybara-z
2026-01-14 21:29:07 +03:00
parent 218a5b544d
commit 80dc53f272
6 changed files with 129 additions and 28 deletions
+6 -2
View File
@@ -39,10 +39,14 @@ async def _try_build_remna_vless(servers: list, email: str) -> tuple[str | None,
return None, None, None
sub_url = data.get("subscriptionUrl") or None
links = data.get("links") or []
best_vless = None
if sub_url and sub_url.lower().startswith("vless://"):
best_vless = sub_url
for link in links:
if isinstance(link, str) and link.lower().startswith("vless://"):
best_vless = link
logger.debug(f"[Remnawave] Found VLESS in links: {link[:60]}...")
break
happ_link = None
if happ_cryptolink_enabled and sub_url:
+17 -10
View File
@@ -6,7 +6,7 @@ from sqlalchemy import update
from sqlalchemy.ext.asyncio import AsyncSession
from config import PUBLIC_LINK, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE
from database import filter_cluster_by_subgroup, get_servers, get_tariff_by_id, store_key
from database import filter_cluster_by_subgroup, filter_cluster_by_tariff, get_servers, get_tariff_by_id, store_key
from database.models import User
from handlers.utils import ALLOWED_GROUP_CODES, check_server_key_limit
from hooks.processors import process_extract_cryptolink_from_result
@@ -96,17 +96,24 @@ async def create_key_on_cluster(
traffic_limit_bytes_value = int(traffic_limit_bytes or 0)
device_limit_value = int(hwid_limit or 0)
if subgroup_title:
subgroup_servers = await filter_cluster_by_subgroup(
if plan is not None:
filtered = await filter_cluster_by_tariff(
session, enabled_servers, plan, cluster_id
)
if filtered is not enabled_servers:
enabled_servers = filtered
elif subgroup_title:
enabled_servers = await filter_cluster_by_subgroup(
session, enabled_servers, subgroup_title, cluster_id, tariff_id=plan
)
elif subgroup_title:
enabled_servers = await filter_cluster_by_subgroup(
session, enabled_servers, subgroup_title, cluster_id, tariff_id=plan
)
if subgroup_servers:
enabled_servers = subgroup_servers
else:
logger.warning(
f"[Key Creation] В кластере {cluster_id} не найдено серверов для подгруппы '{subgroup_title}'. "
f"Использую весь кластер."
)
if not enabled_servers:
logger.warning(f"[Key Creation] Нет серверов после фильтрации по привязкам в кластере {cluster_id}")
return
special = None
if is_trial:
+30 -1
View File
@@ -8,6 +8,7 @@ from config import REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE
from database import (
delete_notification,
filter_cluster_by_subgroup,
filter_cluster_by_tariff,
get_key_details,
get_servers,
get_tariff_by_id,
@@ -15,6 +16,7 @@ from database import (
update_key_expiry,
update_key_link,
)
from handlers.utils import ALLOWED_GROUP_CODES
from hooks.processors import process_get_cryptolink_after_renewal
from logger import (
CLOGGER as logger,
@@ -281,7 +283,19 @@ async def renew_key_in_cluster(
if single_server:
cluster_scope = [single_server]
else:
if target_subgroup:
if plan is not None:
filtered = await filter_cluster_by_tariff(
session, cluster, plan, cluster_id
)
if filtered is not cluster:
cluster_scope = filtered
elif target_subgroup:
cluster_scope = await filter_cluster_by_subgroup(
session, cluster, target_subgroup, cluster_id, tariff_id=plan
)
else:
cluster_scope = cluster
elif target_subgroup:
target = await filter_cluster_by_subgroup(
session, cluster, target_subgroup, cluster_id, tariff_id=plan
)
@@ -289,6 +303,21 @@ async def renew_key_in_cluster(
else:
cluster_scope = cluster
if plan is not None:
tariff_for_filter = await get_tariff_by_id(session, plan)
if tariff_for_filter:
gc = (tariff_for_filter.get("group_code") or "").lower()
if gc in ALLOWED_GROUP_CODES:
bound_servers = [s for s in cluster_scope if gc in (s.get("special_groups") or [])]
if bound_servers:
cluster_scope = bound_servers
else:
logger.info(f"[Renewal] Нет серверов со спецгруппой '{gc}' в {cluster_id}")
if not cluster_scope:
logger.warning(f"[Renewal] Нет серверов после фильтрации в кластере {cluster_id}")
return False
remna_ok = await renew_on_remnawave(
cluster=cluster_scope,
client_id=client_id,
+66 -15
View File
@@ -6,7 +6,8 @@ from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from config import PUBLIC_LINK, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE
from database import filter_cluster_by_subgroup, get_servers, get_tariff_by_id, store_key
from database import filter_cluster_by_subgroup, filter_cluster_by_tariff, get_servers, get_tariff_by_id, store_key
from handlers.utils import ALLOWED_GROUP_CODES
from database.models import Key, Tariff
from handlers.tariffs.tariff_display import GB, get_effective_limits_for_key
from handlers.utils import get_least_loaded_cluster
@@ -50,14 +51,39 @@ async def update_key_on_cluster(
else:
raise ValueError(f"Кластер или сервер с ID/именем {cluster_id} не найден.")
if subgroup_code:
filtered = await filter_cluster_by_subgroup(
if tariff_id is not None:
filtered = await filter_cluster_by_tariff(
session, cluster, tariff_id, cluster_id
)
if filtered is not cluster:
cluster = filtered
elif subgroup_code:
cluster = await filter_cluster_by_subgroup(
session, cluster, subgroup_code, cluster_id, tariff_id=tariff_id
)
elif subgroup_code:
cluster = await filter_cluster_by_subgroup(
session, cluster, subgroup_code, cluster_id, tariff_id=tariff_id
)
if not filtered:
logger.warning(f"[Update] Нет серверов для подгруппы {subgroup_code} в кластере {cluster_id}.")
return client_id, remnawave_link
cluster = filtered
if not cluster:
logger.warning(f"[Update] Нет серверов после фильтрации по привязкам в кластере {cluster_id}")
return client_id, remnawave_link
if tariff_id is not None:
tariff = await get_tariff_by_id(session, tariff_id)
if tariff:
gc = (tariff.get("group_code") or "").lower()
if gc in ALLOWED_GROUP_CODES:
bound_servers = [s for s in cluster if gc in (s.get("special_groups") or [])]
if bound_servers:
cluster = bound_servers
else:
logger.info(f"[Update] Нет серверов со спецгруппой '{gc}' в {cluster_id}")
if not cluster:
logger.warning(f"[Update] Нет серверов после фильтрации по спецгруппам в кластере {cluster_id}")
return client_id, remnawave_link
expire_iso = datetime.utcfromtimestamp(expiry_time / 1000).replace(tzinfo=timezone.utc).isoformat()
@@ -240,16 +266,41 @@ async def update_subscription(
else:
cluster_servers = []
if subgroup_code:
prefiltered = await filter_cluster_by_subgroup(
if tariff_id is not None:
filtered = await filter_cluster_by_tariff(
session, cluster_servers, tariff_id, new_cluster_id
)
if filtered is not cluster_servers:
cluster_servers = filtered
elif subgroup_code:
cluster_servers = await filter_cluster_by_subgroup(
session, cluster_servers, subgroup_code, new_cluster_id, tariff_id=tariff_id
)
elif subgroup_code:
cluster_servers = await filter_cluster_by_subgroup(
session, cluster_servers, subgroup_code, new_cluster_id, tariff_id=tariff_id
)
if not prefiltered:
logger.warning(
f"[Update] Пересоздание пропущено: нет серверов под подгруппу {subgroup_code} в {new_cluster_id}."
)
return
cluster_servers = prefiltered
if not cluster_servers:
logger.warning(
f"[Update] Пересоздание пропущено: нет серверов после фильтрации в {new_cluster_id}."
)
return
if tariff:
gc = (getattr(tariff, "group_code", None) or "").lower()
if gc in ALLOWED_GROUP_CODES:
bound_servers = [s for s in cluster_servers if gc in (s.get("special_groups") or [])]
if bound_servers:
cluster_servers = bound_servers
else:
logger.info(f"[Update] Нет серверов со спецгруппой '{gc}' в {new_cluster_id}")
if not cluster_servers:
logger.warning(
f"[Update] Пересоздание пропущено: нет серверов после фильтрации по спецгруппам в {new_cluster_id}."
)
return
traffic_limit_gb = None
device_limit = 0
@@ -137,6 +137,12 @@ async def notify_users_no_traffic(bot: Bot, session: AsyncSession, current_time:
logger.info("INACTIVE_TRAFFIC_ENABLED <= 0, уведомления о нулевом трафике отключены.")
return
trial_tariffs = await get_tariffs(session, group_code="trial")
trial_tariff_ids = {t["id"] for t in trial_tariffs} if trial_tariffs else set()
if not trial_tariff_ids:
return
remnawave_webapp_enabled = bool(MODES_CONFIG.get("REMNAWAVE_WEBAPP_ENABLED", REMNAWAVE_WEBAPP))
messages = []
@@ -149,6 +155,10 @@ async def notify_users_no_traffic(bot: Bot, session: AsyncSession, current_time:
client_id = key.client_id
expiry_time = key.expiry_time
notified = key.notified
tariff_id = key.tariff_id
if tariff_id not in trial_tariff_ids:
continue
if created_at is None or notified:
continue
Binary file not shown.