Add: uvLoop for non termux env.

Revert: Requirements bypass.

Fixes:
 • Gallery-DL success bug.
 • Stop Channel links triggering in chat.
 • HEIC Image format.
 • Optimize Filters.
 • Re-Load Confirmation in loader.
 • Remove Chat_ID check in join.
 • Isort removing imports.
 • Switch filename case before checking ext.
This commit is contained in:
anonymousx97 2023-07-28 15:04:30 +05:30
parent bc5f5f307a
commit b7287a6685
15 changed files with 88 additions and 67 deletions

View File

@ -38,6 +38,11 @@
# Install Pypi packages
pip install -U setuptools wheel
# For Termux Env:
grep -v uvloop req.txt | xargs -n 1 pip install
# For Non Termux Env:
pip install -r req.txt
#Setup config.env

View File

@ -5,5 +5,10 @@ load_dotenv("config.env")
from .config import Config
from .core.client import BOT
import os
if not os.environ.get("TERMUX_APK_RELEASE"):
import uvloop
uvloop.install()
bot = BOT()

View File

@ -1,8 +1,6 @@
if __name__ == "__main__":
import tracemalloc
tracemalloc.start()
from app import bot
import app.social_dl
tracemalloc.start()
bot.run(bot.boot())

View File

@ -24,4 +24,4 @@ class Gallery_DL(ScraperConfig):
files = glob.glob(f"{self.path}/*")
if not files:
return self.cleanup()
self.link = self.success = True
self.link = self.group = self.success = True

View File

@ -1,7 +1,6 @@
import asyncio
import os
import time
from urllib.parse import urlparse
import yt_dlp
@ -40,19 +39,18 @@ class YT_DL(ScraperConfig):
}
async def download_or_extract(self):
if "/playlist" in self.url:
return
if "youtu" in self.url:
if not urlparse(self.url).query:
if "/playlist" in self.url or "/live" in self.url or os.path.basename(self.url).startswith("@"):
return
self._opts["format"] = "bv[ext=mp4][res=480]+ba[ext=m4a]/b[ext=mp4]"
if "shorts" in self.url:
if "/shorts" in self.url:
self._opts["format"] = "bv[ext=mp4][res=720]+ba[ext=m4a]/b[ext=mp4]"
yt_obj = yt_dlp.YoutubeDL(self._opts)
info = yt_obj.extract_info(self.url, download=False)
if info.get("duration", 0) >= 300:
if not info or info.get("duration", 0) >= 300:
return
await asyncio.to_thread(yt_obj.download, self.url)

View File

