diff --git a/requirements.txt b/requirements.txt index 9df324046..483f67d8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,35 +1,33 @@ aiofiles>=0.6.0 -aiohttp[speedups]>=3.7.3 -asyncurban +aiohttp[speedups]>=3.8.1 +asyncurban>=0.3.3 beautifulsoup4>=4.9.1 -colour +colour>=0.1.5 cowpy>=1.1.0 -dnspython>=2.0.0 -futures==2.2.0 +dnspython==2.3.0 +futures>=3.0.5 gitpython>=3.1.11 google-api-python-client>=1.12.8 google-auth-httplib2>=0.0.4 google-auth-oauthlib>=0.4.2 git+https://github.com/Joeclinton1/google-images-download@patch-1 googletrans==3.1.0a0 -gtts +gtts>=2.2.4 hachoir>=3.1.1 heroku3>=4.2.3 html-telegraph-poster>=0.2.31 lyricsgenius -motor>=2.3.0 -music_tag -numpy -nekosbest +motor==3.2.0 +pymongo==4.4.0 +music_tag>=0.4.3 +numpy>=1.23.2 oauth2client>=4.1.3 Pillow==9.0.1 psutil>=5.7.3 pybase64>=1.1.1 PyDictionary>=2.0.1 -pymediainfo +pymediainfo>=5.1.0 git+https://github.com/ashwinstr/pyrogram.git@x21 -# git+https://github.com/pyrogram/pyrogram.git@master -# pyrogram==1.4.7 pySmartDL>=1.3.4 python-dotenv>=0.15.0 pytz>=2020.4 @@ -40,17 +38,25 @@ search-engine-parser selenium==3.141.0 setuptools>=60.0.4 spamwatch>=0.3.0 -speedtest-cli>=2.1.3 -stagger>=1.0.0 +#speedtest-cli>=2.1.3 +git+https://github.com/Notmarrco/speedtest-cli +git+https://github.com/MichaelCook/stagger telegraph>=1.4.1 -tgcrypto +tgcrypto>=1.2.3 urbandict>=0.5 -vcsi +vcsi>=7.0.13 wget>=3.2 wikipedia>=1.4.0 -youtube_dl -#git+https://github.com/Nekos-life/Async-nekos.life-wrapper +yt_dlp>=2022.8.19 ruamel.yaml==0.17.21 ujson>=4.0.1 youtube-search-python==1.5.1 feedparser>=6.0.2 + + +### Ded / Reqs with issues ### +# nekosbest +# git+https://github.com/pyrogram/pyrogram.git@master +# pyrogram==1.4.7 +# youtube_dl #slow af +# git+https://github.com/Nekos-life/Async-nekos.life-wrapper diff --git a/userge/plugins/admin/gadmin.py b/userge/plugins/admin/gadmin.py index 663acc8dc..f596e2e1d 100644 --- a/userge/plugins/admin/gadmin.py +++ b/userge/plugins/admin/gadmin.py @@ -61,8 +61,8 @@ async def promote_usr(message: Message): can_restrict_members=True, can_invite_users=True, can_pin_messages=True, - can_promote_members=True if "-full" in message.flags else False, - can_manage_voice_chats=True if "-full" in message.flags else False, + can_promote_members=("-full" in message.flags), + can_manage_voice_chats=("-full" in message.flags), ) if custom_rank: await asyncio.sleep(2) @@ -112,14 +112,16 @@ async def demote_usr(message: Message): return try: get_mem = await message.client.get_chat_member(chat_id, user_id) - await message.client.promote_chat_member( + await message.client.restrict_chat_member( + chat_id, + user_id, + ChatPermissions(), + ) + await asyncio.sleep(1) + await message.client.restrict_chat_member( chat_id, user_id, - can_change_info=False, - can_delete_messages=False, - can_restrict_members=False, - can_invite_users=False, - can_pin_messages=False, + message.chat.permissions, ) await message.edit("`šŸ›” Demoted Successfully..`", del_in=5) await CHANNEL.log( diff --git a/userge/plugins/admin/myadminlist.py b/userge/plugins/admin/myadminlist.py new file mode 100644 index 000000000..d15cb8c51 --- /dev/null +++ b/userge/plugins/admin/myadminlist.py @@ -0,0 +1,84 @@ +"""Get Your Admin Groups and Channels""" + +# For USERGE-X +# Idea : https://github.com/kantek/.../kantek/plugins/private/stats.py +# Module By: github/code-rgb [TG - @DeletedUser420] +# Modded to Admin only By: Ryuk (anonymousx97) + +import asyncio + +from pyrogram.errors import FloodWait, UserNotParticipant + +from userge import Message, userge +from userge.utils import post_to_telegraph as pt + + +@userge.on_cmd( + "myadminlist", + about={"header": "List your Admin groups/channels.", "usage": "{tr}myadminlist"}, +) +async def get_your_admin_list(message: Message): + """get info about your Admin group/channels""" + + await message.edit( + "šŸ’ā€ā™‚ļø `Collecting your Telegram Stats ...`\n" + "Please wait it will take some time" + ) + owner = await userge.get_me() + groups_admin = [] + groups_creator = [] + channels_admin = [] + channels_creator = [] + try: + async for dialog in userge.iter_dialogs(): + chat_type = dialog.chat.type + if chat_type not in ["bot", "private"]: + try: + is_admin = await admin_check(dialog.chat.id, owner.id) + is_creator = dialog.chat.is_creator + except UserNotParticipant: + is_admin = False + is_creator = False + if chat_type in ["group", "supergroup"]: + if is_admin: + groups_admin.append(dialog.chat.title) + if is_creator: + groups_creator.append(dialog.chat.title) + else: # Channel + if is_admin: + channels_admin.append(dialog.chat.title) + if is_creator: + channels_creator.append(dialog.chat.title) + except FloodWait as e: + await asyncio.sleep(e.x + 5) + template = f"""Admin Groups/Channels of {owner.first_name}""" + text_ = "" + if channels_creator or groups_creator: + if groups_creator: + text_ += f"""\n

