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
{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}