randydev commited on
Commit
9e73a82
·
verified ·
1 Parent(s): 7ee59b3

Create scripts.py

Browse files
Files changed (1) hide show
  1. scripts.py +308 -0
scripts.py ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import importlib
3
+ import math
4
+ import os
5
+ import re
6
+ import shlex
7
+ import subprocess
8
+ import sys
9
+ import time
10
+ import traceback
11
+ from io import BytesIO
12
+ from types import ModuleType
13
+ from typing import Dict, Tuple
14
+
15
+ import psutil
16
+ from PIL import Image
17
+ from pyrogram import Client, enums, errors
18
+ from pyrogram.errors import FloodWait, MessageNotModified
19
+ from pyrogram.types import Message
20
+
21
+ META_COMMENTS = re.compile(r"^ *# *meta +(\S+) *: *(.*?)\s*$", re.MULTILINE)
22
+ interact_with_to_delete = []
23
+
24
+ def time_formatter(milliseconds: int) -> str:
25
+ """Time Formatter"""
26
+ seconds, milliseconds = divmod(int(milliseconds), 1000)
27
+ minutes, seconds = divmod(seconds, 60)
28
+ hours, minutes = divmod(minutes, 60)
29
+ days, hours = divmod(hours, 24)
30
+ tmp = (
31
+ ((str(days) + " day(s), ") if days else "")
32
+ + ((str(hours) + " hour(s), ") if hours else "")
33
+ + ((str(minutes) + " minute(s), ") if minutes else "")
34
+ + ((str(seconds) + " second(s), ") if seconds else "")
35
+ + ((str(milliseconds) + " millisecond(s), ") if milliseconds else "")
36
+ )
37
+ return tmp[:-2]
38
+
39
+
40
+ def humanbytes(size):
41
+ """Convert Bytes To Bytes So That Human Can Read It"""
42
+ if not size:
43
+ return ""
44
+ power = 2**10
45
+ raised_to_pow = 0
46
+ dict_power_n = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
47
+ while size > power:
48
+ size /= power
49
+ raised_to_pow += 1
50
+ return str(round(size, 2)) + " " + dict_power_n[raised_to_pow] + "B"
51
+
52
+
53
+ async def edit_or_send_as_file(
54
+ tex: str,
55
+ message: Message,
56
+ client: Client,
57
+ caption: str = "<code>Result!</code>",
58
+ file_name: str = "result",
59
+ ):
60
+ """Send As File If Len Of Text Exceeds Tg Limit Else Edit Message"""
61
+ if not tex:
62
+ await message.edit("<code>Wait, What?</code>")
63
+ return
64
+ if len(tex) > 1024:
65
+ await message.edit("<code>OutPut is Too Large, Sending As File!</code>")
66
+ file_names = f"{file_name}.txt"
67
+ with open(file_names, "w") as fn:
68
+ fn.write(tex)
69
+ await client.send_document(message.chat.id, file_names, caption=caption)
70
+ await message.delete()
71
+ if os.path.exists(file_names):
72
+ os.remove(file_names)
73
+ return
74
+ return await message.edit(tex)
75
+
76
+
77
+ def get_text(message: Message) -> None | str:
78
+ """Extract Text From Commands"""
79
+ text_to_return = message.text
80
+ if message.text is None:
81
+ return None
82
+ if " " in text_to_return:
83
+ try:
84
+ return message.text.split(None, 1)[1]
85
+ except IndexError:
86
+ return None
87
+ else:
88
+ return None
89
+
90
+
91
+ async def progress(current, total, message, start, type_of_ps, file_name=None):
92
+ """Progress Bar For Showing Progress While Uploading / Downloading File - Normal"""
93
+ now = time.time()
94
+ diff = now - start
95
+ if round(diff % 10.00) == 0 or current == total:
96
+ percentage = current * 100 / total
97
+ speed = current / diff
98
+ elapsed_time = round(diff) * 1000
99
+ if elapsed_time == 0:
100
+ return
101
+ time_to_completion = round((total - current) / speed) * 1000
102
+ estimated_total_time = elapsed_time + time_to_completion
103
+ progress_str = f"{''.join(['▰' for i in range(math.floor(percentage / 10))])}"
104
+ progress_str += (
105
+ f"{''.join(['▱' for i in range(10 - math.floor(percentage / 10))])}"
106
+ )
107
+ progress_str += f"{round(percentage, 2)}%\n"
108
+ tmp = f"{progress_str}{humanbytes(current)} of {humanbytes(total)}\n"
109
+ tmp += f"ETA: {time_formatter(estimated_total_time)}"
110
+ if file_name:
111
+ try:
112
+ await message.edit(
113
+ f"{type_of_ps}\n**File Name:** `{file_name}`\n{tmp}"
114
+ )
115
+ except FloodWait as e:
116
+ await asyncio.sleep(e.x)
117
+ except MessageNotModified:
118
+ pass
119
+ else:
120
+ try:
121
+ await message.edit(
122
+ f"{type_of_ps}\n{tmp}", parse_mode=enums.ParseMode.MARKDOWN
123
+ )
124
+ except FloodWait as e:
125
+ await asyncio.sleep(e.x)
126
+ except MessageNotModified:
127
+ pass
128
+
129
+
130
+ async def run_cmd(prefix: str) -> Tuple[str, str, int, int]:
131
+ """Run Commands"""
132
+ args = shlex.split(prefix)
133
+ process = await asyncio.create_subprocess_exec(
134
+ *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
135
+ )
136
+ stdout, stderr = await process.communicate()
137
+ return (
138
+ stdout.decode("utf-8", "replace").strip(),
139
+ stderr.decode("utf-8", "replace").strip(),
140
+ process.returncode,
141
+ process.pid,
142
+ )
143
+
144
+
145
+ def mediainfo(media):
146
+ xx = str((str(media)).split("(", maxsplit=1)[0])
147
+ m = ""
148
+ if xx == "MessageMediaDocument":
149
+ mim = media.document.mime_type
150
+ if mim == "application/x-tgsticker":
151
+ m = "sticker animated"
152
+ elif "image" in mim:
153
+ if mim == "image/webp":
154
+ m = "sticker"
155
+ elif mim == "image/gif":
156
+ m = "gif as doc"
157
+ else:
158
+ m = "pic as doc"
159
+ elif "video" in mim:
160
+ if "DocumentAttributeAnimated" in str(media):
161
+ m = "gif"
162
+ elif "DocumentAttributeVideo" in str(media):
163
+ i = str(media.document.attributes[0])
164
+ if "supports_streaming=True" in i:
165
+ m = "video"
166
+ m = "video as doc"
167
+ else:
168
+ m = "video"
169
+ elif "audio" in mim:
170
+ m = "audio"
171
+ else:
172
+ m = "document"
173
+ elif xx == "MessageMediaPhoto":
174
+ m = "pic"
175
+ elif xx == "MessageMediaWebPage":
176
+ m = "web"
177
+ return m
178
+
179
+
180
+ async def edit_or_reply(message, txt):
181
+ """Edit Message If Its From Self, Else Reply To Message"""
182
+ if not message:
183
+ return await message.edit(txt)
184
+ if not message.from_user:
185
+ return await message.edit(txt)
186
+ return await message.edit(txt)
187
+
188
+
189
+ def format_exc(e: Exception, suffix="") -> str:
190
+ traceback.print_exc()
191
+ err = traceback.format_exc()
192
+ if isinstance(e, errors.RPCError):
193
+ return (
194
+ f"<b>Telegram API error!</b>\n"
195
+ f"<code>[{e.CODE} {e.ID or e.NAME}] — {e.MESSAGE.format(value=e.value)}</code>\n\n<b>{suffix}</b>"
196
+ )
197
+ return f"<b>Error!</b>\n" f"<code>{err}</code>"
198
+
199
+
200
+ def import_library(library_name: str, package_name: str = None):
201
+ """
202
+ Loads a library, or installs it in ImportError case
203
+ :param library_name: library name (import example...)
204
+ :param package_name: package name in PyPi (pip install example)
205
+ :return: loaded module
206
+ """
207
+ if package_name is None:
208
+ package_name = library_name
209
+ requirements_list.append(package_name)
210
+
211
+ try:
212
+ return importlib.import_module(library_name)
213
+ except ImportError as exc:
214
+ completed = subprocess.run(
215
+ [sys.executable, "-m", "pip", "install", "--upgrade", package_name], check=True)
216
+ if completed.returncode != 0:
217
+ raise AssertionError(
218
+ f"Failed to install library {package_name} (pip exited with code {completed.returncode})"
219
+ ) from exc
220
+ return importlib.import_module(library_name)
221
+
222
+
223
+ def uninstall_library(package_name: str):
224
+ """
225
+ Uninstalls a library
226
+ :param package_name: package name in PyPi (pip uninstall example)
227
+ """
228
+ completed = subprocess.run(
229
+ [sys.executable, "-m", "pip", "uninstall", "-y", package_name], check=True)
230
+ if completed.returncode != 0:
231
+ raise AssertionError(
232
+ f"Failed to uninstall library {package_name} (pip exited with code {completed.returncode})"
233
+ )
234
+
235
+
236
+ def resize_image(
237
+ input_img, output=None, img_type="PNG", size: int = 512, size2: int = None
238
+ ):
239
+ if output is None:
240
+ output = BytesIO()
241
+ output.name = f"sticker.{img_type.lower()}"
242
+
243
+ with Image.open(input_img) as img:
244
+ # We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512
245
+ # rather than making one side exactly 512, so we have to calculate dimensions manually :(
246
+ if size2 is not None:
247
+ size = (size, size2)
248
+ elif img.width == img.height:
249
+ size = (size, size)
250
+ elif img.width < img.height:
251
+ size = (max(size * img.width // img.height, 1), size)
252
+ else:
253
+ size = (size, max(size * img.height // img.width, 1))
254
+
255
+ img.resize(size).save(output, img_type)
256
+
257
+ return output
258
+
259
+
260
+ def resize_new_image(image_path, output_path, desired_width=None, desired_height=None):
261
+ """
262
+ Resize an image to the desired dimensions while maintaining the aspect ratio.
263
+
264
+ Args:
265
+ image_path (str): Path to the input image file.
266
+ output_path (str): Path to save the resized image.
267
+ desired_width (int, optional): Desired width in pixels. If not provided, the aspect ratio will be maintained.
268
+ desired_height (int, optional): Desired height in pixels. If not provided, the aspect ratio will be maintained.
269
+ """
270
+ image = Image.open(image_path)
271
+
272
+ width, height = image.size
273
+
274
+ aspect_ratio = width / height
275
+
276
+ if desired_width and desired_height:
277
+ new_width, new_height = desired_width, desired_height
278
+ elif desired_height:
279
+ new_width, new_height = int(desired_height * aspect_ratio), desired_height
280
+ else:
281
+ new_width, new_height = 150, 150
282
+
283
+ resized_image = image.resize((new_width, new_height), Image.Resampling.LANCZOS)
284
+
285
+ resized_image.save(output_path)
286
+ if os.path.exists(image_path):
287
+ os.remove(image_path)
288
+
289
+
290
+ def parse_meta_comments(code: str) -> Dict[str, str]:
291
+ try:
292
+ groups = META_COMMENTS.search(code).groups()
293
+ except AttributeError:
294
+ return {}
295
+
296
+ return {groups[i]: groups[i + 1] for i in range(0, len(groups), 2)}
297
+
298
+
299
+ def ReplyCheck(message: Message):
300
+ reply_id = None
301
+
302
+ if message.reply_to_message:
303
+ reply_id = message.reply_to_message.id
304
+
305
+ elif not message.from_user.is_self:
306
+ reply_id = message.id
307
+
308
+ return reply_id