Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
53a306f
Adapt config and add vault data model
QINGYI16621 May 1, 2026
9842d9b
Add storage-backed vault collection flow
QINGYI16621 May 2, 2026
2783137
Add cached replay and paged vault viewer
QINGYI16621 May 2, 2026
645880a
Add owner guard and direct source input
QINGYI16621 May 2, 2026
ae8447b
Route single extraction through vault flow
QINGYI16621 May 2, 2026
06270fe
Open vault page after processing completes
QINGYI16621 May 2, 2026
07e0236
Add start guide and legacy button bridge
QINGYI16621 May 2, 2026
dc4583a
Bypass premium gate for owner
QINGYI16621 May 2, 2026
2e6caa0
Use owner bot and shared session fallbacks
QINGYI16621 May 3, 2026
f350f6d
Handle numeric source input during batch flows
QINGYI16621 May 3, 2026
df39ac4
Make source input global and archive batch files only
QINGYI16621 May 3, 2026
0572e2e
Deduplicate vault files and send visual media as groups
QINGYI16621 May 3, 2026
2742ab3
Fix vault counts and dedupe by file identity
QINGYI16621 May 3, 2026
931a4ed
Expose per-file vault codes from collection pages
QINGYI16621 May 3, 2026
932ff3c
Prevent duplicate vault send callbacks
QINGYI16621 May 3, 2026
4c09e21
Debounce vault send callbacks after completion
QINGYI16621 May 3, 2026
d4d8657
Send collections by source media groups and add vault cleanup script
QINGYI16621 May 3, 2026
34e9a2a
Force page sends to batch visual media into groups
QINGYI16621 May 3, 2026
85b8183
Disallow single-send fallback for collection page sends
QINGYI16621 May 3, 2026
70a84e6
Reuse stored media by content hash before uploading
QINGYI16621 May 3, 2026
935b402
Make vault key parsing robust and explicit on misses
QINGYI16621 May 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 112 additions & 78 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,78 +1,112 @@
# Copyright (c) 2025 devgagan : https://github.com/devgaganin.
# Licensed under the GNU General Public License v3.0.
# See LICENSE file in the repository root for full license text.

import os
from dotenv import load_dotenv
load_dotenv()

# ════════════════════════════════════════════════════════════════════════════════
# ░ CONFIGURATION SETTINGS
# ════════════════════════════════════════════════════════════════════════════════

# VPS --- FILL COOKIES 🍪 in """ ... """
INST_COOKIES = """
# write up here insta cookies
"""

YTUB_COOKIES = """
# write here yt cookies
"""

# ─── BOT / DATABASE CONFIG ──────────────────────────────────────────────────────
API_ID = os.getenv("API_ID", "")
API_HASH = os.getenv("API_HASH", "")
BOT_TOKEN = os.getenv("BOT_TOKEN", "")
MONGO_DB = os.getenv("MONGO_DB", "")
DB_NAME = os.getenv("DB_NAME", "telegram_downloader")

# ─── OWNER / CONTROL SETTINGS ───────────────────────────────────────────────────
OWNER_ID = list(map(int, os.getenv("OWNER_ID", "").split())) # space-separated list
STRING = os.getenv("STRING", None) # optional session string
LOG_GROUP = int(os.getenv("LOG_GROUP", "-1001234456"))
FORCE_SUB = int(os.getenv("FORCE_SUB", "-10012345567"))

# ─── SECURITY KEYS ──────────────────────────────────────────────────────────────
MASTER_KEY = os.getenv("MASTER_KEY", "gK8HzLfT9QpViJcYeB5wRa3DmN7P2xUq") # session encryption
IV_KEY = os.getenv("IV_KEY", "s7Yx5CpVmE3F") # decryption key

# ─── COOKIES HANDLING ───────────────────────────────────────────────────────────
YT_COOKIES = os.getenv("YT_COOKIES", YTUB_COOKIES)
INSTA_COOKIES = os.getenv("INSTA_COOKIES", INST_COOKIES)

# ─── USAGE LIMITS ───────────────────────────────────────────────────────────────
FREEMIUM_LIMIT = int(os.getenv("FREEMIUM_LIMIT", "0"))
PREMIUM_LIMIT = int(os.getenv("PREMIUM_LIMIT", "500"))

# ─── UI / LINKS ─────────────────────────────────────────────────────────────────
JOIN_LINK = os.getenv("JOIN_LINK", "https://t.me/team_spy_pro")
ADMIN_CONTACT = os.getenv("ADMIN_CONTACT", "https://t.me/username_of_admin")

# ════════════════════════════════════════════════════════════════════════════════
# ░ PREMIUM PLANS CONFIGURATION
# ════════════════════════════════════════════════════════════════════════════════

