RemnaWave-bot Update

This commit is contained in:
2026-05-06 15:41:56 +03:00
parent ce7a1f70b2
commit 2cc2f12a21
22 changed files with 3087 additions and 129 deletions

View File

@@ -13,6 +13,28 @@ class PaymentPlanSettings:
code: str
days: int
amount_rub: int
title: str = ""
description: str = ""
squad_groups: tuple[str, ...] = ()
PAYMENT_PRODUCT_PLAN_SPECS: dict[str, tuple[str, str, tuple[str, ...]]] = {
"vpn_white": (
"VPN + Белые списки",
"VPN и белые списки в одном тарифе",
("vpn", "white"),
),
"white": (
"Белые списки",
"Доступ только к белым спискам",
("white",),
),
"vpn": (
"VPN",
"Доступ только к VPN без белых списков",
("vpn",),
),
}
class Settings(BaseSettings):
@@ -78,6 +100,10 @@ class Settings(BaseSettings):
default="30:250,180:600,365:1000",
validation_alias="PAYMENT_PLANS",
)
payment_product_plans_raw: str = Field(
default="",
validation_alias="PAYMENT_PRODUCT_PLANS",
)
payment_transfer_text: str = Field(
default="Переведите оплату по указанным реквизитам и отправьте чек в бот.",
validation_alias="PAYMENT_TRANSFER_TEXT",
@@ -125,6 +151,14 @@ class Settings(BaseSettings):
default="",
validation_alias="PAYMENT_INTERNAL_SQUAD_UUIDS",
)
payment_vpn_squad_uuids_raw: str = Field(
default="",
validation_alias="PAYMENT_VPN_SQUAD_UUIDS",
)
payment_white_squad_uuids_raw: str = Field(
default="",
validation_alias="PAYMENT_WHITE_SQUAD_UUIDS",
)
payment_external_squad_uuid: str = Field(
default="",
validation_alias="PAYMENT_EXTERNAL_SQUAD_UUID",
@@ -237,12 +271,15 @@ class Settings(BaseSettings):
@cached_property
def payment_internal_squad_uuids(self) -> list[str]:
values: list[str] = []
for raw_part in self.payment_internal_squad_uuids_raw.split(","):
part = raw_part.strip()
if part:
values.append(part)
return values
return self._parse_csv_list(self.payment_internal_squad_uuids_raw)
@cached_property
def payment_vpn_squad_uuids(self) -> list[str]:
return self._parse_csv_list(self.payment_vpn_squad_uuids_raw)
@cached_property
def payment_white_squad_uuids(self) -> list[str]:
return self._parse_csv_list(self.payment_white_squad_uuids_raw)
@cached_property
def payment_external_squad_uuid_normalized(self) -> str | None:
@@ -265,6 +302,13 @@ class Settings(BaseSettings):
@cached_property
def payment_plans(self) -> list[PaymentPlanSettings]:
product_plans = self._parse_product_plans(
self.payment_product_plans_raw,
default_days=max(self.payment_plan_duration_days, 1),
)
if product_plans:
return product_plans
values: list[PaymentPlanSettings] = []
for raw_part in self.payment_plans_raw.split(","):
part = raw_part.strip()
@@ -303,3 +347,77 @@ class Settings(BaseSettings):
]
return []
@staticmethod
def _parse_csv_list(raw_value: str) -> list[str]:
values: list[str] = []
for raw_part in raw_value.split(","):
part = raw_part.strip()
if part:
values.append(part)
return values
@staticmethod
def _parse_product_plans(
raw_value: str,
*,
default_days: int,
) -> list[PaymentPlanSettings]:
values: list[PaymentPlanSettings] = []
seen_codes: set[str] = set()
for raw_part in raw_value.split(","):
part = raw_part.strip()
if not part:
continue
fragments = [fragment.strip() for fragment in part.split(":")]
# Legacy format: code:amount (2 fields) → single duration using default_days
if len(fragments) == 2:
code, raw_amount = fragments
pairs = [(str(default_days), raw_amount)]
# Standard format: code:days:amount (3 fields) → single duration
elif len(fragments) == 3:
code = fragments[0]
pairs = [(fragments[1], fragments[2])]
# Extended format: code:days1:amount1:days2:amount2:... (odd number ≥ 5)
elif len(fragments) >= 5 and len(fragments) % 2 == 1:
code = fragments[0]
pairs = [
(fragments[i], fragments[i + 1])
for i in range(1, len(fragments), 2)
]
else:
continue
normalized_code = code.lower()
spec = PAYMENT_PRODUCT_PLAN_SPECS.get(normalized_code)
if spec is None or normalized_code in seen_codes:
continue
title, description, squad_groups = spec
for raw_days, raw_amount in pairs:
if not raw_days.isdigit() or not raw_amount.isdigit():
continue
days = int(raw_days)
amount_rub = int(raw_amount)
if days <= 0 or amount_rub <= 0:
continue
plan_code = f"{normalized_code}_{days}"
values.append(
PaymentPlanSettings(
code=plan_code,
days=days,
amount_rub=amount_rub,
title=title,
description=description,
squad_groups=squad_groups,
)
)
seen_codes.add(normalized_code)
return values