randydev commited on
Commit
7070d2e
·
verified ·
1 Parent(s): 99c95c1

Upload 5 files

Browse files
Akeno/utils/chat.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # Copyright 2020-2023 (c) Randy W @xtdevs, @xtsea
4
+ #
5
+ # from : https://github.com/TeamKillerX
6
+ # Channel : @RendyProjects
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
19
+
20
+ from g4f.client import Client as Clients_g4f
21
+ from datetime import datetime as dt
22
+ from Akeno.utils.logger import LOGS
23
+
24
+ owner_base = f"""
25
+ Your name is Randy Dev. A kind and friendly AI assistant that answers in
26
+ a short and concise answer. Give short step-by-step reasoning if required.
27
+
28
+ - Powered by @xtdevs on telegram
29
+ Today is {dt.now():%A %d %B %Y %H:%M}
30
+ """
31
+
32
+ async def chat_message(question):
33
+ clients_x = Clients_g4f()
34
+ response = clients_x.chat.completions.create(
35
+ model="gpt-4o",
36
+ messages=[
37
+ {"role": "system", "content": owner_base},
38
+ {"role": "user", "content": question}
39
+ ],
40
+ )
41
+ messager = response.choices[0].message.content
42
+ return messager
Akeno/utils/handler.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from pyrogram import Client, filters
2
+
3
+ Akeno = Client.on_message
4
+ Akeno_chat_member_updated = Client.on_chat_member_updated()
Akeno/utils/logger.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import logging
2
+
3
+ logging.basicConfig(level=logging.INFO)
4
+ logging.getLogger("pyrogram").setLevel(logging.ERROR)
5
+
6
+ LOGS = logging.getLogger("[akeno]")
Akeno/utils/spamwatch.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from Akeno.utils.logger import LOGS
3
+ from config import FEDBAN_API_KEY as api_key
4
+
5
+ async def auto_post_gban(user_id, reason):
6
+ url = "https://randydev-ryuzaki-api.hf.space/user/fedban"
7
+ headers = {"accept": "application/json", "api-key": api_key}
8
+ payload = {
9
+ "user_id": user_id,
10
+ "hashtag": "#Spammer",
11
+ "reason": reason,
12
+ }
13
+ response = requests.post(url, json=payload, headers=headers)
14
+ if not response.status_code != 200:
15
+ LOGS.error("Error response status")
16
+ return "Error response status"
17
+ response_data = response.json()
18
+ is_banned = response_data["randydev"].get("is_banned")
19
+ get_message = response_data["randydev"].get("message")
20
+ return is_banned, get_message
21
+
22
+ async def auto_check_gban(user_id):
23
+ url = "https://randydev-ryuzaki-api.hf.space/user/get-fedban"
24
+ headers = {"accept": "application/json", "api-key": api_key}
25
+ payload = {"user_id": user_id}
26
+ response = requests.get(url, json=payload, headers=headers)
27
+ if not response.status_code != 200:
28
+ LOGS.error("Error response status")
29
+ return "Error response status"
30
+ response_data = response.json()
31
+ is_banned = response_data["randydev"].get("is_banned")
32
+ reason = response_data["randydev"].get("reason")
33
+ return [is_banned, reason]
Akeno/utils/tools.py ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import shlex
3
+ import asyncio
4
+ import math
5
+ import os
6
+ import cv2
7
+ import requests
8
+ from typing import Tuple
9
+ import textwrap
10
+
11
+ from PIL import Image, ImageDraw, ImageFont
12
+ from io import BytesIO
13
+ from pymediainfo import MediaInfo
14
+ from bs4 import BeautifulSoup as bs
15
+
16
+ from pyrogram import *
17
+ from pyrogram.enums import *
18
+ from pyrogram.errors import *
19
+ from pyrogram.raw.functions.messages import *
20
+ from pyrogram.raw.types import *
21
+ from pyrogram.types import *
22
+
23
+ DEVS = [1191668125]
24
+
25
+
26
+ def global_no_spam_title(message: Message):
27
+ chat = message.chat
28
+ if chat is not None and hasattr(chat, "title") and chat.title is not None:
29
+ if (
30
+ "#nodevs" in chat.title.lower()
31
+ and message.from_user.status
32
+ not in [enums.ChatMemberStatus.ADMINISTRATOR, enums.ChatMemberStatus.OWNER]
33
+ and message.from_user.id not in DEVS
34
+ ):
35
+ return True
36
+
37
+
38
+ async def add_text_img(image_path, text):
39
+ font_size = 12
40
+ stroke_width = 1
41
+
42
+ if ";" in text:
43
+ upper_text, lower_text = text.split(";")
44
+ else:
45
+ upper_text = text
46
+ lower_text = ""
47
+
48
+ img = Image.open(image_path).convert("RGBA")
49
+ img_info = img.info
50
+ image_width, image_height = img.size
51
+ font = ImageFont.truetype(
52
+ font="resources/default.ttf",
53
+ size=int(image_height * font_size) // 100,
54
+ )
55
+ draw = ImageDraw.Draw(img)
56
+
57
+ char_width, char_height = font.getsize("A")
58
+ chars_per_line = image_width // char_width
59
+ top_lines = textwrap.wrap(upper_text, width=chars_per_line)
60
+ bottom_lines = textwrap.wrap(lower_text, width=chars_per_line)
61
+
62
+ if top_lines:
63
+ y = 10
64
+ for line in top_lines:
65
+ line_width, line_height = font.getsize(line)
66
+ x = (image_width - line_width) / 2
67
+ draw.text(
68
+ (x, y),
69
+ line,
70
+ fill="white",
71
+ font=font,
72
+ stroke_width=stroke_width,
73
+ stroke_fill="black",
74
+ )
75
+ y += line_height
76
+
77
+ if bottom_lines:
78
+ y = image_height - char_height * len(bottom_lines) - 15
79
+ for line in bottom_lines:
80
+ line_width, line_height = font.getsize(line)
81
+ x = (image_width - line_width) / 2
82
+ draw.text(
83
+ (x, y),
84
+ line,
85
+ fill="white",
86
+ font=font,
87
+ stroke_width=stroke_width,
88
+ stroke_fill="black",
89
+ )
90
+ y += line_height
91
+
92
+ final_image = os.path.join("memify.webp")
93
+ img.save(final_image, **img_info)
94
+ return final_image
95
+
96
+ # https://github.com/TeamUltroid/pyUltroid/blob/31c271cf4d35ab700e5880e952e54c82046812c2/pyUltroid/functions/helper.py#L154
97
+
98
+ async def bash(cmd):
99
+ process = await asyncio.create_subprocess_shell(
100
+ cmd,
101
+ stdout=asyncio.subprocess.PIPE,
102
+ stderr=asyncio.subprocess.PIPE,
103
+ )
104
+ stdout, stderr = await process.communicate()
105
+ err = stderr.decode().strip()
106
+ out = stdout.decode().strip()
107
+ return out, err
108
+
109
+ async def resize_media(media: str, video: bool, fast_forward: bool) -> str:
110
+ if video:
111
+ info_ = Media_Info.data(media)
112
+ width = info_["pixel_sizes"][0]
113
+ height = info_["pixel_sizes"][1]
114
+ sec = info_["duration_in_ms"]
115
+ s = round(float(sec)) / 1000
116
+
117
+ if height == width:
118
+ height, width = 512, 512
119
+ elif height > width:
120
+ height, width = 512, -1
121
+ elif width > height:
122
+ height, width = -1, 512
123
+
124
+ resized_video = f"{media}.webm"
125
+ if fast_forward:
126
+ if s > 3:
127
+ fract_ = 3 / s
128
+ ff_f = round(fract_, 2)
129
+ set_pts_ = ff_f - 0.01 if ff_f > fract_ else ff_f
130
+ cmd_f = f"-filter:v 'setpts={set_pts_}*PTS',scale={width}:{height}"
131
+ else:
132
+ cmd_f = f"-filter:v scale={width}:{height}"
133
+ else:
134
+ cmd_f = f"-filter:v scale={width}:{height}"
135
+ fps_ = float(info_["frame_rate"])
136
+ fps_cmd = "-r 30 " if fps_ > 30 else ""
137
+ cmd = f"ffmpeg -i {media} {cmd_f} -ss 00:00:00 -to 00:00:03 -an -c:v libvpx-vp9 {fps_cmd}-fs 256K {resized_video}"
138
+ _, error, __, ___ = await run_cmd(cmd)
139
+ os.remove(media)
140
+ return resized_video
141
+
142
+ image = Image.open(media)
143
+ maxsize = 512
144
+ scale = maxsize / max(image.width, image.height)
145
+ new_size = (int(image.width * scale), int(image.height * scale))
146
+
147
+ image = image.resize(new_size, Image.LANCZOS)
148
+ resized_photo = "sticker.png"
149
+ image.save(resized_photo)
150
+ os.remove(media)
151
+ return resized_photo
152
+
153
+ def get_text(message: Message) -> [None, str]:
154
+ """Extract Text From Commands"""
155
+ text_to_return = message.text
156
+ if message.text is None:
157
+ return None
158
+ if " " in text_to_return:
159
+ try:
160
+ return message.text.split(None, 1)[1]
161
+ except IndexError:
162
+ return None
163
+ else:
164
+ return None
165
+
166
+ def get_arg(message: Message):
167
+ msg = message.text
168
+ msg = msg.replace(" ", "", 1) if msg[1] == " " else msg
169
+ split = msg[1:].replace("\n", " \n").split(" ")
170
+ if " ".join(split[1:]).strip() == "":
171
+ return ""
172
+ return " ".join(split[1:])
173
+
174
+ def get_args(message: Message):
175
+ try:
176
+ message = message.text
177
+ except AttributeError:
178
+ pass
179
+ if not message:
180
+ return False
181
+ message = message.split(maxsplit=1)
182
+ if len(message) <= 1:
183
+ return []
184
+ message = message[1]
185
+ try:
186
+ split = shlex.split(message)
187
+ except ValueError:
188
+ return message
189
+ return list(filter(lambda x: len(x) > 0, split))
190
+
191
+ async def run_cmd(cmd: str) -> Tuple[str, str, int, int]:
192
+ """Run Commands"""
193
+ args = shlex.split(cmd)
194
+ process = await asyncio.create_subprocess_exec(
195
+ *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
196
+ )
197
+ stdout, stderr = await process.communicate()
198
+ return (
199
+ stdout.decode("utf-8", "replace").strip(),
200
+ stderr.decode("utf-8", "replace").strip(),
201
+ process.returncode,
202
+ process.pid,
203
+ )
204
+
205
+ async def convert_to_image(message, client) -> [None, str]:
206
+ """Convert Most Media Formats To Raw Image"""
207
+ if not message:
208
+ return None
209
+ if not message.reply_to_message:
210
+ return None
211
+ final_path = None
212
+ if not (
213
+ message.reply_to_message.video
214
+ or message.reply_to_message.photo
215
+ or message.reply_to_message.sticker
216
+ or message.reply_to_message.media
217
+ or message.reply_to_message.animation
218
+ or message.reply_to_message.audio
219
+ ):
220
+ return None
221
+ if message.reply_to_message.photo:
222
+ final_path = await message.reply_to_message.download()
223
+ elif message.reply_to_message.sticker:
224
+ if message.reply_to_message.sticker.mime_type == "image/webp":
225
+ final_path = "webp_to_png_s_proton.png"
226
+ path_s = await message.reply_to_message.download()
227
+ im = Image.open(path_s)
228
+ im.save(final_path, "PNG")
229
+ else:
230
+ path_s = await client.download_media(message.reply_to_message)
231
+ final_path = "lottie_proton.png"
232
+ cmd = (
233
+ f"lottie_convert.py --frame 0 -if lottie -of png {path_s} {final_path}"
234
+ )
235
+ await run_cmd(cmd)
236
+ elif message.reply_to_message.audio:
237
+ thumb = message.reply_to_message.audio.thumbs[0].file_id
238
+ final_path = await client.download_media(thumb)
239
+ elif message.reply_to_message.video or message.reply_to_message.animation:
240
+ final_path = "fetched_thumb.png"
241
+ vid_path = await client.download_media(message.reply_to_message)
242
+ await run_cmd(f"ffmpeg -i {vid_path} -filter:v scale=500:500 -an {final_path}")
243
+ return final_path
244
+
245
+ async def get_ub_chats(
246
+ client: Client,
247
+ chat_types: list = [
248
+ enums.ChatType.GROUP,
249
+ enums.ChatType.SUPERGROUP,
250
+ enums.ChatType.CHANNEL,
251
+ ],
252
+ is_id_only=True,
253
+ ):
254
+ ub_chats = []
255
+ async for dialog in client.get_dialogs():
256
+ if dialog.chat.type in chat_types:
257
+ if is_id_only:
258
+ ub_chats.append(dialog.chat.id)
259
+ else:
260
+ ub_chats.append(dialog.chat)
261
+ else:
262
+ continue
263
+ return ub_chats
264
+
265
+ def ReplyCheck(message: Message):
266
+ reply_id = None
267
+
268
+ if message.reply_to_message:
269
+ reply_id = message.reply_to_message.id
270
+
271
+ elif not message.from_user.is_self:
272
+ reply_id = message.id
273
+
274
+ return reply_id
275
+
276
+ def SpeedConvert(size):
277
+ power = 2**10
278
+ zero = 0
279
+ units = {0: "", 1: "Kbit/s", 2: "Mbit/s", 3: "Gbit/s", 4: "Tbit/s"}
280
+ while size > power:
281
+ size /= power
282
+ zero += 1
283
+ return f"{round(size, 2)} {units[zero]}"
284
+
285
+ def GetFromUserID(message: Message):
286
+ return message.from_user.id
287
+
288
+ def GetChatID(message: Message):
289
+ return message.chat.id
290
+
291
+ def GetUserMentionable(user: User):
292
+ if user.username:
293
+ username = "@{}".format(user.username)
294
+ else:
295
+ if user.last_name:
296
+ name_string = "{} {}".format(user.first_name, user.last_name)
297
+ else:
298
+ name_string = "{}".format(user.first_name)
299
+
300
+ username = "<a href='tg://user?id={}'>{}</a>".format(user.id, name_string)
301
+
302
+ return username
303
+
304
+ def resize_image(image):
305
+ im = Image.open(image)
306
+ maxsize = (512, 512)
307
+ if (im.width and im.height) < 512:
308
+ size1 = im.width
309
+ size2 = im.height
310
+ if im.width > im.height:
311
+ scale = 512 / size1
312
+ size1new = 512
313
+ size2new = size2 * scale
314
+ else:
315
+ scale = 512 / size2
316
+ size1new = size1 * scale
317
+ size2new = 512
318
+ size1new = math.floor(size1new)
319
+ size2new = math.floor(size2new)
320
+ sizenew = (size1new, size2new)
321
+ im = im.resize(sizenew)
322
+ else:
323
+ im.thumbnail(maxsize)
324
+ file_name = "Sticker.png"
325
+ im.save(file_name, "PNG")
326
+ if os.path.exists(image):
327
+ os.remove(image)
328
+ return file_name
329
+
330
+ class Media_Info:
331
+ def data(media: str) -> dict:
332
+ "Get downloaded media's information"
333
+ found = False
334
+ media_info = MediaInfo.parse(media)
335
+ for track in media_info.tracks:
336
+ if track.track_type == "Video":
337
+ found = True
338
+ type_ = track.track_type
339
+ format_ = track.format
340
+ duration_1 = track.duration
341
+ other_duration_ = track.other_duration
342
+ duration_2 = (
343
+ f"{other_duration_[0]} - ({other_duration_[3]})"
344
+ if other_duration_
345
+ else None
346
+ )
347
+ pixel_ratio_ = [track.width, track.height]
348
+ aspect_ratio_1 = track.display_aspect_ratio
349
+ other_aspect_ratio_ = track.other_display_aspect_ratio
350
+ aspect_ratio_2 = other_aspect_ratio_[0] if other_aspect_ratio_ else None
351
+ fps_ = track.frame_rate
352
+ fc_ = track.frame_count
353
+ media_size_1 = track.stream_size
354
+ other_media_size_ = track.other_stream_size
355
+ media_size_2 = (
356
+ [
357
+ other_media_size_[1],
358
+ other_media_size_[2],
359
+ other_media_size_[3],
360
+ other_media_size_[4],
361
+ ]
362
+ if other_media_size_
363
+ else None
364
+ )
365
+
366
+ dict_ = (
367
+ {
368
+ "media_type": type_,
369
+ "format": format_,
370
+ "duration_in_ms": duration_1,
371
+ "duration": duration_2,
372
+ "pixel_sizes": pixel_ratio_,
373
+ "aspect_ratio_in_fraction": aspect_ratio_1,
374
+ "aspect_ratio": aspect_ratio_2,
375
+ "frame_rate": fps_,
376
+ "frame_count": fc_,
377
+ "file_size_in_bytes": media_size_1,
378
+ "file_size": media_size_2,
379
+ }
380
+ if found
381
+ else None
382
+ )
383
+ return dict_