Skip to content

Commit 07289c9

Browse files
committed
fix: event loop
1 parent c70ca0e commit 07289c9

File tree

2 files changed

+26
-53
lines changed

2 files changed

+26
-53
lines changed

userbot/__init__.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
# --- Globals ---
2424
ACTIVE_CLIENTS: Dict[int, "TelegramClient"] = {}
2525
LOOP: asyncio.AbstractEventLoop = asyncio.get_event_loop()
26-
# Re-adding FAKE and GLOBAL_HELP_INFO to resolve the ImportError in __main__.py
2726
FAKE: Faker = Faker()
2827
GLOBAL_HELP_INFO: Dict[int, Dict[str, str]] = {}
2928

@@ -101,10 +100,8 @@ async def start_individual_client(client: TelegramClient, account: Account) -> N
101100
await client.start()
102101
if await client.is_user_authorized():
103102
logger.info(f"Client for account '{account_name}' (ID: {account_id}) is authorized.")
104-
# Initialize help_info dict for this client
105103
GLOBAL_HELP_INFO[account_id] = {}
106104

107-
# Register core handlers
108105
client.add_event_handler(help_commands_handler, events.NewMessage(outgoing=True, pattern=r"^\.help$"))
109106
client.add_event_handler(about_command_handler, events.NewMessage(outgoing=True, pattern=r"^\.about$"))
110107
client.add_event_handler(list_accounts_handler, events.NewMessage(outgoing=True, pattern=r"^\.listaccs$"))
@@ -113,8 +110,7 @@ async def start_individual_client(client: TelegramClient, account: Account) -> N
113110
client.add_event_handler(toggle_account_handler, events.NewMessage(outgoing=True, pattern=r"^\.toggleacc\s+([a-zA-Z0-9_]+)$"))
114111
client.add_event_handler(set_lang_handler, events.NewMessage(outgoing=True, pattern=r"^\.setlang\s+([a-zA-Z]{2,5})$"))
115112

116-
# Placeholder for module handlers
117-
# await load_account_modules(account_id, client, GLOBAL_HELP_INFO[account_id])
113+
await load_account_modules(account_id, client, GLOBAL_HELP_INFO[account_id])
118114
else:
119115
logger.warning(f"Client for '{account_name}' started, but user is NOT authorized.")
120116
except Exception as e:
@@ -160,19 +156,3 @@ async def manage_clients() -> None:
160156
tasks.append(start_individual_client(new_client, account))
161157

162158
await asyncio.gather(*tasks)
163-
164-
# --- Main Execution Block ---
165-
# This logic ensures the script can be run directly but not when imported.
166-
if __name__ != "userbot":
167-
if LOOP.is_running():
168-
asyncio.ensure_future(db_setup())
169-
asyncio.ensure_future(manage_clients())
170-
else:
171-
try:
172-
LOOP.run_until_complete(db_setup())
173-
LOOP.run_until_complete(manage_clients())
174-
except Exception as e:
175-
logger.critical(f"Failed during initial setup: {e}")
176-
sys.exit(1)
177-
178-
logger.info("Userbot __init__ finished. Client management tasks scheduled.")

userbot/__main__.py

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,38 @@
11
import asyncio
22
import gc
33
import logging
4-
import subprocess
54
import sys
6-
from typing import Dict, Any, Optional, List, Set
5+
from typing import Dict, Any
76

87
from apscheduler.schedulers.asyncio import AsyncIOScheduler
98
from rich.console import Console
10-
from telethon import events, helpers
9+
from telethon import events
1110
from telethon.errors import SessionPasswordNeededError
1211
from telethon.sessions import StringSession
1312
from art import text2art
1413

15-
from userbot import ACTIVE_CLIENTS, LOOP, GLOBAL_HELP_INFO, FAKE, TelegramClient
14+
from userbot import (
15+
ACTIVE_CLIENTS, FAKE, TelegramClient,
16+
db_setup, manage_clients, GLOBAL_HELP_INFO
17+
)
1618
from userbot.src.config import GC_INTERVAL_SECONDS
1719
from userbot.src.db.session import get_db
1820
import userbot.src.db_manager as db_manager
19-
from userbot.src.module_parser import parse_module_metadata
2021

2122
console: Console = Console()
2223
logger: logging.Logger = logging.getLogger(__name__)
2324

2425
# --- Helper Functions ---
2526
async def get_account_id_from_client(client) -> int | None:
26-
"""Gets the account_id associated with a client instance."""
2727
return next((acc_id for acc_id, c in ACTIVE_CLIENTS.items() if c == client), None)
2828

2929
# --- Module Management (Placeholders) ---
3030
async def load_account_modules(account_id: int, client_instance, current_help_info: Dict[str, str]) -> None:
31-
"""Loads all active and trusted modules for a given account."""
3231
console.print(f"[MODULES] - Loading modules for account_id: {account_id}...", style="yellow")
33-
# In a real scenario, this would populate current_help_info based on loaded modules
3432
pass
3533

36-
async def delmod_handler(event: events.NewMessage.Event):
37-
"""Handles unlinking a module and safely uninstalling its dependencies."""
38-
await event.edit("Команда `.delmod` в разработке.")
39-
4034
# --- Account Management Handlers ---
4135
async def list_accounts_handler(event: events.NewMessage.Event):
42-
"""Lists all accounts in the database with their status."""
4336
await event.edit(await event.client.get_string("verifying_creds"))
4437
header = await event.client.get_string("account_list_header")
4538
response_lines = [header]
@@ -66,7 +59,6 @@ async def list_accounts_handler(event: events.NewMessage.Event):
6659
await event.edit("\n".join(response_lines), parse_mode="html")
6760

