Upload 5 files
Browse files- Akeno/utils/chat.py +42 -0
- Akeno/utils/handler.py +4 -0
- Akeno/utils/logger.py +6 -0
- Akeno/utils/spamwatch.py +33 -0
- Akeno/utils/tools.py +383 -0
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_
|