Skip to content

Commit 6fa11af

Browse files
committed
fix: circular import
1 parent 79c3882 commit 6fa11af

File tree

3 files changed

+233
-100
lines changed

3 files changed

+233
-100
lines changed

userbot/__init__.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from telethon import TelegramClient as TelethonTelegramClient, events
88
from telethon.sessions import StringSession
99
from telethon.errors.rpcerrorlist import UserAlreadyParticipantError
10+
from python_socks import ProxyType
1011

1112
from userbot.src.config import API_ID, API_HASH, LOG_LEVEL
1213
from userbot.src.db.session import initialize_database, get_db
@@ -23,7 +24,6 @@
2324

2425
# --- Globals ---
2526
ACTIVE_CLIENTS: Dict[int, "TelegramClient"] = {}
26-
LOOP: asyncio.AbstractEventLoop = asyncio.get_event_loop()
2727
FAKE: Faker = Faker()
2828
GLOBAL_HELP_INFO: Dict[int, Dict[str, str]] = {}
2929

@@ -75,7 +75,7 @@ async def db_setup() -> None:
7575
logger.info("Database schema checked and DB logger attached.")
7676

7777
async def start_individual_client(client: TelegramClient, account: Account) -> None:
78-
from userbot.__main__ import (
78+
from userbot.src.core_handlers import (
7979
load_account_modules, help_commands_handler, about_command_handler,
8080
add_account_handler, delete_account_handler, toggle_account_handler,
8181
list_accounts_handler, set_lang_handler, addmod_handler, delmod_handler,
@@ -104,7 +104,6 @@ async def start_individual_client(client: TelegramClient, account: Account) -> N
104104

105105
try:
106106
await client(JoinChannelRequest('https://t.me/DeBot_userbot'))
107-
logger.info(f"Account '{account.account_name}' successfully subscribed to the main channel.")
108107
except UserAlreadyParticipantError:
109108
pass
110109
except Exception as e:
@@ -143,8 +142,17 @@ async def manage_clients() -> None:
143142

144143
proxy_details = None
145144
if account.proxy_ip and account.proxy_port and account.proxy_type:
146-
# Logic to construct proxy dict for Telethon would go here
147-
pass
145+
proxy_map = {"http": ProxyType.HTTP, "socks4": ProxyType.SOCKS4, "socks5": ProxyType.SOCKS5}
146+
proxy_type_enum = proxy_map.get(account.proxy_type.lower())
147+
if proxy_type_enum:
148+
proxy_details = (
149+
proxy_type_enum,
150+
account.proxy_ip,
151+
account.proxy_port,
152+
True,
153+
encryption_manager.decrypt(account.proxy_username).decode() if account.proxy_username else None,
154+
encryption_manager.decrypt(account.proxy_password).decode() if account.proxy_password else None
155+
)
148156

149157
new_client: TelegramClient = TelegramClient(
150158
session=DbSession(account_id=account.account_id),

userbot/__main__.py

Lines changed: 25 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,123 +2,50 @@
22
import gc
33
import logging
44
import sys
5-
from typing import Dict, Any, List
5+
from typing import Dict, Any
66

77
from apscheduler.schedulers.asyncio import AsyncIOScheduler
88
from rich.console import Console
9-
from telethon import events
10-
from telethon.errors import SessionPasswordNeededError
11-
from telethon.sessions import StringSession
129
from art import text2art
1310

1411
from userbot import (
15-
ACTIVE_CLIENTS, TelegramClient,
16-
db_setup, manage_clients, GLOBAL_HELP_INFO, _generate_random_device
12+
db_setup, manage_clients
1713
)
18-
from userbot.src.config import GC_INTERVAL_SECONDS, LOG_QUEUE_INTERVAL_SECONDS, LOG_QUEUE_BATCH_SIZE, TIMEZONE
14+
from userbot.src.config import GC_INTERVAL_SECONDS, LOG_QUEUE_INTERVAL_SECONDS, TIMEZONE
1915
from userbot.src.db.session import get_db
2016
import userbot.src.db_manager as db_manager
2117
from userbot.src.log_handler import log_queue
22-
from userbot.src.encrypt import encryption_manager
18+
19+
# Suppress noisy APScheduler logs
20+
logging.getLogger('apscheduler').setLevel(logging.WARNING)
2321

2422
console: Console = Console()
2523
logger: logging.Logger = logging.getLogger(__name__)
2624

27-
# --- Log Processing Worker (unchanged) ---
2825
async def process_log_queue():
29-
# ...
30-
pass
31-
32-
# --- Helper Functions (unchanged) ---
33-
async def get_account_id_from_client(client) -> int | None:
34-
# ...
35-
pass
36-
37-
# --- Module Management (Placeholders) ---
38-
async def load_account_modules(account_id: int, client_instance, current_help_info: Dict[str, str]) -> None:
39-
pass
40-
41-
# --- Account Management Handlers ---
42-
async def add_account_handler(event: events.NewMessage.Event):
43-
account_name = event.pattern_match.group(1)
26+
"""Periodically processes logs from the queue and writes them to the DB."""
27+
logs_to_process = []
4428

45-
try:
46-
async with event.client.conversation(event.chat_id, timeout=600) as conv:
47-
# Step 1: API Credentials
48-
await conv.send_message(await event.client.get_string("adding_account", account_name=account_name))
49-
api_id_resp = await conv.get_response(); api_id = api_id_resp.text.strip()
50-
await conv.send_message(await event.client.get_string("prompt_api_hash"))
51-
api_hash_resp = await conv.get_response(); api_hash = api_hash_resp.text.strip()
52-
53-
# Step 2: Live Verification & 2FA
54-
await conv.send_message(await event.client.get_string("verifying_creds"))
55-
temp_client = TelegramClient(StringSession(), int(api_id), api_hash)
56-
# ... (full login logic with phone, code, 2FA as in previous response)
57-
await temp_client.connect()
58-
if not await temp_client.is_user_authorized():
59-
# Simplified for brevity
60-
await conv.send_message("Требуется вход. Пожалуйста, используйте CLI для первого входа.")
61-
return
62-
me = await temp_client.get_me(); user_id = me.id
63-
await temp_client.disconnect()
29+
while not log_queue.empty():
30+
try:
31+
log_item = log_queue.get_nowait()
32+
logs_to_process.append(log_item)
33+
log_queue.task_done()
34+
except asyncio.QueueEmpty:
35+
break
6436

65-
async with get_db() as db:
66-
if await db_manager.get_account_by_user_id(db, user_id):
67-
# ... duplicate check
68-
return
37+
if logs_to_process:
38+
try:
39+
async with get_db() as db_session:
40+
await db_manager.add_logs_bulk(db_session, logs_to_process)
41+
except Exception as e:
42+
logger.error(f"Failed to process log queue batch: {e}", exc_info=True)
6943

70-
# --- New: Proxy Configuration ---
71-
proxy_details: Dict[str, Any] = {}
72-
proxy_prompt = await conv.send_message("Настроить прокси? (да/нет)")
73-
proxy_resp = await conv.get_response()
74-
if proxy_resp.text.lower().startswith('д'):
75-
# ... conversation to get proxy details
76-
pass
77-
78-
# --- New: Device Configuration ---
79-
device_details: Dict[str, str]
80-
device_prompt = await conv.send_message("Указать кастомное устройство? (да/нет)")
81-
device_resp = await conv.get_response()
82-
if device_resp.text.lower().startswith('д'):
83-
# ... conversation to get device model, system version, app version
84-
device_details = {"device_model": "Custom", "system_version": "1.0", "app_version": "1.0"}
85-
else:
86-
device_details = _generate_random_device()
87-
88-
await conv.send_message(await event.client.get_string("prompt_lang")); lang_code = (await conv.get_response()).text.strip() or 'ru'
89-
await conv.send_message(await event.client.get_string("prompt_activate")); is_enabled = (await conv.get_response()).text.lower().startswith('д')
90-
91-
await conv.send_message(await event.client.get_string("saving_to_db"))
92-
async with get_db() as db:
93-
new_acc = await db_manager.add_account(
94-
db, account_name, api_id, api_hash, lang_code, is_enabled,
95-
device_details['device_model'], device_details['system_version'], device_details['app_version'], user_id
96-
)
97-
# ... logic to update proxy if provided
98-
99-
if new_acc:
100-
await conv.send_message(await event.client.get_string("add_acc_success", account_name=account_name))
101-
else:
102-
await conv.send_message(await event.client.get_string("add_acc_fail", account_name=account_name))
103-
104-
except asyncio.TimeoutError:
105-
await event.respond(await event.client.get_string("add_acc_timeout"))
106-
except Exception as e:
107-
logger.error(f"Error in .addacc handler: {e}", exc_info=True)
108-
await event.respond(await event.client.get_string("generic_error", error=str(e)))
109-
110-
111-
# Other handlers (list, delete, toggle, setlang, help, about) are unchanged
112-
async def list_accounts_handler(event: events.NewMessage.Event): pass
113-
async def delete_account_handler(event: events.NewMessage.Event): pass
114-
async def toggle_account_handler(event: events.NewMessage.Event): pass
115-
async def set_lang_handler(event: events.NewMessage.Event): pass
116-
async def help_commands_handler(event: events.NewMessage.Event): pass
117-
async def about_command_handler(event: events.NewMessage.Event): pass
11844

11945
async def main():
12046
"""The main entry point for the userbot."""
12147
console.print(text2art("DeBot", font="random", chr_ignore=True), style="cyan")
48+
console.print("\n coded by @whynothacked", style="yellow")
12249

12350
await db_setup()
12451

@@ -127,6 +54,9 @@ async def main():
12754
scheduler.add_job(process_log_queue, 'interval', seconds=LOG_QUEUE_INTERVAL_SECONDS, id='log_queue_job')
12855
scheduler.start()
12956

57+
console.print(f"-> [system] - GC scheduled every {GC_INTERVAL_SECONDS} seconds.", style="blue")
58+
console.print(f"-> [system] - Log queue processing scheduled every {LOG_QUEUE_INTERVAL_SECONDS} seconds.", style="blue")
59+
13060
await manage_clients()
13161

13262
logger.info("Userbot is running. Press Ctrl+C to stop.")

0 commit comments

Comments
 (0)