managementbot / Powers /utils /web_helpers.py
Captain Ezio
few fixes
948742f
import math
import os
import time
from traceback import format_exc
from pyrogram.types import InlineKeyboardButton as IKB
from pyrogram.types import InlineKeyboardMarkup as IKM
from pyrogram.types import Message
from pytube import YouTube, extract
from youtubesearchpython.__future__ import VideosSearch
from yt_dlp import YoutubeDL
from Powers import youtube_dir
from Powers.bot_class import LOGGER, Gojo
from Powers.utils.sticker_help import resize_file_to_sticker_size
from Powers.utils.web_scrapper import SCRAP_DATA
backUP = "https://artfiles.alphacoders.com/160/160160.jpeg"
def readable_time(seconds: int) -> str:
count = 0
out_time = ""
time_list = []
time_suffix_list = ["secs", "mins", "hrs", "days"]
while count < 4:
count += 1
remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24)
if seconds == 0 and remainder == 0:
break
time_list.append(int(result))
seconds = int(remainder)
for x in range(len(time_list)):
time_list[x] = str(time_list[x]) + time_suffix_list[x]
if len(time_list) == 4:
out_time += f"{time_list.pop()}, "
time_list.reverse()
out_time += " ".join(time_list)
return out_time or "0 secs"
def humanbytes(size: int):
if not size:
return ""
power = 2 ** 10
number = 0
dict_power_n = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
while size > power:
size /= power
number += 1
return f"{str(round(size, 2))} {dict_power_n[number]}B"
async def progress(
current: int, total: int, message: Message, start: float, process: str
):
now = time.time()
diff = now - start
if round(diff % 10.00) == 0 or current == total:
percentage = current * 100 / total
speed = current / diff
elapsed_time = round(diff) * 1000
complete_time = round((total - current) / speed) * 1000
estimated_total_time = elapsed_time + complete_time
progress_str = "**[{0}{1}] : {2}%\n**".format(
"".join(["●" for _ in range(math.floor(percentage / 10))]),
"".join(["β—‹" for _ in range(10 - math.floor(percentage / 10))]),
round(percentage, 2),
)
msg = (
progress_str
+ "__{0}__ **π—ˆπ–Ώ** __{1}__\n**𝖲𝗉𝖾𝖾𝖽:** __{2}/s__\n**𝖀𝖳𝖠:** __{3}__".format(
humanbytes(current),
humanbytes(total),
humanbytes(speed),
readable_time(estimated_total_time / 1000),
)
)
await message.edit_text(f"**{process} ...**\n\n{msg}")
async def get_file_size(file: Message):
if file.photo:
size = file.photo.file_size / 1024
elif file.document:
size = file.document.file_size / 1024
elif file.video:
size = file.video.file_size / 1024
elif file.audio:
size = file.audio.file_size / 1024
elif file.sticker:
size = file.sticker.file_size / 1024
elif file.animation:
size = file.animation.file_size / 1024
elif file.voice:
size = file.voice.file_size / 1024
elif file.video_note:
size = file.video_note.file_size / 1024
if size <= 1024:
return f"{round(size)} kb"
size = size / 1024
if size <= 1024:
return f"{round(size)} mb"
elif size > 1024:
size = size / 1024
return f"{round(size)} gb"
def get_video_id(url):
try:
_id = extract.video_id(url)
return _id or None
except Exception:
return None
def get_duration_in_sec(dur: str):
duration = dur.split(":")
return (
(int(duration[0]) * 60) + int(duration[1])
if len(duration) == 2
else int(duration[0])
)
# Gets yt result of given query.
async def song_search(query, max_results=1):
yt_dict = {}
try:
videos = VideosSearch(query, max_results)
results = await videos.next()
except Exception as e:
LOGGER.error(e)
LOGGER.error(format_exc())
return {0: e}
nums = 1
for i in results["result"]:
durr = i['duration'].split(":")
if len(durr) == 3:
hour_to_sec = int(durr[0]) * 60 * 60
minutes_to_sec = int(durr[1]) * 60
total = hour_to_sec + minutes_to_sec + int(durr[2])
if len(durr) == 2:
minutes_to_sec = int(durr[0]) * 60
total = minutes_to_sec + int(durr[1])
if total <= 600:
dict_form = {
"link": i["link"],
"title": i["title"],
"views": i["viewCount"]["short"],
"channel": i["channel"]["link"],
"duration": i["accessibility"]['duration'],
"DURATION": i["duration"],
"published": i["publishedTime"],
}
try:
dict_form["uploader"] = i["channel"]["name"]
except Exception:
dict_form["uploader"] = "Captain D. Ezio"
try:
thumb = {"thumbnail": i["thumbnails"][0]["url"]}
except Exception:
thumb = {"thumbnail": None}
dict_form.update(thumb)
yt_dict[nums] = dict_form
nums += 1
return yt_dict
song_opts = {
"format": "bestaudio",
"addmetadata": True,
"key": "FFmpegMetadata",
"prefer_ffmpeg": True,
"geo_bypass": True,
"nocheckcertificate": True,
"postprocessors": [
{
"key": "FFmpegExtractAudio",
"preferredcodec": "mp3",
"preferredquality": "480",
}
],
"outtmpl": "%(id)s",
"quiet": True,
"logtostderr": False,
}
video_opts = {
"format": "best",
"addmetadata": True,
"key": "FFmpegMetadata",
"prefer_ffmpeg": True,
"geo_bypass": True,
"nocheckcertificate": True,
"postprocessors": [
{
"key": "FFmpegVideoConvertor",
"preferedformat": "mp4",
}
],
"outtmpl": "%(id)s.mp4",
"quiet": True,
"logtostderr": False,
}
async def youtube_downloader(c: Gojo, m: Message, query: str, type_: str):
if type_ == "a":
opts = song_opts
video = False
song = True
ext = "mp3"
elif type_ == "v":
opts = video_opts
video = True
song = False
ext = "mp4"
# ydl = yt_dlp.YoutubeDL(opts)
dicti = await song_search(query, 1)
if err := dicti.get(0, None):
await m.reply_text(err)
return
if not dicti and type(dicti) != str:
await m.reply_text("File with duration less than or equals to 10 minutes is allowed only")
elif type(dicti) == str:
await m.reply_text(dicti)
return
try:
query = dicti[1]['link']
except KeyError:
return
yt = YouTube(query)
if yt.age_restricted:
await m.reply_text("This video is age restricted")
return
dicti = dicti[1]
f_name = dicti["title"]
views = dicti["views"]
up_url = dicti["channel"]
uploader = dicti["uploader"]
dura = dicti["duration"]
thumb = dicti["thumbnail"]
vid_dur = get_duration_in_sec(dicti["DURATION"])
published_on = dicti["published"]
if thumb:
try:
thumb = SCRAP_DATA(thumb).get_images()
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
except Exception as e:
LOGGER.error(e)
LOGGER.error(format_exc())
LOGGER.info("Using back up image as thumbnail")
thumb = SCRAP_DATA(backUP).get_images()
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
else:
thumb = SCRAP_DATA(backUP).get_images()
thumb = await resize_file_to_sticker_size(thumb[0], 320, 320)
# FILE = ydl.extract_info(query,download=video)
url = query
cap = f"""
β€· Name: `{f_name}`
β€· Duration: `{dura}`
β€· Views: `{views}`
β€· Published: `{published_on}`
Downloaded by: @{c.me.username}
"""
upload_text = f"**⬆️ π–΄π—‰π—…π—ˆπ–Ίπ–½π—‚π—‡π—€ {'audio' if song else 'video'}** \\**⚘ 𝖳𝗂𝗍𝗅𝖾:** `{f_name[:50]}`\n*⚘ 𝖒𝗁𝖺𝗇𝗇𝖾𝗅:** `{uploader}`"
kb = IKM(
[
[IKB(f"✘ {uploader.capitalize()} ✘", url=f"{up_url}")],
[IKB("✘ Youtube url ✘", url=f"{url}")],
]
)
def get_my_file(opts, ext):
try:
with YoutubeDL(opts) as ydl:
ydl.download([query])
info = ydl.extract_info(query, False)
file_name = ydl.prepare_filename(info)
if len(file_name.rsplit(".", 1)) != 2:
file_name = f"{file_name}.{ext}"
new = info['title'].replace('/', '|').replace('\\', '|')
new_file = f"{youtube_dir}{new}.{ext}"
os.rename(file_name, new_file)
return True, new_file
except Exception as e:
return False, str(e)
if song:
success, file_path = get_my_file(opts, ext)
if not success:
await m.reply_text(file_path)
return
msg = await m.reply_text(upload_text)
await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,
performer=uploader, progress=progress, progress_args=(msg, time.time(), upload_text))
await msg.delete()
os.remove(file_path)
return
elif video:
success, file_path = get_my_file(opts, ext)
if not success:
await m.reply_text(file_path)
return
msg = await m.reply_text(upload_text)
await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, progress=progress,
progress_args=(msg, time.time(), upload_text))
await msg.delete()
os.remove(file_path)
return