core: env-driven config, sqlite schema, xray/node management, subscription links
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
e4c2012cf8
8 changed files with 1182 additions and 0 deletions
100
config.py
Normal file
100
config.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import os
|
||||
|
||||
|
||||
def _load_dotenv(path):
|
||||
if not os.path.exists(path):
|
||||
return
|
||||
with open(path, encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, _, value = line.partition("=")
|
||||
os.environ.setdefault(key.strip(), value.strip())
|
||||
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
_load_dotenv(os.path.join(BASE_DIR, ".env"))
|
||||
|
||||
|
||||
def env(key, default=None, required=False):
|
||||
val = os.environ.get(key, default)
|
||||
if required and not val:
|
||||
raise RuntimeError(f"missing required env var: {key} — copy .env.example to .env and fill it in")
|
||||
return val
|
||||
|
||||
|
||||
BOT_TOKEN = env("BOT_TOKEN", required=True)
|
||||
BOT_USERNAME = env("BOT_USERNAME", required=True)
|
||||
ADMIN_IDS = {int(x) for x in env("ADMIN_IDS", "").split(",") if x.strip()}
|
||||
ADMIN_PANEL_PASSWORD = env("ADMIN_PANEL_PASSWORD", required=True)
|
||||
PANEL_DOMAIN = env("PANEL_DOMAIN", required=True)
|
||||
SUB_DOMAIN = env("SUB_DOMAIN", required=True)
|
||||
SITE_DOMAIN = env("SITE_DOMAIN", required=True)
|
||||
|
||||
DB_PATH = os.path.join(BASE_DIR, "mbs.db")
|
||||
XRAY_CONFIG_PATH = "/usr/local/etc/xray/config.json"
|
||||
|
||||
XRAY_PUBLIC_KEY = env("XRAY_PUBLIC_KEY", required=True)
|
||||
REALITY_SNI = env("REALITY_SNI", "www.wildberries.ru")
|
||||
XRAY_SHORT_ID_TCP = env("XRAY_SHORT_ID_TCP", required=True)
|
||||
XRAY_SHORT_ID_GRPC = env("XRAY_SHORT_ID_GRPC", required=True)
|
||||
XRAY_SHORT_ID_XHTTP = env("XRAY_SHORT_ID_XHTTP", required=True)
|
||||
DE1_ADDRESS = env("DE1_ADDRESS", f"de1.{SITE_DOMAIN}")
|
||||
|
||||
DE1_TRANSPORTS = [
|
||||
{
|
||||
"tag": "vless-tcp-reality",
|
||||
"label": "TCP + Reality (основной)",
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"address": DE1_ADDRESS,
|
||||
"port": 443,
|
||||
"public_key": XRAY_PUBLIC_KEY,
|
||||
"short_id": XRAY_SHORT_ID_TCP,
|
||||
"sni": REALITY_SNI,
|
||||
"flow": "xtls-rprx-vision",
|
||||
},
|
||||
{
|
||||
"tag": "vless-grpc-reality",
|
||||
"label": "gRPC + Reality",
|
||||
"network": "grpc",
|
||||
"security": "reality",
|
||||
"address": DE1_ADDRESS,
|
||||
"port": 2053,
|
||||
"public_key": XRAY_PUBLIC_KEY,
|
||||
"short_id": XRAY_SHORT_ID_GRPC,
|
||||
"sni": REALITY_SNI,
|
||||
"service_name": "mbs-grpc",
|
||||
},
|
||||
{
|
||||
"tag": "vless-xhttp-reality",
|
||||
"label": "XHTTP + Reality",
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"address": DE1_ADDRESS,
|
||||
"port": 2087,
|
||||
"public_key": XRAY_PUBLIC_KEY,
|
||||
"short_id": XRAY_SHORT_ID_XHTTP,
|
||||
"sni": REALITY_SNI,
|
||||
"path": "/mbs-xh",
|
||||
},
|
||||
{
|
||||
"tag": "vless-ws-tls",
|
||||
"label": "WebSocket + TLS",
|
||||
"network": "ws",
|
||||
"security": "tls",
|
||||
"address": DE1_ADDRESS,
|
||||
"port": 8880,
|
||||
"path": "/mbs-ws",
|
||||
},
|
||||
]
|
||||
|
||||
PLANS = [
|
||||
{"code": "7d", "label": "7 дней", "days": 7},
|
||||
{"code": "1m", "label": "1 месяц", "days": 30},
|
||||
{"code": "3m", "label": "3 месяца", "days": 90},
|
||||
{"code": "6m", "label": "6 месяцев", "days": 180},
|
||||
{"code": "1y", "label": "1 год", "days": 365},
|
||||
]
|
||||
PLANS_BY_CODE = {p["code"]: p for p in PLANS}
|
||||
Loading…
Add table
Add a link
Reference in a new issue