@ -14,7 +14,6 @@ from app.core import aiohttp_tools, shell
from pyrogram.errors import MediaEmpty, PhotoSaveFileInvalid, WebpageCurlFailed
from pyrogram.types import InputMediaPhoto, InputMediaVideo
# Thanks Jeel Patel for the concept TG[@jeelpatel231]
url_map = {
"tiktok.com": Tiktok,
"www.instagram.com": Instagram,
@ -136,9 +135,9 @@ class ExtractAndSendMedia:
[os.rename(file_, file_ + ".png") for file_ in glob.glob(f"{path}/*.webp")]
images, videos, animations = [], [], []
for file in glob.glob(f"{path}/*"):
if file.endswith((".png", ".jpg", ".jpeg")):
if file.lower().endswith((".png", ".jpg", ".jpeg")):
images.append(InputMediaPhoto(file, caption=caption, has_spoiler=self.spoiler))
if file.endswith((".mp4", ".mkv", ".webm")):
if file.lower().endswith((".mp4", ".mkv", ".webm")):
has_audio = await shell.check_audio(file)
if not has_audio:
animations.append(file)
@ -150,11 +149,12 @@ class ExtractAndSendMedia:
images, videos, animations = [], [], []
downloads = await asyncio.gather(*[aiohttp_tools.in_memory_dl(url) for url in urls])
for file_obj in downloads:
if file_obj.name.endswith((".png", ".jpg", ".jpeg")):
name = file_obj.name.lower()
if name.endswith((".png", ".jpg", ".jpeg")):
images.append(InputMediaPhoto(file_obj, caption=caption, has_spoiler=self.spoiler))
if file_obj.name.endswith((".mp4", ".mkv", ".webm")):
if name.endswith((".mp4", ".mkv", ".webm")):
videos.append(InputMediaVideo(file_obj, caption=caption, has_spoiler=self.spoiler))
if file_obj.name.endswith(".gif"):
if name.endswith(".gif"):
animations.append(file_obj)
return await self.make_chunks(images, videos, animations)

View File

@ -15,7 +15,7 @@ async def session_switch():
await SESSION.close()
async def get_json(url: str, headers: dict = None, params: dict = None, retry: bool = False, json_: bool = False, timeout: int = 10):
async def get_json(url: str, headers: dict = None, params: dict = None, json_: bool = False, timeout: int = 10):
try:
async with SESSION.get(url=url, headers=headers, params=params, timeout=timeout) as ses:
if json_:
@ -31,8 +31,8 @@ async def in_memory_dl(url: str):
async with SESSION.get(url) as remote_file:
bytes_data = await remote_file.read()
file = BytesIO(bytes_data)
name = os.path.basename(urlparse(url).path.rstrip("/"))
if name.endswith(".webp"):
name = os.path.basename(urlparse(url).path.rstrip("/")).lower()
if name.endswith((".webp", ".heic")):
name = name + ".jpg"
if name.endswith(".webm"):
name = name + ".mp4"

21
app/core/client.py Executable file → Normal file
View File

@ -54,15 +54,19 @@ class BOT(Client):
await aiohttp_tools.session_switch()
async def edit_restart_msg(self):
if (restart_msg := os.environ.get("RESTART_MSG")) and (restart_chat := os.environ.get("RESTART_CHAT")):
restart_msg = os.environ.get("RESTART_MSG")
restart_chat = os.environ.get("RESTART_CHAT")
if restart_msg and restart_chat:
await super().get_chat(int(restart_chat))
await super().edit_message_text(chat_id=int(restart_chat), message_id=int(restart_msg), text="#Social-dl\n__Started__")
os.environ.pop("RESTART_MSG", "")
os.environ.pop("RESTART_CHAT", "")
async def import_modules(self):
for module_ in glob.glob("app/*/*.py"):
importlib.import_module(os.path.splitext(module_.replace("/", "."))[0])
for py_module in glob.glob("app/**/*.py", recursive=True):
name = os.path.splitext(py_module)[0]
py_name = name.replace("/", ".")
importlib.import_module(py_name)
async def log(self, text, chat=None, func=None, name="log.txt",disable_web_page_preview=True):
if chat or func:
@ -75,13 +79,18 @@ class BOT(Client):
os.execl(sys.executable, sys.executable, "-m", "app")
async def set_filter_list(self):
if chats_id := Config.AUTO_DL_MESSAGE_ID:
chats_id = Config.AUTO_DL_MESSAGE_ID
blocked_id = Config.BLOCKED_USERS_MESSAGE_ID
users = Config.USERS_MESSAGE_ID
if chats_id:
Config.CHATS = json.loads((await super().get_messages(Config.LOG_CHAT, chats_id)).text)
if blocked_id := Config.BLOCKED_USERS_MESSAGE_ID:
if blocked_id:
Config.BLOCKED_USERS = json.loads((await super().get_messages(Config.LOG_CHAT, blocked_id)).text)
if users := Config.USERS_MESSAGE_ID:
if users:
Config.USERS = json.loads((await super().get_messages(Config.LOG_CHAT, users)).text)
async def send_message(self, chat_id, text, name: str = "output.txt", **kwargs):
if len(str(text)) < 4096:
return Message.parse_message((await super().send_message(chat_id=chat_id, text=text, **kwargs)))

View File

@ -6,14 +6,19 @@ from app import Config
from app.core.MediaHandler import url_map
def DYNAMIC_CHAT_FILTER(_, __, message):
if not message.text or not message.text.startswith("https"):
def Dynamic_Chat_Filter(_, __, message):
if (
not message.text
or not message.text.startswith("https")
or message.chat.id not in Config.CHATS
or message.forward_from_chat
):
return False
chat_check = message.chat.id in Config.CHATS
user_check = True
if user := message.from_user:
user_check = user.id not in Config.BLOCKED_USERS and not user.is_bot
return bool(chat_check and user_check and check_for_urls(message.text.split()))
user = message.from_user
if user and ( user.id in Config.BLOCKED_USERS or user.is_bot ):
return False
url_check = check_for_urls(message.text.split())
return bool(url_check)
def check_for_urls(text_list):
@ -26,16 +31,21 @@ def check_for_urls(text_list):
return True
def DYNAMIC_CMD_FILTER(_, __, message):
if not message.text or not message.text.startswith(Config.TRIGGER):
def Dynamic_Cmd_Filter(_, __, message):
if (
not message.text
or not message.text.startswith(Config.TRIGGER)
or not message.from_user
or message.from_user.id not in Config.USERS
):
return False
cmd_check = message.text.split(maxsplit=1)[0].replace(Config.TRIGGER, "", 1) in Config.CMD_DICT
user_check = False
if user := message.from_user:
user_check = user.id in Config.USERS
reaction_check = bool(not message.reactions)
return bool(cmd_check and user_check and reaction_check)
start_str = message.text.split(maxsplit=1)[0]
cmd = start_str.replace(Config.TRIGGER, "", 1)
cmd_check = cmd in Config.CMD_DICT
reaction_check = not message.reactions
return bool(cmd_check and reaction_check)
chat_filter = _filters.create(DYNAMIC_CHAT_FILTER)
user_filter = _filters.create(DYNAMIC_CMD_FILTER)
chat_filter = _filters.create(Dynamic_Chat_Filter)
user_filter = _filters.create(Dynamic_Cmd_Filter)

View File

@ -3,9 +3,10 @@ import os
async def take_ss(video: str, path: str):
await run_shell_cmd(f'''ffmpeg -hide_banner -loglevel error -ss 0.1 -i "{video}" -vframes 1 "{path}/i.png"''')
if os.path.isfile(path + "/i.png"):
return path + "/i.png"
thumb = f"{path}/i.png"
await run_shell_cmd(f'''ffmpeg -hide_banner -loglevel error -ss 0.1 -i "{video}" -vframes 1 "{thumb}"''')
if os.path.isfile(thumb):
return thumb
async def check_audio(file):

View File

@ -12,11 +12,13 @@ async def loader(bot, message):
or not message.replied.document.file_name.endswith(".py")
):
return await message.reply("reply to a plugin.")
reply = await message.reply("Loading....")
file_name = message.replied.document.file_name.rstrip(".py")
sys.modules.pop(f"app.temp.{file_name}", None)
reload = sys.modules.pop(f"app.temp.{file_name}", None)
status = "Reloaded" if reload else "Loaded"
plugin = await message.replied.download("app/temp/")
try:
importlib.import_module(f"app.temp.{file_name}")
except BaseException:
return await message.reply(str(traceback.format_exc()))
await message.reply(f"Loaded {file_name}.py.")
return await reply.edit(str(traceback.format_exc()))
await reply.edit(f"{status} {file_name}.py.")

