From 83a6b3fbe6d595dbb7e2e71f45c86f5ee338aa12 Mon Sep 17 00:00:00 2001 From: Dmitrii Krosh Date: Fri, 10 Jul 2026 00:44:42 +0300 Subject: [PATCH] month reset --- README.md | 2 +- tests/test_marzban.py | 2 +- vpn_bot/config.py | 10 +++++++++- vpn_bot/marzban.py | 7 ++++--- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6472dee..3df6a22 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Send it to the user. "inbounds": {"vless": ["VLESS TCP REALITY"]}, "expire": "now + 3 days", "data_limit": "10 GiB", - "data_limit_reset_strategy": "no_reset", + "data_limit_reset_strategy": "month", "status": "active" } ``` diff --git a/tests/test_marzban.py b/tests/test_marzban.py index ccf3091..0946d76 100644 --- a/tests/test_marzban.py +++ b/tests/test_marzban.py @@ -17,7 +17,7 @@ def test_build_trial_user_payload_matches_required_proxy_inbound_and_limits(): assert payload["inbounds"] == {"vless": ["VLESS TCP REALITY"]} assert payload["expire"] == 1_700_000_000 + 3 * 24 * 60 * 60 assert payload["data_limit"] == 10 * GIB - assert payload["data_limit_reset_strategy"] == "no_reset" + assert payload["data_limit_reset_strategy"] == "month" assert payload["status"] == "active" assert "Phone: +79990000000" in payload["note"] assert "856850518" not in payload["note"] diff --git a/vpn_bot/config.py b/vpn_bot/config.py index 6ea5bb2..404807f 100644 --- a/vpn_bot/config.py +++ b/vpn_bot/config.py @@ -4,6 +4,14 @@ import tomllib from dataclasses import dataclass from pathlib import Path from typing import Any +from urllib.parse import urlsplit, urlunsplit + + +def normalize_marzban_url(url: str) -> str: + parsed = urlsplit(url.strip().rstrip("/")) + if parsed.scheme and parsed.netloc: + return urlunsplit((parsed.scheme, parsed.netloc, "", "", "")) + return url.strip().rstrip("/") @dataclass(frozen=True) @@ -22,7 +30,7 @@ class Config: return cls( telegram_bot_token=str(data["telegram_bot_token"]), admin_ids={int(item) for item in data.get("admin_ids", [])}, - marzban_url=str(data["marzban_url"]).rstrip("/"), + marzban_url=normalize_marzban_url(str(data["marzban_url"])), marzban_username=str(data["marzban_username"]), marzban_password=str(data["marzban_password"]), payment_text=str(data["payment_text"]), diff --git a/vpn_bot/marzban.py b/vpn_bot/marzban.py index 0360893..8df3770 100644 --- a/vpn_bot/marzban.py +++ b/vpn_bot/marzban.py @@ -18,6 +18,7 @@ from .utils import ( DEFAULT_PROXIES = {"vless": {"flow": "xtls-rprx-vision"}} DEFAULT_INBOUNDS = {"vless": ["VLESS TCP REALITY"]} +DATA_LIMIT_RESET_STRATEGY = "month" class MarzbanError(RuntimeError): @@ -53,7 +54,7 @@ class MarzbanClient: "inbounds": DEFAULT_INBOUNDS, "expire": current + TRIAL_DAYS * 24 * 60 * 60, "data_limit": TRIAL_TRAFFIC_BYTES, - "data_limit_reset_strategy": "no_reset", + "data_limit_reset_strategy": DATA_LIMIT_RESET_STRATEGY, "status": "active", "note": build_marzban_note( first_name=first_name, @@ -128,7 +129,7 @@ class MarzbanClient: payload = { "expire": new_expire, "data_limit": PAID_TRAFFIC_BYTES, - "data_limit_reset_strategy": "no_reset", + "data_limit_reset_strategy": DATA_LIMIT_RESET_STRATEGY, "status": "active", } await self.modify_user(username, payload) @@ -141,7 +142,7 @@ class MarzbanClient: payload = { "expire": new_expire, "data_limit": PAID_TRAFFIC_BYTES, - "data_limit_reset_strategy": "no_reset", + "data_limit_reset_strategy": DATA_LIMIT_RESET_STRATEGY, "status": "active", } await self.modify_user(username, payload)