P0 = {
"d": {
"s": int(os.getenv("PLAN_D_S", 1)),
"du": int(os.getenv("PLAN_D_DU", 1)),
"u": os.getenv("PLAN_D_U", "days"),
"l": os.getenv("PLAN_D_L", "Daily"),
},
"w": {
"s": int(os.getenv("PLAN_W_S", 3)),
"du": int(os.getenv("PLAN_W_DU", 1)),
"u": os.getenv("PLAN_W_U", "weeks"),
"l": os.getenv("PLAN_W_L", "Weekly"),
},
"m": {
"s": int(os.getenv("PLAN_M_S", 5)),
"du": int(os.getenv("PLAN_M_DU", 1)),
"u": os.getenv("PLAN_M_U", "month"),
"l": os.getenv("PLAN_M_L", "Monthly"),
},
}

# ════════════════════════════════════════════════════════════════════════════════
# ░ DEVGAGAN
# ════════════════════════════════════════════════════════════════════════════════
import os
from dotenv import load_dotenv

load_dotenv()


def _getenv(*names, default=""):
for name in names:
value = os.getenv(name)
if value is not None and str(value).strip() != "":
return str(value).strip()
return default


def _getint(*names, default=0):
value = _getenv(*names, default=str(default))
try:
return int(value)
except Exception:
return default


def _get_owner_ids():
raw = _getenv("OWNER_ID", "ADMIN_ID", default="")
if not raw:
return []
if "," in raw:
parts = [part.strip() for part in raw.split(",")]
else:
parts = [part.strip() for part in raw.split()]
ids = []
for part in parts:
if not part:
continue
try:
ids.append(int(part))
except Exception:
pass
return ids


INST_COOKIES = """
# write up here insta cookies
"""

YTUB_COOKIES = """
# write here yt cookies
"""


# Core bot/database config
API_ID = _getenv("API_ID", "TG_API_ID", default="")
API_HASH = _getenv("API_HASH", "TG_API_HASH", default="")
BOT_TOKEN = _getenv("BOT_TOKEN", "TG_BOT_TOKEN", default="")
MONGO_DB = _getenv("MONGO_DB", default="")
DB_NAME = _getenv("DB_NAME", default="telegram_downloader")
STORAGE_CHANNEL_ID = _getint("TG_STORAGE_CHANNEL", "LOG_GROUP", default=0)
BACKUP_CHANNEL_ID = _getint("TG_BACKUP_CHANNEL", default=0)
TEMP_DOWNLOAD_DIR = _getenv(
"TEMP_DIR",
default="/dev/shm/telegram_vault_tmp" if os.path.isdir("/dev/shm") else "/tmp/telegram_vault_tmp"
)


# Owner / control settings
OWNER_ID = _get_owner_ids()
STRING = _getenv("STRING", default=None)
LOG_GROUP = _getint("LOG_GROUP", "TG_STORAGE_CHANNEL", "TG_BACKUP_CHANNEL", default=0)
FORCE_SUB = _getint("FORCE_SUB", "CHANNEL_ID", default=0)


# Security keys
MASTER_KEY = _getenv("MASTER_KEY", "ENCRYPTION_KEY", default="gK8HzLfT9QpViJcYeB5wRa3DmN7P2xUq")
IV_KEY = _getenv("IV_KEY", "DB_PASSWORD", default="s7Yx5CpVmE3F")


# Cookies
YT_COOKIES = _getenv("YT_COOKIES", default=YTUB_COOKIES)
INSTA_COOKIES = _getenv("INSTA_COOKIES", default=INST_COOKIES)


# Limits
FREEMIUM_LIMIT = _getint("FREEMIUM_LIMIT", default=0)
PREMIUM_LIMIT = _getint("PREMIUM_LIMIT", default=500)


# UI / links
JOIN_LINK = _getenv("JOIN_LINK", default="https://t.me/team_spy_pro")
ADMIN_CONTACT = _getenv("ADMIN_CONTACT", default="https://t.me/username_of_admin")


# Premium plan config
P0 = {
"d": {
"s": _getint("PLAN_D_S", default=1),
"du": _getint("PLAN_D_DU", default=1),
"u": _getenv("PLAN_D_U", default="days"),
"l": _getenv("PLAN_D_L", default="Daily"),
},
"w": {
"s": _getint("PLAN_W_S", default=3),
"du": _getint("PLAN_W_DU", default=1),
"u": _getenv("PLAN_W_U", default="weeks"),
"l": _getenv("PLAN_W_L", default="Weekly"),
},
"m": {
"s": _getint("PLAN_M_S", default=5),
"du": _getint("PLAN_M_DU", default=1),
"u": _getenv("PLAN_M_U", default="month"),
"l": _getenv("PLAN_M_L", default="Monthly"),
},
}
20 changes: 11 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
# Licensed under the GNU General Public License v3.0.
# See LICENSE file in the repository root for full license text.

import asyncio
from shared_client import start_client
import importlib
import os
import sys

async def load_and_run_plugins():
await start_client()
plugin_dir = "plugins"
import asyncio
from shared_client import start_client
import importlib
import os
import sys
from utils.func import ensure_vault_indexes

async def load_and_run_plugins():
await start_client()
await ensure_vault_indexes()
plugin_dir = "plugins"
plugins = [f[:-3] for f in os.listdir(plugin_dir) if f.endswith(".py") and f != "__init__.py"]

for plugin in plugins:
Expand Down
Loading