11import asyncio
2+ import io
23import logging
34import os
5+ import shlex
46import sys
57import time
68from datetime import datetime
7- from typing import Dict , Any , List , Set , Optional
9+ from typing import Dict , Any , List , Optional
810
911from telethon import events
1012from telethon .errors import SessionPasswordNeededError
1113from telethon .sessions import SQLiteSession
1214from telethon .tl .functions .updates import GetStateRequest
15+ from telethon .tl .types import DocumentAttributeFilename
1316
14- from userbot import TelegramClient , FAKE , GLOBAL_HELP_INFO , _generate_random_device , ACTIVE_CLIENTS
17+ from userbot import TelegramClient , FAKE , GLOBAL_HELP_INFO , _generate_random_device
1518from userbot .src .db .session import get_db
1619import userbot .src .db_manager as db_manager
1720from userbot .src .locales import translator
@@ -52,7 +55,90 @@ async def update_modules_handler(event: events.NewMessage.Event):
5255 await event .edit ("Команда `.updatemodules` в разработке." )
5356
5457async def logs_handler (event : events .NewMessage .Event ):
55- await event .edit ("Команда `.logs` в разработке." )
58+ """Handles the .logs command for fetching and managing logs."""
59+ await event .edit (await event .client .get_string ("logs_processing" ))
60+
61+ try :
62+ args : List [str ] = shlex .split (event .raw_text )[1 :]
63+ except ValueError :
64+ await event .edit (await event .client .get_string ("logs_err_args" ))
65+ return
66+
67+ if not args :
68+ await event .edit (await event .client .get_string ("help_logs_usage" ))
69+ return
70+
71+ command : str = args [0 ].lower ()
72+
73+ if command == "purge" :
74+ try :
75+ async with event .client .conversation (event .chat_id , timeout = 60 ) as conv :
76+ await conv .send_message (await event .client .get_string ("logs_confirm_purge" ))
77+ response = await conv .get_response ()
78+ if response .text .lower () in ("yes" , "да" ):
79+ async with get_db () as db :
80+ deleted_count = await db_manager .purge_logs (db )
81+ await conv .send_message (await event .client .get_string ("logs_purge_success" , count = deleted_count ))
82+ else :
83+ await conv .send_message (await event .client .get_string ("logs_purge_cancelled" ))
84+ except asyncio .TimeoutError :
85+ await event .respond (await event .client .get_string ("delete_timeout" ))
86+ return
87+
88+ # --- Log Fetching Logic ---
89+ mode : str = "tail"
90+ limit : int = 100
91+ level : Optional [str ] = None
92+ source : Optional [str ] = None
93+
94+ # Parse arguments
95+ if args [0 ].lower () in ["head" , "tail" ]:
96+ mode = args .pop (0 ).lower ()
97+
98+ if args and args [0 ].isdigit ():
99+ limit = int (args .pop (0 ))
100+
101+ for arg in args :
102+ if "=" in arg :
103+ key , value = arg .split ("=" , 1 )
104+ if key .lower () == "level" :
105+ level = value .upper ()
106+ elif key .lower () == "source" :
107+ source = value
108+
109+ async with get_db () as db :
110+ logs_list = await db_manager .get_logs_advanced (db , mode , limit , level , source )
111+
112+ if not logs_list :
113+ await event .edit (await event .client .get_string ("logs_not_found" ))
114+ return
115+
116+ # Prepare file and caption
117+ log_content : str = "\n " .join (
118+ f"[{ log .timestamp .strftime ('%Y-%m-%d %H:%M:%S' )} ] [{ log .level } ] [{ log .module_name or 'System' } ] { log .message } "
119+ for log in logs_list
120+ )
121+
122+ log_file = io .BytesIO (log_content .encode ('utf-8' ))
123+ filename = f"debot_logs_{ datetime .now ().strftime ('%Y%m%d_%H%M%S' )} .log"
124+
125+ caption : str = await event .client .get_string (
126+ "logs_caption" ,
127+ mode = mode ,
128+ lines = limit ,
129+ level = level or "ANY" ,
130+ source = source or "ANY" ,
131+ found = len (logs_list )
132+ )
133+
134+ await event .delete ()
135+ await event .client .send_file (
136+ event .chat_id ,
137+ file = log_file ,
138+ caption = caption ,
139+ attributes = [DocumentAttributeFilename (filename )],
140+ parse_mode = "HTML"
141+ )
56142
57143# --- Account Management Handlers ---
58144async def list_accounts_handler (event : events .NewMessage .Event ):
@@ -233,8 +319,9 @@ async def help_commands_handler(event: events.NewMessage.Event):
233319 help_utils = "\n " .join ([
234320 f"<code>.ping</code> - { await event .client .get_string ('help_ping' )} " ,
235321 f"<code>.restart</code> - { await event .client .get_string ('help_restart' )} " ,
236- f"<code>.updatemodules</code> - { await event .client .get_string ('help_updatemodules' )} " ,
237322 f"<code>.logs</code> - { await event .client .get_string ('help_logs' )} " ,
323+ f"<code>.logs purge</code> - { await event .client .get_string ('help_logs_purge' )} " ,
324+ f"<code>.updatemodules</code> - { await event .client .get_string ('help_updatemodules' )} " ,
238325 f"<code>.about</code> - { await event .client .get_string ('help_about' )} "
239326 ])
240327
@@ -259,12 +346,10 @@ async def ping_handler(event: events.NewMessage.Event):
259346 start_time : float = time .time ()
260347 await event .edit ("Pinging..." )
261348
262- # Measure API latency
263349 api_start_time : float = time .time ()
264350 await event .client (GetStateRequest ())
265351 api_end_time : float = time .time ()
266352
267- # Measure total round-trip latency
268353 end_time : float = time .time ()
269354
270355 total_latency : float = (end_time - start_time ) * 1000
0 commit comments