View File

@ -45,8 +45,6 @@ async def get_ids(bot, message):
@bot.add_cmd(cmd="join")
async def join_chat(bot, message):
chat = message.input
if chat.isdigit():
chat = int(f"-100{chat}")
try:
await bot.join_chat(chat)
except (KeyError, BadRequest):

View File

@ -7,7 +7,7 @@ from pyrogram.enums import ParseMode
from app import Config
from app.core import shell
from app.core import aiohttp_tools as aio
from app.core import aiohttp_tools as aio # isort:skip
# Run shell commands

11
req.txt
View File

@ -0,0 +1,11 @@
aiohttp>=3.8.4
beautifulsoup4>=4.12.2
Brotli>=1.0.9
gallery_dl>=1.25.7
pyrogram>=2.0.106
python-dotenv==0.21.0
PyExecJS>=1.5.1
tenacity>=8.2.2
tgCrypto>=1.2.3
yt-dlp>=2023.6.22
uvloop>=0.17.0

16
run
View File

@ -11,20 +11,4 @@ web.run_app(app, host='0.0.0.0', port=$API_PORT, reuse_port=True, print=None)
fi
requirements=("aiohttp>=3.8.4"
"beautifulsoup4>=4.12.2"
"Brotli>=1.0.9"
"gallery_dl>=1.25.7"
"pyrogram>=2.0.106"
"python-dotenv==0.21.0"
"PyExecJS>=1.5.1"
"tenacity>=8.2.2"
"tgCrypto>=1.2.3"
"yt-dlp>=2023.6.22"
)
for req in "${requirements[@]}"; do
pip install "${req}";
done
python3 -m app