6861
async def add_account_handler(event: events.NewMessage.Event):
69-
"""Interactively adds a new account session."""
7062
account_name = event.pattern_match.group(1)
7163

7264
try:
@@ -82,11 +74,10 @@ async def add_account_handler(event: events.NewMessage.Event):
8274
try:
8375
await temp_client.connect()
8476
if not await temp_client.is_user_authorized():
85-
# This part is highly simplified. A real sign-in flow is more complex.
86-
phone_number = await temp_client.send_code_request(api_id)
77+
phone = await temp_client.send_code_request(api_id)
8778
await conv.send_message(f"Код отправлен. Введите его:")
8879
code = (await conv.get_response()).text.strip()
89-
await temp_client.sign_in(password=code)
80+
await temp_client.sign_in(phone=phone.phone, code=code)
9081
except SessionPasswordNeededError:
9182
await conv.send_message(await event.client.get_string("prompt_2fa"))
9283
two_fa_pass_resp = await conv.get_response(); two_fa_pass = two_fa_pass_resp.text.strip()
@@ -102,7 +93,7 @@ async def add_account_handler(event: events.NewMessage.Event):
10293
return
10394

10495
await conv.send_message(await event.client.get_string("prompt_lang")); lang_code = (await conv.get_response()).text.strip() or 'ru'
105-
await conv.send_message(await event.client.get_string("prompt_activate")); is_enabled = (await conv.get_response()).text.lower().startswith('д')
96+
await conv.send_message(await event.client.get_string("prompt_activate")); is_enabled = (await conv.get_response()).text.lower().startswith(('y', 'д'))
10697

10798
device_model, system_version, app_version = FAKE.android_platform_token(), "SDK 31", "10.1.0"
10899

@@ -125,7 +116,6 @@ async def add_account_handler(event: events.NewMessage.Event):
125116
await event.respond(await event.client.get_string("generic_error", error=str(e)))
126117

127118
async def delete_account_handler(event: events.NewMessage.Event):
128-
"""Deletes an account from the database."""
129119
account_name = event.pattern_match.group(1)
130120
try:
131121
async with event.client.conversation(event.chat_id, timeout=60) as conv:
@@ -143,9 +133,7 @@ async def delete_account_handler(event: events.NewMessage.Event):
143133
except asyncio.TimeoutError:
144134
await event.respond(await event.client.get_string("delete_timeout"))
145135

146-
147136
async def toggle_account_handler(event: events.NewMessage.Event):
148-
"""Enables or disables an account."""
149137
account_name = event.pattern_match.group(1)
150138
async with get_db() as db:
151139
new_status = await db_manager.toggle_account_status(db, account_name)
@@ -158,7 +146,6 @@ async def toggle_account_handler(event: events.NewMessage.Event):
158146
await event.edit(await event.client.get_string("toggle_disabled", account_name=account_name))
159147

160148
async def set_lang_handler(event: events.NewMessage.Event):
161-
"""Sets the language for the current account."""
162149
lang_code = event.pattern_match.group(1).lower()
163150
account_id = await get_account_id_from_client(event.client)
164151
if not account_id: return
@@ -173,7 +160,6 @@ async def set_lang_handler(event: events.NewMessage.Event):
173160
await event.edit(await event.client.get_string("lang_update_fail"))
174161

175162
async def help_commands_handler(event: events.NewMessage.Event):
176-
"""Displays the help message."""
177163
help_management = "\n".join([
178164
f"<code>.listaccs</code> - {await event.client.get_string('help_listaccs')}",
179165
f"<code>.addacc &lt;name&gt;</code> - {await event.client.get_string('help_addacc')}",
@@ -182,28 +168,35 @@ async def help_commands_handler(event: events.NewMessage.Event):
182168
f"<code>.setlang &lt;code&gt;</code> - {await event.client.get_string('help_setlang')}",
183169
f"<code>.about</code> - {await event.client.get_string('help_about')}",
184170
])
185-
186171
final_text = f"{await event.client.get_string('help_header_management')}\n{help_management}"
187172
await event.edit(final_text, parse_mode="HTML")
188173

189174
async def about_command_handler(event: events.NewMessage.Event):
190-
"""Displays information about the userbot."""
191175
await event.edit(await event.client.get_string("about_text"), parse_mode="HTML")
192176

193-
# --- Main Execution ---
194-
if __name__ == "__main__":
177+
async def main():
178+
"""The main entry point for the userbot."""
195179
console.print(text2art("DeBot", font="random", chr_ignore=True), style="cyan")
196180
console.print("\n coded by @whynothacked", style="yellow")
197181

182+
await db_setup()
183+
await manage_clients()
184+
198185
scheduler = AsyncIOScheduler(timezone="UTC")
199186
scheduler.add_job(gc.collect, 'interval', seconds=GC_INTERVAL_SECONDS, id='gc_job')
200187
scheduler.start()
201188
console.print(f"-> [system] - GC scheduled every {GC_INTERVAL_SECONDS} seconds.", style="blue")
202-
189+
190+
logger.info("Userbot is running. Press Ctrl+C to stop.")
191+
# Keep the main coroutine alive indefinitely
192+
await asyncio.Event().wait()
193+
194+
195+
if __name__ == "__main__":
203196
try:
204-
LOOP.run_forever()
197+
asyncio.run(main())
205198
except KeyboardInterrupt:
206199
console.print("\n[MAIN] - Userbot stopped by user.", style="bold yellow")
207-
finally:
208-
if scheduler.running: scheduler.shutdown()
209-
console.print("[MAIN] - Userbot shutdown complete.", style="bold green")
200+
except Exception as e:
201+
logger.critical(f"An unhandled error occurred in main: {e}", exc_info=True)
202+
sys.exit(1)

0 commit comments

Comments
 (0)