Owner of Groups:

\nā€¢ """ + "\nā€¢ ".join( + sorted(groups_creator) + ) + if channels_creator: + text_ += f"""\n\n\n

Owner of Channels:

\nā€¢ """ + "\nā€¢ ".join( + sorted(channels_creator) + ) + if groups_admin: + text_ += f"""\n\n\n

Admin in Groups:

\nā€¢ """ + "\nā€¢ ".join( + sorted(groups_admin) + ) + if channels_admin: + text_ += f"""\n\n\n

Admin in Channels:

\nā€¢ """ + "\nā€¢ ".join( + sorted(channels_admin) + ) + telegraph = pt(template.replace("\n", "
"), text_.replace("\n", "
")) + await message.edit( + f"{template} : \n[šŸ“œ TELEGRAPH]({telegraph})", disable_web_page_preview=True + ) + + +# https://git.colinshark.de/PyroBot/PyroBot/src/branch +# /master/pyrobot/modules/admin.py#L69 +async def admin_check(chat_id: int, user_id: int) -> bool: + check_status = await userge.get_chat_member(chat_id, user_id) + admin_strings = ["creator", "administrator"] + return check_status.status in admin_strings diff --git a/userge/plugins/admin/warns.py b/userge/plugins/admin/warns.py index 2f8e91725..90977bbda 100644 --- a/userge/plugins/admin/warns.py +++ b/userge/plugins/admin/warns.py @@ -93,7 +93,6 @@ async def warn_func(message: Message): wcount += 1 if wcount >= max_warns: - if warn_mode == "mute": warn_mode_text = "muted" elif warn_mode == "kick": diff --git a/userge/plugins/bot/gapps.py b/userge/plugins/bot/gapps.py index 23d8c6b38..6ca0c0b8e 100644 --- a/userge/plugins/bot/gapps.py +++ b/userge/plugins/bot/gapps.py @@ -150,7 +150,6 @@ async def nik_cb(_, callback_query: CallbackQuery): async def back_cb(_, callback_query: CallbackQuery): u_id = callback_query.from_user.id if u_id in Config.OWNER_ID or u_id in Config.SUDO_USERS: - buttons = [ [ InlineKeyboardButton("Open Gapps", callback_data="open_gapps"), diff --git a/userge/plugins/bot/utube_inline.py b/userge/plugins/bot/utube_inline.py index b1715039a..472f22489 100644 --- a/userge/plugins/bot/utube_inline.py +++ b/userge/plugins/bot/utube_inline.py @@ -529,7 +529,6 @@ def download_button(vid: str, body: bool = False): audio_dict = {} # ------------------------------------------------ # for video in vid_data["formats"]: - fr_note = video.get("format_note") fr_id = int(video.get("format_id")) fr_size = video.get("filesize") diff --git a/userge/plugins/fun/memes.py b/userge/plugins/fun/memes.py index ea33b0b2d..444e578a1 100644 --- a/userge/plugins/fun/memes.py +++ b/userge/plugins/fun/memes.py @@ -668,7 +668,6 @@ async def dice_gen(message: Message): @userge.on_cmd("emoji$", about={"header": "Multiple Animated Emojis"}) async def emoji_func(message): - switch = await message.edit_text("šŸ¤”") emoji_s = "šŸ˜† šŸ˜‚ šŸ˜³ šŸ˜’ šŸ§ šŸ¤” šŸ˜ šŸ˜˜ šŸ„° šŸ„³ šŸ˜Œ šŸ˜® šŸ™„ šŸ˜ šŸ˜§ šŸ˜” šŸ˜¢ šŸ˜” šŸ˜Ø šŸŽƒ šŸ¤• šŸ¤’ šŸ˜· šŸ¤§ šŸ¤¢ šŸ¤® šŸ‘ šŸ’ ā¤ šŸ’‹ šŸ˜» šŸŽ‰ šŸŽ„ šŸ‘› šŸ’Ž šŸ™ˆ ā˜ƒ šŸ“ šŸ‘» šŸ’€ šŸ¦  šŸš‘" @@ -682,7 +681,6 @@ async def emoji_func(message): @userge.on_cmd("bigoof$", about={"header": "Use when something is beyond just oof"}) async def bigf_func(message): - animation_chars = [ "`ā”ā”ā”ā”ā”“ā•‹ā•‹ā•‹ā•‹ā”ā”ā”ā”ā”“ \nā”ƒā”ā”ā”“ā”ƒā•‹ā•‹ā•‹ā•‹ā”ƒā”ā”ā”“ā”ƒ \nā”ƒā”ƒā•‹ā”ƒā”£ā”“ā”ā”“ā”ā”«ā”ƒā•‹ā”ƒā”ƒ \nā”ƒā”ƒā•‹ā”ƒā”ƒā”—ā”›ā”—ā”›ā”ƒā”ƒā•‹ā”ƒā”ƒ \nā”ƒā”—ā”ā”›ā”£ā”“ā”ā”“ā”ā”«ā”—ā”ā”›ā”ƒ \nā”—ā”ā”ā”ā”›ā”—ā”›ā”—ā”›ā”—ā”ā”ā”ā”›`", "`ā•­ā”ā”ā”ā•®ā•±ā•±ā•±ā•­ā”ā•® \nā”ƒā•­ā”ā•®ā”ƒā•±ā•±ā•±ā”ƒā•­ā•Æ \nā”ƒā”ƒā•±ā”ƒā”£ā”ā”ā”³ā•Æā•°ā•® \nā”ƒā”ƒā•±ā”ƒā”ƒā•­ā•®ā”£ā•®ā•­ā•Æ \nā”ƒā•°ā”ā•Æā”ƒā•°ā•Æā”ƒā”ƒā”ƒ \nā•°ā”ā”ā”ā”»ā”ā”ā•Æā•°ā•Æ`", diff --git a/userge/plugins/fun/spotify_bio.py b/userge/plugins/fun/spotify_bio.py index 9051e9139..0443c01e5 100644 --- a/userge/plugins/fun/spotify_bio.py +++ b/userge/plugins/fun/spotify_bio.py @@ -225,7 +225,6 @@ def save_spam(which, what): return False async def spotify_bio_(): - while Config.SPOTIFY_MODE: # SPOTIFY skip = False diff --git a/userge/plugins/help.py b/userge/plugins/help.py index 01593d765..b8d8ac544 100644 --- a/userge/plugins/help.py +++ b/userge/plugins/help.py @@ -518,7 +518,6 @@ async def inline_answer(_, inline_query: InlineQuery): ) and Config.SUDO_ENABLED ): - if string == "syntax": owner = [ [ diff --git a/userge/plugins/jutsu/fbans.py b/userge/plugins/jutsu/fbans.py index b668a9ffb..73715f2b9 100644 --- a/userge/plugins/jutsu/fbans.py +++ b/userge/plugins/jutsu/fbans.py @@ -7,6 +7,7 @@ # Thanks @Lostb053 for writing help # plugin modified for USERGE-X by @Kakashi_HTK(TG)/@ashwinstr(GH) # before porting please ask to Kakashi +# Maintained by Ryuk import asyncio import os @@ -28,15 +29,18 @@ async def _init() -> None: f_t = await SAVED_SETTINGS.find_one({"_id": "FBAN_TAG"}) if f_t: Config.FBAN_TAG = f_t["data"] + found = await SAVED_SETTINGS.find_one({"_id": "F_ADEL"}) + if found: + Config.F_ADEL = found["switch"] + else: + Config.F_ADEL = False @userge.on_cmd( "fban_tag", about={ "header": "enable / disable fbanner's tag", - "flags": { - "-c": "check", - }, + "flags": {"-c": "check"}, "usage": "{tr}fban_tag", }, ) @@ -60,21 +64,11 @@ async def fban_sudo_tags(message: Message): ) -async def _init() -> None: - found = await SAVED_SETTINGS.find_one({"_id": "F_ADEL"}) - if found: - Config.F_ADEL = found["switch"] - else: - Config.F_ADEL = False - - @userge.on_cmd( "f_adel", about={ "header": "toggle auto delete Fban confirmation", - "flags": { - "-c": "check", - }, + "flags": {"-c": "check"}, "usage": "{tr}f_adel", }, ) @@ -104,38 +98,26 @@ async def f_adel(message: Message): "header": "Add a chat to fed list", "description": "Add a chat to fed list where message is to be sent", "usage": "{tr}addf", + "flags": {"-fp": "forward proof to fed"}, }, allow_bots=False, allow_channels=False, ) async def addfed_(message: Message): """Adds current chat to connected Feds.""" - chat_id = message.chat.id - chat_t = await userge.get_chat(chat_id) - chat_type = chat_t.type - name = message.input_str or chat_t.title or chat_t.first_name - if chat_type == "private": - found = await FED_LIST.find_one({"schat_id": chat_id}) - if found: - await message.edit( - f"Chat __ID__: `{chat_id}`\nFed: **{found['sfed_name']}**\n\nAlready exists in Fed List !", - del_in=7, - ) - return - await FED_LIST.insert_one( - {"sfed_name": name, "schat_id": chat_id, "chat_type": chat_type} - ) - else: - found = await FED_LIST.find_one({"chat_id": chat_id}) - if found: - await message.edit( - f"Chat __ID__: `{chat_id}`\nFed: **{found['fed_name']}**\n\nAlready exists in Fed List !", - del_in=7, - ) - return - await FED_LIST.insert_one( - {"fed_name": name, "chat_id": chat_id, "chat_type": chat_type} + chat = message.chat + chat_id = chat.id + name = message.filtered_input_str or chat.title or chat.first_name + found = await FED_LIST.find_one({"chat_id": chat_id}) + fp = "-fp" in message.flags + if found: + return await message.edit( + f"Chat __ID__: `{chat_id}`\nFed: **{found['fed_name']}**\n\nAlready exists in Fed List !", + del_in=7, ) + await FED_LIST.insert_one( + {"fed_name": name, "chat_id": chat_id, "chat_type": chat.type, "fp": fp} + ) msg_ = f"__ID__ `{chat_id}` added to Fed: **{name}**" await message.edit(msg_, del_in=7) await CHANNEL.log(msg_) @@ -161,35 +143,23 @@ async def delfed_(message: Message): else: try: chat_ = await message.client.get_chat(message.input_str or message.chat.id) - chat_t = chat_.type + chat_.type chat_id = chat_.id - chat_.title except (PeerIdInvalid, IndexError): chat_id = message.input_str id_ = chat_id.replace("-", "") if not id_.isdigit() or not chat_id.startswith("-"): return await message.err("Provide a valid chat ID...", del_in=7) out = f"Chat ID: {chat_id}\n" - if chat_t == "private": - found = await FED_LIST.find_one({"schat_id": int(chat_id)}) - if found: - msg_ = out + f"Successfully Removed Fed: **{found['sfed_name']}**" - await message.edit(msg_, del_in=7) - await FED_LIST.delete_one(found) - else: - return await message.err( - out + "**Does't exist in your Fed List !**", del_in=7 - ) + found = await FED_LIST.find_one({"chat_id": int(chat_id)}) + if found: + msg_ = out + f"Successfully Removed Fed: **{found['fed_name']}**" + await message.edit(msg_, del_in=7) + await FED_LIST.delete_one(found) else: - found = await FED_LIST.find_one({"chat_id": int(chat_id)}) - if found: - msg_ = out + f"Successfully Removed Fed: **{found['fed_name']}**" - await message.edit(msg_, del_in=7) - await FED_LIST.delete_one(found) - else: - return await message.err( - out + "**Does't exist in your Fed List !**", del_in=7 - ) + return await message.err( + out + "**Does't exist in your Fed List !**", del_in=7 + ) await CHANNEL.log(msg_) @@ -198,9 +168,7 @@ async def delfed_(message: Message): about={ "header": "Fban user", "description": "Fban the user from the list of fed", - "flags": { - "-d": "auto-delete message", - }, + "flags": {"-d": "auto-delete message"}, "usage": "{tr}fban [username|reply to user|user_id] [reason (optional)]", }, allow_bots=False, @@ -212,6 +180,7 @@ async def fban_(message: Message): PROOF_CHANNEL = FBAN_LOG_CHANNEL if FBAN_LOG_CHANNEL else Config.LOG_CHANNEL_ID input = message.filtered_input_str await message.edit(fban_arg[0]) + initialised_in_chat = message.chat.title or message.chat.first_name sudo_ = False if ( message.from_user.id in Config.SUDO_USERS @@ -292,14 +261,9 @@ async def fban_(message: Message): reason = reason or "Not specified." await message.edit(fban_arg[1]) async for data in FED_LIST.find(): - is_chat = True - try: - chat_id = int(data["chat_id"]) - except KeyError: - chat_id = int(data["schat_id"]) - is_chat = False + chat_id = int(data["chat_id"]) - if is_chat: + if data["chat_type"] != "private": total += 1 try: await userge.send_message( @@ -363,8 +327,9 @@ async def fban_(message: Message): fban_arg[3].format(u_link) + f"\n**ID:** {u_id}\n**Reason:** {reason}\n**Status:** {status}\n" ) + msg_ += f"**Ban Initialised in**: __{initialised_in_chat}__" if sudo_: - msg_ += f"**By:** {message.from_user.mention}" + msg_ += f"\n**By:** {message.from_user.mention}" del_ = 3 if "-d" in message.flags or Config.F_ADEL else -1 await message.edit(msg_, del_in=del_) await userge.send_message(int(PROOF_CHANNEL), msg_) @@ -409,6 +374,7 @@ async def fban_p(message: Message): f"`The FBAN_LOG_CHANNEL ID provided ('{FBAN_LOG_CHANNEL}') is invalid, enter correct one.`", del_in=5, ) + initialised_in_chat = message.chat.title or message.chat.first_name if channel_.username is None or channel_.type != "channel": await message.edit( "Proof channel should be a channel and should be public for this command to work...", @@ -515,33 +481,22 @@ async def fban_p(message: Message): total = 0 await message.edit(fban_arg[1]) log_fwd = await userge.forward_messages( - int(FBAN_LOG_CHANNEL), - from_chat_id=chat_id, - message_ids=proof, + int(FBAN_LOG_CHANNEL), from_chat_id=chat_id, message_ids=proof ) reason = reason or "Not specified" - reason += " || {" + f"{log_fwd.link}" + "}" + reason += " || {" + log_fwd.link + "}" if fps: - report_user( - chat=chat_id, - user_id=user, - msg=msg_en, - msg_id=proof, - reason=reason, - ) + report_user(chat=chat_id, user_id=user, msg=msg_en, msg_id=proof, reason=reason) reported = " and reported " else: reported = "" async for data in FED_LIST.find(): - is_chat = True - try: - chat_id = int(data["chat_id"]) - except KeyError: - chat_id = int(data["schat_id"]) - is_chat = False - if is_chat: + chat_id = int(data["chat_id"]) + if data["chat_type"] != "private": total += 1 try: + if data.get("fp"): + await log_fwd.forward(chat_id) await userge.send_message( chat_id, f"/fban {user} {reason}", @@ -604,8 +559,9 @@ async def fban_p(message: Message): fban_arg[3].format(reported, u_link) + f"\n**ID:** {u_id}\n**Reason:** {reason}\n**Status:** {status}\n" ) + msg_ += f"**Ban Initialised in**: __{initialised_in_chat}__" if sudo_: - msg_ += f"**By:** {message.from_user.mention}" + msg_ += f"\n**By:** {message.from_user.mention}" del_ = 3 if "-d" in message.flags or Config.F_ADEL else -1 await message.edit(msg_, del_in=del_, disable_web_page_preview=True) await userge.send_message( @@ -723,13 +679,8 @@ async def unfban_(message: Message): total = 0 await message.edit(fban_arg[1]) async for data in FED_LIST.find(): - is_chat = True - try: - chat_id = int(data["chat_id"]) - except KeyError: - chat_id = int(data["schat_id"]) - is_chat = False - if is_chat: + chat_id = int(data["chat_id"]) + if data["chat_type"] != "private": total += 1 try: async with userge.conversation(chat_id, timeout=8) as conv: @@ -787,32 +738,31 @@ async def unfban_(message: Message): about={ "header": "Fed Chat List", "description": "Get a list of chats added in fed", - "flags": { - "-id": "Show fed group id in list.", - }, + "flags": {"-id": "Show fed group id in list."}, "usage": "{tr}listf", }, ) async def fban_lst_(message: Message): """List all connected Feds.""" - out = "" + normal_feds = "__ā€¢ Normal Feds__ :\n" + sudo_feds = "\nā€¢ __Sudo Fed__ :\n" + proofed_feds = "\n__ā€¢ Proof Logged in Feds__ :\n" total = 0 async for data in FED_LIST.find(): - is_chat = True - try: - chat_id = int(data["chat_id"]) - except KeyError: - chat_id = int(data["schat_id"]) - is_chat = False - if is_chat: + chat_id = int(data["chat_id"]) + id_ = f"'{chat_id}' - " if "-id" in message.flags else "" + if data["chat_type"] != "private": + if fp := data.get("fp"): + proofed_feds += f" {id_}{data['fed_name']}\n" + else: + normal_feds += f" {id_}{data['fed_name']}\n" total += 1 - id_ = f"'{chat_id}' - " if "-id" in message.flags else "" - out += f"ā€¢ Fed: {id_}{data['fed_name']}\n" else: - out += f"\nā€¢ SUDO FED : {data['sfed_name']}\n" + sudo_feds += f" {data['fed_name']}\n" + out = normal_feds + proofed_feds + sudo_feds await message.edit_or_send_as_file( f"**Connected federations: [{total}]**\n\n" + out - if out + if total else "**You haven't connected to any federations yet!**", caption="Connected Fed List", ) diff --git a/userge/plugins/tools/executor.py b/userge/plugins/tools/executor.py index 15e92406e..358ee863b 100644 --- a/userge/plugins/tools/executor.py +++ b/userge/plugins/tools/executor.py @@ -16,7 +16,7 @@ from getpass import getuser from os import geteuid -from userge import Config, Message, userge +from userge import Message, userge from userge.utils import runcmd CHANNEL = userge.getCLogger() @@ -156,19 +156,25 @@ async def term_(message: Message): except ImportError: uid = 1 output = f"{curruser}:~# {cmd}\n" if uid == 0 else f"{curruser}:~$ {cmd}\n" - count = 0 - while not t_obj.finished: - count += 1 + sleep_for = 1 + _stdout = "" + async for stdout in t_obj.get_output(): if message.process_is_canceled: t_obj.cancel() - await message.reply("`process canceled!`") - return - await asyncio.sleep(0.5) - if count >= Config.EDIT_SLEEP_TIMEOUT * 2: - count = 0 - out_data = f"
{output}{t_obj.read_line}
" - await message.try_to_edit(out_data, parse_mode="html") - out_data = f"
{output}{t_obj.get_output}
" + return await message.reply("`process canceled!`") + if _stdout != stdout: + if len(stdout) <= 4096: + await message.edit( + f"{stdout}", + disable_web_page_preview=True, + parse_mode="html", + ) + _stdout = stdout + if sleep_for >= 6: + sleep_for = 1 + sleep_for += 1 + await asyncio.sleep(sleep_for) + out_data = f"
{output}{t_obj.full_std}
" await message.edit_or_send_as_file( out_data, parse_mode="html", filename="term.txt", caption=cmd ) @@ -186,59 +192,40 @@ async def init_func(message: Message): class Term: - """live update term class""" - - def __init__(self, process: asyncio.subprocess.Process) -> None: - self._process = process - self._stdout = b"" - self._stderr = b"" - self._stdout_line = b"" - self._stderr_line = b"" - self._finished = False - - def cancel(self) -> None: - self._process.kill() - - @property - def finished(self) -> bool: - return self._finished - - @property - def read_line(self) -> str: - return (self._stdout_line + self._stderr_line).decode("utf-8").strip() + "Live Term By Ryuk" - @property - def get_output(self) -> str: - return (self._stdout + self._stderr).decode("utf-8").strip() + def __init__(self, process): + self.process = process + self.full_std = "" + self.is_done = False - async def _read_stdout(self) -> None: + async def read_output(self): while True: - line = await self._process.stdout.readline() - if line: - self._stdout_line = line - self._stdout += line - else: + line = (await self.process.stdout.readline()).decode("utf-8") + if not line: break + self.full_std += line + self.is_done = True + await self.process.wait() - async def _read_stderr(self) -> None: - while True: - line = await self._process.stderr.readline() - if line: - self._stderr_line = line - self._stderr += line - else: - break + async def get_output(self): + while not self.is_done: + yield self.full_std - async def worker(self) -> None: - await asyncio.wait([self._read_stdout(), self._read_stderr()]) - await self._process.wait() - self._finished = True + def cancel(self): + if not self.is_done: + self.process.kill() + self._task.cancel() @classmethod - async def execute(cls, cmd: str) -> "Term": - process = await asyncio.create_subprocess_shell( - cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + async def execute(cls, cmd): + sub_process = cls( + process=await asyncio.create_subprocess_shell( + cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT + ) ) - t_obj = cls(process) - asyncio.get_event_loop().create_task(t_obj.worker()) - return t_obj + sub_process._task = asyncio.create_task( + sub_process.read_output(), name="AsyncShell" + ) + await asyncio.sleep(0.5) + return sub_process diff --git a/userge/plugins/tools/neofetch.py b/userge/plugins/tools/neofetch.py index 373ca501a..0504f9a03 100644 --- a/userge/plugins/tools/neofetch.py +++ b/userge/plugins/tools/neofetch.py @@ -79,10 +79,6 @@ async def neo_image(): y += 13 new_pic = BytesIO() photo = photo.resize(photo.size, Image.ANTIALIAS) - if me.id in kakashi: - photo.save(new_pic, format="PNG") - new_pic.name = "NeoFetch.png" - else: - photo.save(new_pic, format="JPG") - new_pic.name = "NeoFetch.jpg" + photo.save(new_pic, format="PNG") + new_pic.name = "NeoFetch.png" return new_pic diff --git a/userge/plugins/useless/song.py b/userge/plugins/useless/song.py index 886e9b0e4..be4c95323 100644 --- a/userge/plugins/useless/song.py +++ b/userge/plugins/useless/song.py @@ -4,13 +4,17 @@ import glob import os import shutil -from subprocess import call +import traceback from time import time -import music_tag +import yt_dlp +from wget import download from userge import Message, userge +LOGGER = userge.getLogger(__name__) +CHANNEL = userge.getCLogger(__name__) + @userge.on_cmd( "song", @@ -25,41 +29,70 @@ async def song_dl(message: Message): audio_path = None thumb_path = None artist = None + thumb = None reply = message.reply_to_message if reply: for link in reply.text.split(): - if link.startswith(("http://www.youtube.com", "https://www.youtube.com")): + if link.startswith( + ( + "https://www.youtube", + "https://youtube", + "https://music.youtube", + "https://youtu.be", + ) + ): reply_query = link break - query = reply_query if reply_query else message.filtered_input_str + query = reply_query or message.filtered_input_str if not query: return await message.edit("Give a song name or link to download.", del_in=5) await message.edit("Searching....") starttime = time() - dl_path = f"downloads/{starttime}" + dl_path = f"downloads/{starttime}/" + query_or_search = query if query.startswith("http") else f"ytsearch:{query}" if "-m" in message.flags: - quality = f"--audio-format mp3 --audio-quality 320K" + aformat = "mp3" + else: + aformat = "opus" + yt_opts = { + "logger": LOGGER, + "outtmpl": dl_path + "%(title)s.%(ext)s", + "format": "bestaudio", + "postprocessors": [ + {"key": "FFmpegExtractAudio", "preferredcodec": aformat}, + {"key": "FFmpegMetadata"}, + {"key": "EmbedThumbnail"}, + ], + } + with yt_dlp.YoutubeDL(yt_opts) as ytdl: + try: + yt_info = ytdl.extract_info(query_or_search) + if not query_or_search.startswith("http"): + yt_info = yt_info["entries"][0] + thumb = yt_info["thumbnails"] + duration = yt_info["formats"][0]["fragments"][0]["duration"] + artist = yt_info["channel"] + except Exception: + await CHANNEL.log(str(traceback.format_exc())) + if thumb: + try: + nthumb = thumb[-11]["url"] + except IndexError: + nthumb = thumb[-1]["url"] + thumb_path = download(nthumb, dl_path) + for i in glob.glob(dl_path + "*"): + if i.endswith((".opus", ".mp3")): + audio_path = i + if audio_path is not None: + await message.edit("Uploading....") + await message.reply_audio( + audio=audio_path, + duration=int(duration), + performer=str(artist), + thumb=thumb_path, + ) + await message.delete() else: - quality = "--audio-format opus" - yt_dl = f"yt-dlp -o {dl_path}/'%(title)s.%(ext)s' --write-thumbnail --extract-audio --embed-thumbnail {quality} --add-metadata 'ytsearch:{query}'" - call(yt_dl, shell=True) - for file_ in glob.glob(dl_path + "/*"): - if file_.lower().endswith((".opus", ".mp3")): - audio_path = file_ - audio_info = music_tag.load_file(audio_path) - duration = audio_info["#length"] - artist = audio_info["artist"] - if file_.lower().endswith((".jpg", ".webp", ".png")): - thumb_path = file_ - if not audio_path: return await message.edit("Not found") - await message.edit("Uploading....") - await message.reply_audio( - audio=audio_path, - duration=int(duration), - performer=str(artist), - thumb=thumb_path, - ) - await message.delete() if os.path.exists(str(dl_path)): shutil.rmtree(dl_path) diff --git a/userge/plugins/utils/ocr.py b/userge/plugins/utils/ocr.py index b192c5b2a..c216c9a91 100644 --- a/userge/plugins/utils/ocr.py +++ b/userge/plugins/utils/ocr.py @@ -73,7 +73,6 @@ async def ocr_gen(message: Message): return if message.reply_to_message: - lang_code = message.input_str or "eng" await message.edit(r"`Trying to Read.. šŸ“–") downloaded_file_name = await message.client.download_media( diff --git a/userge/plugins/utils/speedtest.py b/userge/plugins/utils/speedtest.py index d0c2a7bb1..5eeb51476 100644 --- a/userge/plugins/utils/speedtest.py +++ b/userge/plugins/utils/speedtest.py @@ -6,10 +6,10 @@ # # All rights reserved. +import asyncio import os import speedtest -import wget from userge import Message, userge from userge.utils import humanbytes @@ -34,12 +34,18 @@ async def speedtst(message: Message): test.download() await message.try_to_edit("`Performing upload test . . .`") test.upload() - test.results.share() result = test.results.dict() + url = test.results.share() except Exception as e: await message.err(text=e) return - path = wget.download(result["share"]) + download = await asyncio.create_subprocess_shell(f"wget {url}") + await download.communicate() + file = os.path.basename(url) + if os.path.isfile(file): + path = file + else: + path = url output = f"""**--Started at {result['timestamp']}-- Client: {user}