@@ -27,6 +27,7 @@ def check_session_permissions(session_file: str) -> bool:
27
27
if not os .path .exists (session_file ):
28
28
LOGGER .warning (f"Session file { session_file } not found" )
29
29
return True
30
+
30
31
if not os .access (session_file , os .W_OK ):
31
32
LOGGER .error (f"Session file { session_file } is not writable" )
32
33
try :
@@ -38,18 +39,28 @@ def check_session_permissions(session_file: str) -> bool:
38
39
return False
39
40
return True
40
41
42
+ async def cleanup_restart_data ():
43
+ try :
44
+ await restart_messages .delete_many ({})
45
+ LOGGER .info ("Cleaned up any existing restart messages from database" )
46
+ except Exception as e :
47
+ LOGGER .error (f"Failed to cleanup restart data: { e } " )
48
+
41
49
def setup_restart_handler (app : Client ):
42
50
@app .on_message (filters .command (["restart" , "reboot" , "reload" ], prefixes = COMMAND_PREFIX ) & (filters .private | filters .group ))
43
51
async def restart (client : Client , message ):
44
52
user_id = message .from_user .id
45
53
if not await is_admin (user_id ):
46
54
return
55
+
47
56
LOGGER .info (f"Restart command received from user { user_id } " )
57
+
48
58
response = await client .send_message (
49
59
chat_id = message .chat .id ,
50
- text = "**Restarting bot ... Please wait .**" ,
60
+ text = "**Restarting Bot ... Please Wait .**" ,
51
61
parse_mode = ParseMode .MARKDOWN
52
62
)
63
+
53
64
session_file = "SmartTools.session"
54
65
if not check_session_permissions (session_file ):
55
66
await client .edit_message_text (
@@ -59,6 +70,7 @@ async def restart(client: Client, message):
59
70
parse_mode = ParseMode .MARKDOWN
60
71
)
61
72
return
73
+
62
74
directories = ["downloads" , "temp" , "temp_media" , "data" , "repos" , "temp_dir" ]
63
75
for directory in directories :
64
76
try :
@@ -67,51 +79,165 @@ async def restart(client: Client, message):
67
79
LOGGER .info (f"Cleared directory: { directory } " )
68
80
except Exception as e :
69
81
LOGGER .error (f"Failed to clear directory { directory } : { e } " )
82
+
70
83
log_file = "botlog.txt"
71
84
if os .path .exists (log_file ):
72
85
try :
73
86
os .remove (log_file )
74
87
LOGGER .info (f"Cleared log file: { log_file } " )
75
88
except Exception as e :
76
89
LOGGER .error (f"Failed to clear log file { log_file } : { e } " )
90
+
77
91
start_script = "start.sh"
92
+ main_script = "main.py"
93
+
78
94
if not os .path .exists (start_script ):
79
- LOGGER .error ("Start script not found" )
95
+ if os .path .exists (main_script ):
96
+ LOGGER .warning ("start.sh not found, will try direct python execution" )
97
+ start_script = None
98
+ else :
99
+ LOGGER .error ("Neither start.sh nor main.py found" )
100
+ await client .edit_message_text (
101
+ chat_id = message .chat .id ,
102
+ message_id = response .id ,
103
+ text = "**Failed To Restart Due To Unix Issue❌**" ,
104
+ parse_mode = ParseMode .MARKDOWN
105
+ )
106
+ return
107
+
108
+ try :
109
+ await cleanup_restart_data ()
110
+
111
+ restart_data = {
112
+ "chat_id" : message .chat .id ,
113
+ "msg_id" : response .id
114
+ }
115
+
116
+ await restart_messages .insert_one (restart_data )
117
+ LOGGER .info (f"Stored restart message details for chat { message .chat .id } " )
118
+
119
+ await asyncio .sleep (2 )
120
+
121
+ except Exception as e :
122
+ LOGGER .error (f"Failed to store restart message data: { e } " )
80
123
await client .edit_message_text (
81
124
chat_id = message .chat .id ,
82
125
message_id = response .id ,
83
- text = "**Failed To Restart Due To Unix Issue❌**" ,
126
+ text = "**Failed To Restart Due To Database Issue❌**" ,
84
127
parse_mode = ParseMode .MARKDOWN
85
128
)
86
129
return
130
+
87
131
try :
88
- await restart_messages .insert_one ({
89
- "chat_id" : message .chat .id ,
90
- "msg_id" : response .id
91
- })
92
- LOGGER .info (f"Stored restart message details for chat { message .chat .id } " )
93
- subprocess .Popen (["bash" , start_script ])
132
+ if start_script :
133
+ if not os .access (start_script , os .X_OK ):
134
+ try :
135
+ os .chmod (start_script , 0o755 )
136
+ LOGGER .info (f"Set execute permissions for { start_script } " )
137
+ except Exception as e :
138
+ LOGGER .error (f"Failed to set execute permissions: { e } " )
139
+ raise
140
+
141
+ process = subprocess .Popen (
142
+ ["bash" , start_script ],
143
+ stdin = subprocess .DEVNULL ,
144
+ stdout = None ,
145
+ stderr = None ,
146
+ start_new_session = True
147
+ )
148
+ LOGGER .info ("Started bot using bash script" )
149
+ else :
150
+ import sys
151
+ python_executable = sys .executable
152
+
153
+ process = subprocess .Popen (
154
+ [python_executable , main_script ],
155
+ stdin = subprocess .DEVNULL ,
156
+ stdout = None ,
157
+ stderr = None ,
158
+ start_new_session = True ,
159
+ cwd = os .getcwd ()
160
+ )
161
+ LOGGER .info ("Started bot using direct python execution" )
162
+
163
+ await asyncio .sleep (3 )
164
+
165
+
166
+ if process .poll () is not None :
167
+ if process .returncode != 0 :
168
+ raise subprocess .CalledProcessError (process .returncode , start_script or main_script )
169
+ else :
170
+ LOGGER .info ("Start process completed immediately, checking if this is expected" )
171
+ else :
172
+ LOGGER .info ("Start process is running in background" )
173
+
174
+ LOGGER .info ("Restart executed successfully, shutting down current instance" )
175
+ await asyncio .sleep (2 )
94
176
os ._exit (0 )
95
- except Exception as e :
96
- LOGGER .error (f"Restart command execution failed: { e } " )
177
+
178
+ except subprocess .CalledProcessError as e :
179
+ LOGGER .error (f"Start process failed with return code { e .returncode } " )
180
+ try :
181
+ await restart_messages .delete_one ({"chat_id" : message .chat .id , "msg_id" : response .id })
182
+ except Exception as db_e :
183
+ LOGGER .error (f"Failed to cleanup restart data after script failure: { db_e } " )
184
+
185
+ error_msg = "**Failed To Restart Invalid LF Format❌**" if start_script else "**Failed To Restart Python Script Error❌**"
97
186
await client .edit_message_text (
98
187
chat_id = message .chat .id ,
99
188
message_id = response .id ,
100
- text = "**Failed To Restart Invalid LF Format❌**" ,
189
+ text = error_msg ,
101
190
parse_mode = ParseMode .MARKDOWN
102
191
)
192
+ return
193
+
194
+ except FileNotFoundError :
195
+ LOGGER .error ("Bash shell not found" )
196
+ try :
197
+ await restart_messages .delete_one ({"chat_id" : message .chat .id , "msg_id" : response .id })
198
+ except Exception as db_e :
199
+ LOGGER .error (f"Failed to cleanup restart data after bash error: { db_e } " )
200
+
201
+ await client .edit_message_text (
202
+ chat_id = message .chat .id ,
203
+ message_id = response .id ,
204
+ text = "**Failed To Restart Due To Unix Issue❌**" ,
205
+ parse_mode = ParseMode .MARKDOWN
206
+ )
207
+ return
208
+
209
+ except Exception as e :
210
+ LOGGER .error (f"Restart command execution failed: { e } " )
211
+ try :
212
+ await restart_messages .delete_one ({"chat_id" : message .chat .id , "msg_id" : response .id })
213
+ except Exception as db_e :
214
+ LOGGER .error (f"Failed to cleanup restart data after general error: { db_e } " )
215
+
216
+ try :
217
+ await client .edit_message_text (
218
+ chat_id = message .chat .id ,
219
+ message_id = response .id ,
220
+ text = "**Failed To Restart Due To System Error❌**" ,
221
+ parse_mode = ParseMode .MARKDOWN
222
+ )
223
+ except Exception as msg_e :
224
+ LOGGER .error (f"Failed to update error message: { msg_e } " )
225
+ return
103
226
104
227
@app .on_message (filters .command (["stop" , "kill" , "off" ], prefixes = COMMAND_PREFIX ) & (filters .private | filters .group ))
105
228
async def stop (client : Client , message ):
106
229
user_id = message .from_user .id
107
230
if not await is_admin (user_id ):
108
231
return
232
+
109
233
LOGGER .info (f"Stop command received from user { user_id } " )
234
+
110
235
response = await client .send_message (
111
236
chat_id = message .chat .id ,
112
237
text = "**Stopping bot and clearing data...**" ,
113
238
parse_mode = ParseMode .MARKDOWN
114
239
)
240
+
115
241
directories = ["downloads" , "temp" , "temp_media" , "data" , "repos" ]
116
242
for directory in directories :
117
243
try :
@@ -120,26 +246,49 @@ async def stop(client: Client, message):
120
246
LOGGER .info (f"Cleared directory: { directory } " )
121
247
except Exception as e :
122
248
LOGGER .error (f"Failed to clear directory { directory } : { e } " )
249
+
123
250
log_file = "botlog.txt"
124
251
if os .path .exists (log_file ):
125
252
try :
126
253
os .remove (log_file )
127
254
LOGGER .info (f"Cleared log file: { log_file } " )
128
255
except Exception as e :
129
256
LOGGER .error (f"Failed to clear log file { log_file } : { e } " )
257
+
258
+ try :
259
+ await cleanup_restart_data ()
260
+ LOGGER .info ("Cleaned up restart data before stopping" )
261
+ except Exception as e :
262
+ LOGGER .error (f"Failed to cleanup restart data during stop: { e } " )
263
+
130
264
try :
131
265
await client .edit_message_text (
132
266
chat_id = message .chat .id ,
133
267
message_id = response .id ,
134
268
text = "**Bot stopped successfully, data cleared**" ,
135
269
parse_mode = ParseMode .MARKDOWN
136
270
)
271
+
272
+ await asyncio .sleep (2 )
273
+
274
+ try :
275
+ subprocess .run (["pkill" , "-f" , "main.py" ], check = False , timeout = 5 )
276
+ except (subprocess .TimeoutExpired , FileNotFoundError ):
277
+ LOGGER .warning ("pkill command failed or timed out, using direct exit" )
278
+
137
279
os ._exit (0 )
280
+
138
281
except Exception as e :
139
- LOGGER .error (f"Failed to stop bot: { e } " )
140
- await client .edit_message_text (
141
- chat_id = message .chat .id ,
142
- message_id = response .id ,
143
- text = "**Failed To Stop Bot Due To Telegram Limit ❌ **" ,
144
- parse_mode = ParseMode .MARKDOWN
145
- )
282
+ LOGGER .error (f"Failed to update stop message: { e } " )
283
+ try :
284
+ await client .edit_message_text (
285
+ chat_id = message .chat .id ,
286
+ message_id = response .id ,
287
+ text = "**Failed To Stop Bot Due To Telegram Limit ❌**" ,
288
+ parse_mode = ParseMode .MARKDOWN
289
+ )
290
+ except Exception as msg_e :
291
+ LOGGER .error (f"Failed to update error stop message: { msg_e } " )
292
+
293
+ await asyncio .sleep (2 )
294
+ os ._exit (0 )
0 commit comments