diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..fe58f981e1dfadd66263dc91021e76b880d88df1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.env +.cache +log.txt +.DS_Store +*.session +raw_files/ +cache/ +downloads/ +__pycache__/ +*.session-journal diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..e4c28eac0aa0d7b1c6297a446b021638f6ff439f --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ttf filter=lfs diff=lfs merge=lfs -text diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab980d947014507994bd46a560d9c7d1b688d8e1 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,29 @@ +- Upgrade and Update by : + `sudo apt-get update && sudo apt-get upgrade -y` +- Install Ffmpeg by : + `sudo apt-get install python3-pip ffmpeg -y` +- Install required packages by : + `sudo apt-get install python3 python3-pip -y` +- Install pip by : + `sudo pip3 install -U pip` +- Install Node js by : + `curl -fssL https://deb.nodesource.com/setup_19.x | sudo -E bash - && sudo apt-get install nodejs -y && npm i -g npm` +- Clone the repository by : + `git clone https://github.com/xteam-cloner/Wleowleo && cd Wleowleo` +- Install requirements by : + `pip3 install -U -r requirements.txt` +- Fill your variables in the env by : + `vi sample.env`
+Press `I` on the keyboard for editing env
+Press `Ctrl+C` when you're done with editing env and `:wq` to save the env
+- Rename the env file by : + `mv sample.env .env` +- Install tmux to keep running your bot when you close the terminal by : + `sudo apt install tmux && tmux` +- Finally run the bot by : + `bash start` +- For getting out from tmux session : Press `Ctrl+b` and then `d`
+ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fe58f981e1dfadd66263dc91021e76b880d88df1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.env +.cache +log.txt +.DS_Store +*.session +raw_files/ +cache/ +downloads/ +__pycache__/ +*.session-journal diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1d05a460e13bb63b5b34f60381a8363b9fc48243 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM nikolaik/python-nodejs:python3.10-nodejs19 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ffmpeg \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY . /app/ +WORKDIR /app/ +RUN pip3 install --no-cache-dir -U -r requirements.txt + +CMD bash start diff --git a/DragMusic/Mongo/afkdb.py b/DragMusic/Mongo/afkdb.py new file mode 100644 index 0000000000000000000000000000000000000000..d7ce4bc593ee5cd661aa387981219231302b0666 --- /dev/null +++ b/DragMusic/Mongo/afkdb.py @@ -0,0 +1,33 @@ +from DragMusic.core.mongo import mongodb + +afkdb = mongodb.afk + + +async def is_afk(user_id: int) -> bool: + user = await afkdb.find_one({"user_id": user_id}) + if not user: + return False, {} + return True, user["reason"] + + +async def add_afk(user_id: int, mode): + await afkdb.update_one( + {"user_id": user_id}, {"$set": {"reason": mode}}, upsert=True + ) + + +async def remove_afk(user_id: int): + user = await afkdb.find_one({"user_id": user_id}) + if user: + return await afkdb.delete_one({"user_id": user_id}) + + +async def get_afk_users() -> list: + users = afkdb.find({"user_id": {"$gt": 0}}) + if not users: + return [] + users_list = [] + for user in await users.to_list(length=1000000000): + users_list.append(user) + return users_list + diff --git a/DragMusic/Mongo/nightmodedb.py b/DragMusic/Mongo/nightmodedb.py new file mode 100644 index 0000000000000000000000000000000000000000..8502a4f3de92e3f8df371ef9420d9488d6dd621f --- /dev/null +++ b/DragMusic/Mongo/nightmodedb.py @@ -0,0 +1,24 @@ +from typing import Dict, List, Union +from config import MONGO_DB_URI +from motor.motor_asyncio import AsyncIOMotorClient as MongoCli + + +mongo = MongoCli(MONGO_DB_URI).Rankings + +nightdb = mongo.nightmode + + +async def nightmode_on(chat_id : int) : + return nightdb.insert_one({"chat_id" : chat_id}) + +async def nightmode_off(chat_id : int): + return nightdb.delete_one({"chat_id" : chat_id}) + +async def get_nightchats() -> list: + chats = nightdb.find({"chat_id": {"$lt": 0}}) + if not chats: + return [] + chats_list = [] + for chat in await chats.to_list(length=1000000000): + chats_list.append(chat) + return chats_list diff --git a/DragMusic/Mongo/readable_time.py b/DragMusic/Mongo/readable_time.py new file mode 100644 index 0000000000000000000000000000000000000000..9cd6b5a294a5abc9d32907b00a401865dd9df683 --- /dev/null +++ b/DragMusic/Mongo/readable_time.py @@ -0,0 +1,23 @@ +def get_readable_time(seconds: int) -> str: + count = 0 + readable_time = "" + time_list = [] + time_suffix_list = ["s", "ᴍ", "ʜ", "ᴅᴀʏs"] + + 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: + readable_time += time_list.pop() + ", " + + time_list.reverse() + readable_time += ":".join(time_list) + + return readable_time diff --git a/DragMusic/__init__.py b/DragMusic/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2b41a729304c09b1fd0e2ad059954b4f6997ba5c --- /dev/null +++ b/DragMusic/__init__.py @@ -0,0 +1,27 @@ +from DragMusic.core.bot import Drag +from DragMusic.core.dir import dirr +from DragMusic.core.git import git +from DragMusic.core.userbot import Userbot +from DragMusic.misc import dbb, heroku + +from .logging import LOGGER + +dirr() +#git() +dbb() +heroku() + +app = Drag() +userbot = Userbot() + + +from .platforms import * + +Apple = AppleAPI() +Carbon = CarbonAPI() +SoundCloud = SoundAPI() +Spotify = SpotifyAPI() +Resso = RessoAPI() +Telegram = TeleAPI() +YouTube = YouTubeAPI() + diff --git a/DragMusic/__main__.py b/DragMusic/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..56423fd5e0266787c7a7cc0cf90e8c846d19a31b --- /dev/null +++ b/DragMusic/__main__.py @@ -0,0 +1,61 @@ +import asyncio +import importlib + +from pyrogram import idle +from pytgcalls.exceptions import NoActiveGroupCall + +import config +from DragMusic import LOGGER, app, userbot +from DragMusic.core.call import Drag +from DragMusic.misc import sudo +from DragMusic.plugins import ALL_MODULES +from DragMusic.utils.database import get_banned_users, get_gbanned +from config import BANNED_USERS + + +async def init(): + if ( + not config.STRING1 + and not config.STRING2 + and not config.STRING3 + and not config.STRING4 + and not config.STRING5 + ): + LOGGER(__name__).error("Assɪsᴛᴀɴᴛ ᴄʟɪᴇɴᴛ ᴠᴀʀɪᴀʙʟᴇs ɴᴏᴛ ᴅᴇғɪɴᴇᴅ, ᴇxɪᴛɪɴɢ...") + exit() + await sudo() + try: + users = await get_gbanned() + for user_id in users: + BANNED_USERS.add(user_id) + users = await get_banned_users() + for user_id in users: + BANNED_USERS.add(user_id) + except: + pass + await app.start() + for all_module in ALL_MODULES: + importlib.import_module("DragMusic.plugins" + all_module) + LOGGER("DragMusic.plugins").info("Sᴜᴄᴄᴇssғᴜʟʟʏ Iᴍᴘᴏʀᴛᴇᴅ Mᴏᴅᴜʟᴇs...") + await userbot.start() + await Drag.start() + try: + await Drag.stream_call("https://telegra.ph/file/cba632240b79207bf8a9c.mp4") + except NoActiveGroupCall: + LOGGER("DragMusic").error( + "Pʟᴇᴀsᴇ ᴛᴜʀɴ ᴏɴ ᴛʜᴇ ᴠɪᴅᴇᴏᴄʜᴀᴛ ᴏғ ʏᴏᴜʀ ʟᴏɢ ɢʀᴏᴜᴘ\ᴄʜᴀɴɴᴇʟ\n\nsᴛᴏᴘᴘɪɴɢ Bᴏᴛ..." + ) + exit() + except: + pass + await Drag.decorators() + LOGGER("DragMusic").info("\n 𝑴𝑨𝑫𝑬 𝑩𝒀 𝑫𝑹𝑨𝑮𝑮𝑮 \n") + + await idle() + await app.stop() + await userbot.stop() + LOGGER("DragMusic").info("\n 𝑴𝑨𝑫𝑬 𝑩𝒀 𝑫𝑹𝑨𝑮𝑮𝑮 \n") + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(init()) diff --git a/DragMusic/assets/font.ttf b/DragMusic/assets/font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..80ac6f9c8ac8a45b811cd596e9d9d962c86f103d --- /dev/null +++ b/DragMusic/assets/font.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cb35ce1a08cfbff367f8f4d7960fe7754abc0460f0f4d7ac46d3af924a9d0f3 +size 128248 diff --git a/DragMusic/assets/font2.ttf b/DragMusic/assets/font2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d96c354a157ad5954629b9d908e358a48fc6dc43 --- /dev/null +++ b/DragMusic/assets/font2.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5d5b5672d46b4482346a6695121cae0110372568cb30ba723808886ecda4c12 +size 22020 diff --git a/DragMusic/core/bot.py b/DragMusic/core/bot.py new file mode 100644 index 0000000000000000000000000000000000000000..837cdbe000e5d5a9f651385275ddf4db3ba79aa8 --- /dev/null +++ b/DragMusic/core/bot.py @@ -0,0 +1,54 @@ +from pyrogram import Client, errors +from pyrogram.enums import ChatMemberStatus, ParseMode + +import config + +from ..logging import LOGGER + + +class Drag(Client): + def __init__(self): + LOGGER(__name__).info(f"Starting Bot...") + super().__init__( + name="DragMusic", + api_id=config.API_ID, + api_hash=config.API_HASH, + bot_token=config.BOT_TOKEN, + in_memory=True, + parse_mode=ParseMode.HTML, + max_concurrent_transmissions=7, + ) + + async def start(self): + await super().start() + self.id = self.me.id + self.name = self.me.first_name + " " + (self.me.last_name or "") + self.username = self.me.username + self.mention = self.me.mention + + try: + await self.send_message( + chat_id=config.LOGGER_ID, + text=f"» {self.mention} ʙᴏᴛ sᴛᴀʀᴛᴇᴅ :\n\nɪᴅ : {self.id}\nɴᴀᴍᴇ : {self.name}\nᴜsᴇʀɴᴀᴍᴇ : @{self.username}", + ) + except (errors.ChannelInvalid, errors.PeerIdInvalid): + LOGGER(__name__).error( + "Bot has failed to access the log group/channel. Make sure that you have added your bot to your log group/channel." + ) + exit() + except Exception as ex: + LOGGER(__name__).error( + f"Bot has failed to access the log group/channel.\n Reason : {type(ex).__name__}." + ) + exit() + + a = await self.get_chat_member(config.LOGGER_ID, self.id) + if a.status != ChatMemberStatus.ADMINISTRATOR: + LOGGER(__name__).error( + "Please promote your bot as an admin in your log group/channel." + ) + exit() + LOGGER(__name__).info(f"Music Bot Started as {self.name}") + + async def stop(self): + await super().stop() diff --git a/DragMusic/core/call.py b/DragMusic/core/call.py new file mode 100644 index 0000000000000000000000000000000000000000..398130f3f71f51f5eee4ab6992d22a9fddded5f2 --- /dev/null +++ b/DragMusic/core/call.py @@ -0,0 +1,635 @@ +import asyncio +import os +from datetime import datetime, timedelta +from typing import Union + +from pyrogram import Client +from pyrogram.types import InlineKeyboardMarkup +from ntgcalls import TelegramServerError +from pytgcalls import PyTgCalls +from pytgcalls.exceptions import ( + AlreadyJoinedError, + NoActiveGroupCall, +) +from pytgcalls.types import ( + MediaStream, + AudioQuality, + VideoQuality, + Update, +) +from pytgcalls.types.stream import StreamAudioEnded + +import config +from DragMusic import LOGGER, YouTube, app +from DragMusic.misc import db +from DragMusic.utils.database import ( + add_active_chat, + add_active_video_chat, + get_lang, + get_loop, + group_assistant, + is_autoend, + music_on, + remove_active_chat, + remove_active_video_chat, + set_loop, +) +from DragMusic.utils.exceptions import AssistantErr +from DragMusic.utils.formatters import check_duration, seconds_to_min, speed_converter +from DragMusic.utils.inline.play import stream_markup +from DragMusic.utils.stream.autoclear import auto_clean +from DragMusic.utils.thumbnails import get_thumb +from strings import get_string + +autoend = {} +counter = {} +loop = asyncio.get_event_loop_policy().get_event_loop() + + +async def _clear_(chat_id): + db[chat_id] = [] + await remove_active_video_chat(chat_id) + await remove_active_chat(chat_id) + + +class Call(PyTgCalls): + def __init__(self): + self.userbot1 = Client( + name="AnonXAss1", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING1), + ) + self.one = PyTgCalls( + self.userbot1, + cache_duration=100, + ) + self.userbot2 = Client( + name="AnonXAss2", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING2), + ) + self.two = PyTgCalls( + self.userbot2, + cache_duration=100, + ) + self.userbot3 = Client( + name="AnonXAss3", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING3), + ) + self.three = PyTgCalls( + self.userbot3, + cache_duration=100, + ) + self.userbot4 = Client( + name="AnonXAss4", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING4), + ) + self.four = PyTgCalls( + self.userbot4, + cache_duration=100, + ) + self.userbot5 = Client( + name="AnonXAss5", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING5), + ) + self.five = PyTgCalls( + self.userbot5, + cache_duration=100, + ) + + async def pause_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + await assistant.pause_stream(chat_id) + + async def mute_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + await assistant.mute_stream(chat_id) + + async def unmute_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + await assistant.unmute_stream(chat_id) + + async def get_participant(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + participant = await assistant.get_participants(chat_id) + return participant + + async def resume_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + await assistant.resume_stream(chat_id) + + async def stop_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + try: + await _clear_(chat_id) + await assistant.leave_group_call(chat_id) + except: + pass + + async def stop_stream_force(self, chat_id: int): + try: + if config.STRING1: + await self.one.leave_group_call(chat_id) + except: + pass + try: + if config.STRING2: + await self.two.leave_group_call(chat_id) + except: + pass + try: + if config.STRING3: + await self.three.leave_group_call(chat_id) + except: + pass + try: + if config.STRING4: + await self.four.leave_group_call(chat_id) + except: + pass + try: + if config.STRING5: + await self.five.leave_group_call(chat_id) + except: + pass + try: + await _clear_(chat_id) + except: + pass + + async def speedup_stream(self, chat_id: int, file_path, speed, playing): + assistant = await group_assistant(self, chat_id) + if str(speed) != "1.0": + base = os.path.basename(file_path) + chatdir = os.path.join(os.getcwd(), "playback", str(speed)) + if not os.path.isdir(chatdir): + os.makedirs(chatdir) + out = os.path.join(chatdir, base) + if not os.path.isfile(out): + if str(speed) == "0.5": + vs = 2.0 + if str(speed) == "0.75": + vs = 1.35 + if str(speed) == "1.5": + vs = 0.68 + if str(speed) == "2.0": + vs = 0.5 + proc = await asyncio.create_subprocess_shell( + cmd=( + "ffmpeg " + "-i " + f"{file_path} " + "-filter:v " + f"setpts={vs}*PTS " + "-filter:a " + f"atempo={speed} " + f"{out}" + ), + stdin=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + await proc.communicate() + else: + out = file_path + dur = await loop.run_in_executor(None, check_duration, out) + dur = int(dur) + played, con_seconds = speed_converter(playing[0]["played"], speed) + duration = seconds_to_min(dur) + stream = ( + MediaStream( + out, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ffmpeg_parameters=f"-ss {played} -to {duration}", + ) + if playing[0]["streamtype"] == "video" + else MediaStream( + out, + audio_parameters=AudioQuality.HIGH, + ffmpeg_parameters=f"-ss {played} -to {duration}", + video_flags=MediaStream.IGNORE, + ) + ) + if str(db[chat_id][0]["file"]) == str(file_path): + await assistant.change_stream(chat_id, stream) + else: + raise AssistantErr("Umm") + if str(db[chat_id][0]["file"]) == str(file_path): + exis = (playing[0]).get("old_dur") + if not exis: + db[chat_id][0]["old_dur"] = db[chat_id][0]["dur"] + db[chat_id][0]["old_second"] = db[chat_id][0]["seconds"] + db[chat_id][0]["played"] = con_seconds + db[chat_id][0]["dur"] = duration + db[chat_id][0]["seconds"] = dur + db[chat_id][0]["speed_path"] = out + db[chat_id][0]["speed"] = speed + + async def force_stop_stream(self, chat_id: int): + assistant = await group_assistant(self, chat_id) + try: + check = db.get(chat_id) + check.pop(0) + except: + pass + await remove_active_video_chat(chat_id) + await remove_active_chat(chat_id) + try: + await assistant.leave_group_call(chat_id) + except: + pass + + async def skip_stream( + self, + chat_id: int, + link: str, + video: Union[bool, str] = None, + image: Union[bool, str] = None, + ): + assistant = await group_assistant(self, chat_id) + if video: + stream = MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + else: + stream = MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + await assistant.change_stream( + chat_id, + stream, + ) + + async def seek_stream(self, chat_id, file_path, to_seek, duration, mode): + assistant = await group_assistant(self, chat_id) + stream = ( + MediaStream( + file_path, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ffmpeg_parameters=f"-ss {to_seek} -to {duration}", + ) + if mode == "video" + else MediaStream( + file_path, + audio_parameters=AudioQuality.HIGH, + ffmpeg_parameters=f"-ss {to_seek} -to {duration}", + video_flags=MediaStream.IGNORE, + ) + ) + await assistant.change_stream(chat_id, stream) + + async def stream_call(self, link): + assistant = await group_assistant(self, config.LOGGER_ID) + await assistant.join_group_call( + config.LOGGER_ID, + MediaStream(link), + ) + await asyncio.sleep(0.2) + await assistant.leave_group_call(config.LOGGER_ID) + + async def join_call( + self, + chat_id: int, + original_chat_id: int, + link, + video: Union[bool, str] = None, + image: Union[bool, str] = None, + ): + assistant = await group_assistant(self, chat_id) + language = await get_lang(chat_id) + _ = get_string(language) + if video: + stream = MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + else: + stream = ( + MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + if video + else MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + ) + try: + await assistant.join_group_call( + chat_id, + stream, + ) + except NoActiveGroupCall: + raise AssistantErr(_["call_8"]) + except AlreadyJoinedError: + raise AssistantErr(_["call_9"]) + except TelegramServerError: + raise AssistantErr(_["call_10"]) + except Exception as e: + if "phone.CreateGroupCall" in str(e): + raise AssistantErr(_["call_8"]) + await add_active_chat(chat_id) + await music_on(chat_id) + if video: + await add_active_video_chat(chat_id) + if await is_autoend(): + counter[chat_id] = {} + users = len(await assistant.get_participants(chat_id)) + if users == 1: + autoend[chat_id] = datetime.now() + timedelta(minutes=1) + + async def change_stream(self, client, chat_id): + check = db.get(chat_id) + popped = None + loop = await get_loop(chat_id) + try: + if loop == 0: + popped = check.pop(0) + else: + loop = loop - 1 + await set_loop(chat_id, loop) + await auto_clean(popped) + if not check: + await _clear_(chat_id) + return await client.leave_group_call(chat_id) + except: + try: + await _clear_(chat_id) + return await client.leave_group_call(chat_id) + except: + return + else: + queued = check[0]["file"] + language = await get_lang(chat_id) + _ = get_string(language) + title = (check[0]["title"]).title() + user = check[0]["by"] + original_chat_id = check[0]["chat_id"] + streamtype = check[0]["streamtype"] + videoid = check[0]["vidid"] + db[chat_id][0]["played"] = 0 + if exis := (check[0]).get("old_dur"): + db[chat_id][0]["dur"] = exis + db[chat_id][0]["seconds"] = check[0]["old_second"] + db[chat_id][0]["speed_path"] = None + db[chat_id][0]["speed"] = 1.0 + video = str(streamtype) == "video" + if "live_" in queued: + n, link = await YouTube.video(videoid, True) + if n == 0: + return await app.send_message( + original_chat_id, + text=_["call_6"], + ) + if video: + stream = MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + else: + stream = MediaStream( + link, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + try: + await client.change_stream(chat_id, stream) + except Exception: + return await app.send_message( + original_chat_id, + text=_["call_6"], + ) + img = await get_thumb(videoid) + button = stream_markup2(_, chat_id) + run = await app.send_photo( + chat_id=original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif "vid_" in queued: + mystic = await app.send_message(original_chat_id, _["call_7"]) + try: + file_path, direct = await YouTube.download( + videoid, + mystic, + videoid=True, + video=str(streamtype) == "video", + ) + except: + return await mystic.edit_text( + _["call_6"], disable_web_page_preview=True + ) + if video: + stream = MediaStream( + file_path, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + else: + stream = MediaStream( + file_path, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + try: + await client.change_stream(chat_id, stream) + except: + return await app.send_message( + original_chat_id, + text=_["call_6"], + ) + img = await get_thumb(videoid) + button = stream_markup(_, videoid, chat_id) + await mystic.delete() + run = await app.send_photo( + chat_id=original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + elif "index_" in queued: + stream = ( + MediaStream( + videoid, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + if str(streamtype) == "video" + else MediaStream( + videoid, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + ) + try: + await client.change_stream(chat_id, stream) + except: + return await app.send_message( + original_chat_id, + text=_["call_6"], + ) + button = stream_markup2(_, chat_id) + run = await app.send_photo( + chat_id=original_chat_id, + photo=config.STREAM_IMG_URL, + caption=_["stream_2"].format(user), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + else: + if video: + stream = MediaStream( + queued, + audio_parameters=AudioQuality.HIGH, + video_parameters=VideoQuality.SD_480p, + ) + else: + stream = MediaStream( + queued, + audio_parameters=AudioQuality.HIGH, + video_flags=MediaStream.IGNORE, + ) + try: + await client.change_stream(chat_id, stream) + except: + return await app.send_message( + original_chat_id, + text=_["call_6"], + ) + if videoid == "telegram": + button = stream_markup2(_, chat_id) + run = await app.send_photo( + chat_id=original_chat_id, + photo=( + config.TELEGRAM_AUDIO_URL + if str(streamtype) == "audio" + else config.TELEGRAM_VIDEO_URL + ), + caption=_["stream_1"].format( + config.SUPPORT_CHAT, title[:23], check[0]["dur"], user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif videoid == "soundcloud": + button = stream_markup2(_, chat_id) + run = await app.send_photo( + chat_id=original_chat_id, + photo=config.SOUNCLOUD_IMG_URL, + caption=_["stream_1"].format( + config.SUPPORT_CHAT, title[:23], check[0]["dur"], user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + else: + img = await get_thumb(videoid) + button = stream_markup(_, videoid, chat_id) + run = await app.send_photo( + chat_id=original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + + async def ping(self): + pings = [] + if config.STRING1: + pings.append(await self.one.ping) + if config.STRING2: + pings.append(await self.two.ping) + if config.STRING3: + pings.append(await self.three.ping) + if config.STRING4: + pings.append(await self.four.ping) + if config.STRING5: + pings.append(await self.five.ping) + return str(round(sum(pings) / len(pings), 3)) + + async def start(self): + LOGGER(__name__).info("Starting PyTgCalls Client...\n") + if config.STRING1: + await self.one.start() + if config.STRING2: + await self.two.start() + if config.STRING3: + await self.three.start() + if config.STRING4: + await self.four.start() + if config.STRING5: + await self.five.start() + + async def decorators(self): + @self.one.on_kicked() + @self.two.on_kicked() + @self.three.on_kicked() + @self.four.on_kicked() + @self.five.on_kicked() + @self.one.on_closed_voice_chat() + @self.two.on_closed_voice_chat() + @self.three.on_closed_voice_chat() + @self.four.on_closed_voice_chat() + @self.five.on_closed_voice_chat() + @self.one.on_left() + @self.two.on_left() + @self.three.on_left() + @self.four.on_left() + @self.five.on_left() + async def stream_services_handler(_, chat_id: int): + await self.stop_stream(chat_id) + + @self.one.on_stream_end() + @self.two.on_stream_end() + @self.three.on_stream_end() + @self.four.on_stream_end() + @self.five.on_stream_end() + async def stream_end_handler(client, update: Update): + if not isinstance(update, StreamAudioEnded): + return + await self.change_stream(client, update.chat_id) + + +Drag= Call() diff --git a/DragMusic/core/dir.py b/DragMusic/core/dir.py new file mode 100644 index 0000000000000000000000000000000000000000..7506cc646c787bf2fc34a4b696207104d6d5179c --- /dev/null +++ b/DragMusic/core/dir.py @@ -0,0 +1,20 @@ +import os + +from ..logging import LOGGER + + +def dirr(): + for file in os.listdir(): + if file.endswith(".jpg"): + os.remove(file) + elif file.endswith(".jpeg"): + os.remove(file) + elif file.endswith(".png"): + os.remove(file) + + if "downloads" not in os.listdir(): + os.mkdir("downloads") + if "cache" not in os.listdir(): + os.mkdir("cache") + + LOGGER(__name__).info("Directories Updated.") diff --git a/DragMusic/core/git.py b/DragMusic/core/git.py new file mode 100644 index 0000000000000000000000000000000000000000..8f0f417c03fe34b4036d6ede1f89ba9272296de3 --- /dev/null +++ b/DragMusic/core/git.py @@ -0,0 +1,71 @@ +import asyncio +import shlex +from typing import Tuple + +from git import Repo +from git.exc import GitCommandError, InvalidGitRepositoryError + +import config + +from ..logging import LOGGER + + +def install_req(cmd: str) -> Tuple[str, str, int, int]: + async def install_requirements(): + args = shlex.split(cmd) + process = await asyncio.create_subprocess_exec( + *args, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await process.communicate() + return ( + stdout.decode("utf-8", "replace").strip(), + stderr.decode("utf-8", "replace").strip(), + process.returncode, + process.pid, + ) + + return asyncio.get_event_loop().run_until_complete(install_requirements()) + + +def git(): + REPO_LINK = config.UPSTREAM_REPO + if config.GIT_TOKEN: + GIT_USERNAME = REPO_LINK.split("com/")[1].split("/")[0] + TEMP_REPO = REPO_LINK.split("https://")[1] + UPSTREAM_REPO = f"https://{GIT_USERNAME}:{config.GIT_TOKEN}@{TEMP_REPO}" + else: + UPSTREAM_REPO = config.UPSTREAM_REPO + try: + repo = Repo() + LOGGER(__name__).info(f"Git Client Found [VPS DEPLOYER]") + except GitCommandError: + LOGGER(__name__).info(f"Invalid Git Command") + except InvalidGitRepositoryError: + repo = Repo.init() + if "origin" in repo.remotes: + origin = repo.remote("origin") + else: + origin = repo.create_remote("origin", UPSTREAM_REPO) + origin.fetch() + repo.create_head( + config.UPSTREAM_BRANCH, + origin.refs[config.UPSTREAM_BRANCH], + ) + repo.heads[config.UPSTREAM_BRANCH].set_tracking_branch( + origin.refs[config.UPSTREAM_BRANCH] + ) + repo.heads[config.UPSTREAM_BRANCH].checkout(True) + try: + repo.create_remote("origin", config.UPSTREAM_REPO) + except BaseException: + pass + nrs = repo.remote("origin") + nrs.fetch(config.UPSTREAM_BRANCH) + try: + nrs.pull(config.UPSTREAM_BRANCH) + except GitCommandError: + repo.git.reset("--hard", "FETCH_HEAD") + install_req("pip3 install --no-cache-dir -r requirements.txt") + LOGGER(__name__).info(f"Fetching updates from upstream repository...") diff --git a/DragMusic/core/mongo.py b/DragMusic/core/mongo.py new file mode 100644 index 0000000000000000000000000000000000000000..47016a675b1cd211ec74e79577be8cd0b71b5a4b --- /dev/null +++ b/DragMusic/core/mongo.py @@ -0,0 +1,14 @@ +from motor.motor_asyncio import AsyncIOMotorClient + +from config import MONGO_DB_URI + +from ..logging import LOGGER + +LOGGER(__name__).info("Connecting to your Mongo Database...") +try: + _mongo_async_ = AsyncIOMotorClient(MONGO_DB_URI) + mongodb = _mongo_async_.Anon + LOGGER(__name__).info("Connected to your Mongo Database.") +except: + LOGGER(__name__).error("Failed to connect to your Mongo Database.") + exit() diff --git a/DragMusic/core/userbot.py b/DragMusic/core/userbot.py new file mode 100644 index 0000000000000000000000000000000000000000..7ddd0a8326b59aafdeaf0c23d21b7d543ccab3a4 --- /dev/null +++ b/DragMusic/core/userbot.py @@ -0,0 +1,170 @@ +from pyrogram import Client + +import config + +from ..logging import LOGGER + +assistants = [] +assistantids = [] + + +class Userbot(Client): + def __init__(self): + self.one = Client( + name="AnonXAss1", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING1), + no_updates=True, + ) + self.two = Client( + name="AnonXAss2", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING2), + no_updates=True, + ) + self.three = Client( + name="AnonXAss3", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING3), + no_updates=True, + ) + self.four = Client( + name="AnonXAss4", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING4), + no_updates=True, + ) + self.five = Client( + name="AnonXAss5", + api_id=config.API_ID, + api_hash=config.API_HASH, + session_string=str(config.STRING5), + no_updates=True, + ) + + async def start(self): + LOGGER(__name__).info(f"Starting Assistants...") + if config.STRING1: + await self.one.start() + try: + await self.one.join_chat("dragbackup") + await self.one.join_chat("dragbackup") + except: + pass + assistants.append(1) + try: + await self.one.send_message(config.LOGGER_ID, "Assistant Started") + except: + LOGGER(__name__).error( + "Assistant Account 1 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin!" + ) + exit() + self.one.id = self.one.me.id + self.one.name = self.one.me.mention + self.one.username = self.one.me.username + assistantids.append(self.one.id) + LOGGER(__name__).info(f"Assistant Started as {self.one.name}") + + if config.STRING2: + await self.two.start() + try: + await self.two.join_chat("dragbackup") + await self.two.join_chat("dragbackup") + except: + pass + assistants.append(2) + try: + await self.two.send_message(config.LOGGER_ID, "Assistant Started") + except: + LOGGER(__name__).error( + "Assistant Account 2 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin!" + ) + exit() + self.two.id = self.two.me.id + self.two.name = self.two.me.mention + self.two.username = self.two.me.username + assistantids.append(self.two.id) + LOGGER(__name__).info(f"Assistant Two Started as {self.two.name}") + + if config.STRING3: + await self.three.start() + try: + await self.three.join_chat("dragbackup") + await self.three.join_chat("dragbackup") + except: + pass + assistants.append(3) + try: + await self.three.send_message(config.LOGGER_ID, "Assistant Started") + except: + LOGGER(__name__).error( + "Assistant Account 3 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! " + ) + exit() + self.three.id = self.three.me.id + self.three.name = self.three.me.mention + self.three.username = self.three.me.username + assistantids.append(self.three.id) + LOGGER(__name__).info(f"Assistant Three Started as {self.three.name}") + + if config.STRING4: + await self.four.start() + try: + await self.four.join_chat("dragbackup") + await self.four.join_chat("dragbackup") + except: + pass + assistants.append(4) + try: + await self.four.send_message(config.LOGGER_ID, "Assistant Started") + except: + LOGGER(__name__).error( + "Assistant Account 4 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! " + ) + exit() + self.four.id = self.four.me.id + self.four.name = self.four.me.mention + self.four.username = self.four.me.username + assistantids.append(self.four.id) + LOGGER(__name__).info(f"Assistant Four Started as {self.four.name}") + + if config.STRING5: + await self.five.start() + try: + await self.five.join_chat("dragbackup") + await self.five.join_chat("dragbackup") + except: + pass + assistants.append(5) + try: + await self.five.send_message(config.LOGGER_ID, "Assistant Started") + except: + LOGGER(__name__).error( + "Assistant Account 5 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! " + ) + exit() + self.five.id = self.five.me.id + self.five.name = self.five.me.mention + self.five.username = self.five.me.username + assistantids.append(self.five.id) + LOGGER(__name__).info(f"Assistant Five Started as {self.five.name}") + + async def stop(self): + LOGGER(__name__).info(f"Stopping Assistants...") + try: + if config.STRING1: + await self.one.stop() + if config.STRING2: + await self.two.stop() + if config.STRING3: + await self.three.stop() + if config.STRING4: + await self.four.stop() + if config.STRING5: + await self.five.stop() + except: + pass diff --git a/DragMusic/logging.py b/DragMusic/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..ebc72c9b87d0c6cff029161f1218fd5b1cbaea23 --- /dev/null +++ b/DragMusic/logging.py @@ -0,0 +1,19 @@ +import logging + +logging.basicConfig( + level=logging.INFO, + format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s", + datefmt="%d-%b-%y %H:%M:%S", + handlers=[ + logging.FileHandler("logs.txt"), + logging.StreamHandler(), + ], +) + +logging.getLogger("httpx").setLevel(logging.ERROR) +logging.getLogger("pyrogram").setLevel(logging.ERROR) +logging.getLogger("pytgcalls").setLevel(logging.ERROR) + + +def LOGGER(name: str) -> logging.Logger: + return logging.getLogger(name) diff --git a/DragMusic/misc.py b/DragMusic/misc.py new file mode 100644 index 0000000000000000000000000000000000000000..8df7657e07702faa5a57f60ab0fdb4f86956cb18 --- /dev/null +++ b/DragMusic/misc.py @@ -0,0 +1,75 @@ +import socket +import time + +import heroku3 +from pyrogram import filters + +import config +from DragMusic.core.mongo import mongodb + +from .logging import LOGGER + +SUDOERS = filters.user() + +HAPP = None +_boot_ = time.time() + + +def is_heroku(): + return "heroku" in socket.getfqdn() + + +XCB = [ + "/", + "@", + ".", + "com", + ":", + "git", + "heroku", + "push", + str(config.HEROKU_API_KEY), + "https", + str(config.HEROKU_APP_NAME), + "HEAD", + "master", +] + + +def dbb(): + global db + db = {} + LOGGER(__name__).info(f"Local Database Initialized.") + + +async def sudo(): + global SUDOERS + SUDOERS.add(config.OWNER_ID) + sudoersdb = mongodb.sudoers + sudoers = await sudoersdb.find_one({"sudo": "sudo"}) + sudoers = [] if not sudoers else sudoers["sudoers"] + if config.OWNER_ID not in sudoers: + sudoers.append(config.OWNER_ID) + await sudoersdb.update_one( + {"sudo": "sudo"}, + {"$set": {"sudoers": sudoers}}, + upsert=True, + ) + if sudoers: + for user_id in sudoers: + SUDOERS.add(user_id) + LOGGER(__name__).info(f"Sudoers Loaded.") + + +def heroku(): + global HAPP + if is_heroku: + if config.HEROKU_API_KEY and config.HEROKU_APP_NAME: + try: + Heroku = heroku3.from_key(config.HEROKU_API_KEY) + HAPP = Heroku.app(config.HEROKU_APP_NAME) + LOGGER(__name__).info(f"Heroku App Configured") + except BaseException: + LOGGER(__name__).warning( + f"Please make sure your Heroku API Key and Your App name are configured correctly in the heroku." + ) diff --git a/DragMusic/platforms/Apple.py b/DragMusic/platforms/Apple.py new file mode 100644 index 0000000000000000000000000000000000000000..4030261b18ec116adda573d3f250f072fe29f09c --- /dev/null +++ b/DragMusic/platforms/Apple.py @@ -0,0 +1,71 @@ +import re +from typing import Union + +import aiohttp +from bs4 import BeautifulSoup +from youtubesearchpython.__future__ import VideosSearch + + +class AppleAPI: + def __init__(self): + self.regex = r"^(https:\/\/music.apple.com\/)(.*)$" + self.base = "https://music.apple.com/in/playlist/" + + async def valid(self, link: str): + if re.search(self.regex, link): + return True + else: + return False + + async def track(self, url, playid: Union[bool, str] = None): + if playid: + url = self.base + url + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status != 200: + return False + html = await response.text() + soup = BeautifulSoup(html, "html.parser") + search = None + for tag in soup.find_all("meta"): + if tag.get("property", None) == "og:title": + search = tag.get("content", None) + if search is None: + return False + results = VideosSearch(search, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + ytlink = result["link"] + vidid = result["id"] + duration_min = result["duration"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + track_details = { + "title": title, + "link": ytlink, + "vidid": vidid, + "duration_min": duration_min, + "thumb": thumbnail, + } + return track_details, vidid + + async def playlist(self, url, playid: Union[bool, str] = None): + if playid: + url = self.base + url + playlist_id = url.split("playlist/")[1] + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status != 200: + return False + html = await response.text() + soup = BeautifulSoup(html, "html.parser") + applelinks = soup.find_all("meta", attrs={"property": "music:song"}) + results = [] + for item in applelinks: + try: + xx = (((item["content"]).split("album/")[1]).split("/")[0]).replace( + "-", " " + ) + except: + xx = ((item["content"]).split("album/")[1]).split("/")[0] + results.append(xx) + return results, playlist_id diff --git a/DragMusic/platforms/Carbon.py b/DragMusic/platforms/Carbon.py new file mode 100644 index 0000000000000000000000000000000000000000..89435cb804a0285cbbe1b8456caae289927356a7 --- /dev/null +++ b/DragMusic/platforms/Carbon.py @@ -0,0 +1,106 @@ +import random +from os.path import realpath + +import aiohttp +from aiohttp import client_exceptions + + +class UnableToFetchCarbon(Exception): + pass + + +themes = [ + "3024-night", + "a11y-dark", + "blackboard", + "base16-dark", + "base16-light", + "cobalt", + "duotone-dark", + "dracula-pro", + "hopscotch", + "lucario", + "material", + "monokai", + "nightowl", + "nord", + "oceanic-next", + "one-light", + "one-dark", + "panda-syntax", + "parasio-dark", + "seti", + "shades-of-purple", + "solarized+dark", + "solarized+light", + "synthwave-84", + "twilight", + "verminal", + "vscode", + "yeti", + "zenburn", +] + +colour = [ + "#FF0000", + "#FF5733", + "#FFFF00", + "#008000", + "#0000FF", + "#800080", + "#A52A2A", + "#FF00FF", + "#D2B48C", + "#00FFFF", + "#808000", + "#800000", + "#00FFFF", + "#30D5C8", + "#00FF00", + "#008080", + "#4B0082", + "#EE82EE", + "#FFC0CB", + "#000000", + "#FFFFFF", + "#808080", +] + + +class CarbonAPI: + def __init__(self): + self.language = "auto" + self.drop_shadow = True + self.drop_shadow_blur = "68px" + self.drop_shadow_offset = "20px" + self.font_family = "JetBrains Mono" + self.width_adjustment = True + self.watermark = False + + async def generate(self, text: str, user_id): + async with aiohttp.ClientSession( + headers={"Content-Type": "application/json"}, + ) as ses: + params = { + "code": text, + } + params["backgroundColor"] = random.choice(colour) + params["theme"] = random.choice(themes) + params["dropShadow"] = self.drop_shadow + params["dropShadowOffsetY"] = self.drop_shadow_offset + params["dropShadowBlurRadius"] = self.drop_shadow_blur + params["fontFamily"] = self.font_family + params["language"] = self.language + params["watermark"] = self.watermark + params["widthAdjustment"] = self.width_adjustment + try: + request = await ses.post( + "https://carbonara.solopov.dev/api/cook", + json=params, + ) + except client_exceptions.ClientConnectorError: + raise UnableToFetchCarbon("Can not reach the Host!") + resp = await request.read() + with open(f"cache/carbon{user_id}.jpg", "wb") as f: + f.write(resp) + return realpath(f.name) diff --git a/DragMusic/platforms/Resso.py b/DragMusic/platforms/Resso.py new file mode 100644 index 0000000000000000000000000000000000000000..f960a51e7328418b8b2b79d8494aed79d0d1441d --- /dev/null +++ b/DragMusic/platforms/Resso.py @@ -0,0 +1,54 @@ +import re +from typing import Union + +import aiohttp +from bs4 import BeautifulSoup +from youtubesearchpython.__future__ import VideosSearch + + +class RessoAPI: + def __init__(self): + self.regex = r"^(https:\/\/m.resso.com\/)(.*)$" + self.base = "https://m.resso.com/" + + async def valid(self, link: str): + if re.search(self.regex, link): + return True + else: + return False + + async def track(self, url, playid: Union[bool, str] = None): + if playid: + url = self.base + url + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status != 200: + return False + html = await response.text() + soup = BeautifulSoup(html, "html.parser") + for tag in soup.find_all("meta"): + if tag.get("property", None) == "og:title": + title = tag.get("content", None) + if tag.get("property", None) == "og:description": + des = tag.get("content", None) + try: + des = des.split("·")[0] + except: + pass + if des == "": + return + results = VideosSearch(title, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + ytlink = result["link"] + vidid = result["id"] + duration_min = result["duration"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + track_details = { + "title": title, + "link": ytlink, + "vidid": vidid, + "duration_min": duration_min, + "thumb": thumbnail, + } + return track_details, vidid diff --git a/DragMusic/platforms/Soundcloud.py b/DragMusic/platforms/Soundcloud.py new file mode 100644 index 0000000000000000000000000000000000000000..b015ded15eba8557c35c88470b95167c619c8d20 --- /dev/null +++ b/DragMusic/platforms/Soundcloud.py @@ -0,0 +1,39 @@ +from os import path + +from yt_dlp import YoutubeDL + +from DragMusic.utils.formatters import seconds_to_min + + +class SoundAPI: + def __init__(self): + self.opts = { + "outtmpl": "downloads/%(id)s.%(ext)s", + "format": "best", + "retries": 3, + "nooverwrites": False, + "continuedl": True, + } + + async def valid(self, link: str): + if "soundcloud" in link: + return True + else: + return False + + async def download(self, url): + d = YoutubeDL(self.opts) + try: + info = d.extract_info(url) + except: + return False + xyz = path.join("downloads", f"{info['id']}.{info['ext']}") + duration_min = seconds_to_min(info["duration"]) + track_details = { + "title": info["title"], + "duration_sec": info["duration"], + "duration_min": duration_min, + "uploader": info["uploader"], + "filepath": xyz, + } + return track_details, xyz diff --git a/DragMusic/platforms/Spotify.py b/DragMusic/platforms/Spotify.py new file mode 100644 index 0000000000000000000000000000000000000000..ad2e139797d6a3d253af635a74661a5a7b8afbf8 --- /dev/null +++ b/DragMusic/platforms/Spotify.py @@ -0,0 +1,98 @@ +import re + +import spotipy +from spotipy.oauth2 import SpotifyClientCredentials +from youtubesearchpython.__future__ import VideosSearch + +import config + + +class SpotifyAPI: + def __init__(self): + self.regex = r"^(https:\/\/open.spotify.com\/)(.*)$" + self.client_id = config.SPOTIFY_CLIENT_ID + self.client_secret = config.SPOTIFY_CLIENT_SECRET + if config.SPOTIFY_CLIENT_ID and config.SPOTIFY_CLIENT_SECRET: + self.client_credentials_manager = SpotifyClientCredentials( + self.client_id, self.client_secret + ) + self.spotify = spotipy.Spotify( + client_credentials_manager=self.client_credentials_manager + ) + else: + self.spotify = None + + async def valid(self, link: str): + if re.search(self.regex, link): + return True + else: + return False + + async def track(self, link: str): + track = self.spotify.track(link) + info = track["name"] + for artist in track["artists"]: + fetched = f' {artist["name"]}' + if "Various Artists" not in fetched: + info += fetched + results = VideosSearch(info, limit=1) + for result in (await results.next())["result"]: + ytlink = result["link"] + title = result["title"] + vidid = result["id"] + duration_min = result["duration"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + track_details = { + "title": title, + "link": ytlink, + "vidid": vidid, + "duration_min": duration_min, + "thumb": thumbnail, + } + return track_details, vidid + + async def playlist(self, url): + playlist = self.spotify.playlist(url) + playlist_id = playlist["id"] + results = [] + for item in playlist["tracks"]["items"]: + music_track = item["track"] + info = music_track["name"] + for artist in music_track["artists"]: + fetched = f' {artist["name"]}' + if "Various Artists" not in fetched: + info += fetched + results.append(info) + return results, playlist_id + + async def album(self, url): + album = self.spotify.album(url) + album_id = album["id"] + results = [] + for item in album["tracks"]["items"]: + info = item["name"] + for artist in item["artists"]: + fetched = f' {artist["name"]}' + if "Various Artists" not in fetched: + info += fetched + results.append(info) + + return ( + results, + album_id, + ) + + async def artist(self, url): + artistinfo = self.spotify.artist(url) + artist_id = artistinfo["id"] + results = [] + artisttoptracks = self.spotify.artist_top_tracks(url) + for item in artisttoptracks["tracks"]: + info = item["name"] + for artist in item["artists"]: + fetched = f' {artist["name"]}' + if "Various Artists" not in fetched: + info += fetched + results.append(info) + + return results, artist_id diff --git a/DragMusic/platforms/Telegram.py b/DragMusic/platforms/Telegram.py new file mode 100644 index 0000000000000000000000000000000000000000..d7f9a27515200d5a7579c1c61d6857c259280dbc --- /dev/null +++ b/DragMusic/platforms/Telegram.py @@ -0,0 +1,176 @@ +import asyncio +import os +import time +from typing import Union + +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Voice + +import config +from DragMusic import app +from DragMusic.utils.formatters import ( + check_duration, + convert_bytes, + get_readable_time, + seconds_to_min, +) + + +class TeleAPI: + def __init__(self): + self.chars_limit = 4096 + self.sleep = 5 + + async def send_split_text(self, message, string): + n = self.chars_limit + out = [(string[i : i + n]) for i in range(0, len(string), n)] + j = 0 + for x in out: + if j <= 2: + j += 1 + await message.reply_text(x, disable_web_page_preview=True) + return True + + async def get_link(self, message): + return message.link + + async def get_filename(self, file, audio: Union[bool, str] = None): + try: + file_name = file.file_name + if file_name is None: + file_name = "ᴛᴇʟᴇɢʀᴀᴍ ᴀᴜᴅɪᴏ" if audio else "ᴛᴇʟᴇɢʀᴀᴍ ᴠɪᴅᴇᴏ" + except: + file_name = "ᴛᴇʟᴇɢʀᴀᴍ ᴀᴜᴅɪᴏ" if audio else "ᴛᴇʟᴇɢʀᴀᴍ ᴠɪᴅᴇᴏ" + return file_name + + async def get_duration(self, file): + try: + dur = seconds_to_min(file.duration) + except: + dur = "Unknown" + return dur + + async def get_duration(self, filex, file_path): + try: + dur = seconds_to_min(filex.duration) + except: + try: + dur = await asyncio.get_event_loop().run_in_executor( + None, check_duration, file_path + ) + dur = seconds_to_min(dur) + except: + return "Unknown" + return dur + + async def get_filepath( + self, + audio: Union[bool, str] = None, + video: Union[bool, str] = None, + ): + if audio: + try: + file_name = ( + audio.file_unique_id + + "." + + ( + (audio.file_name.split(".")[-1]) + if (not isinstance(audio, Voice)) + else "ogg" + ) + ) + except: + file_name = audio.file_unique_id + "." + "ogg" + file_name = os.path.join(os.path.realpath("downloads"), file_name) + if video: + try: + file_name = ( + video.file_unique_id + "." + (video.file_name.split(".")[-1]) + ) + except: + file_name = video.file_unique_id + "." + "mp4" + file_name = os.path.join(os.path.realpath("downloads"), file_name) + return file_name + + async def download(self, _, message, mystic, fname): + lower = [0, 8, 17, 38, 64, 77, 96] + higher = [5, 10, 20, 40, 66, 80, 99] + checker = [5, 10, 20, 40, 66, 80, 99] + speed_counter = {} + if os.path.exists(fname): + return True + + async def down_load(): + async def progress(current, total): + if current == total: + return + current_time = time.time() + start_time = speed_counter.get(message.id) + check_time = current_time - start_time + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ᴄᴀɴᴄᴇʟ", + callback_data="stop_downloading", + ), + ] + ] + ) + percentage = current * 100 / total + percentage = str(round(percentage, 2)) + speed = current / check_time + eta = int((total - current) / speed) + eta = get_readable_time(eta) + if not eta: + eta = "0 sᴇᴄᴏɴᴅs" + total_size = convert_bytes(total) + completed_size = convert_bytes(current) + speed = convert_bytes(speed) + percentage = int((percentage.split("."))[0]) + for counter in range(7): + low = int(lower[counter]) + high = int(higher[counter]) + check = int(checker[counter]) + if low < percentage <= high: + if high == check: + try: + await mystic.edit_text( + text=_["tg_1"].format( + app.mention, + total_size, + completed_size, + percentage[:5], + speed, + eta, + ), + reply_markup=upl, + ) + checker[counter] = 100 + except: + pass + + speed_counter[message.id] = time.time() + try: + await app.download_media( + message.reply_to_message, + file_name=fname, + progress=progress, + ) + try: + elapsed = get_readable_time( + int(int(time.time()) - int(speed_counter[message.id])) + ) + except: + elapsed = "0 sᴇᴄᴏɴᴅs" + await mystic.edit_text(_["tg_2"].format(elapsed)) + except: + await mystic.edit_text(_["tg_3"]) + + task = asyncio.create_task(down_load()) + config.lyrical[mystic.id] = task + await task + verify = config.lyrical.get(mystic.id) + if not verify: + return False + config.lyrical.pop(mystic.id) + return True diff --git a/DragMusic/platforms/Youtube.py b/DragMusic/platforms/Youtube.py new file mode 100644 index 0000000000000000000000000000000000000000..e37a13bc568d3cc94895bba85bffdde7d00ded20 --- /dev/null +++ b/DragMusic/platforms/Youtube.py @@ -0,0 +1,470 @@ +import asyncio +import os +import re +import json +from typing import Union +import requests +import yt_dlp +from pyrogram.enums import MessageEntityType +from pyrogram.types import Message +from youtubesearchpython.__future__ import VideosSearch +from DragMusic.utils.database import is_on_off +from DragMusic.utils.formatters import time_to_seconds +import os +import glob +import random +import logging +import aiohttp +import config +from config import API_URL, API_KEY + + +def cookie_txt_file(): + cookie_dir = f"{os.getcwd()}/cookies" + cookies_files = [f for f in os.listdir(cookie_dir) if f.endswith(".txt")] + + cookie_file = os.path.join(cookie_dir, random.choice(cookies_files)) + return cookie_file + + +async def download_song(link: str): + video_id = link.split('v=')[-1].split('&')[0] + + download_folder = "downloads" + for ext in ["mp3", "m4a", "webm"]: + file_path = f"{download_folder}/{video_id}.{ext}" + if os.path.exists(file_path): + #print(f"File already exists: {file_path}") + return file_path + + song_url = f"{API_URL}/song/{video_id}?api={API_KEY}" + async with aiohttp.ClientSession() as session: + while True: + try: + async with session.get(song_url) as response: + if response.status != 200: + raise Exception(f"API request failed with status code {response.status}") + data = await response.json() + status = data.get("status", "").lower() + if status == "downloading": + await asyncio.sleep(2) + continue + elif status == "error": + error_msg = data.get("error") or data.get("message") or "Unknown error" + raise Exception(f"API error: {error_msg}") + elif status == "done": + download_url = data.get("link") + if not download_url: + raise Exception("API response did not provide a download URL.") + break + else: + raise Exception(f"Unexpected status '{status}' from API.") + except Exception as e: + print(f"Error while checking API status: {e}") + return None + + try: + file_format = data.get("format", "mp3") + file_extension = file_format.lower() + file_name = f"{video_id}.{file_extension}" + download_folder = "downloads" + os.makedirs(download_folder, exist_ok=True) + file_path = os.path.join(download_folder, file_name) + + async with session.get(download_url) as file_response: + with open(file_path, 'wb') as f: + while True: + chunk = await file_response.content.read(8192) + if not chunk: + break + f.write(chunk) + return file_path + except aiohttp.ClientError as e: + print(f"Network or client error occurred while downloading: {e}") + return None + except Exception as e: + print(f"Error occurred while downloading song: {e}") + return None + return None + +async def check_file_size(link): + async def get_format_info(link): + proc = await asyncio.create_subprocess_exec( + "yt-dlp", + "--cookies", cookie_txt_file(), + "-J", + link, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate() + if proc.returncode != 0: + print(f'Error:\n{stderr.decode()}') + return None + return json.loads(stdout.decode()) + + def parse_size(formats): + total_size = 0 + for format in formats: + if 'filesize' in format: + total_size += format['filesize'] + return total_size + + info = await get_format_info(link) + if info is None: + return None + + formats = info.get('formats', []) + if not formats: + print("No formats found.") + return None + + total_size = parse_size(formats) + return total_size + +async def shell_cmd(cmd): + proc = await asyncio.create_subprocess_shell( + cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + out, errorz = await proc.communicate() + if errorz: + if "unavailable videos are hidden" in (errorz.decode("utf-8")).lower(): + return out.decode("utf-8") + else: + return errorz.decode("utf-8") + return out.decode("utf-8") + + +class YouTubeAPI: + def __init__(self): + self.base = "https://www.youtube.com/watch?v=" + self.regex = r"(?:youtube\.com|youtu\.be)" + self.status = "https://www.youtube.com/oembed?url=" + self.listbase = "https://youtube.com/playlist?list=" + self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + + async def exists(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if re.search(self.regex, link): + return True + else: + return False + + async def url(self, message_1: Message) -> Union[str, None]: + messages = [message_1] + if message_1.reply_to_message: + messages.append(message_1.reply_to_message) + text = "" + offset = None + length = None + for message in messages: + if offset: + break + if message.entities: + for entity in message.entities: + if entity.type == MessageEntityType.URL: + text = message.text or message.caption + offset, length = entity.offset, entity.length + break + elif message.caption_entities: + for entity in message.caption_entities: + if entity.type == MessageEntityType.TEXT_LINK: + return entity.url + if offset in (None,): + return None + return text[offset : offset + length] + + async def details(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + duration_min = result["duration"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + vidid = result["id"] + if str(duration_min) == "None": + duration_sec = 0 + else: + duration_sec = int(time_to_seconds(duration_min)) + return title, duration_min, duration_sec, thumbnail, vidid + + async def title(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + return title + + async def duration(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + duration = result["duration"] + return duration + + async def thumbnail(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + return thumbnail + + async def video(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + proc = await asyncio.create_subprocess_exec( + "yt-dlp", + "--cookies",cookie_txt_file(), + "-g", + "-f", + "best[height<=?720][width<=?1280]", + f"{link}", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await proc.communicate() + if stdout: + return 1, stdout.decode().split("\n")[0] + else: + return 0, stderr.decode() + + async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None): + if videoid: + link = self.listbase + link + if "&" in link: + link = link.split("&")[0] + playlist = await shell_cmd( + f"yt-dlp -i --get-id --flat-playlist --cookies {cookie_txt_file()} --playlist-end {limit} --skip-download {link}" + ) + try: + result = playlist.split("\n") + for key in result: + if key == "": + result.remove(key) + except: + result = [] + return result + + async def track(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + results = VideosSearch(link, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + duration_min = result["duration"] + vidid = result["id"] + yturl = result["link"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + track_details = { + "title": title, + "link": yturl, + "vidid": vidid, + "duration_min": duration_min, + "thumb": thumbnail, + } + return track_details, vidid + + async def formats(self, link: str, videoid: Union[bool, str] = None): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + ytdl_opts = {"quiet": True, "cookiefile" : cookie_txt_file()} + ydl = yt_dlp.YoutubeDL(ytdl_opts) + with ydl: + formats_available = [] + r = ydl.extract_info(link, download=False) + for format in r["formats"]: + try: + str(format["format"]) + except: + continue + if not "dash" in str(format["format"]).lower(): + try: + format["format"] + format["filesize"] + format["format_id"] + format["ext"] + format["format_note"] + except: + continue + formats_available.append( + { + "format": format["format"], + "filesize": format["filesize"], + "format_id": format["format_id"], + "ext": format["ext"], + "format_note": format["format_note"], + "yturl": link, + } + ) + return formats_available, link + + async def slider( + self, + link: str, + query_type: int, + videoid: Union[bool, str] = None, + ): + if videoid: + link = self.base + link + if "&" in link: + link = link.split("&")[0] + a = VideosSearch(link, limit=10) + result = (await a.next()).get("result") + title = result[query_type]["title"] + duration_min = result[query_type]["duration"] + vidid = result[query_type]["id"] + thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0] + return title, duration_min, thumbnail, vidid + + async def download( + self, + link: str, + mystic, + video: Union[bool, str] = None, + videoid: Union[bool, str] = None, + songaudio: Union[bool, str] = None, + songvideo: Union[bool, str] = None, + format_id: Union[bool, str] = None, + title: Union[bool, str] = None, + ) -> str: + if videoid: + link = self.base + link + loop = asyncio.get_running_loop() + def audio_dl(): + ydl_optssx = { + "format": "bestaudio/best", + "outtmpl": "downloads/%(id)s.%(ext)s", + "geo_bypass": True, + "nocheckcertificate": True, + "quiet": True, + "cookiefile" : cookie_txt_file(), + "no_warnings": True, + } + x = yt_dlp.YoutubeDL(ydl_optssx) + info = x.extract_info(link, False) + xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}") + if os.path.exists(xyz): + return xyz + x.download([link]) + return xyz + + def video_dl(): + ydl_optssx = { + "format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])", + "outtmpl": "downloads/%(id)s.%(ext)s", + "geo_bypass": True, + "nocheckcertificate": True, + "quiet": True, + "cookiefile" : cookie_txt_file(), + "no_warnings": True, + } + x = yt_dlp.YoutubeDL(ydl_optssx) + info = x.extract_info(link, False) + xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}") + if os.path.exists(xyz): + return xyz + x.download([link]) + return xyz + + def song_video_dl(): + formats = f"{format_id}+140" + fpath = f"downloads/{title}" + ydl_optssx = { + "format": formats, + "outtmpl": fpath, + "geo_bypass": True, + "nocheckcertificate": True, + "quiet": True, + "no_warnings": True, + "cookiefile" : cookie_txt_file(), + "prefer_ffmpeg": True, + "merge_output_format": "mp4", + } + x = yt_dlp.YoutubeDL(ydl_optssx) + x.download([link]) + + def song_audio_dl(): + fpath = f"downloads/{title}.%(ext)s" + ydl_optssx = { + "format": format_id, + "outtmpl": fpath, + "geo_bypass": True, + "nocheckcertificate": True, + "quiet": True, + "no_warnings": True, + "cookiefile" : cookie_txt_file(), + "prefer_ffmpeg": True, + "postprocessors": [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "192", + } + ], + } + x = yt_dlp.YoutubeDL(ydl_optssx) + x.download([link]) + + if songvideo: + await download_song(link) + fpath = f"downloads/{link}.mp3" + return fpath + elif songaudio: + await download_song(link) + fpath = f"downloads/{link}.mp3" + return fpath + elif video: + if await is_on_off(1): + direct = True + downloaded_file = await download_song(link) + else: + proc = await asyncio.create_subprocess_exec( + "yt-dlp", + "--cookies",cookie_txt_file(), + "-g", + "-f", + "best[height<=?720][width<=?1280]", + f"{link}", + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await proc.communicate() + if stdout: + downloaded_file = stdout.decode().split("\n")[0] + direct = False + else: + file_size = await check_file_size(link) + if not file_size: + print("None file Size") + return + total_size_mb = file_size / (1024 * 1024) + if total_size_mb > 250: + print(f"File size {total_size_mb:.2f} MB exceeds the 100MB limit.") + return None + direct = True + downloaded_file = await loop.run_in_executor(None, video_dl) + else: + direct = True + downloaded_file = await download_song(link) + return downloaded_file, direct diff --git a/DragMusic/platforms/__init__.py b/DragMusic/platforms/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..935aa560ab834900590a884d6f29a683ac92e5bc --- /dev/null +++ b/DragMusic/platforms/__init__.py @@ -0,0 +1,7 @@ +from .Apple import AppleAPI +from .Carbon import CarbonAPI +from .Resso import RessoAPI +from .Soundcloud import SoundAPI +from .Spotify import SpotifyAPI +from .Telegram import TeleAPI +from .Youtube import YouTubeAPI diff --git a/DragMusic/plugins/__init__.py b/DragMusic/plugins/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..255d2b3a048fb2c8ba13da4dd801d3a03bd8178c --- /dev/null +++ b/DragMusic/plugins/__init__.py @@ -0,0 +1,19 @@ +import glob +from os.path import dirname, isfile + + +def __list_all_modules(): + work_dir = dirname(__file__) + mod_paths = glob.glob(work_dir + "/*/*.py") + + all_modules = [ + (((f.replace(work_dir, "")).replace("/", "."))[:-3]) + for f in mod_paths + if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") + ] + + return all_modules + + +ALL_MODULES = sorted(__list_all_modules()) +__all__ = ALL_MODULES + ["ALL_MODULES"] diff --git a/DragMusic/plugins/admins/auth.py b/DragMusic/plugins/admins/auth.py new file mode 100644 index 0000000000000000000000000000000000000000..81a4959beedd0f665092c9b707eba8911172c6b8 --- /dev/null +++ b/DragMusic/plugins/admins/auth.py @@ -0,0 +1,89 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.utils import extract_user, int_to_alpha +from DragMusic.utils.database import ( + delete_authuser, + get_authuser, + get_authuser_names, + save_authuser, +) +from DragMusic.utils.decorators import AdminActual, language +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS, adminlist + + +@app.on_message(filters.command("auth") & filters.group & ~BANNED_USERS) +@AdminActual +async def auth(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + token = await int_to_alpha(user.id) + _check = await get_authuser_names(message.chat.id) + count = len(_check) + if int(count) == 25: + return await message.reply_text(_["auth_1"]) + if token not in _check: + assis = { + "auth_user_id": user.id, + "auth_name": user.first_name, + "admin_id": message.from_user.id, + "admin_name": message.from_user.first_name, + } + get = adminlist.get(message.chat.id) + if get: + if user.id not in get: + get.append(user.id) + await save_authuser(message.chat.id, token, assis) + return await message.reply_text(_["auth_2"].format(user.mention)) + else: + return await message.reply_text(_["auth_3"].format(user.mention)) + + +@app.on_message(filters.command("unauth") & filters.group & ~BANNED_USERS) +@AdminActual +async def unauthusers(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + token = await int_to_alpha(user.id) + deleted = await delete_authuser(message.chat.id, token) + get = adminlist.get(message.chat.id) + if get: + if user.id in get: + get.remove(user.id) + if deleted: + return await message.reply_text(_["auth_4"].format(user.mention)) + else: + return await message.reply_text(_["auth_5"].format(user.mention)) + + +@app.on_message( + filters.command(["authlist", "authusers"]) & filters.group & ~BANNED_USERS +) +@language +async def authusers(client, message: Message, _): + _wtf = await get_authuser_names(message.chat.id) + if not _wtf: + return await message.reply_text(_["setting_4"]) + else: + j = 0 + mystic = await message.reply_text(_["auth_6"]) + text = _["auth_7"].format(message.chat.title) + for umm in _wtf: + _umm = await get_authuser(message.chat.id, umm) + user_id = _umm["auth_user_id"] + admin_id = _umm["admin_id"] + admin_name = _umm["admin_name"] + try: + user = (await app.get_users(user_id)).first_name + j += 1 + except: + continue + text += f"{j}➤ {user}[{user_id}]\n" + text += f" {_['auth_8']} {admin_name}[{admin_id}]\n\n" + await mystic.edit_text(text, reply_markup=close_markup(_)) diff --git a/DragMusic/plugins/admins/callback.py b/DragMusic/plugins/admins/callback.py new file mode 100644 index 0000000000000000000000000000000000000000..98284dd93812af65796d42b513ab290f7fb5db7b --- /dev/null +++ b/DragMusic/plugins/admins/callback.py @@ -0,0 +1,397 @@ +import asyncio + +from pyrogram import filters +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +from DragMusic import YouTube, app +from DragMusic.core.call import Drag +from DragMusic.misc import SUDOERS, db +from DragMusic.utils.database import ( + get_active_chats, + get_lang, + get_upvote_count, + is_active_chat, + is_music_playing, + is_nonadmin_chat, + music_off, + music_on, + set_loop, +) +from DragMusic.utils.decorators.language import languageCB +from DragMusic.utils.formatters import seconds_to_min +from DragMusic.utils.inline import close_markup, stream_markup, stream_markup_timer +from DragMusic.utils.stream.autoclear import auto_clean +from DragMusic.utils.thumbnails import get_thumb +from config import ( + BANNED_USERS, + SUPPORT_CHAT, + SOUNCLOUD_IMG_URL, + STREAM_IMG_URL, + TELEGRAM_AUDIO_URL, + TELEGRAM_VIDEO_URL, + adminlist, + confirmer, + votemode, +) +from strings import get_string + +checker = {} +upvoters = {} + + +@app.on_callback_query(filters.regex("ADMIN") & ~BANNED_USERS) +@languageCB +async def del_back_playlist(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + command, chat = callback_request.split("|") + if "_" in str(chat): + bet = chat.split("_") + chat = bet[0] + counter = bet[1] + chat_id = int(chat) + if not await is_active_chat(chat_id): + return await CallbackQuery.answer(_["general_5"], show_alert=True) + mention = CallbackQuery.from_user.mention + if command == "UpVote": + if chat_id not in votemode: + votemode[chat_id] = {} + if chat_id not in upvoters: + upvoters[chat_id] = {} + + voters = (upvoters[chat_id]).get(CallbackQuery.message.id) + if not voters: + upvoters[chat_id][CallbackQuery.message.id] = [] + + vote = (votemode[chat_id]).get(CallbackQuery.message.id) + if not vote: + votemode[chat_id][CallbackQuery.message.id] = 0 + + if CallbackQuery.from_user.id in upvoters[chat_id][CallbackQuery.message.id]: + (upvoters[chat_id][CallbackQuery.message.id]).remove( + CallbackQuery.from_user.id + ) + votemode[chat_id][CallbackQuery.message.id] -= 1 + else: + (upvoters[chat_id][CallbackQuery.message.id]).append( + CallbackQuery.from_user.id + ) + votemode[chat_id][CallbackQuery.message.id] += 1 + upvote = await get_upvote_count(chat_id) + get_upvotes = int(votemode[chat_id][CallbackQuery.message.id]) + if get_upvotes >= upvote: + votemode[chat_id][CallbackQuery.message.id] = upvote + try: + exists = confirmer[chat_id][CallbackQuery.message.id] + current = db[chat_id][0] + except: + return await CallbackQuery.edit_message_text(f"ғᴀɪʟᴇᴅ.") + try: + if current["vidid"] != exists["vidid"]: + return await CallbackQuery.edit_message.text(_["admin_35"]) + if current["file"] != exists["file"]: + return await CallbackQuery.edit_message.text(_["admin_35"]) + except: + return await CallbackQuery.edit_message_text(_["admin_36"]) + try: + await CallbackQuery.edit_message_text(_["admin_37"].format(upvote)) + except: + pass + command = counter + mention = "ᴜᴘᴠᴏᴛᴇs" + else: + if ( + CallbackQuery.from_user.id + in upvoters[chat_id][CallbackQuery.message.id] + ): + await CallbackQuery.answer(_["admin_38"], show_alert=True) + else: + await CallbackQuery.answer(_["admin_39"], show_alert=True) + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=f"👍 {get_upvotes}", + callback_data=f"ADMIN UpVote|{chat_id}_{counter}", + ) + ] + ] + ) + await CallbackQuery.answer(_["admin_40"], show_alert=True) + return await CallbackQuery.edit_message_reply_markup(reply_markup=upl) + else: + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + if CallbackQuery.from_user.id not in SUDOERS: + admins = adminlist.get(CallbackQuery.message.chat.id) + if not admins: + return await CallbackQuery.answer(_["admin_13"], show_alert=True) + else: + if CallbackQuery.from_user.id not in admins: + return await CallbackQuery.answer( + _["admin_14"], show_alert=True + ) + if command == "Pause": + if not await is_music_playing(chat_id): + return await CallbackQuery.answer(_["admin_1"], show_alert=True) + await CallbackQuery.answer() + await music_off(chat_id) + await Drag.pause_stream(chat_id) + await CallbackQuery.message.reply_text( + _["admin_2"].format(mention), reply_markup=close_markup(_) + ) + elif command == "Resume": + if await is_music_playing(chat_id): + return await CallbackQuery.answer(_["admin_3"], show_alert=True) + await CallbackQuery.answer() + await music_on(chat_id) + await Drag.resume_stream(chat_id) + await CallbackQuery.message.reply_text( + _["admin_4"].format(mention), reply_markup=close_markup(_) + ) + elif command == "Stop" or command == "End": + await CallbackQuery.answer() + await Drag.stop_stream(chat_id) + await set_loop(chat_id, 0) + await CallbackQuery.message.reply_text( + _["admin_5"].format(mention), reply_markup=close_markup(_) + ) + await CallbackQuery.message.delete() + elif command == "Skip" or command == "Replay": + check = db.get(chat_id) + if command == "Skip": + txt = f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀" + popped = None + try: + popped = check.pop(0) + if popped: + await auto_clean(popped) + if not check: + await CallbackQuery.edit_message_text( + f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀" + ) + await CallbackQuery.message.reply_text( + text=_["admin_6"].format( + mention, CallbackQuery.message.chat.title + ), + reply_markup=close_markup(_), + ) + try: + return await Drag.stop_stream(chat_id) + except: + return + except: + try: + await CallbackQuery.edit_message_text( + f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀" + ) + await CallbackQuery.message.reply_text( + text=_["admin_6"].format( + mention, CallbackQuery.message.chat.title + ), + reply_markup=close_markup(_), + ) + return await Drag.stop_stream(chat_id) + except: + return + else: + txt = f"➻ sᴛʀᴇᴀᴍ ʀᴇ-ᴘʟᴀʏᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀" + await CallbackQuery.answer() + queued = check[0]["file"] + title = (check[0]["title"]).title() + user = check[0]["by"] + duration = check[0]["dur"] + streamtype = check[0]["streamtype"] + videoid = check[0]["vidid"] + status = True if str(streamtype) == "video" else None + db[chat_id][0]["played"] = 0 + exis = (check[0]).get("old_dur") + if exis: + db[chat_id][0]["dur"] = exis + db[chat_id][0]["seconds"] = check[0]["old_second"] + db[chat_id][0]["speed_path"] = None + db[chat_id][0]["speed"] = 1.0 + if "live_" in queued: + n, link = await YouTube.video(videoid, True) + if n == 0: + return await CallbackQuery.message.reply_text( + text=_["admin_7"].format(title), + reply_markup=close_markup(_), + ) + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, link, video=status, image=image) + except: + return await CallbackQuery.message.reply_text(_["call_6"]) + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await CallbackQuery.message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + duration, + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_)) + elif "vid_" in queued: + mystic = await CallbackQuery.message.reply_text( + _["call_7"], disable_web_page_preview=True + ) + try: + file_path, direct = await YouTube.download( + videoid, + mystic, + videoid=True, + video=status, + ) + except: + return await mystic.edit_text(_["call_6"]) + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, file_path, video=status, image=image) + except: + return await mystic.edit_text(_["call_6"]) + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await CallbackQuery.message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + duration, + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_)) + await mystic.delete() + elif "index_" in queued: + try: + await Drag.skip_stream(chat_id, videoid, video=status) + except: + return await CallbackQuery.message.reply_text(_["call_6"]) + button = stream_markup(_, chat_id) + run = await CallbackQuery.message.reply_photo( + photo=STREAM_IMG_URL, + caption=_["stream_2"].format(user), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_)) + else: + if videoid == "telegram": + image = None + elif videoid == "soundcloud": + image = None + else: + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, queued, video=status, image=image) + except: + return await CallbackQuery.message.reply_text(_["call_6"]) + if videoid == "telegram": + button = stream_markup(_, chat_id) + run = await CallbackQuery.message.reply_photo( + photo=TELEGRAM_AUDIO_URL + if str(streamtype) == "audio" + else TELEGRAM_VIDEO_URL, + caption=_["stream_1"].format( + SUPPORT_CHAT, title[:23], duration, user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif videoid == "soundcloud": + button = stream_markup(_, chat_id) + run = await CallbackQuery.message.reply_photo( + photo=SOUNCLOUD_IMG_URL + if str(streamtype) == "audio" + else TELEGRAM_VIDEO_URL, + caption=_["stream_1"].format( + SUPPORT_CHAT, title[:23], duration, user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + else: + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await CallbackQuery.message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + duration, + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_)) + + +async def markup_timer(): + while not await asyncio.sleep(7): + active_chats = await get_active_chats() + for chat_id in active_chats: + try: + if not await is_music_playing(chat_id): + continue + playing = db.get(chat_id) + if not playing: + continue + duration_seconds = int(playing[0]["seconds"]) + if duration_seconds == 0: + continue + try: + mystic = playing[0]["mystic"] + except: + continue + try: + check = checker[chat_id][mystic.id] + if check is False: + continue + except: + pass + try: + language = await get_lang(chat_id) + _ = get_string(language) + except: + _ = get_string("en") + try: + buttons = stream_markup_timer( + _, + chat_id, + seconds_to_min(playing[0]["played"]), + playing[0]["dur"], + ) + await mystic.edit_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except: + continue + except: + continue + + +asyncio.create_task(markup_timer()) diff --git a/DragMusic/plugins/admins/loop.py b/DragMusic/plugins/admins/loop.py new file mode 100644 index 0000000000000000000000000000000000000000..313a3e71b33ab42c23078a3efe84b07eb99535eb --- /dev/null +++ b/DragMusic/plugins/admins/loop.py @@ -0,0 +1,46 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.utils.database import get_loop, set_loop +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message(filters.command(["loop", "cloop"]) & filters.group & ~BANNED_USERS) +@AdminRightsCheck +async def admins(cli, message: Message, _, chat_id): + usage = _["admin_17"] + if len(message.command) != 2: + return await message.reply_text(usage) + state = message.text.split(None, 1)[1].strip() + if state.isnumeric(): + state = int(state) + if 1 <= state <= 10: + got = await get_loop(chat_id) + if got != 0: + state = got + state + if int(state) > 10: + state = 10 + await set_loop(chat_id, state) + return await message.reply_text( + text=_["admin_18"].format(state, message.from_user.mention), + reply_markup=close_markup(_), + ) + else: + return await message.reply_text(_["admin_17"]) + elif state.lower() == "enable": + await set_loop(chat_id, 10) + return await message.reply_text( + text=_["admin_18"].format(state, message.from_user.mention), + reply_markup=close_markup(_), + ) + elif state.lower() == "disable": + await set_loop(chat_id, 0) + return await message.reply_text( + _["admin_19"].format(message.from_user.mention), + reply_markup=close_markup(_), + ) + else: + return await message.reply_text(usage) diff --git a/DragMusic/plugins/admins/pause.py b/DragMusic/plugins/admins/pause.py new file mode 100644 index 0000000000000000000000000000000000000000..efd8faaa0fe16821f4c424b9658cae1030c157fe --- /dev/null +++ b/DragMusic/plugins/admins/pause.py @@ -0,0 +1,21 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.utils.database import is_music_playing, music_off +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message(filters.command(["pause", "cpause"]) & filters.group & ~BANNED_USERS) +@AdminRightsCheck +async def pause_admin(cli, message: Message, _, chat_id): + if not await is_music_playing(chat_id): + return await message.reply_text(_["admin_1"]) + await music_off(chat_id) + await Drag.pause_stream(chat_id) + await message.reply_text( + _["admin_2"].format(message.from_user.mention), reply_markup=close_markup(_) + ) diff --git a/DragMusic/plugins/admins/resume.py b/DragMusic/plugins/admins/resume.py new file mode 100644 index 0000000000000000000000000000000000000000..3bf6f5fe45f4c2161c55e0847e3f7222da739eb4 --- /dev/null +++ b/DragMusic/plugins/admins/resume.py @@ -0,0 +1,21 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.utils.database import is_music_playing, music_on +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message(filters.command(["resume", "cresume"]) & filters.group & ~BANNED_USERS) +@AdminRightsCheck +async def resume_com(cli, message: Message, _, chat_id): + if await is_music_playing(chat_id): + return await message.reply_text(_["admin_3"]) + await music_on(chat_id) + await Drag.resume_stream(chat_id) + await message.reply_text( + _["admin_4"].format(message.from_user.mention), reply_markup=close_markup(_) + ) diff --git a/DragMusic/plugins/admins/seek.py b/DragMusic/plugins/admins/seek.py new file mode 100644 index 0000000000000000000000000000000000000000..71455ac2ce37a18617ca237e884047ce6e3c0561 --- /dev/null +++ b/DragMusic/plugins/admins/seek.py @@ -0,0 +1,75 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import YouTube, app +from DragMusic.core.call import Drag +from DragMusic.misc import db +from DragMusic.utils import AdminRightsCheck, seconds_to_min +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message( + filters.command(["seek", "cseek", "seekback", "cseekback"]) + & filters.group + & ~BANNED_USERS +) +@AdminRightsCheck +async def seek_comm(cli, message: Message, _, chat_id): + if len(message.command) == 1: + return await message.reply_text(_["admin_20"]) + query = message.text.split(None, 1)[1].strip() + if not query.isnumeric(): + return await message.reply_text(_["admin_21"]) + playing = db.get(chat_id) + if not playing: + return await message.reply_text(_["queue_2"]) + duration_seconds = int(playing[0]["seconds"]) + if duration_seconds == 0: + return await message.reply_text(_["admin_22"]) + file_path = playing[0]["file"] + duration_played = int(playing[0]["played"]) + duration_to_skip = int(query) + duration = playing[0]["dur"] + if message.command[0][-2] == "c": + if (duration_played - duration_to_skip) <= 10: + return await message.reply_text( + text=_["admin_23"].format(seconds_to_min(duration_played), duration), + reply_markup=close_markup(_), + ) + to_seek = duration_played - duration_to_skip + 1 + else: + if (duration_seconds - (duration_played + duration_to_skip)) <= 10: + return await message.reply_text( + text=_["admin_23"].format(seconds_to_min(duration_played), duration), + reply_markup=close_markup(_), + ) + to_seek = duration_played + duration_to_skip + 1 + mystic = await message.reply_text(_["admin_24"]) + if "vid_" in file_path: + n, file_path = await YouTube.video(playing[0]["vidid"], True) + if n == 0: + return await message.reply_text(_["admin_22"]) + check = (playing[0]).get("speed_path") + if check: + file_path = check + if "index_" in file_path: + file_path = playing[0]["vidid"] + try: + await Drag.seek_stream( + chat_id, + file_path, + seconds_to_min(to_seek), + duration, + playing[0]["streamtype"], + ) + except: + return await mystic.edit_text(_["admin_26"], reply_markup=close_markup(_)) + if message.command[0][-2] == "c": + db[chat_id][0]["played"] -= duration_to_skip + else: + db[chat_id][0]["played"] += duration_to_skip + await mystic.edit_text( + text=_["admin_25"].format(seconds_to_min(to_seek), message.from_user.mention), + reply_markup=close_markup(_), + ) diff --git a/DragMusic/plugins/admins/shuffle.py b/DragMusic/plugins/admins/shuffle.py new file mode 100644 index 0000000000000000000000000000000000000000..908e5647851adafbe87cc822192c0f877dc1e61c --- /dev/null +++ b/DragMusic/plugins/admins/shuffle.py @@ -0,0 +1,33 @@ +import random + +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import db +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message( + filters.command(["shuffle", "cshuffle"]) & filters.group & ~BANNED_USERS +) +@AdminRightsCheck +async def admins(Client, message: Message, _, chat_id): + check = db.get(chat_id) + if not check: + return await message.reply_text(_["queue_2"]) + try: + popped = check.pop(0) + except: + return await message.reply_text(_["admin_15"], reply_markup=close_markup(_)) + check = db.get(chat_id) + if not check: + check.insert(0, popped) + return await message.reply_text(_["admin_15"], reply_markup=close_markup(_)) + random.shuffle(check) + check.insert(0, popped) + await message.reply_text( + _["admin_16"].format(message.from_user.mention), reply_markup=close_markup(_) + ) diff --git a/DragMusic/plugins/admins/skip.py b/DragMusic/plugins/admins/skip.py new file mode 100644 index 0000000000000000000000000000000000000000..b862420c53f40dda2b86151c1543158f3e67a6ca --- /dev/null +++ b/DragMusic/plugins/admins/skip.py @@ -0,0 +1,232 @@ +from pyrogram import filters +from pyrogram.types import InlineKeyboardMarkup, Message + +import config +from DragMusic import YouTube, app +from DragMusic.core.call import Drag +from DragMusic.misc import db +from DragMusic.utils.database import get_loop +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup, stream_markup +from DragMusic.utils.stream.autoclear import auto_clean +from DragMusic.utils.thumbnails import get_thumb +from config import BANNED_USERS + + +@app.on_message( + filters.command(["skip", "cskip", "next", "cnext"]) & filters.group & ~BANNED_USERS +) +@AdminRightsCheck +async def skip(cli, message: Message, _, chat_id): + if not len(message.command) < 2: + loop = await get_loop(chat_id) + if loop != 0: + return await message.reply_text(_["admin_8"]) + state = message.text.split(None, 1)[1].strip() + if state.isnumeric(): + state = int(state) + check = db.get(chat_id) + if check: + count = len(check) + if count > 2: + count = int(count - 1) + if 1 <= state <= count: + for x in range(state): + popped = None + try: + popped = check.pop(0) + except: + return await message.reply_text(_["admin_12"]) + if popped: + await auto_clean(popped) + if not check: + try: + await message.reply_text( + text=_["admin_6"].format( + message.from_user.mention, + message.chat.title, + ), + reply_markup=close_markup(_), + ) + await Drag.stop_stream(chat_id) + except: + return + break + else: + return await message.reply_text(_["admin_11"].format(count)) + else: + return await message.reply_text(_["admin_10"]) + else: + return await message.reply_text(_["queue_2"]) + else: + return await message.reply_text(_["admin_9"]) + else: + check = db.get(chat_id) + popped = None + try: + popped = check.pop(0) + if popped: + await auto_clean(popped) + if not check: + await message.reply_text( + text=_["admin_6"].format( + message.from_user.mention, message.chat.title + ), + reply_markup=close_markup(_), + ) + try: + return await Drag.stop_stream(chat_id) + except: + return + except: + try: + await message.reply_text( + text=_["admin_6"].format( + message.from_user.mention, message.chat.title + ), + reply_markup=close_markup(_), + ) + return await Drag.stop_stream(chat_id) + except: + return + queued = check[0]["file"] + title = (check[0]["title"]).title() + user = check[0]["by"] + streamtype = check[0]["streamtype"] + videoid = check[0]["vidid"] + status = True if str(streamtype) == "video" else None + db[chat_id][0]["played"] = 0 + exis = (check[0]).get("old_dur") + if exis: + db[chat_id][0]["dur"] = exis + db[chat_id][0]["seconds"] = check[0]["old_second"] + db[chat_id][0]["speed_path"] = None + db[chat_id][0]["speed"] = 1.0 + if "live_" in queued: + n, link = await YouTube.video(videoid, True) + if n == 0: + return await message.reply_text(_["admin_7"].format(title)) + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, link, video=status, image=image) + except: + return await message.reply_text(_["call_6"]) + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif "vid_" in queued: + mystic = await message.reply_text(_["call_7"], disable_web_page_preview=True) + try: + file_path, direct = await YouTube.download( + videoid, + mystic, + videoid=True, + video=status, + ) + except: + return await mystic.edit_text(_["call_6"]) + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, file_path, video=status, image=image) + except: + return await mystic.edit_text(_["call_6"]) + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + await mystic.delete() + elif "index_" in queued: + try: + await Drag.skip_stream(chat_id, videoid, video=status) + except: + return await message.reply_text(_["call_6"]) + button = stream_markup(_, chat_id) + run = await message.reply_photo( + photo=config.STREAM_IMG_URL, + caption=_["stream_2"].format(user), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + else: + if videoid == "telegram": + image = None + elif videoid == "soundcloud": + image = None + else: + try: + image = await YouTube.thumbnail(videoid, True) + except: + image = None + try: + await Drag.skip_stream(chat_id, queued, video=status, image=image) + except: + return await message.reply_text(_["call_6"]) + if videoid == "telegram": + button = stream_markup(_, chat_id) + run = await message.reply_photo( + photo=config.TELEGRAM_AUDIO_URL + if str(streamtype) == "audio" + else config.TELEGRAM_VIDEO_URL, + caption=_["stream_1"].format( + config.SUPPORT_CHAT, title[:23], check[0]["dur"], user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif videoid == "soundcloud": + button = stream_markup(_, chat_id) + run = await message.reply_photo( + photo=config.SOUNCLOUD_IMG_URL + if str(streamtype) == "audio" + else config.TELEGRAM_VIDEO_URL, + caption=_["stream_1"].format( + config.SUPPORT_CHAT, title[:23], check[0]["dur"], user + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + else: + button = stream_markup(_, chat_id) + img = await get_thumb(videoid) + run = await message.reply_photo( + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{videoid}", + title[:23], + check[0]["dur"], + user, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" diff --git a/DragMusic/plugins/admins/speed.py b/DragMusic/plugins/admins/speed.py new file mode 100644 index 0000000000000000000000000000000000000000..4ec6eacbf1d9ea1d70a5df2f9e2266c4b61d15d5 --- /dev/null +++ b/DragMusic/plugins/admins/speed.py @@ -0,0 +1,112 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.misc import SUDOERS, db +from DragMusic.utils import AdminRightsCheck +from DragMusic.utils.database import is_active_chat, is_nonadmin_chat +from DragMusic.utils.decorators.language import languageCB +from DragMusic.utils.inline import close_markup, speed_markup +from config import BANNED_USERS, adminlist + +checker = [] + + +@app.on_message( + filters.command(["cspeed", "speed", "cslow", "slow", "playback", "cplayback"]) + & filters.group + & ~BANNED_USERS +) +@AdminRightsCheck +async def playback(cli, message: Message, _, chat_id): + playing = db.get(chat_id) + if not playing: + return await message.reply_text(_["queue_2"]) + duration_seconds = int(playing[0]["seconds"]) + if duration_seconds == 0: + return await message.reply_text(_["admin_27"]) + file_path = playing[0]["file"] + if "downloads" not in file_path: + return await message.reply_text(_["admin_27"]) + upl = speed_markup(_, chat_id) + return await message.reply_text( + text=_["admin_28"].format(app.mention), + reply_markup=upl, + ) + + +@app.on_callback_query(filters.regex("SpeedUP") & ~BANNED_USERS) +@languageCB +async def del_back_playlist(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + chat, speed = callback_request.split("|") + chat_id = int(chat) + if not await is_active_chat(chat_id): + return await CallbackQuery.answer(_["general_5"], show_alert=True) + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + if CallbackQuery.from_user.id not in SUDOERS: + admins = adminlist.get(CallbackQuery.message.chat.id) + if not admins: + return await CallbackQuery.answer(_["admin_13"], show_alert=True) + else: + if CallbackQuery.from_user.id not in admins: + return await CallbackQuery.answer(_["admin_14"], show_alert=True) + playing = db.get(chat_id) + if not playing: + return await CallbackQuery.answer(_["queue_2"], show_alert=True) + duration_seconds = int(playing[0]["seconds"]) + if duration_seconds == 0: + return await CallbackQuery.answer(_["admin_27"], show_alert=True) + file_path = playing[0]["file"] + if "downloads" not in file_path: + return await CallbackQuery.answer(_["admin_27"], show_alert=True) + checkspeed = (playing[0]).get("speed") + if checkspeed: + if str(checkspeed) == str(speed): + if str(speed) == str("1.0"): + return await CallbackQuery.answer( + _["admin_29"], + show_alert=True, + ) + else: + if str(speed) == str("1.0"): + return await CallbackQuery.answer( + _["admin_29"], + show_alert=True, + ) + if chat_id in checker: + return await CallbackQuery.answer( + _["admin_30"], + show_alert=True, + ) + else: + checker.append(chat_id) + try: + await CallbackQuery.answer( + _["admin_31"], + ) + except: + pass + mystic = await CallbackQuery.edit_message_text( + text=_["admin_32"].format(CallbackQuery.from_user.mention), + ) + try: + await Drag.speedup_stream( + chat_id, + file_path, + speed, + playing, + ) + except: + if chat_id in checker: + checker.remove(chat_id) + return await mystic.edit_text(_["admin_33"], reply_markup=close_markup(_)) + if chat_id in checker: + checker.remove(chat_id) + await mystic.edit_text( + text=_["admin_34"].format(speed, CallbackQuery.from_user.mention), + reply_markup=close_markup(_), + ) diff --git a/DragMusic/plugins/admins/stop.py b/DragMusic/plugins/admins/stop.py new file mode 100644 index 0000000000000000000000000000000000000000..997daa1393bb391b8613d934a60c8c313c8ce2d4 --- /dev/null +++ b/DragMusic/plugins/admins/stop.py @@ -0,0 +1,23 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.utils.database import set_loop +from DragMusic.utils.decorators import AdminRightsCheck +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS + + +@app.on_message( + filters.command(["end", "stop", "cend", "cstop"]) & filters.group & ~BANNED_USERS +) +@AdminRightsCheck +async def stop_music(cli, message: Message, _, chat_id): + if not len(message.command) == 1: + return + await Drag.stop_stream(chat_id) + await set_loop(chat_id, 0) + await message.reply_text( + _["admin_5"].format(message.from_user.mention), reply_markup=close_markup(_) + ) diff --git a/DragMusic/plugins/admins/tagall.py b/DragMusic/plugins/admins/tagall.py new file mode 100644 index 0000000000000000000000000000000000000000..ead7a330d8fb91670bae340557faf52d552c071a --- /dev/null +++ b/DragMusic/plugins/admins/tagall.py @@ -0,0 +1,290 @@ +from DragMusic import app +import asyncio +import random +from pyrogram import Client, filters +from pyrogram.enums import ChatType, ChatMemberStatus +from pyrogram.errors import UserNotParticipant +from pyrogram.types import ChatPermissions + +spam_chats = [] + +EMOJI = [ "🦋🦋🦋🦋🦋", + "🧚🌸🧋🍬🫖", + "🥀🌷🌹🌺💐", + "🌸🌿💮🌱🌵", + "❤️💚💙💜🖤", + "💓💕💞💗💖", + "🌸💐🌺🌹🦋", + "🍔🦪🍛🍲🥗", + "🍎🍓🍒🍑🌶️", + "🧋🥤🧋🥛🍷", + "🍬🍭🧁🎂🍡", + "🍨🧉🍺☕🍻", + "🥪🥧🍦🍥🍚", + "🫖☕🍹🍷🥛", + "☕🧃🍩🍦🍙", + "🍁🌾💮🍂🌿", + "🌨️🌥️⛈️🌩️🌧️", + "🌷🏵️🌸🌺💐", + "💮🌼🌻🍀🍁", + "🧟🦸🦹🧙👸", + "🧅🍠🥕🌽🥦", + "🐷🐹🐭🐨🐻‍❄️", + "🦋🐇🐀🐈🐈‍⬛", + "🌼🌳🌲🌴🌵", + "🥩🍋🍐🍈🍇", + "🍴🍽️🔪🍶🥃", + "🕌🏰🏩⛩️🏩", + "🎉🎊🎈🎂🎀", + "🪴🌵🌴🌳🌲", + "🎄🎋🎍🎑🎎", + "🦅🦜🕊️🦤🦢", + "🦤🦩🦚🦃🦆", + "🐬🦭🦈🐋🐳", + "🐔🐟🐠🐡🦐", + "🦩🦀🦑🐙🦪", + "🐦🦂🕷️🕸️🐚", + "🥪🍰🥧🍨🍨", + " 🥬🍉🧁🧇", + ] + +TAGMES = [ " **➠ ʜᴇʏ ʙᴀʙʏ ᴋᴀʜᴀ ʜᴏ 🤗** ", + " **➠ ᴏʏᴇ sᴏ ɢʏᴇ ᴋʏᴀ ᴏɴʟɪɴᴇ ᴀᴀᴏ 😊** ", + " **➠ ᴠᴄ ᴄʜᴀʟᴏ ʙᴀᴛᴇɴ ᴋᴀʀᴛᴇ ʜᴀɪɴ ᴋᴜᴄʜ ᴋᴜᴄʜ 😃** ", + " **➠ ᴋʜᴀɴᴀ ᴋʜᴀ ʟɪʏᴇ ᴊɪ..?? 🥲** ", + " **➠ ɢʜᴀʀ ᴍᴇ sᴀʙ ᴋᴀɪsᴇ ʜᴀɪɴ ᴊɪ 🥺** ", + " **➠ ᴘᴛᴀ ʜᴀɪ ʙᴏʜᴏᴛ ᴍɪss ᴋᴀʀ ʀʜɪ ᴛʜɪ ᴀᴀᴘᴋᴏ 🤭** ", + " **➠ ᴏʏᴇ ʜᴀʟ ᴄʜᴀʟ ᴋᴇsᴀ ʜᴀɪ..?? 🤨** ", + " **➠ ᴍᴇʀɪ ʙʜɪ sᴇᴛᴛɪɴɢ ᴋᴀʀʙᴀ ᴅᴏɢᴇ..?? 🙂** ", + " **➠ ᴀᴀᴘᴋᴀ ɴᴀᴍᴇ ᴋʏᴀ ʜᴀɪ..?? 🥲** ", + " **➠ ɴᴀsᴛᴀ ʜᴜᴀ ᴀᴀᴘᴋᴀ..?? 😋** ", + " **➠ ᴍᴇʀᴇ ᴋᴏ ᴀᴘɴᴇ ɢʀᴏᴜᴘ ᴍᴇ ᴋɪᴅɴᴀᴘ ᴋʀ ʟᴏ 😍** ", + " **➠ ᴀᴀᴘᴋɪ ᴘᴀʀᴛɴᴇʀ ᴀᴀᴘᴋᴏ ᴅʜᴜɴᴅ ʀʜᴇ ʜᴀɪɴ ᴊʟᴅɪ ᴏɴʟɪɴᴇ ᴀʏɪᴀᴇ 😅** ", + " **➠ ᴍᴇʀᴇ sᴇ ᴅᴏsᴛɪ ᴋʀᴏɢᴇ..?? 🤔** ", + " **➠ sᴏɴᴇ ᴄʜᴀʟ ɢʏᴇ ᴋʏᴀ 🙄** ", + " **➠ ᴇᴋ sᴏɴɢ ᴘʟᴀʏ ᴋʀᴏ ɴᴀ ᴘʟss 😕** ", + " **➠ ᴀᴀᴘ ᴋᴀʜᴀ sᴇ ʜᴏ..?? 🙃** ", + " **➠ ʜᴇʟʟᴏ ᴊɪ ɴᴀᴍᴀsᴛᴇ 😛** ", + " **➠ ʜᴇʟʟᴏ ʙᴀʙʏ ᴋᴋʀʜ..? 🤔** ", + " **➠ ᴅᴏ ʏᴏᴜ ᴋɴᴏᴡ ᴡʜᴏ ɪs ᴍʏ ᴏᴡɴᴇʀ.? ☺️** ", + " **➠ ᴄʜʟᴏ ᴋᴜᴄʜ ɢᴀᴍᴇ ᴋʜᴇʟᴛᴇ ʜᴀɪɴ.🤗** ", + " **➠ ᴀᴜʀ ʙᴀᴛᴀᴏ ᴋᴀɪsᴇ ʜᴏ ʙᴀʙʏ 😇** ", + " **➠ ᴛᴜᴍʜᴀʀɪ ᴍᴜᴍᴍʏ ᴋʏᴀ ᴋᴀʀ ʀᴀʜɪ ʜᴀɪ 🤭** ", + " **➠ ᴍᴇʀᴇ sᴇ ʙᴀᴛ ɴᴏɪ ᴋʀᴏɢᴇ 🥺** ", + " **➠ ᴏʏᴇ ᴘᴀɢᴀʟ ᴏɴʟɪɴᴇ ᴀᴀ ᴊᴀ 😶** ", + " **➠ ᴀᴀᴊ ʜᴏʟɪᴅᴀʏ ʜᴀɪ ᴋʏᴀ sᴄʜᴏᴏʟ ᴍᴇ..?? 🤔** ", + " **➠ ᴏʏᴇ ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ 😜** ", + " **➠ sᴜɴᴏ ᴇᴋ ᴋᴀᴍ ʜᴀɪ ᴛᴜᴍsᴇ 🙂** ", + " **➠ ᴋᴏɪ sᴏɴɢ ᴘʟᴀʏ ᴋʀᴏ ɴᴀ 😪** ", + " **➠ ɴɪᴄᴇ ᴛᴏ ᴍᴇᴇᴛ ᴜʜ ☺** ", + " **➠ ᴍᴇʀᴀ ʙᴀʙᴜ ɴᴇ ᴛʜᴀɴᴀ ᴋʜᴀʏᴀ ᴋʏᴀ..? 🙊** ", + " **➠ sᴛᴜᴅʏ ᴄᴏᴍᴘʟᴇᴛᴇ ʜᴜᴀ?? 😺** ", + " **➠ ʙᴏʟᴏ ɴᴀ ᴋᴜᴄʜ ʏʀʀ 🥲** ", + " **➠ sᴏɴᴀʟɪ ᴋᴏɴ ʜᴀɪ...?? 😅** ", + " **➠ ᴛᴜᴍʜᴀʀɪ ᴇᴋ ᴘɪᴄ ᴍɪʟᴇɢɪ..? 😅** ", + " **➠ ᴍᴜᴍᴍʏ ᴀᴀ ɢʏɪ ᴋʏᴀ 😆** ", + " **➠ ᴏʀ ʙᴀᴛᴀᴏ ʙʜᴀʙʜɪ ᴋᴀɪsɪ ʜᴀɪ 😉** ", + " **➠ ɪ ʟᴏᴠᴇ ʏᴏᴜ 💚** ", + " **➠ ᴅᴏ ʏᴏᴜ ʟᴏᴠᴇ ᴍᴇ..? 👀** ", + " **➠ ʀᴀᴋʜɪ ᴋᴀʙ ʙᴀɴᴅ ʀᴀʜɪ ʜᴏ..?? 🙉** ", + " **➠ ᴇᴋ sᴏɴɢ sᴜɴᴀᴜ..? 😹** ", + " **➠ ᴏɴʟɪɴᴇ ᴀᴀ ᴊᴀ ʀᴇ sᴏɴɢ sᴜɴᴀ ʀᴀʜɪ ʜᴜ 😻** ", + " **➠ ɪɴsᴛᴀɢʀᴀᴍ ᴄʜᴀʟᴀᴛᴇ ʜᴏ..?? 🙃** ", + " **➠ ᴡʜᴀᴛsᴀᴘᴘ ɴᴜᴍʙᴇʀ ᴅᴏɢᴇ ᴀᴘɴᴀ ᴛᴜᴍ..? 😕** ", + " **➠ ᴛᴜᴍʜᴇ ᴋᴏɴ sᴀ ᴍᴜsɪᴄ sᴜɴɴᴀ ᴘᴀsᴀɴᴅ ʜᴀɪ..? 🙃** ", + " **➠ sᴀʀᴀ ᴋᴀᴍ ᴋʜᴀᴛᴀᴍ ʜᴏ ɢʏᴀ ᴀᴀᴘᴋᴀ..? 🙃** ", + " **➠ ᴋᴀʜᴀ sᴇ ʜᴏ ᴀᴀᴘ 😊** ", + " **➠ sᴜɴᴏ ɴᴀ 🧐** ", + " **➠ ᴍᴇʀᴀ ᴇᴋ ᴋᴀᴀᴍ ᴋᴀʀ ᴅᴏɢᴇ..? ♥️** ", + " **➠ ʙʏ ᴛᴀᴛᴀ ᴍᴀᴛ ʙᴀᴀᴛ ᴋᴀʀɴᴀ ᴀᴀᴊ ᴋᴇ ʙᴀᴅ 😠** ", + " **➠ ᴍᴏᴍ ᴅᴀᴅ ᴋᴀɪsᴇ ʜᴀɪɴ..? ❤** ", + " **➠ ᴋʏᴀ ʜᴜᴀ..? 🤔** ", + " **➠ ʙᴏʜᴏᴛ ʏᴀᴀᴅ ᴀᴀ ʀʜɪ ʜᴀɪ 😒** ", + " **➠ ʙʜᴜʟ ɢʏᴇ ᴍᴜᴊʜᴇ 😏** ", + " **➠ ᴊᴜᴛʜ ɴʜɪ ʙᴏʟɴᴀ ᴄʜᴀʜɪʏᴇ 🤐** ", + " **➠ ᴋʜᴀ ʟᴏ ʙʜᴀᴡ ᴍᴀᴛ ᴋʀᴏ ʙᴀᴀᴛ 😒** ", + " **➠ ᴋʏᴀ ʜᴜᴀ 😮** " + " **➠ ʜɪɪ ʜᴏɪ ʜᴇʟʟᴏ 👀** ", + " **➠ ᴀᴀᴘᴋᴇ ᴊᴀɪsᴀ ᴅᴏsᴛ ʜᴏ sᴀᴛʜ ᴍᴇ ғɪʀ ɢᴜᴍ ᴋɪs ʙᴀᴀᴛ ᴋᴀ 🙈** ", + " **➠ ᴀᴀᴊ ᴍᴇ sᴀᴅ ʜᴏᴏɴ ☹️** ", + " **➠ ᴍᴜsᴊʜsᴇ ʙʜɪ ʙᴀᴀᴛ ᴋᴀʀ ʟᴏ ɴᴀ 🥺** ", + " **➠ ᴋʏᴀ ᴋᴀʀ ʀᴀʜᴇ ʜᴏ 👀** ", + " **➠ ᴋʏᴀ ʜᴀʟ ᴄʜᴀʟ ʜᴀɪ 🙂** ", + " **➠ ᴋᴀʜᴀ sᴇ ʜᴏ ᴀᴀᴘ..?🤔** ", + " **➠ ᴄʜᴀᴛᴛɪɴɢ ᴋᴀʀ ʟᴏ ɴᴀ..🥺** ", + " **➠ ᴍᴇ ᴍᴀsᴏᴏᴍ ʜᴜ ɴᴀ 🥺** ", + " **➠ ᴋᴀʟ ᴍᴀᴊᴀ ᴀʏᴀ ᴛʜᴀ ɴᴀ 😅** ", + " **➠ ɢʀᴏᴜᴘ ᴍᴇ ʙᴀᴀᴛ ᴋʏᴜ ɴᴀʜɪ ᴋᴀʀᴛᴇ ʜᴏ 😕** ", + " **➠ ᴀᴀᴘ ʀᴇʟᴀᴛɪᴏᴍsʜɪᴘ ᴍᴇ ʜᴏ..? 👀** ", + " **➠ ᴋɪᴛɴᴀ ᴄʜᴜᴘ ʀᴀʜᴛᴇ ʜᴏ ʏʀʀ 😼** ", + " **➠ ᴀᴀᴘᴋᴏ ɢᴀɴᴀ ɢᴀɴᴇ ᴀᴀᴛᴀ ʜᴀɪ..? 😸** ", + " **➠ ɢʜᴜᴍɴᴇ ᴄʜᴀʟᴏɢᴇ..?? 🙈** ", + " **➠ ᴋʜᴜs ʀᴀʜᴀ ᴋᴀʀᴏ 🤞** ", + " **➠ ʜᴀᴍ ᴅᴏsᴛ ʙᴀɴ sᴀᴋᴛᴇ ʜᴀɪ...? 🥰** ", + " **➠ ᴋᴜᴄʜ ʙᴏʟ ᴋʏᴜ ɴʜɪ ʀᴀʜᴇ ʜᴏ.. 🥺** ", + " **➠ ᴋᴜᴄʜ ᴍᴇᴍʙᴇʀs ᴀᴅᴅ ᴋᴀʀ ᴅᴏ 🥲** ", + " **➠ sɪɴɢʟᴇ ʜᴏ ʏᴀ ᴍɪɴɢʟᴇ 😉** ", + " **➠ ᴀᴀᴏ ᴘᴀʀᴛʏ ᴋᴀʀᴛᴇ ʜᴀɪɴ 🥳** ", + " **➠ ʙɪᴏ ᴍᴇ ʟɪɴᴋ ʜᴀɪ ᴊᴏɪɴ ᴋᴀʀ ʟᴏ 🧐** ", + " **➠ ᴍᴜᴊʜᴇ ʙʜᴜʟ ɢʏᴇ ᴋʏᴀ 🥺** ", + " **➠ ʏᴀʜᴀ ᴀᴀ ᴊᴀᴏ @THE_FRIENDZ ᴍᴀsᴛɪ ᴋᴀʀᴇɴɢᴇ 🤭** ", + " **➠ ᴛʀᴜᴛʜ ᴀɴᴅ ᴅᴀʀᴇ ᴋʜᴇʟᴏɢᴇ..? 😊** ", + " **➠ ᴀᴀᴊ ᴍᴜᴍᴍʏ ɴᴇ ᴅᴀᴛᴀ ʏʀʀ 🥺** ", + " **➠ ᴊᴏɪɴ ᴋᴀʀ ʟᴏ 🤗** ", + " **➠ ᴇᴋ ᴅɪʟ ʜᴀɪ ᴇᴋ ᴅɪʟ ʜɪ ᴛᴏ ʜᴀɪ 😗** ", + " **➠ ᴛᴜᴍʜᴀʀᴇ ᴅᴏsᴛ ᴋᴀʜᴀ ɢʏᴇv🥺** ", + " **➠ ᴍʏ ᴄᴜᴛᴇ ᴏᴡɴᴇʀ @RoY_EdiTX 🥰** ", + " **➠ ᴋᴀʜᴀ ᴋʜᴏʏᴇ ʜᴏ ᴊᴀᴀɴ 😜** ", + " **➠ ɢᴏᴏᴅ ɴɪɢʜᴛ ᴊɪ ʙʜᴜᴛ ʀᴀᴛ ʜᴏ ɢʏɪ 🥰** ", + ] + +VC_TAG = [ "**➠ ᴏʏᴇ ᴠᴄ ᴀᴀᴏ ɴᴀ ᴘʟs 😒**", + "**➠ ᴊᴏɪɴ ᴠᴄ ғᴀsᴛ ɪᴛs ɪᴍᴀᴘᴏʀᴛᴀɴᴛ 😐**", + "**➠ ʙᴀʙʏ ᴄᴏᴍᴇ ᴏɴ ᴠᴄ ғᴀsᴛ 🙄**", + "**➠ ᴄʜᴜᴘ ᴄʜᴀᴘ ᴠᴄ ᴘʀ ᴀᴀᴏ 🤫**", + "**➠ ᴍᴀɪɴ ᴠᴄ ᴍᴇ ᴛᴜᴍᴀʀᴀ ᴡᴀɪᴛ ᴋʀ ʀʜɪ 🥺**", + "**➠ ᴠᴄ ᴘᴀʀ ᴀᴀᴏ ʙᴀᴀᴛ ᴋʀᴛᴇ ʜᴀɪ ☺️**", + "**➠ ʙᴀʙᴜ ᴠᴄ ᴀᴀ ᴊᴀɪʏᴇ ᴇᴋ ʙᴀʀ 🤨**", + "**➠ ᴠᴄ ᴘᴀʀ ʏᴇ ʀᴜssɪᴀɴ ᴋʏᴀ ᴋᴀʀ ʀʜɪ ʜᴀɪ 😮‍💨**", + "**➠ ᴠᴄ ᴘᴀʀ ᴀᴀᴏ ᴠᴀʀɴᴀ ʙᴀɴ ʜᴏ ᴊᴀᴏɢᴇ 🤭**", + "**➠ sᴏʀʀʏ ʙᴀʙʏ ᴘʟs ᴠᴄ ᴀᴀ ᴊᴀᴏ ɴᴀ 😢**", + "**➠ ᴠᴄ ᴀᴀɴᴀ ᴇᴋ ᴄʜɪᴊ ᴅɪᴋʜᴀᴛɪ ʜᴜ 😮**", + "**➠ ᴠᴄ ᴍᴇ ᴄʜᴇᴄᴋ ᴋʀᴋᴇ ʙᴀᴛᴀɴᴀ ᴋᴏɴ sᴀ sᴏɴɢ ᴘʟᴀʏ ʜᴏ ʀʜᴀ ʜᴀɪ.. 💫**", + "**➠ ᴠᴄ ᴊᴏɪɴ ᴋʀɴᴇ ᴍᴇ ᴋʏᴀ ᴊᴀᴛᴀ ʜᴀɪ ᴛʜᴏʀᴀ ᴅᴇʀ ᴋᴀʀ ʟᴏ ɴᴀ 😇**", + "**➠ ᴊᴀɴᴇᴍᴀɴ ᴠᴄ ᴀᴀᴏ ɴᴀ ʟɪᴠᴇ sʜᴏᴡ ᴅɪᴋʜᴀᴛɪ ʜᴏᴏɴ.. 😵‍💫**", + "**➠ ᴏᴡɴᴇʀ ʙᴀʙᴜ ᴠᴄ ᴛᴀᴘᴋᴏ ɴᴀ... 😕**", + "**➠ ʜᴇʏ ᴄᴜᴛɪᴇ ᴠᴄ ᴀᴀɴᴀ ᴛᴏ ᴇᴋ ʙᴀᴀʀ... 🌟**", + "**➠ ᴠᴄ ᴘᴀʀ ᴀᴀ ʀʜᴇ ʜᴏ ʏᴀ ɴᴀ... ✨**", + "**➠ ᴠᴄ ᴘᴀʀ ᴀᴀ ᴊᴀ ᴠʀɴᴀ ɢʜᴀʀ sᴇ ᴜᴛʜᴡᴀ ᴅᴜɴɢɪ... 🌝**", + "**➠ ʙᴀʙʏ ᴠᴄ ᴘᴀʀ ᴋʙ ᴀᴀ ʀʜᴇ ʜᴏ. 💯**", + ] + + +@app.on_message(filters.command(["tagall", "tagmember" ], prefixes=["/", "@", "#"])) +async def mentionall(client, message): + chat_id = message.chat.id + if message.chat.type == ChatType.PRIVATE: + return await message.reply("๏ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴏɴʟʏ ғᴏʀ ɢʀᴏᴜᴘs.") + + is_admin = False + try: + participant = await client.get_chat_member(chat_id, message.from_user.id) + except UserNotParticipant: + is_admin = False + else: + if participant.status in ( + ChatMemberStatus.ADMINISTRATOR, + ChatMemberStatus.OWNER + ): + is_admin = True + if not is_admin: + return await message.reply("๏ ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ʙᴀʙʏ, ᴏɴʟʏ ᴀᴅᴍɪɴs ᴄᴀɴ ᴛᴀɢ ᴍᴇᴍʙᴇʀs. ") + + if message.reply_to_message and message.text: + return await message.reply("/tagall ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ ᴛʏᴘᴇ ʟɪᴋᴇ ᴛʜɪs / ʀᴇᴘʟʏ ᴀɴʏ ᴍᴇssᴀɢᴇ ɴᴇxᴛ ᴛɪᴍᴇ ʙᴏᴛ ᴛᴀɢɢɪɴɢ...") + elif message.text: + mode = "text_on_cmd" + msg = message.text + elif message.reply_to_message: + mode = "text_on_reply" + msg = message.reply_to_message + if not msg: + return await message.reply("/tagall ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ ᴛʏᴘᴇ ʟɪᴋᴇ ᴛʜɪs / ʀᴇᴘʟʏ ᴀɴʏ ᴍᴇssᴀɢᴇ ɴᴇxᴛ ᴛɪᴍᴇ ғᴏᴛ ᴛᴀɢɢɪɴɢ...") + else: + return await message.reply("/tagall ɢᴏᴏᴅ ᴍᴏʀɴɪɴɢ ᴛʏᴘᴇ ʟɪᴋᴇ ᴛʜɪs / ʀᴇᴘʟʏ ᴀɴʏ ᴍᴇssᴀɢᴇ ɴᴇxᴛ ᴛɪᴍᴇ ʙᴏᴛ ᴛᴀɢɢɪɴɢ...") + if chat_id in spam_chats: + return await message.reply("๏ ᴘʟᴇᴀsᴇ ᴀᴛ ғɪʀsᴛ sᴛᴏᴘ ʀᴜɴɴɪɴɢ ᴍᴇɴᴛɪᴏɴ ᴘʀᴏᴄᴇss...") + spam_chats.append(chat_id) + usrnum = 0 + usrtxt = "" + async for usr in client.get_chat_members(chat_id): + if not chat_id in spam_chats: + break + if usr.user.is_bot: + continue + usrnum += 1 + usrtxt += f"[{usr.user.first_name}](tg://user?id={usr.user.id}) " + + if usrnum == 1: + if mode == "text_on_cmd": + txt = f"{usrtxt} {random.choice(TAGMES)}" + await client.send_message(chat_id, txt) + elif mode == "text_on_reply": + await msg.reply(f"[{random.choice(EMOJI)}](tg://user?id={usr.user.id})") + await asyncio.sleep(4) + usrnum = 0 + usrtxt = "" + try: + spam_chats.remove(chat_id) + except: + pass + + +@app.on_message(filters.command(["vctag"], prefixes=["/", "@", "#"])) +async def mention_allvc(client, message): + chat_id = message.chat.id + if message.chat.type == ChatType.PRIVATE: + return await message.reply("๏ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴏɴʟʏ ғᴏʀ ɢʀᴏᴜᴘs.") + + is_admin = False + try: + participant = await client.get_chat_member(chat_id, message.from_user.id) + except UserNotParticipant: + is_admin = False + else: + if participant.status in ( + ChatMemberStatus.ADMINISTRATOR, + ChatMemberStatus.OWNER + ): + is_admin = True + if not is_admin: + return await message.reply("๏ ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ʙᴀʙʏ, ᴏɴʟʏ ᴀᴅᴍɪɴs ᴄᴀɴ ᴛᴀɢ ᴍᴇᴍʙᴇʀs. ") + if chat_id in spam_chats: + return await message.reply("๏ ᴘʟᴇᴀsᴇ ᴀᴛ ғɪʀsᴛ sᴛᴏᴘ ʀᴜɴɴɪɴɢ ᴍᴇɴᴛɪᴏɴ ᴘʀᴏᴄᴇss...") + spam_chats.append(chat_id) + usrnum = 0 + usrtxt = "" + async for usr in client.get_chat_members(chat_id): + if not chat_id in spam_chats: + break + if usr.user.is_bot: + continue + usrnum += 1 + usrtxt += f"[{usr.user.first_name}](tg://user?id={usr.user.id}) " + + if usrnum == 1: + txt = f"{usrtxt} {random.choice(VC_TAG)}" + await client.send_message(chat_id, txt) + await asyncio.sleep(4) + usrnum = 0 + usrtxt = "" + try: + spam_chats.remove(chat_id) + except: + pass + + + +@app.on_message(filters.command(["cancel", "tagstop", "vcstop"])) +async def cancel_spam(client, message): + if not message.chat.id in spam_chats: + return await message.reply("๏ ᴄᴜʀʀᴇɴᴛʟʏ ɪ'ᴍ ɴᴏᴛ ᴛᴀɢɢɪɴɢ ʙᴀʙʏ.") + is_admin = False + try: + participant = await client.get_chat_member(message.chat.id, message.from_user.id) + except UserNotParticipant: + is_admin = False + else: + if participant.status in ( + ChatMemberStatus.ADMINISTRATOR, + ChatMemberStatus.OWNER + ): + is_admin = True + if not is_admin: + return await message.reply("๏ ʏᴏᴜ ᴀʀᴇ ɴᴏᴛ ᴀᴅᴍɪɴ ʙᴀʙʏ, ᴏɴʟʏ ᴀᴅᴍɪɴs ᴄᴀɴ ᴛᴀɢ ᴍᴇᴍʙᴇʀs.") + else: + try: + spam_chats.remove(message.chat.id) + except: + pass + return await message.reply("๏ ᴍᴇɴᴛɪᴏɴ ᴘʀᴏᴄᴇss sᴛᴏᴘᴘᴇᴅ ๏") diff --git a/DragMusic/plugins/admins/zombies.py b/DragMusic/plugins/admins/zombies.py new file mode 100644 index 0000000000000000000000000000000000000000..e5993d80e0d180f66ca4d40001826d255ca33aa4 --- /dev/null +++ b/DragMusic/plugins/admins/zombies.py @@ -0,0 +1,184 @@ +import os +import asyncio +from pyrogram import Client, filters +from pyrogram.types import Message +from pyrogram import enums +from pyrogram.enums import ChatMemberStatus +from pyrogram.errors import FloodWait +from DragMusic import app +from time import time +import asyncio +from DragMusic.utils.extraction import extract_user + +# Define a dictionary to track the last message timestamp for each user +user_last_message_time = {} +user_command_count = {} +# Define the threshold for command spamming (e.g., 20 commands within 60 seconds) +SPAM_THRESHOLD = 2 +SPAM_WINDOW_SECONDS = 5 + +# ------------------------------------------------------------------------------- # + +chatQueue = [] + +stopProcess = False + +# ------------------------------------------------------------------------------- # + + +@app.on_message(filters.command(["zombies", "Deletedaccounts"])) +async def remove(client, message): + + global stopProcess + try: + try: + sender = await app.get_chat_member(message.chat.id, message.from_user.id) + has_permissions = sender.privileges + except: + has_permissions = message.sender_chat + if has_permissions: + bot = await app.get_chat_member(message.chat.id, "self") + if bot.status == ChatMemberStatus.MEMBER: + await message.reply( + "➠ | ɪ ɴᴇᴇᴅ ᴀᴅᴍɪɴ ᴘᴇʀᴍɪssɪᴏɴs ᴛᴏ ʀᴇᴍᴏᴠᴇ ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄᴏᴜɴᴛs." + ) + else: + if len(chatQueue) > 30: + await message.reply( + "➠ | ɪ'ᴍ ᴀʟʀᴇᴀᴅʏ ᴡᴏʀᴋɪɴɢ ᴏɴ ᴍʏ ᴍᴀxɪᴍᴜᴍ ɴᴜᴍʙᴇʀ ᴏғ 30 ᴄʜᴀᴛs ᴀᴛ ᴛʜᴇ ᴍᴏᴍᴇɴᴛ. ᴘʟᴇᴀsᴇ ᴛʀʏ ᴀɢᴀɪɴ sʜᴏʀᴛʟʏ." + ) + else: + if message.chat.id in chatQueue: + await message.reply( + "➠ | ᴛʜᴇʀᴇ's ᴀʟʀᴇᴀᴅʏ ᴀɴ ᴏɴɢɪɪɴɢ ᴘʀᴏᴄᴇss ɪɴ ᴛʜɪs ᴄʜᴀᴛ. ᴘʟᴇᴀsᴇ [ /stop ] ᴛᴏ sᴛᴀʀᴛ ᴀ ɴᴇᴡ ᴏɴᴇ." + ) + else: + chatQueue.append(message.chat.id) + deletedList = [] + async for member in app.get_chat_members(message.chat.id): + if member.user.is_deleted == True: + deletedList.append(member.user) + else: + pass + lenDeletedList = len(deletedList) + if lenDeletedList == 0: + await message.reply("⟳ | ɴᴏ ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄᴏᴜɴᴛs ɪɴ ᴛʜɪs ᴄʜᴀᴛ.") + chatQueue.remove(message.chat.id) + else: + k = 0 + processTime = lenDeletedList * 1 + temp = await app.send_message( + message.chat.id, + f"🧭 | ᴛᴏᴛᴀʟ ᴏғ {lenDeletedList} ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄᴏᴜɴᴛs ʜᴀs ʙᴇᴇɴ ᴅᴇᴛᴇᴄᴛᴇᴅ.\n🥀 | ᴇsᴛɪᴍᴀᴛᴇᴅ ᴛɪᴍᴇ: {processTime} sᴇᴄᴏɴᴅs ғʀᴏᴍ ɴᴏᴡ.", + ) + if stopProcess: + stopProcess = False + while len(deletedList) > 0 and not stopProcess: + deletedAccount = deletedList.pop(0) + try: + await app.ban_chat_member( + message.chat.id, deletedAccount.id + ) + except Exception: + pass + k += 1 + await asyncio.sleep(10) + if k == lenDeletedList: + await message.reply( + f"✅ | sᴜᴄᴄᴇssғᴜʟʟʏ ʀᴇᴍᴏᴠᴇᴅ ᴀʟʟ ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄɪᴜɴᴛs ғʀᴏᴍ ᴛʜɪs ᴄʜᴀᴛ." + ) + await temp.delete() + else: + await message.reply( + f"✅ | sᴜᴄᴄᴇssғᴜʟʟʏ ʀᴇᴍᴏᴠᴇᴅ {k} ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄᴏᴜɴᴛs ғʀᴏᴍ ᴛʜɪs ᴄʜᴀᴛ." + ) + await temp.delete() + chatQueue.remove(message.chat.id) + else: + await message.reply( + "👮🏻 | sᴏʀʀʏ, ᴏɴʟʏ ᴀᴅᴍɪɴ ᴄᴀɴ ᴇxᴇᴄᴜᴛᴇ ᴛʜɪs ᴄᴏᴍᴍᴀɴᴅ." + ) + except FloodWait as e: + await asyncio.sleep(e.value) + + +# ------------------------------------------------------------------------------- # + + +@app.on_message(filters.command(["admins", "staff"])) +async def admins(client, message): + + try: + adminList = [] + ownerList = [] + async for admin in app.get_chat_members( + message.chat.id, filter=enums.ChatMembersFilter.ADMINISTRATORS + ): + if admin.privileges.is_Dragmous == False: + if admin.user.is_bot == True: + pass + elif admin.status == ChatMemberStatus.OWNER: + ownerList.append(admin.user) + else: + adminList.append(admin.user) + else: + pass + lenAdminList = len(ownerList) + len(adminList) + text2 = f"**ɢʀᴏᴜᴘ sᴛᴀғғ - {message.chat.title}**\n\n" + try: + owner = ownerList[0] + if owner.username == None: + text2 += f"👑 ᴏᴡɴᴇʀ\n└ {owner.mention}\n\n👮🏻 ᴀᴅᴍɪɴs\n" + else: + text2 += f"👑 ᴏᴡɴᴇʀ\n└ @{owner.username}\n\n👮🏻 ᴀᴅᴍɪɴs\n" + except: + text2 += f"👑 ᴏᴡɴᴇʀ\n└ Hidden\n\n👮🏻 ᴀᴅᴍɪɴs\n" + if len(adminList) == 0: + text2 += "└ ᴀᴅᴍɪɴs ᴀʀᴇ ʜɪᴅᴅᴇɴ" + await app.send_message(message.chat.id, text2) + else: + while len(adminList) > 1: + admin = adminList.pop(0) + if admin.username == None: + text2 += f"├ {admin.mention}\n" + else: + text2 += f"├ @{admin.username}\n" + else: + admin = adminList.pop(0) + if admin.username == None: + text2 += f"└ {admin.mention}\n\n" + else: + text2 += f"└ @{admin.username}\n\n" + text2 += f"✅ | ᴛᴏᴛᴀʟ ɴᴜᴍʙᴇʀ ᴏғ ᴀᴅᴍɪɴs: {lenAdminList}" + await app.send_message(message.chat.id, text2) + except FloodWait as e: + await asyncio.sleep(e.value) + + +# ------------------------------------------------------------------------------- # + + +@app.on_message(filters.command("bots")) +async def bots(client, message): + + try: + botList = [] + async for bot in app.get_chat_members( + message.chat.id, filter=enums.ChatMembersFilter.BOTS + ): + botList.append(bot.user) + lenBotList = len(botList) + text3 = f"ʙᴏᴛ ʟɪsᴛ - {message.chat.title}\n\n🤖 ʙᴏᴛs\n" + while len(botList) > 1: + bot = botList.pop(0) + text3 += f"├ @{bot.username}\n" + else: + bot = botList.pop(0) + text3 += f" @{bot.username}\n\n" + text3 += f"✅ | ᴛᴏᴛᴀʟ ɴᴜᴍʙᴇʀ ᴏғ ʙᴏᴛs: {lenBotList}" + await app.send_message(message.chat.id, text3) + except FloodWait as e: + await asyncio.sleep(e.value) + + +# ------------------------------------------------------------------------------- # diff --git a/DragMusic/plugins/bot/approve.text b/DragMusic/plugins/bot/approve.text new file mode 100644 index 0000000000000000000000000000000000000000..2986b91b3fd1f0e2de839875e657e4502b3f1475 --- /dev/null +++ b/DragMusic/plugins/bot/approve.text @@ -0,0 +1,28 @@ +from DragMusic import app +from os import environ +from pyrogram import Client, filters +from pyrogram.types import ChatJoinRequest +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +EVAA = [ + [ + InlineKeyboardButton(text="ᴀᴅᴅ ᴍᴇ ʙᴀʙʏ", url=f"https://t.me/DragMusicBot?startgroup=true"), + ], +] + +# Extract environment variables or provide default values +chat_id_env = environ.get("CHAT_ID") +CHAT_ID = [int(app) for app in chat_id_env.split(",")] if chat_id_env else [] + +TEXT = environ.get("APPROVED_WELCOME_TEXT", "❅ ʜᴇʟʟᴏ ʙᴀʙʏ {mention}\n\n❅ ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ {title}\n\n") +APPROVED = environ.get("APPROVED_WELCOME", "on").lower() + +# Define an event handler for chat join requests +@app.on_chat_join_request((filters.group | filters.channel) & filters.chat(CHAT_ID) if CHAT_ID else (filters.group | filters.channel)) +async def autoapprove(client: app, message: ChatJoinRequest): + chat = message.chat # Chat + user = message.from_user # User + print(f"๏ {user.first_name} ᴊᴏɪɴᴇᴅ 🤝") # Logs + await client.approve_chat_join_request(chat_id=chat.id, user_id=user.id) + if APPROVED == "on": + await client.send_message(chat_id=chat.id, text=TEXT.format(mention=user.mention, title=chat.title),reply_markup=InlineKeyboardMarkup(EVAA),) diff --git a/DragMusic/plugins/bot/fakeinfo.py b/DragMusic/plugins/bot/fakeinfo.py new file mode 100644 index 0000000000000000000000000000000000000000..3c3f866997b8f8ea092f3f90194359c498d2c90d --- /dev/null +++ b/DragMusic/plugins/bot/fakeinfo.py @@ -0,0 +1,47 @@ +import requests +from DragMusic import app as Checker +from pyrogram import filters + + +@Checker.on_message(filters.command("fake")) +async def address(_, message): + message_text = message.text.strip() + words = message_text.split() + + if len(words) > 1: + query = words[1].strip() + url = f"https://randomuser.me/api/?nat={query}" + response = requests.get(url) + data = response.json() + + if "results" in data: + user_data = data["results"][0] + + + name = f"{user_data['name']['title']} {user_data['name']['first']} {user_data['name']['last']}" + address = f"{user_data['location']['street']['number']} {user_data['location']['street']['name']}" + city = user_data['location']['city'] + state = user_data['location']['state'] + country = user_data['location']['country'] + postal = user_data['location']['postcode'] + email = user_data['email'] + phone = user_data['phone'] + picture_url = user_data['picture']['large'] + + + caption = f""" +﹝⌬﹞**ɴᴀᴍᴇ** ⇢ {name} +﹝⌬﹞**ᴀᴅᴅʀᴇss** ⇢ {address} +﹝⌬﹞**ᴄᴏᴜɴᴛʀʏ** ⇢ {country} +﹝⌬﹞**ᴄɪᴛʏ** ⇢ {city} +﹝⌬﹞**sᴛᴀᴛᴇ** ⇢ {state} +﹝⌬﹞**ᴘᴏsᴛᴀʟ** ⇢ {postal} +﹝⌬﹞**ᴇᴍᴀɪʟ** ⇢ {email} +﹝⌬﹞**ᴘʜᴏɴᴇ** ⇢ {phone} + + """ + + + await message.reply_photo(photo=picture_url, caption=caption) + else: + await message.reply_text("ᴏᴏᴘs ɴᴏᴛ ғᴏᴜɴᴅ ᴀɴʏ ᴀᴅᴅʀᴇss.") diff --git a/DragMusic/plugins/bot/help.py b/DragMusic/plugins/bot/help.py new file mode 100644 index 0000000000000000000000000000000000000000..2532c36aff932b7d7ef8d537d5ff2b4bc6b610cd --- /dev/null +++ b/DragMusic/plugins/bot/help.py @@ -0,0 +1,90 @@ +from typing import Union + +from pyrogram import filters, types +from pyrogram.types import InlineKeyboardMarkup, Message + +from DragMusic import app +from DragMusic.utils import help_pannel +from DragMusic.utils.database import get_lang +from DragMusic.utils.decorators.language import LanguageStart, languageCB +from DragMusic.utils.inline.help import help_back_markup, private_help_panel +from config import BANNED_USERS, START_IMG_URL, SUPPORT_CHAT +from strings import get_string, helpers + + +@app.on_message(filters.command(["help"]) & filters.private & ~BANNED_USERS) +@app.on_callback_query(filters.regex("settings_back_helper") & ~BANNED_USERS) +async def helper_private( + client: app, update: Union[types.Message, types.CallbackQuery] +): + is_callback = isinstance(update, types.CallbackQuery) + if is_callback: + try: + await update.answer() + except: + pass + chat_id = update.message.chat.id + language = await get_lang(chat_id) + _ = get_string(language) + keyboard = help_pannel(_, True) + await update.edit_message_text( + _["help_1"].format(SUPPORT_CHAT), reply_markup=keyboard + ) + else: + try: + await update.delete() + except: + pass + language = await get_lang(update.chat.id) + _ = get_string(language) + keyboard = help_pannel(_) + await update.reply_photo( + photo=START_IMG_URL, + caption=_["help_1"].format(SUPPORT_CHAT), + reply_markup=keyboard, + ) + + +@app.on_message(filters.command(["help"]) & filters.group & ~BANNED_USERS) +@LanguageStart +async def help_com_group(client, message: Message, _): + keyboard = private_help_panel(_) + await message.reply_text(_["help_2"], reply_markup=InlineKeyboardMarkup(keyboard)) + + +@app.on_callback_query(filters.regex("help_callback") & ~BANNED_USERS) +@languageCB +async def helper_cb(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + cb = callback_data.split(None, 1)[1] + keyboard = help_back_markup(_) + if cb == "hb1": + await CallbackQuery.edit_message_text(helpers.HELP_1, reply_markup=keyboard) + elif cb == "hb2": + await CallbackQuery.edit_message_text(helpers.HELP_2, reply_markup=keyboard) + elif cb == "hb3": + await CallbackQuery.edit_message_text(helpers.HELP_3, reply_markup=keyboard) + elif cb == "hb4": + await CallbackQuery.edit_message_text(helpers.HELP_4, reply_markup=keyboard) + elif cb == "hb5": + await CallbackQuery.edit_message_text(helpers.HELP_5, reply_markup=keyboard) + elif cb == "hb6": + await CallbackQuery.edit_message_text(helpers.HELP_6, reply_markup=keyboard) + elif cb == "hb7": + await CallbackQuery.edit_message_text(helpers.HELP_7, reply_markup=keyboard) + elif cb == "hb8": + await CallbackQuery.edit_message_text(helpers.HELP_8, reply_markup=keyboard) + elif cb == "hb9": + await CallbackQuery.edit_message_text(helpers.HELP_9, reply_markup=keyboard) + elif cb == "hb10": + await CallbackQuery.edit_message_text(helpers.HELP_10, reply_markup=keyboard) + elif cb == "hb11": + await CallbackQuery.edit_message_text(helpers.HELP_11, reply_markup=keyboard) + elif cb == "hb12": + await CallbackQuery.edit_message_text(helpers.HELP_12, reply_markup=keyboard) + elif cb == "hb13": + await CallbackQuery.edit_message_text(helpers.HELP_13, reply_markup=keyboard) + elif cb == "hb14": + await CallbackQuery.edit_message_text(helpers.HELP_14, reply_markup=keyboard) + elif cb == "hb15": + await CallbackQuery.edit_message_text(helpers.HELP_15, reply_markup=keyboard) diff --git a/DragMusic/plugins/bot/inline.py b/DragMusic/plugins/bot/inline.py new file mode 100644 index 0000000000000000000000000000000000000000..7b4040d307c130c61dccba537287ed677d06f3c2 --- /dev/null +++ b/DragMusic/plugins/bot/inline.py @@ -0,0 +1,68 @@ +from pyrogram.types import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultPhoto, +) +from youtubesearchpython.__future__ import VideosSearch + +from DragMusic import app +from DragMusic.utils.inlinequery import answer +from config import BANNED_USERS + + +@app.on_inline_query(~BANNED_USERS) +async def inline_query_handler(client, query): + text = query.query.strip().lower() + answers = [] + if text.strip() == "": + try: + await client.answer_inline_query(query.id, results=answer, cache_time=10) + except: + return + else: + a = VideosSearch(text, limit=20) + result = (await a.next()).get("result") + for x in range(15): + title = (result[x]["title"]).title() + duration = result[x]["duration"] + views = result[x]["viewCount"]["short"] + thumbnail = result[x]["thumbnails"][0]["url"].split("?")[0] + channellink = result[x]["channel"]["link"] + channel = result[x]["channel"]["name"] + link = result[x]["link"] + published = result[x]["publishedTime"] + description = f"{views} | {duration} ᴍɪɴᴜᴛᴇs | {channel} | {published}" + buttons = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ʏᴏᴜᴛᴜʙᴇ 🎄", + url=link, + ) + ], + ] + ) + searched_text = f""" +❄ ᴛɪᴛʟᴇ : {title} + +⏳ ᴅᴜʀᴀᴛɪᴏɴ : {duration} ᴍɪɴᴜᴛᴇs +👀 ᴠɪᴇᴡs : {views} +🎥 ᴄʜᴀɴɴᴇʟ : {channel} +⏰ ᴘᴜʙʟɪsʜᴇᴅ ᴏɴ : {published} + + +➻ ɪɴʟɪɴᴇ sᴇᴀʀᴄʜ ᴍᴏᴅᴇ ʙʏ {app.name}""" + answers.append( + InlineQueryResultPhoto( + photo_url=thumbnail, + title=title, + thumb_url=thumbnail, + description=description, + caption=searched_text, + reply_markup=buttons, + ) + ) + try: + return await client.answer_inline_query(query.id, results=answers) + except: + return diff --git a/DragMusic/plugins/bot/mustjoin.py b/DragMusic/plugins/bot/mustjoin.py new file mode 100644 index 0000000000000000000000000000000000000000..015dee97a8f82dc9bd7415cdf574c1c64facc960 --- /dev/null +++ b/DragMusic/plugins/bot/mustjoin.py @@ -0,0 +1,61 @@ +import random +from pyrogram import Client, filters +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message +from pyrogram.errors import ChatAdminRequired, UserNotParticipant, ChatWriteForbidden +from DragMusic import app + +MISHI = [ + "https://graph.org/file/f86b71018196c5cfe7344.jpg", + "https://graph.org/file/a3db9af88f25bb1b99325.jpg", + "https://graph.org/file/5b344a55f3d5199b63fa5.jpg", + "https://graph.org/file/84de4b440300297a8ecb3.jpg", + "https://graph.org/file/84e84ff778b045879d24f.jpg", + "https://graph.org/file/a4a8f0e5c0e6b18249ffc.jpg", + "https://graph.org/file/ed92cada78099c9c3a4f7.jpg", + "https://graph.org/file/d6360613d0fa7a9d2f90b.jpg" + "https://graph.org/file/37248e7bdff70c662a702.jpg", + "https://graph.org/file/0bfe29d15e918917d1305.jpg", + "https://graph.org/file/16b1a2828cc507f8048bd.jpg", + "https://graph.org/file/e6b01f23f2871e128dad8.jpg", + "https://graph.org/file/cacbdddee77784d9ed2b7.jpg", + "https://graph.org/file/ddc5d6ec1c33276507b19.jpg", + "https://graph.org/file/39d7277189360d2c85b62.jpg", + "https://graph.org/file/5846b9214eaf12c3ed100.jpg", + "https://graph.org/file/ad4f9beb4d526e6615e18.jpg", + "https://graph.org/file/3514efaabe774e4f181f2.jpg", +] + +#-------------------------- + +MUST_JOIN = "ERROR_RESPON_TIMEOUT" +#------------------------ +@app.on_message(filters.incoming & filters.private, group=-1) +async def must_join_channel(app: Client, msg: Message): + if not MUST_JOIN: + return + try: + try: + await app.get_chat_member(MUST_JOIN, msg.from_user.id) + except UserNotParticipant: + if MUST_JOIN.isalpha(): + link = "https://t.me/" + MUST_JOIN + else: + chat_info = await app.get_chat(MUST_JOIN) + link = chat_info.invite_link + try: + await msg.reply_photo(random.choice(MISHI), caption=f"❅ ʜᴇʏ ᴛʜᴇʀᴇ, ɴɪᴄᴇ ᴛᴏ ᴍᴇᴇᴛ ᴜʜʜ !\n\n❅ ɪғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴜsᴇ ˹ʙᴜɢ ✘ ϻʊsɪx ˼, ᴛʜᴇɴ ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴇʟᴏᴡ ʙᴜᴛᴛᴏɴ ᴀɴᴅ ʏᴏᴜ ᴊᴏɪɴᴇᴅ, ᴛʜᴇɴ ʏᴏᴜ ᴄᴀɴ ᴜsᴇ ᴀʟʟ ᴍʏ ᴄᴏᴍᴍᴀɴᴅs ", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("ᴜᴘᴅᴀᴛᴇ", url="https://t.me/haatsoja"), + InlineKeyboardButton("sᴜᴘᴘᴏʀᴛ", url="https://t.me/dragbackup"), + ] + ] + ) + ) + await msg.stop_propagation() + except ChatWriteForbidden: + pass + except ChatAdminRequired: + print(f"๏ ᴘʀᴏᴍᴏᴛᴇ ᴍᴇ ᴀs ᴀɴ ᴀᴅᴍɪɴ ɪɴ ᴛʜᴇ ᴍᴜsᴛ_ᴊᴏɪɴ ᴄʜᴀᴛ ๏: {MUST_JOIN} !") + diff --git a/DragMusic/plugins/bot/settings.py b/DragMusic/plugins/bot/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..b3dfc4d82880e0acdf3bec7d464a5555105d9e7c --- /dev/null +++ b/DragMusic/plugins/bot/settings.py @@ -0,0 +1,391 @@ +from pyrogram import filters +from pyrogram.enums import ChatType +from pyrogram.errors import MessageNotModified +from pyrogram.types import ( + CallbackQuery, + InlineKeyboardButton, + InlineKeyboardMarkup, + Message, +) + +from DragMusic import app +from DragMusic.utils.database import ( + add_nonadmin_chat, + get_authuser, + get_authuser_names, + get_playmode, + get_playtype, + get_upvote_count, + is_nonadmin_chat, + is_skipmode, + remove_nonadmin_chat, + set_playmode, + set_playtype, + set_upvotes, + skip_off, + skip_on, +) +from DragMusic.utils.decorators.admins import ActualAdminCB +from DragMusic.utils.decorators.language import language, languageCB +from DragMusic.utils.inline.settings import ( + auth_users_markup, + playmode_users_markup, + setting_markup, + vote_mode_markup, +) +from DragMusic.utils.inline.start import private_panel +from config import BANNED_USERS, OWNER_ID + + +@app.on_message( + filters.command(["settings", "setting"]) & filters.group & ~BANNED_USERS +) +@language +async def settings_mar(client, message: Message, _): + buttons = setting_markup(_) + await message.reply_text( + _["setting_1"].format(app.mention, message.chat.id, message.chat.title), + reply_markup=InlineKeyboardMarkup(buttons), + ) + + +@app.on_callback_query(filters.regex("settings_helper") & ~BANNED_USERS) +@languageCB +async def settings_cb(client, CallbackQuery, _): + try: + await CallbackQuery.answer(_["set_cb_5"]) + except: + pass + buttons = setting_markup(_) + return await CallbackQuery.edit_message_text( + _["setting_1"].format( + app.mention, + CallbackQuery.message.chat.id, + CallbackQuery.message.chat.title, + ), + reply_markup=InlineKeyboardMarkup(buttons), + ) + + +@app.on_callback_query(filters.regex("settingsback_helper") & ~BANNED_USERS) +@languageCB +async def settings_back_markup(client, CallbackQuery: CallbackQuery, _): + try: + await CallbackQuery.answer() + except: + pass + if CallbackQuery.message.chat.type == ChatType.PRIVATE: + await app.resolve_peer(OWNER_ID) + OWNER = OWNER_ID + buttons = private_panel(_) + return await CallbackQuery.edit_message_text( + _["start_2"].format(CallbackQuery.from_user.mention, app.mention), + reply_markup=InlineKeyboardMarkup(buttons), + ) + else: + buttons = setting_markup(_) + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + + +@app.on_callback_query( + filters.regex( + pattern=r"^(SEARCHANSWER|PLAYMODEANSWER|PLAYTYPEANSWER|AUTHANSWER|ANSWERVOMODE|VOTEANSWER|PM|AU|VM)$" + ) + & ~BANNED_USERS +) +@languageCB +async def without_Admin_rights(client, CallbackQuery, _): + command = CallbackQuery.matches[0].group(1) + if command == "SEARCHANSWER": + try: + return await CallbackQuery.answer(_["setting_2"], show_alert=True) + except: + return + if command == "PLAYMODEANSWER": + try: + return await CallbackQuery.answer(_["setting_5"], show_alert=True) + except: + return + if command == "PLAYTYPEANSWER": + try: + return await CallbackQuery.answer(_["setting_6"], show_alert=True) + except: + return + if command == "AUTHANSWER": + try: + return await CallbackQuery.answer(_["setting_3"], show_alert=True) + except: + return + if command == "VOTEANSWER": + try: + return await CallbackQuery.answer( + _["setting_8"], + show_alert=True, + ) + except: + return + if command == "ANSWERVOMODE": + current = await get_upvote_count(CallbackQuery.message.chat.id) + try: + return await CallbackQuery.answer( + _["setting_9"].format(current), + show_alert=True, + ) + except: + return + if command == "PM": + try: + await CallbackQuery.answer(_["set_cb_2"], show_alert=True) + except: + pass + playmode = await get_playmode(CallbackQuery.message.chat.id) + if playmode == "Direct": + Direct = True + else: + Direct = None + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + Group = True + else: + Group = None + playty = await get_playtype(CallbackQuery.message.chat.id) + if playty == "Everyone": + Playtype = None + else: + Playtype = True + buttons = playmode_users_markup(_, Direct, Group, Playtype) + if command == "AU": + try: + await CallbackQuery.answer(_["set_cb_1"], show_alert=True) + except: + pass + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + buttons = auth_users_markup(_, True) + else: + buttons = auth_users_markup(_) + if command == "VM": + mode = await is_skipmode(CallbackQuery.message.chat.id) + current = await get_upvote_count(CallbackQuery.message.chat.id) + buttons = vote_mode_markup(_, current, mode) + try: + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except MessageNotModified: + return + + +@app.on_callback_query(filters.regex("FERRARIUDTI") & ~BANNED_USERS) +@ActualAdminCB +async def addition(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + mode = callback_data.split(None, 1)[1] + if not await is_skipmode(CallbackQuery.message.chat.id): + return await CallbackQuery.answer(_["setting_10"], show_alert=True) + current = await get_upvote_count(CallbackQuery.message.chat.id) + if mode == "M": + final = current - 2 + print(final) + if final == 0: + return await CallbackQuery.answer( + _["setting_11"], + show_alert=True, + ) + if final <= 2: + final = 2 + await set_upvotes(CallbackQuery.message.chat.id, final) + else: + final = current + 2 + print(final) + if final == 17: + return await CallbackQuery.answer( + _["setting_12"], + show_alert=True, + ) + if final >= 15: + final = 15 + await set_upvotes(CallbackQuery.message.chat.id, final) + buttons = vote_mode_markup(_, final, True) + try: + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except MessageNotModified: + return + + +@app.on_callback_query( + filters.regex(pattern=r"^(MODECHANGE|CHANNELMODECHANGE|PLAYTYPECHANGE)$") + & ~BANNED_USERS +) +@ActualAdminCB +async def playmode_ans(client, CallbackQuery, _): + command = CallbackQuery.matches[0].group(1) + if command == "CHANNELMODECHANGE": + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + await add_nonadmin_chat(CallbackQuery.message.chat.id) + Group = None + else: + await remove_nonadmin_chat(CallbackQuery.message.chat.id) + Group = True + playmode = await get_playmode(CallbackQuery.message.chat.id) + if playmode == "Direct": + Direct = True + else: + Direct = None + playty = await get_playtype(CallbackQuery.message.chat.id) + if playty == "Everyone": + Playtype = None + else: + Playtype = True + buttons = playmode_users_markup(_, Direct, Group, Playtype) + if command == "MODECHANGE": + try: + await CallbackQuery.answer(_["set_cb_3"], show_alert=True) + except: + pass + playmode = await get_playmode(CallbackQuery.message.chat.id) + if playmode == "Direct": + await set_playmode(CallbackQuery.message.chat.id, "Inline") + Direct = None + else: + await set_playmode(CallbackQuery.message.chat.id, "Direct") + Direct = True + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + Group = True + else: + Group = None + playty = await get_playtype(CallbackQuery.message.chat.id) + if playty == "Everyone": + Playtype = False + else: + Playtype = True + buttons = playmode_users_markup(_, Direct, Group, Playtype) + if command == "PLAYTYPECHANGE": + try: + await CallbackQuery.answer(_["set_cb_3"], show_alert=True) + except: + pass + playty = await get_playtype(CallbackQuery.message.chat.id) + if playty == "Everyone": + await set_playtype(CallbackQuery.message.chat.id, "Admin") + Playtype = False + else: + await set_playtype(CallbackQuery.message.chat.id, "Everyone") + Playtype = True + playmode = await get_playmode(CallbackQuery.message.chat.id) + if playmode == "Direct": + Direct = True + else: + Direct = None + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + Group = True + else: + Group = None + buttons = playmode_users_markup(_, Direct, Group, Playtype) + try: + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except MessageNotModified: + return + + +@app.on_callback_query(filters.regex(pattern=r"^(AUTH|AUTHLIST)$") & ~BANNED_USERS) +@ActualAdminCB +async def authusers_mar(client, CallbackQuery, _): + command = CallbackQuery.matches[0].group(1) + if command == "AUTHLIST": + _authusers = await get_authuser_names(CallbackQuery.message.chat.id) + if not _authusers: + try: + return await CallbackQuery.answer(_["setting_4"], show_alert=True) + except: + return + else: + try: + await CallbackQuery.answer(_["set_cb_4"], show_alert=True) + except: + pass + j = 0 + await CallbackQuery.edit_message_text(_["auth_6"]) + msg = _["auth_7"].format(CallbackQuery.message.chat.title) + for note in _authusers: + _note = await get_authuser(CallbackQuery.message.chat.id, note) + user_id = _note["auth_user_id"] + admin_id = _note["admin_id"] + admin_name = _note["admin_name"] + try: + user = await app.get_users(user_id) + user = user.first_name + j += 1 + except: + continue + msg += f"{j}➤ {user}[{user_id}]\n" + msg += f" {_['auth_8']} {admin_name}[{admin_id}]\n\n" + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], callback_data=f"AU" + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data=f"close", + ), + ] + ] + ) + try: + return await CallbackQuery.edit_message_text(msg, reply_markup=upl) + except MessageNotModified: + return + try: + await CallbackQuery.answer(_["set_cb_3"], show_alert=True) + except: + pass + if command == "AUTH": + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + await add_nonadmin_chat(CallbackQuery.message.chat.id) + buttons = auth_users_markup(_) + else: + await remove_nonadmin_chat(CallbackQuery.message.chat.id) + buttons = auth_users_markup(_, True) + try: + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except MessageNotModified: + return + + +@app.on_callback_query(filters.regex("VOMODECHANGE") & ~BANNED_USERS) +@ActualAdminCB +async def vote_change(client, CallbackQuery, _): + command = CallbackQuery.matches[0].group(1) + try: + await CallbackQuery.answer(_["set_cb_3"], show_alert=True) + except: + pass + mod = None + if await is_skipmode(CallbackQuery.message.chat.id): + await skip_off(CallbackQuery.message.chat.id) + else: + mod = True + await skip_on(CallbackQuery.message.chat.id) + current = await get_upvote_count(CallbackQuery.message.chat.id) + buttons = vote_mode_markup(_, current, mod) + + try: + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + except MessageNotModified: + return diff --git a/DragMusic/plugins/bot/start.py b/DragMusic/plugins/bot/start.py new file mode 100644 index 0000000000000000000000000000000000000000..06a7f4f8555e5e1b7dc44d147c09598eb0ccc476 --- /dev/null +++ b/DragMusic/plugins/bot/start.py @@ -0,0 +1,169 @@ +import time +from pyrogram import filters +from pyrogram.enums import ChatType +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message +from youtubesearchpython.__future__ import VideosSearch + +import config +from DragMusic import app +from DragMusic.misc import _boot_ +from DragMusic.plugins.sudo.sudoers import sudoers_list +from DragMusic.utils.database import ( + add_served_chat, + add_served_user, + blacklisted_chats, + get_lang, + is_banned_user, + is_on_off, +) +from DragMusic.utils.formatters import get_readable_time +from DragMusic.utils.inline import help_pannel, private_panel, start_panel +from config import BANNED_USERS, LOGGER_ID +from strings import get_string # Import get_string at the top + +@app.on_message(filters.command(["start"]) & filters.private & ~BANNED_USERS) +async def start_pm(client, message: Message): + await add_served_user(message.from_user.id) + + language = await get_lang(message.chat.id) # Get language inside the function + _ = get_string(language) # Get the translation object + + if len(message.text.split()) > 1: + name = message.text.split(None, 1)[1] + if name[0:4] == "help": + keyboard = help_pannel(_) + await message.reply_sticker("CAACAgEAAxkBAAJYdWZLJQqyG4fMdFFHFbTZDZPczqfnAAJUAgACODjZR-6jaMt58aQENQQ") + return await message.reply_video( + video="https://files.catbox.moe/l372oy.mp4", + caption=_["help_1"].format(config.SUPPORT_CHAT), + reply_markup=keyboard, + ) + elif name[0:3] == "sud": # Example: Handling sudo + await sudoers_list(client=client, message=message, _=_) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} ᴊᴜsᴛ sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ᴄʜᴇᴄᴋ sᴜᴅᴏʟɪsᴛ.\n\nᴜsᴇʀ ɪᴅ : {message.from_user.id}\nᴜsᴇʀɴᴀᴍᴇ : @{message.from_user.username}", + message_thread_id=12327 # Send to the specific thread + ) + return + elif name[0:3] == "inf": # Example: Handling info + m = await message.reply_text("🔎") + query = (str(name)).replace("info_", "", 1) + query = f"https://www.youtube.com/watch?v={query}" + results = VideosSearch(query, limit=1) + for result in (await results.next())["result"]: + title = result["title"] + duration = result["duration"] + views = result["viewCount"]["short"] + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + channellink = result["channel"]["link"] + channel = result["channel"]["name"] + link = result["link"] + published = result["publishedTime"] + searched_text = _["start_6"].format( + title, duration, views, published, channellink, channel, app.mention + ) + key = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(text=_["S_B_8"], url=link), + InlineKeyboardButton(text=_["S_B_9"], url=config.SUPPORT_CHAT), + ], + ] + ) + await m.delete() + await app.send_photo( + chat_id=message.chat.id, + photo=thumbnail, + caption=searched_text, + reply_markup=key, + ) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} ᴊᴜsᴛ sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ ᴛᴏ ᴄʜᴇᴄᴋ ᴛʀᴀᴄᴋ ɪɴғᴏʀᴍᴀᴛɪᴏɴ.\n\nᴜsᴇʀ ɪᴅ : {message.from_user.id}\nᴜsᴇʀɴᴀᴍᴇ : @{message.from_user.username}", + message_thread_id=12327 # Send to the specific thread + ) + return + + else: + out = private_panel(_) + await message.reply_sticker("CAACAgEAAxkBAAJYdWZLJQqyG4fMdFFHFbTZDZPczqfnAAJUAgACODjZR-6jaMt58aQENQQ") + await message.reply_video( + video="https://telegra.ph/file/d2532972423ce5c4b632e.mp4", + caption=_["start_2"].format(message.from_user.mention, app.mention), + reply_markup=InlineKeyboardMarkup(out), + ) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} ᴊᴜsᴛ sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ.\n\nᴜsᴇʀ ɪᴅ : {message.from_user.id}\nᴜsᴇʀɴᴀᴍᴇ : @{message.from_user.username}", + message_thread_id=12327 # Send to the specific thread + ) + +@app.on_message(filters.command(["start"]) & filters.group & ~BANNED_USERS) +async def start_gp(client, message: Message): + language = await get_lang(message.chat.id) # Get language inside the function + _ = get_string(language) # Get the translation object + + out = start_panel(_) + uptime = int(time.time() - _boot_) + await message.reply_video( + video="https://telegra.ph/file/d2532972423ce5c4b632e.mp4", + caption=_["start_1"].format(app.mention, get_readable_time(uptime)), + reply_markup=InlineKeyboardMarkup(out), + ) + await add_served_chat(message.chat.id) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} ᴊᴜsᴛ sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ ɪɴ ᴀ ɢʀᴏᴜᴘ.\n\nᴜsᴇʀ ɪᴅ : {message.from_user.id}\nᴜsᴇʀɴᴀᴍᴇ : @{message.from_user.username}", + message_thread_id=12327 # Send to the specific thread + ) + +@app.on_message(filters.new_chat_members, group=-1) +async def welcome(client, message: Message): + for member in message.new_chat_members: + try: + language = await get_lang(message.chat.id) + _ = get_string(language) + if await is_banned_user(member.id): + await message.chat.ban_member(member.id) + continue + if member.id == app.id: + if message.chat.type != ChatType.SUPERGROUP: + await message.reply_text(_["start_4"]) + return await app.leave_chat(message.chat.id) + if message.chat.id in await blacklisted_chats(): + await message.reply_text( + _["start_5"].format( + app.mention, + f"https://t.me/{app.username}?start=sudolist", + config.SUPPORT_CHAT, + ), + disable_web_page_preview=True, + ) + return await app.leave_chat(message.chat.id) + + out = start_panel(_) + await message.reply_video( + video="https://telegra.ph/file/d2532972423ce5c4b632e.mp4", + caption=_["start_3"].format( + message.from_user.first_name, + app.mention, + message.chat.title, + app.mention, + ), + reply_markup=InlineKeyboardMarkup(out), + ) + await add_served_chat(message.chat.id) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{member.mention} ᴊᴜsᴛ ᴊᴏɪɴᴇᴅ ᴛʜᴇ ᴄʜᴀᴛ.\n\nᴜsᴇʀ ɪᴅ : {member.id}\nᴜsᴇʀɴᴀᴍᴇ : @{member.username}", + message_thread_id=12327 # Send to the specific thread + ) + await message.stop_propagation() + except Exception as ex: + print(ex) diff --git a/DragMusic/plugins/goodnight.py b/DragMusic/plugins/goodnight.py new file mode 100644 index 0000000000000000000000000000000000000000..1b1fc4b101393139f611a42d1553f9fbaaf8dadf --- /dev/null +++ b/DragMusic/plugins/goodnight.py @@ -0,0 +1,42 @@ +import re +from dotenv import load_dotenv +from pyrogram import filters +import random +from pyrogram.types import Message +from pyrogram import Client, filters +from DragMusic import app + + + +# "/gn" command ka handler +@app.on_message(filters.command("oodnight", prefixes="g")) +def goodnight_command_handler(client: Client, message: Message): + # Randomly decide whether to send a sticker or an emoji + send_sticker = random.choice([True, False]) + + # Send a sticker or an emoji based on the random choice + if send_sticker: + client.send_sticker(message.chat.id, get_random_sticker()) + else: + client.send_message(message.chat.id, get_random_emoji()) + +# Function to get a random sticker +def get_random_sticker(): + stickers = [ + "CAACAgQAAx0Ce9_hCAACaEVlwn7HeZhgwyVfKHc3WUGC_447IAACLgwAAkQwKVPtub8VAR018x4E", + "CAACAgIAAx0Ce9_hCAACaEplwn7dvj7G0-a1v3wlbN281RMX2QACUgwAAligOUoi7DhLVTsNsh4E", + "CAACAgIAAx0Ce9_hCAACaFBlwn8AAZNB9mOUvz5oAyM7CT-5pjAAAtEKAALa7NhLvbTGyDLbe1IeBA", + "CAACAgUAAx0CcmOuMwACldVlwn9ZHHF2-S-CuMSYabwwtVGC3AACOAkAAoqR2VYDjyK6OOr_Px4E", + "CAACAgIAAx0Ce9_hCAACaFVlwn-fG58GKoEmmZpVovxEj4PodAACfwwAAqozQUrt2xSTf5Ac4h4E", + ] + return random.choice(stickers) + +# Function to get a random emoji +def get_random_emoji(): + emojis = [ + "😴", + "😪", + "💤", + + ] + return random.choice(emojis) diff --git a/DragMusic/plugins/misc/autoleave.py b/DragMusic/plugins/misc/autoleave.py new file mode 100644 index 0000000000000000000000000000000000000000..554f5e1601d603f3b6e58e959c2ec1ec070ad1a2 --- /dev/null +++ b/DragMusic/plugins/misc/autoleave.py @@ -0,0 +1,74 @@ +import asyncio +from datetime import datetime + +from pyrogram.enums import ChatType + +import config +from DragMusic import app +from DragMusic.core.call import Drag, autoend +from DragMusic.utils.database import get_client, is_active_chat, is_autoend + + +async def auto_leave(): + if config.AUTO_LEAVING_ASSISTANT: + while not await asyncio.sleep(900): + from DragMusic.core.userbot import assistants + + for num in assistants: + client = await get_client(num) + left = 0 + try: + async for i in client.get_dialogs(): + if i.chat.type in [ + ChatType.SUPERGROUP, + ChatType.GROUP, + ChatType.CHANNEL, + ]: + if ( + i.chat.id != config.LOGGER_ID + and i.chat.id != -1001686672798 + and i.chat.id != -1001549206010 + ): + if left == 20: + continue + if not await is_active_chat(i.chat.id): + try: + await client.leave_chat(i.chat.id) + left += 1 + except: + continue + except: + pass + + +asyncio.create_task(auto_leave()) + + +async def auto_end(): + while not await asyncio.sleep(5): + ender = await is_autoend() + if not ender: + continue + for chat_id in autoend: + timer = autoend.get(chat_id) + if not timer: + continue + if datetime.now() > timer: + if not await is_active_chat(chat_id): + autoend[chat_id] = {} + continue + autoend[chat_id] = {} + try: + await Drag.stop_stream(chat_id) + except: + continue + try: + await app.send_message( + chat_id, + "» ʙᴏᴛ ᴀᴜᴛᴏᴍᴀᴛɪᴄᴀʟʟʏ ʟᴇғᴛ ᴠɪᴅᴇᴏᴄʜᴀᴛ ʙᴇᴄᴀᴜsᴇ ɴᴏ ᴏɴᴇ ᴡᴀs ʟɪsᴛᴇɴɪɴɢ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.", + ) + except: + continue + + +asyncio.create_task(auto_end()) diff --git a/DragMusic/plugins/misc/broadcast.py b/DragMusic/plugins/misc/broadcast.py new file mode 100644 index 0000000000000000000000000000000000000000..3c5046f508eb067650c6e38fd3d29593398d729f --- /dev/null +++ b/DragMusic/plugins/misc/broadcast.py @@ -0,0 +1,169 @@ +import asyncio + +from pyrogram import filters +from pyrogram.enums import ChatMembersFilter +from pyrogram.errors import FloodWait + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import ( + get_active_chats, + get_authuser_names, + get_client, + get_served_chats, + get_served_users, +) +from DragMusic.utils.decorators.language import language +from DragMusic.utils.formatters import alpha_to_int +from config import adminlist + +IS_BROADCASTING = False + + +@app.on_message(filters.command("broadcast") & SUDOERS) +@language +async def braodcast_message(client, message, _): + global IS_BROADCASTING + if message.reply_to_message: + x = message.reply_to_message.id + y = message.chat.id + else: + if len(message.command) < 2: + return await message.reply_text(_["broad_2"]) + query = message.text.split(None, 1)[1] + if "-pin" in query: + query = query.replace("-pin", "") + if "-nobot" in query: + query = query.replace("-nobot", "") + if "-pinloud" in query: + query = query.replace("-pinloud", "") + if "-assistant" in query: + query = query.replace("-assistant", "") + if "-user" in query: + query = query.replace("-user", "") + if query == "": + return await message.reply_text(_["broad_8"]) + + IS_BROADCASTING = True + await message.reply_text(_["broad_1"]) + + if "-nobot" not in message.text: + sent = 0 + pin = 0 + chats = [] + schats = await get_served_chats() + for chat in schats: + chats.append(int(chat["chat_id"])) + for i in chats: + try: + m = ( + await app.forward_messages(i, y, x) + if message.reply_to_message + else await app.send_message(i, text=query) + ) + if "-pin" in message.text: + try: + await m.pin(disable_notification=True) + pin += 1 + except: + continue + elif "-pinloud" in message.text: + try: + await m.pin(disable_notification=False) + pin += 1 + except: + continue + sent += 1 + await asyncio.sleep(0.2) + except FloodWait as fw: + flood_time = int(fw.value) + if flood_time > 200: + continue + await asyncio.sleep(flood_time) + except: + continue + try: + await message.reply_text(_["broad_3"].format(sent, pin)) + except: + pass + + if "-user" in message.text: + susr = 0 + served_users = [] + susers = await get_served_users() + for user in susers: + served_users.append(int(user["user_id"])) + for i in served_users: + try: + m = ( + await app.forward_messages(i, y, x) + if message.reply_to_message + else await app.send_message(i, text=query) + ) + susr += 1 + await asyncio.sleep(0.2) + except FloodWait as fw: + flood_time = int(fw.value) + if flood_time > 200: + continue + await asyncio.sleep(flood_time) + except: + pass + try: + await message.reply_text(_["broad_4"].format(susr)) + except: + pass + + if "-assistant" in message.text: + aw = await message.reply_text(_["broad_5"]) + text = _["broad_6"] + from DragMusic.core.userbot import assistants + + for num in assistants: + sent = 0 + client = await get_client(num) + async for dialog in client.get_dialogs(): + try: + await client.forward_messages( + dialog.chat.id, y, x + ) if message.reply_to_message else await client.send_message( + dialog.chat.id, text=query + ) + sent += 1 + await asyncio.sleep(3) + except FloodWait as fw: + flood_time = int(fw.value) + if flood_time > 200: + continue + await asyncio.sleep(flood_time) + except: + continue + text += _["broad_7"].format(num, sent) + try: + await aw.edit_text(text) + except: + pass + IS_BROADCASTING = False + + +async def auto_clean(): + while not await asyncio.sleep(10): + try: + served_chats = await get_active_chats() + for chat_id in served_chats: + if chat_id not in adminlist: + adminlist[chat_id] = [] + async for user in app.get_chat_members( + chat_id, filter=ChatMembersFilter.ADMINISTRATORS + ): + if user.privileges.can_manage_video_chats: + adminlist[chat_id].append(user.user.id) + authusers = await get_authuser_names(chat_id) + for user in authusers: + user_id = await alpha_to_int(user) + adminlist[chat_id].append(user_id) + except: + continue + + +asyncio.create_task(auto_clean()) diff --git a/DragMusic/plugins/misc/love.py b/DragMusic/plugins/misc/love.py new file mode 100644 index 0000000000000000000000000000000000000000..2ba11a1d8ee097b43c0c67edfd4706e181add5ab --- /dev/null +++ b/DragMusic/plugins/misc/love.py @@ -0,0 +1,38 @@ +from pyrogram import Client, filters +import random +from DragMusic import app + +def get_random_message(love_percentage): + if love_percentage <= 30: + return random.choice([ + "Love is in the air but needs a little spark.", + "A good start but there's room to grow.", + "It's just the beginning of something beautiful." + ]) + elif love_percentage <= 70: + return random.choice([ + "A strong connection is there. Keep nurturing it.", + "You've got a good chance. Work on it.", + "Love is blossoming, keep going." + ]) + else: + return random.choice([ + "Wow! It's a match made in heaven!", + "Perfect match! Cherish this bond.", + "Destined to be together. Congratulations!" + ]) + +@app.on_message(filters.command("love", prefixes="/")) +def love_command(client, message): + command, *args = message.text.split(" ") + if len(args) >= 2: + name1 = args[0].strip() + name2 = args[1].strip() + + love_percentage = random.randint(10, 100) + love_message = get_random_message(love_percentage) + + response = f"{name1}💕 + {name2}💕 = {love_percentage}%\n\n{love_message}" + else: + response = "Please enter two names after /love command." + app.send_message(message.chat.id, response) diff --git a/DragMusic/plugins/misc/quote.txt b/DragMusic/plugins/misc/quote.txt new file mode 100644 index 0000000000000000000000000000000000000000..10e67139e541355830752546770caa88e9033233 --- /dev/null +++ b/DragMusic/plugins/misc/quote.txt @@ -0,0 +1,273 @@ +# <============================================== IMPORTS =========================================================> +import base64 +import os +from random import choice + +from aiohttp import ContentTypeError +from PIL import Image +from telethon.tl import types +from telethon.utils import get_display_name, get_peer_id + +from DragMusic.events import register + +# <=======================================================================================================> + + +# <================================================ CLASS & FUNCTION =======================================================> +class Quotly: + _API = "https://bot.lyo.su/quote/generate" + _entities = { + types.MessageEntityPhone: "phone_number", + types.MessageEntityMention: "mention", + types.MessageEntityBold: "bold", + types.MessageEntityCashtag: "cashtag", + types.MessageEntityStrike: "strikethrough", + types.MessageEntityHashtag: "hashtag", + types.MessageEntityEmail: "email", + types.MessageEntityMentionName: "text_mention", + types.MessageEntityUnderline: "underline", + types.MessageEntityUrl: "url", + types.MessageEntityTextUrl: "text_link", + types.MessageEntityBotCommand: "bot_command", + types.MessageEntityCode: "code", + types.MessageEntityPre: "pre", + } + + async def _format_quote(self, event, reply=None, sender=None, type_="private"): + async def telegraph(file_): + file = file_ + ".png" + Image.open(file_).save(file, "PNG") + files = {"file": open(file, "rb").read()} + uri = ( + "https://telegra.ph" + + ( + await async_searcher( + "https://telegra.ph/upload", post=True, data=files, re_json=True + ) + )[0]["src"] + ) + os.remove(file) + os.remove(file_) + return uri + + reply = ( + { + "name": get_display_name(reply.sender) or "Deleted Account", + "text": reply.raw_text, + "chatId": reply.chat_id, + } + if reply + else {} + ) + + is_fwd = event.fwd_from + name, last_name = None, None + + if sender and sender.id not in DEV_USERS: + id_ = get_peer_id(sender) + name = get_display_name(sender) + elif not is_fwd: + id_ = event.sender_id + sender = await event.get_sender() + name = get_display_name(sender) + else: + id_, sender = None, None + name = is_fwd.from_name + if is_fwd.from_id: + id_ = get_peer_id(is_fwd.from_id) + try: + sender = await event.client.get_entity(id_) + name = get_display_name(sender) + except ValueError: + pass + if sender and hasattr(sender, "last_name"): + last_name = sender.last_name + + entities = ( + [ + { + "type": self._entities[type(entity)], + **{k: v for k, v in entity.to_dict().items() if k != "_"}, + } + for entity in event.entities + ] + if event.entities + else [] + ) + + message = { + "entities": entities, + "chatId": id_, + "avatar": True, + "from": { + "id": id_, + "first_name": (name or (sender.first_name if sender else None)) + or "Deleted Account", + "last_name": last_name, + "username": sender.username if sender else None, + "language_code": "en", + "title": name, + "name": name or "Unknown", + "type": type_, + }, + "text": event.raw_text, + "replyMessage": reply, + } + + if event.document and event.document.thumbs: + file_ = await event.download_media(thumb=-1) + uri = await telegraph(file_) + message["media"] = {"url": uri} + + return message + + async def create_quotly( + self, + event, + url="https://quote-api.example.com/generate", + reply={}, + bg=None, + sender=None, + OQAPI=True, + file_name="quote.webp", + ): + if not isinstance(event, list): + event = [event] + if OQAPI: + url = Quotly._API + bg = bg or "#1b1429" + content = { + "type": "quote", + "format": "webp", + "backgroundColor": bg, + "width": 512, + "height": 768, + "scale": 2, + "messages": [ + await self._format_quote(message, reply=reply, sender=sender) + for message in event + ], + } + try: + request = await async_searcher(url, post=True, json=content, re_json=True) + except ContentTypeError as er: + if url != self._API: + return await self.create_quotly( + self._API, post=True, json=content, re_json=True + ) + raise er + + if request.get("ok"): + with open(file_name, "wb") as file: + image = base64.decodebytes(request["result"]["image"].encode("utf-8")) + file.write(image) + return file_name + raise Exception(str(request)) + + +quotly = Quotly() + + +async def async_searcher( + url: str, + post: bool = None, + headers: dict = None, + params: dict = None, + json: dict = None, + data: dict = None, + ssl=None, + re_json: bool = False, + re_content: bool = False, + real: bool = False, + *args, + **kwargs +): + try: + import aiohttp + except ImportError: + raise DependencyMissingError( + "'aiohttp' is not installed!\nThis function requires aiohttp to be installed." + ) + + async with aiohttp.ClientSession(headers=headers) as client: + data = await ( + client.post(url, json=json, data=data, ssl=ssl, *args, **kwargs) + if post + else client.get(url, params=params, ssl=ssl, *args, **kwargs) + ) + return await ( + data.json() if re_json else data.read() if re_content else data.text() + ) + + +@register(pattern="^/q(?: |$)(.*)") +async def quott_(event): + match = event.pattern_match.group(1).strip() + if not event.is_reply: + return await event.reply("Please reply to a message.") + + msg = await event.reply("Creating quote, please wait.") + reply = await event.get_reply_message() + replied_to, reply_ = None, None + + if match: + spli_ = match.split(maxsplit=1) + if (spli_[0] in ["r", "reply"]) or ( + spli_[0].isdigit() and int(spli_[0]) in range(1, 21) + ): + if spli_[0].isdigit(): + if not event.client.is_bot: + reply_ = await event.client.get_messages( + event.chat_id, + min_id=event.reply_to_msg_id - 1, + reverse=True, + limit=int(spli_[0]), + ) + else: + id_ = reply.id + reply_ = [] + for msg_ in range(id_, id_ + int(spli_[0])): + msh = await event.client.get_messages(event.chat_id, ids=msg_) + if msh: + reply_.append(msh) + else: + replied_to = await reply.get_reply_message() + try: + match = spli_[1] + except IndexError: + match = None + + user = None + + if not reply_: + reply_ = reply + + if match: + match = match.split(maxsplit=1) + + if match: + if match[0].startswith("@") or match[0].isdigit(): + try: + match_ = await event.client.parse_id(match[0]) + user = await event.client.get_entity(match_) + except ValueError: + pass + match = match[1] if len(match) == 2 else None + else: + match = match[0] + + if match == "random": + match = choice(all_col) + + try: + file = await quotly.create_quotly( + reply_, bg=match, reply=replied_to, sender=user + ) + except Exception as er: + return await msg.edit(str(er)) + + message = await reply.reply("", file=file) + os.remove(file) + await msg.delete() + return message + diff --git a/DragMusic/plugins/misc/seeker.py b/DragMusic/plugins/misc/seeker.py new file mode 100644 index 0000000000000000000000000000000000000000..25cf5f6f4afced2dc80ebc9c9dc8b24c3be75fd6 --- /dev/null +++ b/DragMusic/plugins/misc/seeker.py @@ -0,0 +1,24 @@ +import asyncio + +from DragMusic.misc import db +from DragMusic.utils.database import get_active_chats, is_music_playing + + +async def timer(): + while not await asyncio.sleep(1): + active_chats = await get_active_chats() + for chat_id in active_chats: + if not await is_music_playing(chat_id): + continue + playing = db.get(chat_id) + if not playing: + continue + duration = int(playing[0]["seconds"]) + if duration == 0: + continue + if db[chat_id][0]["played"] >= duration: + continue + db[chat_id][0]["played"] += 1 + + +asyncio.create_task(timer()) diff --git a/DragMusic/plugins/misc/truth_dare.py b/DragMusic/plugins/misc/truth_dare.py new file mode 100644 index 0000000000000000000000000000000000000000..c66e572200088447e8bfb12ea95b290334bf0621 --- /dev/null +++ b/DragMusic/plugins/misc/truth_dare.py @@ -0,0 +1,35 @@ +from pyrogram import Client, filters +import requests +import random +from DragMusic import app + +# Truth or Dare API URLs +truth_api_url = "https://api.truthordarebot.xyz/v1/truth" +dare_api_url = "https://api.truthordarebot.xyz/v1/dare" + + +@app.on_message(filters.command("truth")) +def get_truth(client, message): + try: + # Make a GET request to the Truth API + response = requests.get(truth_api_url) + if response.status_code == 200: + truth_question = response.json()["question"] + message.reply_text(f"Truth question:\n\n{truth_question}") + else: + message.reply_text("Failed to fetch a truth question. Please try again later.") + except Exception as e: + message.reply_text("An error occurred while fetching a truth question. Please try again later.") + +@app.on_message(filters.command("dare")) +def get_dare(client, message): + try: + # Make a GET request to the Dare API + response = requests.get(dare_api_url) + if response.status_code == 200: + dare_question = response.json()["question"] + message.reply_text(f"Dare question:\n\n{dare_question}") + else: + message.reply_text("Failed to fetch a dare question. Please try again later.") + except Exception as e: + message.reply_text("An error occurred while fetching a dare question. Please try again later.") diff --git a/DragMusic/plugins/misc/watcher.py b/DragMusic/plugins/misc/watcher.py new file mode 100644 index 0000000000000000000000000000000000000000..0679e7bf1216242aa686d166c23d8a011add73af --- /dev/null +++ b/DragMusic/plugins/misc/watcher.py @@ -0,0 +1,14 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag + +welcome = 20 +close = 30 + + +@app.on_message(filters.video_chat_started, group=welcome) +@app.on_message(filters.video_chat_ended, group=close) +async def welcome(_, message: Message): + await Drag.stop_stream_force(message.chat.id) diff --git a/DragMusic/plugins/play/channel.py b/DragMusic/plugins/play/channel.py new file mode 100644 index 0000000000000000000000000000000000000000..e7536881de8691631ad46451e5d5a795c41bd990 --- /dev/null +++ b/DragMusic/plugins/play/channel.py @@ -0,0 +1,49 @@ +from pyrogram import filters +from pyrogram.enums import ChatMembersFilter, ChatMemberStatus, ChatType +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.utils.database import set_cmode +from DragMusic.utils.decorators.admins import AdminActual +from config import BANNED_USERS + + +@app.on_message(filters.command(["channelplay"]) & filters.group & ~BANNED_USERS) +@AdminActual +async def playmode_(client, message: Message, _): + if len(message.command) < 2: + return await message.reply_text(_["cplay_1"].format(message.chat.title)) + query = message.text.split(None, 2)[1].lower().strip() + if (str(query)).lower() == "disable": + await set_cmode(message.chat.id, None) + return await message.reply_text(_["cplay_7"]) + elif str(query) == "linked": + chat = await app.get_chat(message.chat.id) + if chat.linked_chat: + chat_id = chat.linked_chat.id + await set_cmode(message.chat.id, chat_id) + return await message.reply_text( + _["cplay_3"].format(chat.linked_chat.title, chat.linked_chat.id) + ) + else: + return await message.reply_text(_["cplay_2"]) + else: + try: + chat = await app.get_chat(query) + except: + return await message.reply_text(_["cplay_4"]) + if chat.type != ChatType.CHANNEL: + return await message.reply_text(_["cplay_5"]) + try: + async for user in app.get_chat_members( + chat.id, filter=ChatMembersFilter.ADMINISTRATORS + ): + if user.status == ChatMemberStatus.OWNER: + cusn = user.user.username + crid = user.user.id + except: + return await message.reply_text(_["cplay_4"]) + if crid != message.from_user.id: + return await message.reply_text(_["cplay_6"].format(chat.title, cusn)) + await set_cmode(message.chat.id, chat.id) + return await message.reply_text(_["cplay_3"].format(chat.title, chat.id)) diff --git a/DragMusic/plugins/play/live.py b/DragMusic/plugins/play/live.py new file mode 100644 index 0000000000000000000000000000000000000000..8660a1c33b13916da9b59a56ba96e638c03ff898 --- /dev/null +++ b/DragMusic/plugins/play/live.py @@ -0,0 +1,60 @@ +from pyrogram import filters + +from DragMusic import YouTube, app +from DragMusic.utils.channelplay import get_channeplayCB +from DragMusic.utils.decorators.language import languageCB +from DragMusic.utils.stream.stream import stream +from config import BANNED_USERS + + +@app.on_callback_query(filters.regex("LiveStream") & ~BANNED_USERS) +@languageCB +async def play_live_stream(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + vidid, user_id, mode, cplay, fplay = callback_request.split("|") + if CallbackQuery.from_user.id != int(user_id): + try: + return await CallbackQuery.answer(_["playcb_1"], show_alert=True) + except: + return + try: + chat_id, channel = await get_channeplayCB(_, cplay, CallbackQuery) + except: + return + video = True if mode == "v" else None + user_name = CallbackQuery.from_user.first_name + await CallbackQuery.message.delete() + try: + await CallbackQuery.answer() + except: + pass + mystic = await CallbackQuery.message.reply_text( + _["play_2"].format(channel) if channel else _["play_1"] + ) + try: + details, track_id = await YouTube.track(vidid, True) + except: + return await mystic.edit_text(_["play_3"]) + ffplay = True if fplay == "f" else None + if not details["duration_min"]: + try: + await stream( + _, + mystic, + user_id, + details, + chat_id, + user_name, + CallbackQuery.message.chat.id, + video, + streamtype="live", + forceplay=ffplay, + ) + except Exception as e: + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + else: + return await mystic.edit_text("» ɴᴏᴛ ᴀ ʟɪᴠᴇ sᴛʀᴇᴀᴍ.") + await mystic.delete() diff --git a/DragMusic/plugins/play/play.py b/DragMusic/plugins/play/play.py new file mode 100644 index 0000000000000000000000000000000000000000..7693298b26475cba564ad0e94e19cf327b1ed464 --- /dev/null +++ b/DragMusic/plugins/play/play.py @@ -0,0 +1,554 @@ +import random +import string + +from pyrogram import filters +from pyrogram.types import InlineKeyboardMarkup, InputMediaPhoto, Message +from pytgcalls.exceptions import NoActiveGroupCall + +import config +from DragMusic import Apple, Resso, SoundCloud, Spotify, Telegram, YouTube, app +from DragMusic.core.call import Drag +from DragMusic.utils import seconds_to_min, time_to_seconds +from DragMusic.utils.channelplay import get_channeplayCB +from DragMusic.utils.decorators.language import languageCB +from DragMusic.utils.decorators.play import PlayWrapper +from DragMusic.utils.formatters import formats +from DragMusic.utils.inline import ( + botplaylist_markup, + livestream_markup, + playlist_markup, + slider_markup, + track_markup, +) +from DragMusic.utils.logger import play_logs +from DragMusic.utils.stream.stream import stream +from config import BANNED_USERS, lyrical + + +@app.on_message( + filters.command( + [ + "play", + "vplay", + "cplay", + "cvplay", + "playforce", + "vplayforce", + "cplayforce", + "cvplayforce", + ] + ) + & filters.group + & ~BANNED_USERS +) +@PlayWrapper +async def play_commnd( + client, + message: Message, + _, + chat_id, + video, + channel, + playmode, + url, + fplay, +): + mystic = await message.reply_text( + _["play_2"].format(channel) if channel else _["play_1"] + ) + plist_id = None + slider = None + plist_type = None + spotify = None + user_id = message.from_user.id + user_name = message.from_user.first_name + audio_telegram = ( + (message.reply_to_message.audio or message.reply_to_message.voice) + if message.reply_to_message + else None + ) + video_telegram = ( + (message.reply_to_message.video or message.reply_to_message.document) + if message.reply_to_message + else None + ) + if audio_telegram: + if audio_telegram.file_size > 104857600: + return await mystic.edit_text(_["play_5"]) + duration_min = seconds_to_min(audio_telegram.duration) + if (audio_telegram.duration) > config.DURATION_LIMIT: + return await mystic.edit_text( + _["play_6"].format(config.DURATION_LIMIT_MIN, app.mention) + ) + file_path = await Telegram.get_filepath(audio=audio_telegram) + if await Telegram.download(_, message, mystic, file_path): + message_link = await Telegram.get_link(message) + file_name = await Telegram.get_filename(audio_telegram, audio=True) + dur = await Telegram.get_duration(audio_telegram, file_path) + details = { + "title": file_name, + "link": message_link, + "path": file_path, + "dur": dur, + } + + try: + await stream( + _, + mystic, + user_id, + details, + chat_id, + user_name, + message.chat.id, + streamtype="telegram", + forceplay=fplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + return await mystic.delete() + return + elif video_telegram: + if message.reply_to_message.document: + try: + ext = video_telegram.file_name.split(".")[-1] + if ext.lower() not in formats: + return await mystic.edit_text( + _["play_7"].format(f"{' | '.join(formats)}") + ) + except: + return await mystic.edit_text( + _["play_7"].format(f"{' | '.join(formats)}") + ) + if video_telegram.file_size > config.TG_VIDEO_FILESIZE_LIMIT: + return await mystic.edit_text(_["play_8"]) + file_path = await Telegram.get_filepath(video=video_telegram) + if await Telegram.download(_, message, mystic, file_path): + message_link = await Telegram.get_link(message) + file_name = await Telegram.get_filename(video_telegram) + dur = await Telegram.get_duration(video_telegram, file_path) + details = { + "title": file_name, + "link": message_link, + "path": file_path, + "dur": dur, + } + try: + await stream( + _, + mystic, + user_id, + details, + chat_id, + user_name, + message.chat.id, + video=True, + streamtype="telegram", + forceplay=fplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + return await mystic.delete() + return + elif url: + if await YouTube.exists(url): + if "playlist" in url: + try: + details = await YouTube.playlist( + url, + config.PLAYLIST_FETCH_LIMIT, + message.from_user.id, + ) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "playlist" + plist_type = "yt" + if "&" in url: + plist_id = (url.split("=")[1]).split("&")[0] + else: + plist_id = url.split("=")[1] + img = config.PLAYLIST_IMG_URL + cap = _["play_9"] + else: + try: + details, track_id = await YouTube.track(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "youtube" + img = details["thumb"] + cap = _["play_10"].format( + details["title"], + details["duration_min"], + ) + elif await Spotify.valid(url): + spotify = True + if not config.SPOTIFY_CLIENT_ID and not config.SPOTIFY_CLIENT_SECRET: + return await mystic.edit_text( + "» sᴘᴏᴛɪғʏ ɪs ɴᴏᴛ sᴜᴘᴘᴏʀᴛᴇᴅ ʏᴇᴛ.\n\nᴘʟᴇᴀsᴇ ᴛʀʏ ᴀɢᴀɪɴ ʟᴀᴛᴇʀ." + ) + if "track" in url: + try: + details, track_id = await Spotify.track(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "youtube" + img = details["thumb"] + cap = _["play_10"].format(details["title"], details["duration_min"]) + elif "playlist" in url: + try: + details, plist_id = await Spotify.playlist(url) + except Exception: + return await mystic.edit_text(_["play_3"]) + streamtype = "playlist" + plist_type = "spplay" + img = config.SPOTIFY_PLAYLIST_IMG_URL + cap = _["play_11"].format(app.mention, message.from_user.mention) + elif "album" in url: + try: + details, plist_id = await Spotify.album(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "playlist" + plist_type = "spalbum" + img = config.SPOTIFY_ALBUM_IMG_URL + cap = _["play_11"].format(app.mention, message.from_user.mention) + elif "artist" in url: + try: + details, plist_id = await Spotify.artist(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "playlist" + plist_type = "spartist" + img = config.SPOTIFY_ARTIST_IMG_URL + cap = _["play_11"].format(message.from_user.first_name) + else: + return await mystic.edit_text(_["play_15"]) + elif await Apple.valid(url): + if "album" in url: + try: + details, track_id = await Apple.track(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "youtube" + img = details["thumb"] + cap = _["play_10"].format(details["title"], details["duration_min"]) + elif "playlist" in url: + spotify = True + try: + details, plist_id = await Apple.playlist(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "playlist" + plist_type = "apple" + cap = _["play_12"].format(app.mention, message.from_user.mention) + img = url + else: + return await mystic.edit_text(_["play_3"]) + elif await Resso.valid(url): + try: + details, track_id = await Resso.track(url) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "youtube" + img = details["thumb"] + cap = _["play_10"].format(details["title"], details["duration_min"]) + elif await SoundCloud.valid(url): + try: + details, track_path = await SoundCloud.download(url) + except: + return await mystic.edit_text(_["play_3"]) + duration_sec = details["duration_sec"] + if duration_sec > config.DURATION_LIMIT: + return await mystic.edit_text( + _["play_6"].format( + config.DURATION_LIMIT_MIN, + app.mention, + ) + ) + try: + await stream( + _, + mystic, + user_id, + details, + chat_id, + user_name, + message.chat.id, + streamtype="soundcloud", + forceplay=fplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + return await mystic.delete() + else: + try: + await Aviax.stream_call(url) + except NoActiveGroupCall: + await mystic.edit_text(_["black_9"]) + return await app.send_message( + chat_id=config.LOG_GROUP_ID, + text=_["play_17"], + ) + except Exception as e: + print(f"Error: {e}") + return await mystic.edit_text(_["general_2"].format(type(e).__name__)) + await mystic.edit_text(_["str_2"]) + try: + await stream( + _, + mystic, + message.from_user.id, + url, + chat_id, + message.from_user.first_name, + message.chat.id, + video=video, + streamtype="index", + forceplay=fplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + return await play_logs(message, streamtype="M3u8 or Index Link") + else: + if len(message.command) < 2: + buttons = botplaylist_markup(_) + return await mystic.edit_text( + _["play_18"], + reply_markup=InlineKeyboardMarkup(buttons), + ) + slider = True + query = message.text.split(None, 1)[1] + if "-v" in query: + query = query.replace("-v", "") + try: + details, track_id = await YouTube.track(query) + except: + return await mystic.edit_text(_["play_3"]) + streamtype = "youtube" + if str(playmode) == "Direct": + if not plist_type: + if details["duration_min"]: + duration_sec = time_to_seconds(details["duration_min"]) + if duration_sec > config.DURATION_LIMIT: + return await mystic.edit_text( + _["play_6"].format(config.DURATION_LIMIT_MIN, app.mention) + ) + else: + buttons = livestream_markup( + _, + track_id, + user_id, + "v" if video else "a", + "c" if channel else "g", + "f" if fplay else "d", + ) + return await mystic.edit_text( + _["play_13"], + reply_markup=InlineKeyboardMarkup(buttons), + ) + try: + await stream( + _, + mystic, + user_id, + details, + chat_id, + user_name, + message.chat.id, + video=video, + streamtype=streamtype, + spotify=spotify, + forceplay=fplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + await mystic.delete() + return await play_logs(message, streamtype=streamtype) + else: + if plist_type: + ran_hash = "".join( + random.choices(string.ascii_uppercase + string.digits, k=10) + ) + lyrical[ran_hash] = plist_id + buttons = playlist_markup( + _, + ran_hash, + message.from_user.id, + plist_type, + "c" if channel else "g", + "f" if fplay else "d", + ) + await mystic.delete() + await message.reply_photo( + photo=img, + caption=cap, + reply_markup=InlineKeyboardMarkup(buttons), + ) + return await play_logs(message, streamtype=f"Playlist : {plist_type}") + else: + if slider: + buttons = slider_markup( + _, + track_id, + message.from_user.id, + query, + 0, + "c" if channel else "g", + "f" if fplay else "d", + ) + await mystic.delete() + await message.reply_photo( + photo=details["thumb"], + caption=_["play_10"].format( + details["title"].title(), + details["duration_min"], + ), + reply_markup=InlineKeyboardMarkup(buttons), + ) + return await play_logs(message, streamtype=f"Searched on Youtube") + else: + buttons = track_markup( + _, + track_id, + message.from_user.id, + "c" if channel else "g", + "f" if fplay else "d", + ) + await mystic.delete() + await message.reply_photo( + photo=img, + caption=cap, + reply_markup=InlineKeyboardMarkup(buttons), + ) + return await play_logs(message, streamtype=f"URL Searched Inline") + + +@app.on_callback_query(filters.regex("MusicStream") & ~BANNED_USERS) +@languageCB +async def play_music(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + vidid, user_id, mode, cplay, fplay = callback_request.split("|") + if CallbackQuery.from_user.id != int(user_id): + try: + return await CallbackQuery.answer(_["playcb_1"], show_alert=True) + except: + return + try: + chat_id, channel = await get_channeplayCB(_, cplay, CallbackQuery) + except: + return + user_name = CallbackQuery.from_user.first_name + try: + await CallbackQuery.message.delete() + await CallbackQuery.answer() + except: + pass + mystic = await CallbackQuery.message.reply_text( + _["play_2"].format(channel) if channel else _["play_1"] + ) + try: + details, track_id = await YouTube.track(vidid, True) + except: + return await mystic.edit_text(_["play_3"]) + if details["duration_min"]: + duration_sec = time_to_seconds(details["duration_min"]) + if duration_sec > config.DURATION_LIMIT: + return await mystic.edit_text( + _["play_6"].format(config.DURATION_LIMIT_MIN, app.mention) + ) + else: + buttons = livestream_markup( + _, + track_id, + CallbackQuery.from_user.id, + mode, + "c" if cplay == "c" else "g", + "f" if fplay else "d", + ) + return await mystic.edit_text( + _["play_13"], + reply_markup=InlineKeyboardMarkup(buttons), + ) + video = True if mode == "v" else None + ffplay = True if fplay == "f" else None + try: + await stream( + _, + mystic, + CallbackQuery.from_user.id, + details, + chat_id, + user_name, + CallbackQuery.message.chat.id, + video, + streamtype="youtube", + forceplay=ffplay, + ) + except Exception as e: + print(f"Error: {e}") + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_2"].format(ex_type) + return await mystic.edit_text(err) + return await mystic.delete() + + +@app.on_callback_query(filters.regex("DragmousAdmin") & ~BANNED_USERS) +async def Dragmous_check(client, CallbackQuery): + try: + await CallbackQuery.answer( + "» ʀᴇᴠᴇʀᴛ ʙᴀᴄᴋ ᴛᴏ ᴜsᴇʀ ᴀᴄᴄᴏᴜɴᴛ :\n\nᴏᴘᴇɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ sᴇᴛᴛɪɴɢs.\n-> ᴀᴅᴍɪɴɪsᴛʀᴀᴛᴏʀs\n-> ᴄʟɪᴄᴋ ᴏɴ ʏᴏᴜʀ ɴᴀᴍᴇ\n-> ᴜɴᴄʜᴇᴄᴋ ᴀɴᴏɴʏᴍᴏᴜs ᴀᴅᴍɪɴ ᴘᴇʀᴍɪssɪᴏɴs.", + show_alert=True, + ) + except: + pass + + +@app.on_callback_query(filters.regex("AviaxPlaylists") & ~BANNED_USERS) +@languageCB +async def play_playlists_command(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + ( + videoid, + user_id, + ptype, + mode, + cplay, + fplay, + ) = callback_request.split("|") + if CallbackQuery.from_user.id != int(user_id): + try: + return await CallbackQuery.answer(_["playcb_1"], show_alert=True) + except: + return + try: + chat_id, channel = await get_channeplayCB(_, cplay, CallbackQuery) + except: + return + user_name = CallbackQuery.from_user.first_name + await CallbackQuery.message.delete() + try: + await CallbackQuery.answer() + except: + pass + mystic = await CallbackQuery.message.reply_text( + _["play_2"].format(channel) if channel else _["play_1"] + ) + videoid = lyrical.get(videoid) + video = Tr diff --git a/DragMusic/plugins/play/playlist.py b/DragMusic/plugins/play/playlist.py new file mode 100644 index 0000000000000000000000000000000000000000..e73a8d09574d43ae4a9dfb8c4596812dbadbd2c0 --- /dev/null +++ b/DragMusic/plugins/play/playlist.py @@ -0,0 +1,908 @@ +import os +import requests +from random import randint +from DragMusic.utils.database import ( + add_served_chat, + add_served_user, + blacklisted_chats, + get_lang, + is_banned_user, + is_on_off, +) + +from pykeyboard import InlineKeyboard +from pyrogram import filters +from pyrogram.types import ( + InlineKeyboardButton, + CallbackQuery, + InlineKeyboardMarkup, + Message, +) +from DragMusic.utils import close_markup +from config import BANNED_USERS, SERVER_PLAYLIST_LIMIT +from DragMusic import Carbon, app +from DragMusic.utils.decorators.language import language, languageCB +from DragMusic.utils.inline.playlist import ( + botplaylist_markup, + get_playlist_markup, + warning_markup, +) +from DragMusic.utils.pastebin import DragBin +import time +import asyncio +import yt_dlp +from youtube_search import YoutubeSearch +from youtubesearchpython import VideosSearch +from youtubesearchpython import SearchVideos + +from DragMusic.utils.stream.stream import stream +from typing import Dict, List, Union +from time import time +import asyncio +from DragMusic.utils.extraction import extract_user + +#youtube api key +YOUTUBE_API_KEY = 'AIzaSyAisAILkwpcmK7TC79R6UhQ3isSqUnHvhY' # Regenerate your key and replace this + + +# Define a dictionary to track the last message timestamp for each user +user_last_message_time = {} +user_command_count = {} +# Define the threshold for command spamming (e.g., 20 commands within 60 seconds) +SPAM_THRESHOLD = 2 +SPAM_WINDOW_SECONDS = 5 +from DragMusic.core.mongo import mongodb + + +playlistdb = mongodb.playlist +playlist = [] +# Playlist Databse + + +async def _get_playlists(chat_id: int) -> Dict[str, int]: + _notes = await playlistdb.find_one({"chat_id": chat_id}) + if not _notes: + return {} + return _notes["notes"] + + +async def get_playlist_names(chat_id: int) -> List[str]: + _notes = [] + for note in await _get_playlists(chat_id): + _notes.append(note) + return _notes + + +async def get_playlist(chat_id: int, name: str) -> Union[bool, dict]: + name = name + _notes = await _get_playlists(chat_id) + if name in _notes: + return _notes[name] + else: + return False + + +async def save_playlist(chat_id: int, name: str, note: dict): + name = name + _notes = await _get_playlists(chat_id) + _notes[name] = note + await playlistdb.update_one( + {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True + ) + + +async def delete_playlist(chat_id: int, name: str) -> bool: + notesd = await _get_playlists(chat_id) + name = name + if name in notesd: + del notesd[name] + await playlistdb.update_one( + {"chat_id": chat_id}, + {"$set": {"notes": notesd}}, + upsert=True, + ) + return True + return False + + +# Command +ADDPLAYLIST_COMMAND = "addplaylist" +SHOWPLAYLIST_COMMAND = "showplaylist" +DELETEPLAYLIST_COMMAND = "delplaylist" +ADDSONG = "addsong" + +@app.on_message(filters.command("ADDSONG") & ~BANNED_USERS) +@language +async def add_song(client, message: Message, _): + if len(message.command) < 2: + return await message.reply_text( + " Pʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ sᴏɴɢ ɴᴀᴍᴇ ᴀғᴛᴇʀ ᴛʜᴇ ᴄᴏᴍᴍᴀɴᴅ..\n\n➥ Example:\n\n▷ /ᴀᴅᴅsᴏɴɢ Sᴏɴɢ Nᴀᴍᴇ" + ) + + song_name = " ".join(message.command[1:]) # Join the command arguments to form the song name + adding = await message.reply_text("Sᴇᴀʀᴄʜɪɴɢ ғᴏʀ ᴛʜᴇ sᴏɴɢ, ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..") + + # Search for the song on YouTube + search_url = f'https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&q={song_name}&key={YOUTUBE_API_KEY}' + + try: + response = requests.get(search_url) + data = response.json() + + if 'items' not in data or not data['items']: + return await message.reply_text("Nᴏ sᴏɴɢ ғᴏᴜɴᴅ ᴡɪᴛʜ ᴛʜᴇ ᴘʀᴏᴠɪᴅᴇᴅ ɴᴀᴍᴇ.") + + user_id = message.from_user.id + item = data['items'][0] + video_id = item['id']['videoId'] + title = item['snippet']['title'] + duration = "Unknown" # Placeholder for duration + + # Save the song item + song = { + "videoid": video_id, + "title": title, + "duration": duration, + } + + await save_playlist(user_id, video_id, song) + + await adding.delete() + return await message.reply_text( + text="Sᴏɴɢ ʜᴀs ʙᴇᴇɴ ᴀᴅᴅᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ғʀᴏᴍ ʏᴏᴜʀ sᴇᴀʀᴄʜ\n\n Iғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇᴍᴏᴠᴇ ᴀɴʏ sᴏɴɢ ᴛʜᴇɴ ᴄʟɪᴄᴋ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ.\n\n Cʜᴇᴄᴋ ʙʏ » /playlist\n\n Pʟᴀʏ ʙʏ » /Pʟᴀʏ" + ) + + except Exception as e: + return await message.reply_text(f"Eʀʀᴏʀ sᴇᴀʀᴄʜɪɴɢ ғᴏʀ sᴏɴɢ: {str(e)}") +@app.on_message(filters.command(SHOWPLAYLIST_COMMAND) & ~BANNED_USERS) +@language +async def check_playlist(client, message: Message, _): + user_id = message.from_user.id + current_time = time() + # Update the last message timestamp for the user + last_message_time = user_last_message_time.get(user_id, 0) + + if current_time - last_message_time < SPAM_WINDOW_SECONDS: + # If less than the spam window time has passed since the last message + user_last_message_time[user_id] = current_time + user_command_count[user_id] = user_command_count.get(user_id, 0) + 1 + if user_command_count[user_id] > SPAM_THRESHOLD: + # Block the user if they exceed the threshold + hu = await message.reply_text( + f"**{message.from_user.mention} ᴘʟᴇᴀsᴇ ᴅᴏɴᴛ ᴅᴏ sᴘᴀᴍ, ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ ᴀғᴛᴇʀ 5 sᴇᴄ**" + ) + await asyncio.sleep(3) + await hu.delete() + return + else: + # If more than the spam window time has passed, reset the command count and update the message timestamp + user_command_count[user_id] = 1 + user_last_message_time[user_id] = current_time + + _playlist = await get_playlist_names(message.from_user.id) + if _playlist: + get = await message.reply_text(_["playlist_2"]) + else: + return await message.reply_text(_["playlist_3"]) + msg = _["playlist_4"] + count = 0 + for shikhar in _playlist: + _note = await get_playlist(message.from_user.id, shikhar) + title = _note["title"] + title = title.title() + duration = _note["duration"] + count += 1 + msg += f"\n\n{count}- {title[:70]}\n" + msg += _["playlist_5"].format(duration) + link = await DragBin(msg) + lines = msg.count("\n") + if lines >= 17: + car = os.linesep.join(msg.split(os.linesep)[:17]) + else: + car = msg + carbon = await Carbon.generate(car, randint(100, 10000000000)) + await get.delete() + await message.reply_photo(carbon, caption=_["playlist_15"].format(link)) + + +async def get_keyboard(_, user_id): + keyboard = InlineKeyboard(row_width=5) + _playlist = await get_playlist_names(user_id) + count = len(_playlist) + for x in _playlist: + _note = await get_playlist(user_id, x) + title = _note["title"] + title = title.title() + keyboard.row( + InlineKeyboardButton( + text=title, + callback_data=f"del_playlist {x}", + ) + ) + keyboard.row( + InlineKeyboardButton( + text=_["PL_B_5"], + callback_data=f"delete_warning", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data=f"close"), + ) + return keyboard, count + + +@app.on_message(filters.command(DELETEPLAYLIST_COMMAND) & ~BANNED_USERS) +@language +async def del_plist_msg(client, message: Message, _): + user_id = message.from_user.id + current_time = time() + # Update the last message timestamp for the user + last_message_time = user_last_message_time.get(user_id, 0) + + if current_time - last_message_time < SPAM_WINDOW_SECONDS: + # If less than the spam window time has passed since the last message + user_last_message_time[user_id] = current_time + user_command_count[user_id] = user_command_count.get(user_id, 0) + 1 + if user_command_count[user_id] > SPAM_THRESHOLD: + # Block the user if they exceed the threshold + hu = await message.reply_text( + f"**{message.from_user.mention} ᴘʟᴇᴀsᴇ ᴅᴏɴᴛ ᴅᴏ sᴘᴀᴍ, ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ ᴀғᴛᴇʀ 5 sᴇᴄ**" + ) + await asyncio.sleep(3) + await hu.delete() + return + else: + # If more than the spam window time has passed, reset the command count and update the message timestamp + user_command_count[user_id] = 1 + user_last_message_time[user_id] = current_time + + _playlist = await get_playlist_names(message.from_user.id) + if _playlist: + get = await message.reply_text(_["playlist_2"]) + else: + return await message.reply_text(_["playlist_3"]) + keyboard, count = await get_keyboard(_, message.from_user.id) + await get.edit_text(_["playlist_7"].format(count), reply_markup=keyboard) + + +@app.on_callback_query(filters.regex("play_playlist") & ~BANNED_USERS) +@languageCB +async def play_playlist(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + mode = callback_data.split(None, 1)[1] + user_id = CallbackQuery.from_user.id + _playlist = await get_playlist_names(user_id) + if not _playlist: + try: + return await CallbackQuery.answer( + _["playlist_3"], + show_alert=True, + ) + except: + return + chat_id = CallbackQuery.message.chat.id + user_name = CallbackQuery.from_user.first_name + await CallbackQuery.message.delete() + result = [] + try: + await CallbackQuery.answer() + except: + pass + video = True if mode == "v" else None + mystic = await CallbackQuery.message.reply_text(_["play_1"]) + for vidids in _playlist: + result.append(vidids) + try: + await stream( + _, + mystic, + user_id, + result, + chat_id, + user_name, + CallbackQuery.message.chat.id, + video, + streamtype="playlist", + ) + except Exception as e: + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_3"].format(ex_type) + return await mystic.edit_text(err) + return await mystic.delete() + + +@app.on_message( + filters.command(["playplaylist", "vplayplaylist"]) & ~BANNED_USERS & filters.group +) +@languageCB +async def play_playlist_command(client, message, _): + mode = message.command[0][0] + user_id = message.from_user.id + _playlist = await get_playlist_names(user_id) + if not _playlist: + try: + return await message.reply( + _["playlist_3"], + quote=True, + ) + except: + return + + chat_id = message.chat.id + user_name = message.from_user.first_name + + try: + await message.delete() + except: + pass + + result = [] + video = True if mode == "v" else None + mystic = await message.reply_text(_["play_1"]) + + for vidids in _playlist: + result.append(vidids) + + try: + await stream( + _, + mystic, + user_id, + result, + chat_id, + user_name, + message.chat.id, + video, + streamtype="playlist", + ) + except Exception as e: + ex_type = type(e).__name__ + err = e if ex_type == "AssistantErr" else _["general_3"].format(ex_type) + return await mystic.edit_text(err) + + return await mystic.delete() + + +import json + + +# Combined add_playlist function +@app.on_message(filters.command(ADDPLAYLIST_COMMAND) & ~BANNED_USERS) +@language +async def add_playlist(client, message: Message, _): + if len(message.command) < 2: + return await message.reply_text( + "Pʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ YᴏᴜTᴜʙᴇ ᴘʟᴀʏʟɪsᴛ ʟɪɴᴋ ᴀғᴛᴇʀ ᴛʜᴇ ᴄᴏᴍᴍᴀɴᴅ.\n\n Exᴀᴍᴘʟᴇ: \n\n /ᴀᴅᴅᴘʟᴀʏʟɪsᴛ ʜᴛᴛᴘs://ᴡᴡᴡ.ʏᴏᴜᴛᴜʙᴇ.ᴄᴏᴍ/ᴘʟᴀʏʟɪsᴛ?ʟɪsᴛ=YOUR_PLAYLIST_ID" + ) + + query = message.command[1] + + # Check if the provided input is a YouTube playlist link + if "youtube.com/playlist" in query: + adding = await message.reply_text("Aᴅᴅɪɴɢ sᴏɴɢs ᴛᴏ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ, ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..") + + # Extract the playlist ID from the link + playlist_id = query.split("list=")[-1].split("&")[0] + + # Fetch playlist items using YouTube Data API + url = f'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId={playlist_id}&key={YOUTUBE_API_KEY}' + + try: + response = requests.get(url) + data = response.json() + + if 'items' not in data or not data['items']: + return await message.reply_text("Nᴏ sᴏɴɢs ғᴏᴜɴᴅ ɪɴ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ...") + + user_id = message.from_user.id + for item in data['items']: + video_id = item['snippet']['resourceId']['videoId'] + title = item['snippet']['title'] + # Duration is not available in playlistItems, you may need to fetch it separately + duration = "Unknown" # Placeholder for duration + + # Save the playlist item + plist = { + "videoid": video_id, + "title": title, + "duration": duration, + } + + await save_playlist(user_id, video_id, plist) + + keyboardes = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ Want to remove any songs? ๏", + callback_data=f"open_playlist {user_id}", + ) + ] + ] + ) + + await adding.delete() + return await message.reply_text( + text="Aʟʟ sᴏɴɢs ʜᴀᴠᴇ ʙᴇᴇɴ ᴀᴅᴅᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ғʀᴏᴍ ʏᴏᴜʀ YᴏᴜTᴜʙᴇ ᴘʟᴀʏʟɪsᴛ ʟɪɴᴋ\n\n Iғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇᴍᴏᴠᴇ ᴀɴʏ sᴏɴɢ ᴛʜᴇɴ ᴄʟɪᴄᴋ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ.\n\n Check by » /playlist**\n\n Play by » /play \n ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ /ᴅᴇʟᴇᴛᴇᴘʟᴀʏʟɪsᴛ \n", + reply_markup=keyboardes, + ) + + except Exception as e: + return await message.reply_text(f"Eʀʀᴏʀ ғᴇᴛᴄʜɪɴɢ ᴘʟᴀʏʟɪsᴛ: {str(e)}") + + else: + return await message.reply_text("Pʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ ᴠᴀʟɪᴅ YᴏᴜTᴜʙᴇ ᴘʟᴀʏʟɪsᴛ ʟɪɴᴋ.") + pass + + if "youtube.com/@" in query: + addin = await message.reply_text( + "ᴀᴅᴅɪɴɢ sᴏɴɢs ɪɴ ᴘʟᴀʏʟɪsᴛ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..**" + ) + try: + from pytube import YouTube + + channel_username = query + videos = YouTube_videos(f"{query}/videos") + video_urls = [video["url"] for video in videos] + + except Exception as e: + # Handle exception + return await message.reply_text(f"Error: {e}") + + if not video_urls: + return await message.reply_text( + "ɴᴏ sᴏɴɢs ғᴏᴜɴᴅ ɪɴ ᴛʜᴇ YᴏᴜTᴜʙᴇ ᴄʜᴀɴɴᴇʟ.\n\n ᴛʀʏ ᴏᴛʜᴇʀ YᴏᴜTᴜʙᴇ ᴄʜᴀɴɴᴇʟ ʟɪɴᴋ" + ) + + user_id = message.from_user.id + for video_url in video_urls: + videosid = query.split("/")[-1].split("?")[0] + + try: + yt = YouTube(f"https://youtu.be/{videosid}") + title = yt.title + duration = yt.length + except Exception as e: + return await message.reply_text(f"ᴇʀʀᴏʀ ғᴇᴛᴄʜɪɴɢ ᴠɪᴅᴇᴏ ɪɴғᴏ: {e}") + + plist = { + "videoid": video_id, + "title": title, + "duration": duration, + } + + await save_playlist(user_id, video_id, plist) + keyboardes = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ ᴡᴀɴᴛ ʀᴇᴍᴏᴠᴇ ᴀɴʏ sᴏɴɢs? ๏", + callback_data=f"open_playlist {user_id}", + ) + ] + ] + ) + await addin.delete() + return await message.reply_text( + text="ᴀʟʟ sᴏɴɢs ʜᴀs ʙᴇᴇɴ ᴀᴅᴅᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ғʀᴏᴍ ʏᴏᴜʀ ʏᴏᴜᴛᴜʙᴇ channel ʟɪɴᴋ \n\n ɪғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇᴍᴏᴠᴇ ᴀɴʏ sᴏɴɢ ᴛʜᴇɴ ᴄʟɪᴄᴋ ɢɪᴠᴇɴ ʙᴇʟᴏᴡ ʙᴜᴛᴛᴏɴ.\n\n ᴄʜᴇᴄᴋ ʙʏ » /playlist \n\n ᴘʟᴀʏ ʙʏ » /play \n ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ /ᴅᴇʟᴇᴛᴇᴘʟᴀʏʟɪsᴛ \n", + reply_markup=keyboardes, + ) + pass + + # Check if the provided input is a YouTube video link + if "https://youtu.be" in query: + try: + add = await message.reply_text( + "ᴀᴅᴅɪɴɢ sᴏɴɢs ɪɴ ᴘʟᴀʏʟɪsᴛ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ.." + ) + from pytube import Playlist + from pytube import YouTube + + # Extract video ID from the YouTube lin + videoid = query.split("/")[-1].split("?")[0] + user_id = message.from_user.id + thumbnail = f"https://img.youtube.com/vi/{videoid}/maxresdefault.jpg" + _check = await get_playlist(user_id, videoid) + if _check: + try: + await add.delete() + return await message.reply_photo(thumbnail, caption=_["playlist_8"]) + except KeyError: + pass + + _count = await get_playlist_names(user_id) + count = len(_count) + if count == SERVER_PLAYLIST_LIMIT: + try: + return await message.reply_text( + _["playlist_9"].format(SERVER_PLAYLIST_LIMIT) + ) + except KeyError: + pass + + try: + yt = YouTube(f"https://youtu.be/{videoid}") + title = yt.title + duration = yt.length + thumbnail = f"https://img.youtube.com/vi/{videoid}/maxresdefault.jpg" + plist = { + "videoid": videoid, + "title": title, + "duration": duration, + } + await save_playlist(user_id, videoid, plist) + + # Create inline keyboard with remove button + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ Remove from Playlist ๏", + callback_data=f"remove_playlist {videoid}", + ) + ] + ] + ) + await add.delete() + await message.reply_photo( + thumbnail, + caption="ᴀᴅᴅᴇᴅ sᴏɴɢ ɪɴ ʏᴏᴜʀ ʙᴏᴛ ᴘʟᴀʏʟɪsᴛ ✅ \n\n ᴄʜᴇᴄᴋ ʙʏ /playlist \n\n ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ /ᴅᴇʟᴇᴛᴇᴘʟᴀʏʟɪsᴛ\n\n ➥ ᴀɴᴅ ᴘʟᴀʏ ʙʏ » /play (ɢʀᴏᴜᴘs ᴏɴʟʏ)", + reply_markup=keyboard, + ) + except Exception as e: + print(f"Error: {e}") + await message.reply_text(str(e)) + except Exception as e: + return await message.reply_text(str(e)) + pass + else: + from DragMusic import YouTube + + # Add a specific song by name + query = " ".join(message.command[1:]) + print(query) + + try: + results = YoutubeSearch(query, max_results=1).to_dict() + link = f"https://youtube.com{results[0]['url_suffix']}" + title = results[0]["title"][:40] + thumbnail = results[0]["thumbnails"][0] + thumb_name = f"{title}.jpg" + thumb = requests.get(thumbnail, allow_redirects=True) + open(thumb_name, "wb").write(thumb.content) + duration = results[0]["duration"] + videoid = results[0]["id"] + # Add these lines to define views and channel_name + views = results[0]["views"] + channel_name = results[0]["channel"] + + user_id = message.from_user.id + _check = await get_playlist(user_id, videoid) + if _check: + try: + return await message.reply_photo(thumbnail, caption=_["playlist_8"]) + except KeyError: + pass + + _count = await get_playlist_names(user_id) + count = len(_count) + if count == SERVER_PLAYLIST_LIMIT: + try: + return await message.reply_text( + _["playlist_9"].format(SERVER_PLAYLIST_LIMIT) + ) + except KeyError: + pass + + m = await message.reply("ᴀᴅᴅɪɴɢ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ...") + title, duration_min, _, _, _ = await YouTube.details(videoid, True) + title = (title[:50]).title() + plist = { + "videoid": videoid, + "title": title, + "duration": duration_min, + } + + await save_playlist(user_id, videoid, plist) + + # Create inline keyboard with remove button + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ Remove from Playlist ๏", + callback_data=f"remove_playlist {videoid}", + ) + ] + ] + ) + await m.delete() + await message.reply_photo( + thumbnail, + caption="ᴀᴅᴅᴇᴅ sᴏɴɢ ɪɴ ʏᴏᴜʀ ʙᴏᴛ ᴘʟᴀʏʟɪsᴛ ✅ \n\n➥ ᴄʜᴇᴄᴋ ʙʏ » /playlist \n\n ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ /ᴅᴇʟᴇᴛᴇᴘʟᴀʏʟɪsᴛ \n\n ᴀɴᴅ ᴘʟᴀʏ ʙʏ » /play (ɢʀᴏᴜᴘs ᴏɴʟʏ)", + reply_markup=keyboard, + ) + + except KeyError: + return await message.reply_text("ɪɴᴠᴀʟɪᴅ ᴅᴀᴛᴀ ғᴏʀᴍᴀᴛ ʀᴇᴄᴇɪᴠᴇᴅ.") + except Exception as e: + pass + + +@app.on_callback_query(filters.regex("open_playlist") & ~BANNED_USERS) +@languageCB +async def open_playlist(client, CallbackQuery, _): + _playlist = await get_playlist_names(CallbackQuery.from_user.id) + if _playlist: + get = await CallbackQuery.message.edit_text(_["playlist_2"]) + else: + return await CallbackQuery.message.edit_text(_["playlist_3"]) + keyboard, count = await get_keyboard(_, CallbackQuery.from_user.id) + await get.edit_text(_["playlist_7"].format(count), reply_markup=keyboard) + + +@app.on_callback_query(filters.regex("remove_playlist") & ~BANNED_USERS) +@languageCB +async def del_plist(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + videoid = callback_data.split(None, 1)[1] + user_id = CallbackQuery.from_user.id + deleted = await delete_playlist(CallbackQuery.from_user.id, videoid) + if deleted: + try: + await CallbackQuery.answer(_["playlist_11"], show_alert=True) + except: + pass + else: + try: + return await CallbackQuery.answer(_["playlist_12"], show_alert=True) + except: + return + keyboards = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ ʀᴇᴄᴏᴠᴇʀ ʏᴏᴜʀ sᴏɴɢ ๏", callback_data=f"recover_playlist {videoid}" + ) + ] + ] + ) + return await CallbackQuery.edit_message_text( + text="ʏᴏᴜʀ sᴏɴɢ ʜᴀs ʙᴇᴇɴ ᴅᴇʟᴇᴛᴇᴅ ғʀᴏᴍ ʏᴏᴜʀ ʙᴏᴛ ᴘʟᴀʏʟɪsᴛ \n\n ɪғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇᴄᴏᴠᴇʀ ʏᴏᴜʀ sᴏɴɢ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ ᴛʜᴇɴ ᴄʟɪᴄᴋ ɢɪᴠᴇɴ ʙᴇʟᴏᴡ ʙᴜᴛᴛᴏɴ", + reply_markup=keyboards, + ) + + +@app.on_callback_query(filters.regex("recover_playlist") & ~BANNED_USERS) +@languageCB +async def add_playlist(client, CallbackQuery, _): + from DragMusic import YouTube + + callback_data = CallbackQuery.data.strip() + videoid = callback_data.split(None, 1)[1] + user_id = CallbackQuery.from_user.id + _check = await get_playlist(user_id, videoid) + if _check: + try: + return await CallbackQuery.answer(_["playlist_8"], show_alert=True) + except: + return + _count = await get_playlist_names(user_id) + count = len(_count) + if count == SERVER_PLAYLIST_LIMIT: + try: + return await CallbackQuery.answer( + _["playlist_9"].format(SERVER_PLAYLIST_LIMIT), + show_alert=True, + ) + except: + return + ( + title, + duration_min, + duration_sec, + thumbnail, + vidid, + ) = await YouTube.details(videoid, True) + title = (title[:50]).title() + plist = { + "videoid": vidid, + "title": title, + "duration": duration_min, + } + await save_playlist(user_id, videoid, plist) + try: + title = (title[:30]).title() + keyboardss = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "๏ ʀᴇᴍᴏᴠᴇ ᴀɢᴀɪɴ ๏", callback_data=f"remove_playlist {videoid}" + ) + ] + ] + ) + return await CallbackQuery.edit_message_text( + text=" ʀᴇᴄᴏᴠᴇʀᴇᴅ sᴏɴɢ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ \n\n Cʜᴇᴄᴋ Pʟᴀʏʟɪsᴛ ʙʏ /playlist \n\n ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ /ᴅᴇʟᴇᴛᴇᴘʟᴀʏʟɪsᴛ \n\n ᴀɴᴅ ᴘʟᴀʏ ᴘʟᴀʏʟɪsᴛ ʙʏ /play", + reply_markup=keyboardss, + ) + except: + return + + +@app.on_callback_query(filters.regex("add_playlist") & ~BANNED_USERS) +@languageCB +async def add_playlist(client, CallbackQuery, _): + await CallbackQuery.answer( + "➻ᴛᴏ ᴀᴅᴅ ᴀ sᴏɴɢ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ ᴊᴜsᴛ ᴛʏᴘᴇ /addplaylist (Here your song name)\n\n ᴇxᴀᴍᴘʟᴇ » /addplaylist Blue Eyes Blue tyes.", + show_alert=True, + ) + + +@app.on_callback_query(filters.regex("shukla_playlist") & ~BANNED_USERS) +@languageCB +async def add_playlists(client, CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + videoid = callback_data.split(None, 1)[1] + user_id = CallbackQuery.from_user.id + from DragMusic import YouTube + + _check = await get_playlist(user_id, videoid) + if _check: + try: + from DragMusic import YouTube + + return await CallbackQuery.answer(_["playlist_8"], show_alert=True) + except: + return + _count = await get_playlist_names(user_id) + count = len(_count) + if count == SERVER_PLAYLIST_LIMIT: + try: + return await CallbackQuery.answer( + _["playlist_9"].format(SERVER_PLAYLIST_LIMIT), + show_alert=True, + ) + except: + return + ( + title, + duration_min, + duration_sec, + thumbnail, + vidid, + ) = await YouTube.details(videoid, True) + title = (title[:50]).title() + plist = { + "videoid": vidid, + "title": title, + "duration": duration_min, + } + await save_playlist(user_id, videoid, plist) + try: + title = (title[:30]).title() + return await CallbackQuery.answer( + _["playlist_10"].format(title), show_alert=True + ) + except: + return + + +# New command +DELETE_ALL_PLAYLIST_COMMAND = "delallplaylist" + + +@app.on_message(filters.command(DELETE_ALL_PLAYLIST_COMMAND) & ~BANNED_USERS) +@language +async def delete_all_playlists(client, message, _): + from DragMusic import YouTube + + user_id = message.from_user.id + _playlist = await get_playlist_names(user_id) + if _playlist: + try: + upl = warning_markup(_) + await message.reply_text(_["playlist_14"], reply_markup=upl) + except: + pass + else: + await message.reply_text(_["playlist_3"]) + + +@app.on_callback_query(filters.regex("del_playlist") & ~BANNED_USERS) +@languageCB +async def del_plist(client, CallbackQuery, _): + from DragMusic import YouTube + + callback_data = CallbackQuery.data.strip() + videoid = callback_data.split(None, 1)[1] + user_id = CallbackQuery.from_user.id + deleted = await delete_playlist(CallbackQuery.from_user.id, videoid) + if deleted: + try: + await CallbackQuery.answer(_["playlist_11"], show_alert=True) + except: + pass + else: + try: + return await CallbackQuery.answer(_["playlist_12"], show_alert=True) + except: + return + keyboard, count = await get_keyboard(_, user_id) + return await CallbackQuery.edit_message_reply_markup(reply_markup=keyboard) + + +@app.on_callback_query(filters.regex("delete_whole_playlist") & ~BANNED_USERS) +@languageCB +async def del_whole_playlist(client, CallbackQuery, _): + from DragMusic import YouTube + + _playlist = await get_playlist_names(CallbackQuery.from_user.id) + for x in _playlist: + await CallbackQuery.answer( + "➻ ᴏᴋ sɪʀ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ.\n\n➥ ᴅᴇʟᴇᴛɪɴɢ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ...", show_alert=True + ) + await delete_playlist(CallbackQuery.from_user.id, x) + return await CallbackQuery.edit_message_text(_["playlist_13"]) + + +@app.on_callback_query(filters.regex("get_playlist_playmode") & ~BANNED_USERS) +@languageCB +async def get_playlist_playmode_(client, CallbackQuery, _): + try: + await CallbackQuery.answer() + except: + pass + buttons = get_playlist_markup(_) + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + + +@app.on_callback_query(filters.regex("delete_warning") & ~BANNED_USERS) +@languageCB +async def delete_warning_message(client, CallbackQuery, _): + from DragMusic import YouTube + + try: + await CallbackQuery.answer() + except: + pass + upl = warning_markup(_) + return await CallbackQuery.edit_message_text(_["playlist_14"], reply_markup=upl) + + +@app.on_callback_query(filters.regex("home_play") & ~BANNED_USERS) +@languageCB +async def home_play_(client, CallbackQuery, _): + from DragMusic import YouTube + + try: + await CallbackQuery.answer() + except: + pass + buttons = botplaylist_markup(_) + return await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + + +@app.on_callback_query(filters.regex("del_back_playlist") & ~BANNED_USERS) +@languageCB +async def del_back_playlist(client, CallbackQuery, _): + from DragMusic import YouTube + + user_id = CallbackQuery.from_user.id + _playlist = await get_playlist_names(user_id) + if _playlist: + try: + await CallbackQuery.answer(_["playlist_2"], show_alert=True) + except: + pass + else: + try: + return await CallbackQuery.answer(_["playlist_3"], show_alert=True) + except: + return + keyboard, count = await get_keyboard(_, user_id) + return await CallbackQuery.edit_message_text( + _["playlist_7"].format(count), reply_markup=keyboard + ) diff --git a/DragMusic/plugins/play/playmode.py b/DragMusic/plugins/play/playmode.py new file mode 100644 index 0000000000000000000000000000000000000000..0755ce1c9a6ca3bd71c8900e9d04ca875e35d6da --- /dev/null +++ b/DragMusic/plugins/play/playmode.py @@ -0,0 +1,33 @@ +from pyrogram import filters +from pyrogram.types import InlineKeyboardMarkup, Message + +from DragMusic import app +from DragMusic.utils.database import get_playmode, get_playtype, is_nonadmin_chat +from DragMusic.utils.decorators import language +from DragMusic.utils.inline.settings import playmode_users_markup +from config import BANNED_USERS + + +@app.on_message(filters.command(["playmode", "mode"]) & filters.group & ~BANNED_USERS) +@language +async def playmode_(client, message: Message, _): + playmode = await get_playmode(message.chat.id) + if playmode == "Direct": + Direct = True + else: + Direct = None + is_non_admin = await is_nonadmin_chat(message.chat.id) + if not is_non_admin: + Group = True + else: + Group = None + playty = await get_playtype(message.chat.id) + if playty == "Everyone": + Playtype = None + else: + Playtype = True + buttons = playmode_users_markup(_, Direct, Group, Playtype) + response = await message.reply_text( + _["play_22"].format(message.chat.title), + reply_markup=InlineKeyboardMarkup(buttons), + ) diff --git a/DragMusic/plugins/plugins/Gemini.txt b/DragMusic/plugins/plugins/Gemini.txt new file mode 100644 index 0000000000000000000000000000000000000000..e72b98b7b7885820110ae55a2b3ef363b7ca5649 --- /dev/null +++ b/DragMusic/plugins/plugins/Gemini.txt @@ -0,0 +1,35 @@ +import requests +from MukeshAPI import api +from pyrogram import filters +from pyrogram.enums import ChatAction +from DragMusic import app + + +@app.on_message(filters.command(["gemini"])) +async def gemini_handler(client, message): + await app.send_chat_action(message.chat.id, ChatAction.TYPING) + if ( + message.text.startswith(f"/gemini@{app.username}") + and len(message.text.split(" ", 1)) > 1 + ): + user_input = message.text.split(" ", 1)[1] + elif message.reply_to_message and message.reply_to_message.text: + user_input = message.reply_to_message.text + else: + if len(message.command) > 1: + user_input = " ".join(message.command[1:]) + else: + await message.reply_text("ᴇxᴀᴍᴘʟᴇ :- `/gemini hi?`") + return + + try: + response = api.gemini(user_input) + await app.send_chat_action(message.chat.id, ChatAction.TYPING) + x = response["results"] + if x: + await message.reply_text(x, quote=True) + else: + await message.reply_text("sᴏʀʀʏ sɪʀ! ᴘʟᴇᴀsᴇ Tʀʏ ᴀɢᴀɪɴ") + except requests.exceptions.RequestException as e: + pass + diff --git a/DragMusic/plugins/plugins/ask.py b/DragMusic/plugins/plugins/ask.py new file mode 100644 index 0000000000000000000000000000000000000000..5ce3860440bea44b844d1a9e9396b9f5054c96c0 --- /dev/null +++ b/DragMusic/plugins/plugins/ask.py @@ -0,0 +1,34 @@ +from pyrogram import filters +from pyrogram.enums import ChatAction, ParseMode +from DragMusic import app +import aiohttp + +# Function to fetch data from Akeno API +async def fetch_data_from_akeno(question): + url = "https://web-3ypd.onrender.com/api/cohere" # API endpoint + params = {"query": question} # Pass query as a parameter + + async with aiohttp.ClientSession() as session: + async with session.get(url, params=params) as response: + data = await response.json() + return data.get("results", "No response received.") # Extract the answer + +# Command handler for /ask +@app.on_message(filters.command("ask")) +async def ask_command(client, message): + chat_id = message.chat.id + user_id = message.from_user.id + + # Indicate typing action + await app.send_chat_action(chat_id, ChatAction.TYPING) + + if len(message.command) < 2: + await message.reply_text("Exᴀᴍᴘʟᴇ ᴜsᴀɢᴇ: /ask [your question]") + return + + question = " ".join(message.command[1:]) # Get the question from command arguments + response = await fetch_data_from_akeno(question) + + formatted_response = f"
{response}
" + + await message.reply_text(formatted_response, parse_mode=ParseMode.HTML) diff --git a/DragMusic/plugins/plugins/brave.py b/DragMusic/plugins/plugins/brave.py new file mode 100644 index 0000000000000000000000000000000000000000..b753be440aa0d26e99ab96eb73d0dc9eea31fa1a --- /dev/null +++ b/DragMusic/plugins/plugins/brave.py @@ -0,0 +1,42 @@ +import requests +from pyrogram import filters +from pyrogram.enums import ChatAction +from DragMusic import app + +# Add your Brave Search API key (if required) +BRAVE_SEARCH_API_KEY = "your_brave_api_key" # Leave empty if no key is needed + +@app.on_message(filters.command(["search", "brave"])) +async def brave_search_handler(client, message): + chat_id = message.chat.id + + # Indicate typing action + await app.send_chat_action(chat_id, ChatAction.TYPING) + + # Retrieve the search query from the message + if len(message.command) > 1: + search_query = " ".join(message.command[1:]) + else: + await message.reply_text("Exᴀᴍᴘʟᴇ ᴜsᴀɢᴇ: /sᴇᴀʀᴄʜ Qᴜᴇsᴛɪᴏɴ ᴏʀ Tᴏᴘɪᴄ.") + return + + try: + # Brave Search API Endpoint + search_url = f"https://search.brave.com/api/v1/search?q={search_query}&source=web" + + # Make the request to Brave's API + response = requests.get(search_url, headers={"Authorization": f"Bearer {BRAVE_SEARCH_API_KEY}"}) + response.raise_for_status() + results = response.json() + + # Extract and format the results + if "web" in results and len(results["web"]["results"]) > 0: + reply_text = "**Top Search Results:**\n" + for index, result in enumerate(results["web"]["results"][:5], 1): # Limit to 5 results + reply_text += f"{index}. [{result['title']}]({result['url']})\n" + await message.reply_text(reply_text, disable_web_page_preview=True) + else: + await message.reply_text("No results found for your query. Please try with a different keyword.") + + except Exception as e: + await message.reply_text(f"» Error: {str(e)}. Please try again later.") diff --git a/DragMusic/plugins/plugins/dsong.py b/DragMusic/plugins/plugins/dsong.py new file mode 100644 index 0000000000000000000000000000000000000000..2e04e9e040bac54c614d8259d2c502203e26e53c --- /dev/null +++ b/DragMusic/plugins/plugins/dsong.py @@ -0,0 +1,146 @@ +import os +from datetime import timedelta +from pyrogram.enums import ParseMode + +import wget +from pyrogram import Client +from pyrogram import filters +from pyrogram.types import Message +from yt_dlp import YoutubeDL +from youtubesearchpython import VideosSearch +from DragMusic import app + + +@app.on_message(filters.command(["vsong"])) +async def vsong_cmd(client, message): + """Command to download and send a YouTube video.""" + if len(message.command) < 2: + return await message.reply_text( + "❌ Video not found,\nPlease enter the correct video title.", + ) + infomsg = await message.reply_text("🔍 Searching...", quote=False) + try: + search = VideosSearch(message.text.split(None, 1)[1], limit=1).result()["result"][0] + link = f"https://youtu.be/{search['id']}" + except Exception as error: + return await infomsg.edit(f"🔍 Searching...\n\n{error}") + + ydl_opts = { + "format": "bestvideo+bestaudio", + "outtmpl": "%(title)s.%(ext)s", + "merge_output_format": "mp4", + "cookiefile": "cookies.txt", + } + + try: + await infomsg.edit("Downloading video...") + with YoutubeDL(ydl_opts) as ydl: + info_dict = ydl.extract_info(link, download=True) + file_name = ydl.prepare_filename(info_dict) + title = info_dict.get("title", "Unknown") + duration = info_dict.get("duration", 0) + views = info_dict.get("view_count", 0) + channel = info_dict.get("uploader", "Unknown") + thumb = info_dict.get("thumbnail", None) + except Exception as error: + return await infomsg.edit(f"
Downloading video...\n\n{error}
") + + thumbnail_path = None + try: + if thumb: + thumbnail_path = wget.download(thumb) + await client.send_video( + message.chat.id, + video=file_name, + thumb=thumbnail_path, + file_name=title, + duration=duration, + supports_streaming=True, + caption=( + f"
Information {title}
\n\n" + f"
Name: {title}\n" + f" Duration: {timedelta(seconds=duration)}\n" + f" Views: {views:,}\n" + f" Channel: {channel}\n" + f" Link: YouTube
\n\n" + f"
⚡ Powered by: @haatsoja
" + ), + reply_to_message_id=message.id, + ) + finally: + if thumbnail_path and os.path.isfile(thumbnail_path): + os.remove(thumbnail_path) + if file_name and os.path.isfile(file_name): + os.remove(file_name) + await infomsg.delete() + + +@app.on_message(filters.command(["song"])) +async def song_cmd(client, message): + """Command to download and send a YouTube audio file.""" + if len(message.command) < 2: + return await message.reply_text( + "❌ Audio not found,\nPlease enter the correct audio title.", + ) + infomsg = await message.reply_text("🔍 Searching...", quote=False) + try: + search = VideosSearch(message.text.split(None, 1)[1], limit=1).result()["result"][0] + link = f"https://youtu.be/{search['id']}" + except Exception as error: + return await infomsg.edit(f"🔍 Searching...\n\n{error}") + + ydl_opts = { + "format": "bestaudio/best", + "outtmpl": "%(title)s.%(ext)s", + "postprocessors": [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "192", + } + ], + "cookiefile": "cookies.txt", + } + + try: + await infomsg.edit("Downloading audio...") + with YoutubeDL(ydl_opts) as ydl: + info_dict = ydl.extract_info(link, download=True) + file_name = ydl.prepare_filename(info_dict).replace(".webm", ".mp3") + title = info_dict.get("title", "Unknown") + duration = info_dict.get("duration", 0) + views = info_dict.get("view_count", 0) + channel = info_dict.get("uploader", "Unknown") + thumb = info_dict.get("thumbnail", None) + except Exception as error: + return await infomsg.edit(f"
Downloading audio...\n\n{error}
") + + thumbnail_path = None + try: + if thumb: + thumbnail_path = wget.download(thumb) + await client.send_audio( + message.chat.id, + audio=file_name, + thumb=thumbnail_path, + file_name=title, + performer=channel, + duration=duration, + caption=( + f"
Information {title}
\n\n" + f"
Name: {title}\n" + f" Duration: {timedelta(seconds=duration)}\n" + f" Views: {views:,}\n" + f" Channel: {channel}\n" + f" Link: YouTube
\n\n" + f"
⚡ Powered by: @haatsoja
" + ), + parse_mode=ParseMode.HTML, + reply_to_message_id=message.id, + ) + finally: + if thumbnail_path and os.path.isfile(thumbnail_path): + os.remove(thumbnail_path) + if file_name and os.path.isfile(file_name): + os.remove(file_name) + await infomsg.delete() diff --git a/DragMusic/plugins/plugins/getimg.py b/DragMusic/plugins/plugins/getimg.py new file mode 100644 index 0000000000000000000000000000000000000000..bbe96ae0993a2645f94e02f24a1b947356d0b674 --- /dev/null +++ b/DragMusic/plugins/plugins/getimg.py @@ -0,0 +1,59 @@ +import requests +from pyrogram import filters +from pyrogram.enums import ChatAction +from DragMusic import app + +# Getimg API key (replace with your actual key) +GETIMG_API_KEY = "key-ICLT6PNtwcDA5PKI7DmuKMXrueoKcDybWuHrXX1o9V8eszHCAOabBpvq2d7ZWewTa5A50ntiXEkDcMo1ewE5exp6LxuOAAr" +GETIMG_API_URL = "https://api.getimg.ai/v1/essential-v2/text-to-image" + +# Function to generate an image using Getimg API +def generate_image(prompt): + headers = { + "Authorization": f"Bearer {GETIMG_API_KEY}", + "Content-Type": "application/json" + } + + # Request payload to send to Getimg API + data = { + "prompt": prompt, + "style": "artistic", # You can change the style based on the available options + "width": 512, + "height": 512 + } + + # Make the API request + response = requests.post(GETIMG_API_URL, json=data, headers=headers) + + if response.status_code == 200: + # Extract image URL from the response + image_url = response.json().get("image_url") + return image_url + else: + return None + +# Command handler to generate an image +@app.on_message(filters.command("generate_image")) +async def generate_image_handler(client, message): + chat_id = message.chat.id + await app.send_chat_action(chat_id, ChatAction.TYPING) + + # Get the prompt from the user input + if len(message.command) > 1: + prompt = " ".join(message.command[1:]) + else: + await message.reply_text("Usage: /generate_image ") + return + + try: + # Call the function to generate the image via Getimg API + image_url = generate_image(prompt) + + if image_url: + # Send the generated image URL back to the user + await message.reply_photo(photo=image_url, caption=f"Generated image for prompt: {prompt}") + else: + await message.reply_text("Sorry, I couldn't generate the image. Please try again later.") + except Exception as e: + await message.reply_text(f"Error: {str(e)}. Please try again later.") + diff --git a/DragMusic/plugins/plugins/gpt.py b/DragMusic/plugins/plugins/gpt.py new file mode 100644 index 0000000000000000000000000000000000000000..31470a9e7961b75d9f37140ac08d5bc0c8d433ce --- /dev/null +++ b/DragMusic/plugins/plugins/gpt.py @@ -0,0 +1,74 @@ +import openai +from pyrogram import filters +from pyrogram.enums import ChatAction +from DragMusic import app + +# Set your OpenAI API key +openai.api_key = "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" +# To store conversations (per user basis, using a dictionary for simplicity) +user_conversations = {} + +@app.on_message(filters.command(["chatgpt", "gpt"])) # Add support for "gpt" +async def ask_handler(client, message): + user_id = message.from_user.id + chat_id = message.chat.id + + # Indicate typing action + await app.send_chat_action(chat_id, ChatAction.TYPING) + + # Retrieve the user's input + if len(message.command) > 1: + user_input = " ".join(message.command[1:]) + elif message.reply_to_message and message.reply_to_message.text: + user_input = message.reply_to_message.text + else: + await message.reply_text("Exᴀᴍᴘʟᴇ ᴜsᴀɢᴇ: /ᴄʜᴀᴛɢᴘᴛ Hᴏᴡ ᴅᴏᴇs ʀᴇᴄᴜʀsɪᴏɴ ᴡᴏʀᴋ?") + return + + # Initialize the conversation history if it's a new user + if user_id not in user_conversations: + user_conversations[user_id] = [ + {"role": "system", "content": "You are a helpful assistant who can answer any questions."} + ] + + # Append the user's input to the conversation + user_conversations[user_id].append({"role": "user", "content": user_input}) + + try: + # Call the OpenAI API with the full conversation history + response = openai.ChatCompletion.create( + model="gpt-3.5-turbo", # Use "gpt-4" if needed + messages=user_conversations[user_id] + ) + + # Get the assistant's response + assistant_response = response["choices"][0]["message"]["content"].strip() + + # Append the assistant's response to the conversation history + user_conversations[user_id].append({"role": "assistant", "content": assistant_response}) + + # Send the assistant's response to the user + await message.reply_text(assistant_response, quote=True) + + except Exception as e: + await message.reply_text(f"**» Error:** {str(e)}. Please try again later.") + +@app.on_message(filters.command(["reset"])) +async def reset_handler(client, message): + user_id = message.from_user.id + if user_id in user_conversations: + user_conversations.pop(user_id) + await message.reply_text("Cᴏɴᴠᴇʀsᴀᴛɪᴏɴ ᴄᴏɴᴛᴇxᴛ ʜᴀs ʙᴇᴇɴ ʀᴇsᴇᴛ.") + +@app.on_message(filters.command(["setrole"])) +async def set_role_handler(client, message): + user_id = message.from_user.id + if len(message.command) > 1: + role_content = " ".join(message.command[1:]) + user_conversations[user_id] = [ + {"role": "system", "content": role_content} + ] + await message.reply_text(f"Sʏsᴛᴇᴍ ʀᴏʟᴇ sᴇᴛ ᴛᴏ: {role_content}") + else: + await message.reply_text("Exᴀᴍᴘʟᴇ ᴜsᴀɢᴇ: /sᴇᴛʀᴏʟᴇ Yᴏᴜ ᴀʀᴇ ᴀ ғʀɪᴇɴᴅʟʏ AI.") + diff --git a/DragMusic/plugins/plugins/sgb.py b/DragMusic/plugins/plugins/sgb.py new file mode 100644 index 0000000000000000000000000000000000000000..01cbc39c09d2f7b1179aaaeb6f73afec3a3b7529 --- /dev/null +++ b/DragMusic/plugins/plugins/sgb.py @@ -0,0 +1,68 @@ +import asyncio +import random +from pyrogram import Client, filters +from pyrogram.types import Message +from pyrogram.raw.functions.messages import DeleteHistory +from DragMusic import userbot as us, app +from DragMusic.core.userbot import assistants + +@app.on_message(filters.command(["sg", "sgb"], prefixes=["/", "!", ".", "-"])) +async def sg(client: Client, message: Message): + if not message: + return + + # Determine target user from command or reply + if message.reply_to_message: + target = message.reply_to_message.from_user.id + elif len(message.command) > 1: + target = message.command[1] # Extract the username or ID from the command + else: + return await message.reply("ᴘʀᴏᴠɪᴅᴇ ᴀ ᴜsᴇʀɴᴀᴍᴇ, ᴜsᴇʀ ɪᴅ, ᴏʀ ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴜsᴇʀ's ᴍᴇssᴀɢᴇ.") + + # Indicate processing + lol = await message.reply("ᴘʀᴏᴄᴇssɪɴɢ...") + for i in range(3): + await asyncio.sleep(0.5) + await lol.edit("ᴘʀᴏᴄᴇssɪɴɢ" + "." * (i + 1) + "") + + try: + # Resolve the target user + user = await client.get_users(target) + except Exception as e: + return await lol.edit(f"Invalid user: {e}") + + # Pick a bot randomly + bots = ["sangmata_bot", "sangmata_beta_bot"] + sg_bot = random.choice(bots) + + # Select the userbot + if 1 in assistants: + ubot = us.one + else: + return await lol.edit("No available assistant bot found.") + + try: + # Send the ID or username to the Sangmata bot + bot_message = await ubot.send_message(sg_bot, f"{user.id}") + await bot_message.delete() # Delete the sent message to avoid clutter + except Exception as e: + return await lol.edit(f"Error while sending message to Sangmata bot: {e}") + + await asyncio.sleep(1) + + # Retrieve Sangmata's response + async for stalk in ubot.search_messages(sg_bot): + if stalk.text: + await message.reply(f"{stalk.text}") + break + else: + await message.reply("ᴛʜᴇ ʙᴏᴛ ɪs ᴜɴʀᴇsᴘᴏɴsɪᴠᴇ.") + + # Delete Sangmata's chat history for privacy + try: + user_info = await ubot.resolve_peer(sg_bot) + await ubot.send(DeleteHistory(peer=user_info, max_id=0, revoke=True)) + except Exception: + pass + + await lol.delete() diff --git a/DragMusic/plugins/plugins/web.py b/DragMusic/plugins/plugins/web.py new file mode 100644 index 0000000000000000000000000000000000000000..e549388ccc006bd78bf43faea1adad3b870d6a11 --- /dev/null +++ b/DragMusic/plugins/plugins/web.py @@ -0,0 +1,35 @@ +from pyrogram import filters +from pyrogram.enums import ChatAction, ParseMode +from DragMusic import app +import aiohttp + +# Function to fetch data from the web API +async def fetch_data_from_api(question): + url = "https://app-paal-chat-1003522928061.us-east1.run.app/api/chat/web" + headers = {"Content-Type": "application/json", "Accept": "application/json"} + payload = {"prompt": question, "bid": "edwo6pg1"} + + async with aiohttp.ClientSession() as session: + async with session.post(url, headers=headers, json=payload) as response: + data = await response.json() + return data.get("answer", "No response received.") + +# Command handler for /web +@app.on_message(filters.command("web")) +async def web_command(client, message): + chat_id = message.chat.id + user_id = message.from_user.id + + # Indicate typing action + await app.send_chat_action(chat_id, ChatAction.TYPING) + + if len(message.command) < 2: + await message.reply_text("Exᴀᴍᴘʟᴇ ᴜsᴀɢᴇ: /web [your search!]") + return + + question = " ".join(message.command[1:]) # Get the query from command arguments + response = await fetch_data_from_api(question) + + formatted_response = f"
{response}
" + + await message.reply_text(formatted_response, parse_mode=ParseMode.HTML) diff --git a/DragMusic/plugins/sudo/autoend.py b/DragMusic/plugins/sudo/autoend.py new file mode 100644 index 0000000000000000000000000000000000000000..e39a7ca5210439ec87601120f6e2b8f16cd6219b --- /dev/null +++ b/DragMusic/plugins/sudo/autoend.py @@ -0,0 +1,24 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import autoend_off, autoend_on + + +@app.on_message(filters.command("autoend") & SUDOERS) +async def auto_end_stream(_, message: Message): + usage = "ᴇxᴀᴍᴘʟᴇ :\n\n/autoend [ᴇɴᴀʙʟᴇ | ᴅɪsᴀʙʟᴇ]" + if len(message.command) != 2: + return await message.reply_text(usage) + state = message.text.split(None, 1)[1].strip().lower() + if state == "enable": + await autoend_on() + await message.reply_text( + "» ᴀᴜᴛᴏ ᴇɴᴅ sᴛʀᴇᴀᴍ ᴇɴᴀʙʟᴇᴅ.\n\nᴀssɪsᴛᴀɴᴛ ᴡɪʟʟ ᴀᴜᴛᴏᴍᴀᴛɪᴄᴀʟʟʏ ʟᴇᴀᴠᴇ ᴛʜᴇ ᴠɪᴅᴇᴏᴄʜᴀᴛ ᴀғᴛᴇʀ ғᴇᴡ ᴍɪɴs ᴡʜᴇɴ ɴᴏ ᴏɴᴇ ɪs ʟɪsᴛᴇɴɪɴɢ." + ) + elif state == "disable": + await autoend_off() + await message.reply_text("» ᴀᴜᴛᴏ ᴇɴᴅ sᴛʀᴇᴀᴍ ᴅɪsᴀʙʟᴇᴅ.") + else: + await message.reply_text(usage) diff --git a/DragMusic/plugins/sudo/blchat.py b/DragMusic/plugins/sudo/blchat.py new file mode 100644 index 0000000000000000000000000000000000000000..43bc94da1b40031d161df85f92ea9e7bafa9880f --- /dev/null +++ b/DragMusic/plugins/sudo/blchat.py @@ -0,0 +1,61 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import blacklist_chat, blacklisted_chats, whitelist_chat +from DragMusic.utils.decorators.language import language +from config import BANNED_USERS + + +@app.on_message(filters.command(["blchat", "blacklistchat"]) & SUDOERS) +@language +async def blacklist_chat_func(client, message: Message, _): + if len(message.command) != 2: + return await message.reply_text(_["black_1"]) + chat_id = int(message.text.strip().split()[1]) + if chat_id in await blacklisted_chats(): + return await message.reply_text(_["black_2"]) + blacklisted = await blacklist_chat(chat_id) + if blacklisted: + await message.reply_text(_["black_3"]) + else: + await message.reply_text(_["black_9"]) + try: + await app.leave_chat(chat_id) + except: + pass + + +@app.on_message( + filters.command(["whitelistchat", "unblacklistchat", "unblchat"]) & SUDOERS +) +@language +async def white_funciton(client, message: Message, _): + if len(message.command) != 2: + return await message.reply_text(_["black_4"]) + chat_id = int(message.text.strip().split()[1]) + if chat_id not in await blacklisted_chats(): + return await message.reply_text(_["black_5"]) + whitelisted = await whitelist_chat(chat_id) + if whitelisted: + return await message.reply_text(_["black_6"]) + await message.reply_text(_["black_9"]) + + +@app.on_message(filters.command(["blchats", "blacklistedchats"]) & ~BANNED_USERS) +@language +async def all_chats(client, message: Message, _): + text = _["black_7"] + j = 0 + for count, chat_id in enumerate(await blacklisted_chats(), 1): + try: + title = (await app.get_chat(chat_id)).title + except: + title = "ᴘʀɪᴠᴀᴛᴇ ᴄʜᴀᴛ" + j = 1 + text += f"{count}. {title}[{chat_id}]\n" + if j == 0: + await message.reply_text(_["black_8"].format(app.mention)) + else: + await message.reply_text(text) diff --git a/DragMusic/plugins/sudo/block.py b/DragMusic/plugins/sudo/block.py new file mode 100644 index 0000000000000000000000000000000000000000..1d32e969ce873994b65222794acb1f5beceeb477 --- /dev/null +++ b/DragMusic/plugins/sudo/block.py @@ -0,0 +1,59 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import add_gban_user, remove_gban_user +from DragMusic.utils.decorators.language import language +from DragMusic.utils.extraction import extract_user +from config import BANNED_USERS + + +@app.on_message(filters.command(["block"]) & SUDOERS) +@language +async def useradd(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + if user.id in BANNED_USERS: + return await message.reply_text(_["block_1"].format(user.mention)) + await add_gban_user(user.id) + BANNED_USERS.add(user.id) + await message.reply_text(_["block_2"].format(user.mention)) + + +@app.on_message(filters.command(["unblock"]) & SUDOERS) +@language +async def userdel(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + if user.id not in BANNED_USERS: + return await message.reply_text(_["block_3"].format(user.mention)) + await remove_gban_user(user.id) + BANNED_USERS.remove(user.id) + await message.reply_text(_["block_4"].format(user.mention)) + + +@app.on_message(filters.command(["blocked", "blockedusers", "blusers"]) & SUDOERS) +@language +async def sudoers_list(client, message: Message, _): + if not BANNED_USERS: + return await message.reply_text(_["block_5"]) + mystic = await message.reply_text(_["block_6"]) + msg = _["block_7"] + count = 0 + for users in BANNED_USERS: + try: + user = await app.get_users(users) + user = user.first_name if not user.mention else user.mention + count += 1 + except: + continue + msg += f"{count}➤ {user}\n" + if count == 0: + return await mystic.edit_text(_["block_5"]) + else: + return await mystic.edit_text(msg) diff --git a/DragMusic/plugins/sudo/gban.py b/DragMusic/plugins/sudo/gban.py new file mode 100644 index 0000000000000000000000000000000000000000..fa9e21a9fd7db589fa5701e109b470aea6be61e3 --- /dev/null +++ b/DragMusic/plugins/sudo/gban.py @@ -0,0 +1,136 @@ +import asyncio +from pyrogram import filters +from pyrogram.errors import FloodWait +from pyrogram.types import Message +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils import get_readable_time +from DragMusic.utils.database import ( + add_banned_user, + get_banned_count, + get_banned_users, + get_served_chats, + is_banned_user, + remove_banned_user, + is_on_off +) +from DragMusic.utils.decorators.language import language +from DragMusic.utils.extraction import extract_user +from config import BANNED_USERS, LOGGER_ID +@app.on_message(filters.command(["gban", "globalban"]) & SUDOERS) +@language +async def global_ban(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + if user.id == message.from_user.id: + return await message.reply_text(_["gban_1"]) + elif user.id == app.id: + return await message.reply_text(_["gban_2"]) + elif user.id in SUDOERS: + return await message.reply_text(_["gban_3"]) + is_gbanned = await is_banned_user(user.id) + if is_gbanned: + return await message.reply_text(_["gban_4"].format(user.mention)) + if user.id not in BANNED_USERS: + BANNED_USERS.add(user.id) + served_chats = [] + chats = await get_served_chats() + for chat in chats: + served_chats.append(int(chat["chat_id"])) + time_expected = get_readable_time(len(served_chats)) + mystic = await message.reply_text(_["gban_5"].format(user.mention, time_expected)) + number_of_chats = 0 + for chat_id in served_chats: + try: + await app.ban_chat_member(chat_id, user.id) + number_of_chats += 1 + except FloodWait as fw: + await asyncio.sleep(int(fw.value)) + except: + continue + await add_banned_user(user.id) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} has globally banned {user.mention}.\n" + f"User ID: {user.id}\n" + f"Banned in {number_of_chats} chats.", + message_thread_id=12357 + ) + await message.reply_text( + _["gban_6"].format( + app.mention, + message.chat.title, + message.chat.id, + user.mention, + user.id, + message.from_user.mention, + number_of_chats, + ) + ) + await mystic.delete() + +@app.on_message(filters.command(["ungban"]) & SUDOERS) +@language +async def global_un(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + is_gbanned = await is_banned_user(user.id) + if not is_gbanned: + return await message.reply_text(_["gban_7"].format(user.mention)) + if user.id in BANNED_USERS: + BANNED_USERS.remove(user.id) + served_chats = [] + chats = await get_served_chats() + for chat in chats: + served_chats.append(int(chat["chat_id"])) + time_expected = get_readable_time(len(served_chats)) + mystic = await message.reply_text(_["gban_8"].format(user.mention, time_expected)) + number_of_chats = 0 + for chat_id in served_chats: + try: + await app.unban_chat_member(chat_id, user.id) + number_of_chats += 1 + except FloodWait as fw: + await asyncio.sleep(int(fw.value)) + except: + continue + await remove_banned_user(user.id) + if await is_on_off(2): + await app.send_message( + chat_id=LOGGER_ID, + text=f"{message.from_user.mention} has unbanned {user.mention}.\n" + f"User ID: {user.id}\n" + f"Unbanned from {number_of_chats} chats.", + message_thread_id=12357 + ) + await message.reply_text(_["gban_9"].format(user.mention, number_of_chats)) + await mystic.delete() + +@app.on_message(filters.command(["gbannedusers", "gbanlist"]) & SUDOERS) +@language +async def gbanned_list(client, message: Message, _): + counts = await get_banned_count() + if counts == 0: + return await message.reply_text(_["gban_10"]) + mystic = await message.reply_text(_["gban_11"]) + msg = _["gban_12"] + count = 0 + users = await get_banned_users() + for user_id in users: + count += 1 + try: + user = await app.get_users(user_id) + user = user.first_name if not user.mention else user.mention + msg += f"{count}➤ {user}\n" + except Exception: + msg += f"{count}➤ {user_id}\n" + continue + if count == 0: + return await mystic.edit_text(_["gban_10"]) + else: + return await mystic.edit_text(msg) diff --git a/DragMusic/plugins/sudo/logger.py b/DragMusic/plugins/sudo/logger.py new file mode 100644 index 0000000000000000000000000000000000000000..61eafd462da1136601264c554aedf2074de5586f --- /dev/null +++ b/DragMusic/plugins/sudo/logger.py @@ -0,0 +1,23 @@ +from pyrogram import filters + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import add_off, add_on +from DragMusic.utils.decorators.language import language + + +@app.on_message(filters.command(["logger"]) & SUDOERS) +@language +async def logger(client, message, _): + usage = _["log_1"] + if len(message.command) != 2: + return await message.reply_text(usage) + state = message.text.split(None, 1)[1].strip().lower() + if state == "enable": + await add_on(2) + await message.reply_text(_["log_2"]) + elif state == "disable": + await add_off(2) + await message.reply_text(_["log_3"]) + else: + await message.reply_text(usage) diff --git a/DragMusic/plugins/sudo/maintenance.py b/DragMusic/plugins/sudo/maintenance.py new file mode 100644 index 0000000000000000000000000000000000000000..b2d1c3d7860eeb25c7bdfd6e358476bed0a30614 --- /dev/null +++ b/DragMusic/plugins/sudo/maintenance.py @@ -0,0 +1,39 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import ( + get_lang, + is_maintenance, + maintenance_off, + maintenance_on, +) +from strings import get_string + + +@app.on_message(filters.command(["maintenance"]) & SUDOERS) +async def maintenance(client, message: Message): + try: + language = await get_lang(message.chat.id) + _ = get_string(language) + except: + _ = get_string("en") + usage = _["maint_1"] + if len(message.command) != 2: + return await message.reply_text(usage) + state = message.text.split(None, 1)[1].strip().lower() + if state == "enable": + if await is_maintenance() is False: + await message.reply_text(_["maint_4"]) + else: + await maintenance_on() + await message.reply_text(_["maint_2"].format(app.mention)) + elif state == "disable": + if await is_maintenance() is False: + await maintenance_off() + await message.reply_text(_["maint_3"].format(app.mention)) + else: + await message.reply_text(_["maint_5"]) + else: + await message.reply_text(usage) diff --git a/DragMusic/plugins/sudo/restart.py b/DragMusic/plugins/sudo/restart.py new file mode 100644 index 0000000000000000000000000000000000000000..07eb5d88321c1be971b4286961d65e2e18baa363 --- /dev/null +++ b/DragMusic/plugins/sudo/restart.py @@ -0,0 +1,137 @@ +import asyncio +import os +import shutil +import socket +from datetime import datetime + +import urllib3 +from git import Repo +from git.exc import GitCommandError, InvalidGitRepositoryError +from pyrogram import filters + +import config +from DragMusic import app +from DragMusic.misc import HAPP, SUDOERS, XCB +from DragMusic.utils.database import ( + get_active_chats, + remove_active_chat, + remove_active_video_chat, +) +from DragMusic.utils.decorators.language import language +from DragMusic.utils.pastebin import DragBin + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + +async def is_heroku(): + return "heroku" in socket.getfqdn() + + +@app.on_message(filters.command(["getlog", "logs", "getlogs"]) & SUDOERS) +@language +async def log_(client, message, _): + try: + await message.reply_document(document="log.txt") + except: + await message.reply_text(_["server_1"]) + + +@app.on_message(filters.command(["update", "gitpull"]) & SUDOERS) +@language +async def update_(client, message, _): + if await is_heroku(): + if HAPP is None: + return await message.reply_text(_["server_2"]) + response = await message.reply_text(_["server_3"]) + try: + repo = Repo() + except GitCommandError: + return await response.edit(_["server_4"]) + except InvalidGitRepositoryError: + return await response.edit(_["server_5"]) + to_exc = f"git fetch origin {config.UPSTREAM_BRANCH} &> /dev/null" + os.system(to_exc) + await asyncio.sleep(7) + verification = "" + REPO_ = repo.remotes.origin.url.split(".git")[0] + for checks in repo.iter_commits(f"HEAD..origin/{config.UPSTREAM_BRANCH}"): + verification = str(checks.count()) + if verification == "": + return await response.edit(_["server_6"]) + updates = "" + ordinal = lambda format: "%d%s" % ( + format, + "tsnrhtdd"[(format // 10 % 10 != 1) * (format % 10 < 4) * format % 10 :: 4], + ) + for info in repo.iter_commits(f"HEAD..origin/{config.UPSTREAM_BRANCH}"): + updates += f"➣ #{info.count()}: {info.summary} ʙʏ -> {info.author}\n\t\t\t\t➥ ᴄᴏᴍᴍɪᴛᴇᴅ ᴏɴ : {ordinal(int(datetime.fromtimestamp(info.committed_date).strftime('%d')))} {datetime.fromtimestamp(info.committed_date).strftime('%b')}, {datetime.fromtimestamp(info.committed_date).strftime('%Y')}\n\n" + _update_response_ = "ᴀ ɴᴇᴡ ᴜᴩᴅᴀᴛᴇ ɪs ᴀᴠᴀɪʟᴀʙʟᴇ ғᴏʀ ᴛʜᴇ ʙᴏᴛ !\n\n➣ ᴩᴜsʜɪɴɢ ᴜᴩᴅᴀᴛᴇs ɴᴏᴡ\n\nᴜᴩᴅᴀᴛᴇs:\n\n" + _final_updates_ = _update_response_ + updates + if len(_final_updates_) > 4096: + url = await DragBin(updates) + nrs = await response.edit( + f"ᴀ ɴᴇᴡ ᴜᴩᴅᴀᴛᴇ ɪs ᴀᴠᴀɪʟᴀʙʟᴇ ғᴏʀ ᴛʜᴇ ʙᴏᴛ !\n\n➣ ᴩᴜsʜɪɴɢ ᴜᴩᴅᴀᴛᴇs ɴᴏᴡ\n\nᴜᴩᴅᴀᴛᴇs :\n\nᴄʜᴇᴄᴋ ᴜᴩᴅᴀᴛᴇs" + ) + else: + nrs = await response.edit(_final_updates_, disable_web_page_preview=True) + os.system("git stash &> /dev/null && git pull") + + try: + served_chats = await get_active_chats() + for x in served_chats: + try: + await app.send_message( + chat_id=int(x), + text=_["server_8"].format(app.mention), + ) + await remove_active_chat(x) + await remove_active_video_chat(x) + except: + pass + await response.edit(f"{nrs.text}\n\n{_['server_7']}") + except: + pass + + if await is_heroku(): + try: + os.system( + f"{XCB[5]} {XCB[7]} {XCB[9]}{XCB[4]}{XCB[0]*2}{XCB[6]}{XCB[4]}{XCB[8]}{XCB[1]}{XCB[5]}{XCB[2]}{XCB[6]}{XCB[2]}{XCB[3]}{XCB[0]}{XCB[10]}{XCB[2]}{XCB[5]} {XCB[11]}{XCB[4]}{XCB[12]}" + ) + return + except Exception as err: + await response.edit(f"{nrs.text}\n\n{_['server_9']}") + return await app.send_message( + chat_id=config.LOGGER_ID, + text=_["server_10"].format(err), + ) + else: + os.system("pip3 install -r requirements.txt") + os.system(f"kill -9 {os.getpid()} && bash start") + exit() + + +@app.on_message(filters.command(["sleep"]) & SUDOERS) +async def restart_(_, message): + response = await message.reply_text("ʀᴇsᴛᴀʀᴛɪɴɢ...") + ac_chats = await get_active_chats() + for x in ac_chats: + try: + await app.send_message( + chat_id=int(x), + text=f"{app.mention} ɪs ʀᴇsᴛᴀʀᴛɪɴɢ...\n\nʏᴏᴜ ᴄᴀɴ sᴛᴀʀᴛ ᴩʟᴀʏɪɴɢ ᴀɢᴀɪɴ ᴀғᴛᴇʀ 15-20 sᴇᴄᴏɴᴅs.", + ) + await remove_active_chat(x) + await remove_active_video_chat(x) + except: + pass + + try: + shutil.rmtree("downloads") + shutil.rmtree("raw_files") + shutil.rmtree("cache") + except: + pass + await response.edit_text( + "» ʀᴇsᴛᴀʀᴛ ᴘʀᴏᴄᴇss sᴛᴀʀᴛᴇᴅ, ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ ғᴏʀ ғᴇᴡ sᴇᴄᴏɴᴅs ᴜɴᴛɪʟ ᴛʜᴇ ʙᴏᴛ sᴛᴀʀᴛs..." + ) + os.system(f"kill -9 {os.getpid()} && bash start") diff --git a/DragMusic/plugins/sudo/sudoers.py b/DragMusic/plugins/sudo/sudoers.py new file mode 100644 index 0000000000000000000000000000000000000000..4550ec953818d5822a374a2b511e9603cabe16c6 --- /dev/null +++ b/DragMusic/plugins/sudo/sudoers.py @@ -0,0 +1,71 @@ +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import add_sudo, remove_sudo +from DragMusic.utils.decorators.language import language +from DragMusic.utils.extraction import extract_user +from DragMusic.utils.inline import close_markup +from config import BANNED_USERS, OWNER_ID + + +@app.on_message(filters.command(["addsudo"]) & filters.user(OWNER_ID)) +@language +async def useradd(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + if user.id in SUDOERS: + return await message.reply_text(_["sudo_1"].format(user.mention)) + added = await add_sudo(user.id) + if added: + SUDOERS.add(user.id) + await message.reply_text(_["sudo_2"].format(user.mention)) + else: + await message.reply_text(_["sudo_8"]) + + +@app.on_message(filters.command(["delsudo", "rmsudo"]) & filters.user(OWNER_ID)) +@language +async def userdel(client, message: Message, _): + if not message.reply_to_message: + if len(message.command) != 2: + return await message.reply_text(_["general_1"]) + user = await extract_user(message) + if user.id not in SUDOERS: + return await message.reply_text(_["sudo_3"].format(user.mention)) + removed = await remove_sudo(user.id) + if removed: + SUDOERS.remove(user.id) + await message.reply_text(_["sudo_4"].format(user.mention)) + else: + await message.reply_text(_["sudo_8"]) + + +@app.on_message(filters.command(["sudolist", "listsudo", "sudoers"]) & ~BANNED_USERS) +@language +async def sudoers_list(client, message: Message, _): + text = _["sudo_5"] + user = await app.get_users(OWNER_ID) + user = user.first_name if not user.mention else user.mention + text += f"1➤ {user}\n" + count = 0 + smex = 0 + for user_id in SUDOERS: + if user_id != OWNER_ID: + try: + user = await app.get_users(user_id) + user = user.first_name if not user.mention else user.mention + if smex == 0: + smex += 1 + text += _["sudo_6"] + count += 1 + text += f"{count}➤ {user}\n" + except: + continue + if not text: + await message.reply_text(_["sudo_7"]) + else: + await message.reply_text(text, reply_markup=close_markup(_)) diff --git a/DragMusic/plugins/tools/active.py b/DragMusic/plugins/tools/active.py new file mode 100644 index 0000000000000000000000000000000000000000..1eb1c016bd184174ee956c69726642f2367130d7 --- /dev/null +++ b/DragMusic/plugins/tools/active.py @@ -0,0 +1,81 @@ +from pyrogram import filters,Client +from pyrogram.types import Message,InlineKeyboardMarkup, InlineKeyboardButton +from unidecode import unidecode + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import ( + get_active_chats, + get_active_video_chats, + remove_active_chat, + remove_active_video_chat, +) + + +@app.on_message(filters.command(["activevc", "activevoice"]) & SUDOERS) +async def activevc(_, message: Message): + mystic = await message.reply_text("» ɢᴇᴛᴛɪɴɢ ᴀᴄᴛɪᴠᴇ ᴠᴏɪᴄᴇ ᴄʜᴀᴛs ʟɪsᴛ...") + served_chats = await get_active_chats() + text = "" + j = 0 + for x in served_chats: + try: + title = (await app.get_chat(x)).title + except: + await remove_active_chat(x) + continue + try: + if (await app.get_chat(x)).username: + user = (await app.get_chat(x)).username + text += f"{j + 1}. {unidecode(title).upper()} [{x}]\n" + else: + text += ( + f"{j + 1}. {unidecode(title).upper()} [{x}]\n" + ) + j += 1 + except: + continue + if not text: + await mystic.edit_text(f"» ɴᴏ ᴀᴄᴛɪᴠᴇ ᴠᴏɪᴄᴇ ᴄʜᴀᴛs ᴏɴ {app.mention}.") + else: + await mystic.edit_text( + f"» ʟɪsᴛ ᴏғ ᴄᴜʀʀᴇɴᴛʟʏ ᴀᴄᴛɪᴠᴇ ᴠᴏɪᴄᴇ ᴄʜᴀᴛs :\n\n{text}", + disable_web_page_preview=True, + ) + + +@app.on_message(filters.command(["activev", "activevideo"]) & SUDOERS) +async def activevi_(_, message: Message): + mystic = await message.reply_text("» ɢᴇᴛᴛɪɴɢ ᴀᴄᴛɪᴠᴇ ᴠɪᴅᴇᴏ ᴄʜᴀᴛs ʟɪsᴛ...") + served_chats = await get_active_video_chats() + text = "" + j = 0 + for x in served_chats: + try: + title = (await app.get_chat(x)).title + except: + await remove_active_video_chat(x) + continue + try: + if (await app.get_chat(x)).username: + user = (await app.get_chat(x)).username + text += f"{j + 1}. {unidecode(title).upper()} [{x}]\n" + else: + text += ( + f"{j + 1}. {unidecode(title).upper()} [{x}]\n" + ) + j += 1 + except: + continue + if not text: + await mystic.edit_text(f"» ɴᴏ ᴀᴄᴛɪᴠᴇ ᴠɪᴅᴇᴏ ᴄʜᴀᴛs ᴏɴ {app.mention}.") + else: + await mystic.edit_text( + f"» ʟɪsᴛ ᴏғ ᴄᴜʀʀᴇɴᴛʟʏ ᴀᴄᴛɪᴠᴇ ᴠɪᴅᴇᴏ ᴄʜᴀᴛs :\n\n{text}", + disable_web_page_preview=True, + ) +@app.on_message(filters.command(["ac","av"]) & SUDOERS) +async def start(client: Client, message: Message): + ac_audio = str(len(await get_active_chats())) + ac_video = str(len(await get_active_video_chats())) + await message.reply_text(f"✫ ᴀᴄᴛɪᴠᴇ ᴄʜᴀᴛs ɪɴғᴏ :\n\nᴠᴏɪᴄᴇ : {ac_audio}\nᴠɪᴅᴇᴏ : {ac_video}", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton('✯ ᴄʟᴏsᴇ ✯', callback_data=f"close")]])) diff --git a/DragMusic/plugins/tools/afk.py b/DragMusic/plugins/tools/afk.py new file mode 100644 index 0000000000000000000000000000000000000000..0fe31f61642449974e58d799c6f3e04179bdb513 --- /dev/null +++ b/DragMusic/plugins/tools/afk.py @@ -0,0 +1,381 @@ +import time, re +from config import BOT_USERNAME +from pyrogram.enums import MessageEntityType +from pyrogram import filters +from pyrogram.types import Message +from DragMusic import app +from DragMusic.Mongo.readable_time import get_readable_time +from DragMusic.Mongo.afkdb import add_afk, is_afk, remove_afk + + + +@app.on_message(filters.command(["afk", "brb"], prefixes=["/", "!"])) +async def active_afk(_, message: Message): + if message.sender_chat: + return + user_id = message.from_user.id + verifier, reasondb = await is_afk(user_id) + if verifier: + await remove_afk(user_id) + try: + afktype = reasondb["type"] + timeafk = reasondb["time"] + data = reasondb["data"] + reasonafk = reasondb["reason"] + seenago = get_readable_time((int(time.time() - timeafk))) + if afktype == "text": + send = await message.reply_text( + f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}", + disable_web_page_preview=True, + ) + if afktype == "text_reason": + send = await message.reply_text( + f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}", + disable_web_page_preview=True, + ) + if afktype == "animation": + if str(reasonafk) == "None": + send = await message.reply_animation( + data, + caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ for {seenago}", + ) + else: + send = await message.reply_animation( + data, + caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ for {seenago}\n\nReason: {reasonafk}", + ) + if afktype == "photo": + if str(reasonafk) == "None": + send = await message.reply_photo( + photo=f"downloads/{user_id}.jpg", + caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}", + ) + else: + send = await message.reply_photo( + photo=f"downloads/{user_id}.jpg", + caption=f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}", + ) + except Exception: + send = await message.reply_text( + f"{message.from_user.first_name} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ", + disable_web_page_preview=True, + ) + + if len(message.command) == 1 and not message.reply_to_message: + details = { + "type": "text", + "time": time.time(), + "data": None, + "reason": None, + } + elif len(message.command) > 1 and not message.reply_to_message: + _reason = (message.text.split(None, 1)[1].strip())[:100] + details = { + "type": "text_reason", + "time": time.time(), + "data": None, + "reason": _reason, + } + elif len(message.command) == 1 and message.reply_to_message.animation: + _data = message.reply_to_message.animation.file_id + details = { + "type": "animation", + "time": time.time(), + "data": _data, + "reason": None, + } + elif len(message.command) > 1 and message.reply_to_message.animation: + _data = message.reply_to_message.animation.file_id + _reason = (message.text.split(None, 1)[1].strip())[:100] + details = { + "type": "animation", + "time": time.time(), + "data": _data, + "reason": _reason, + } + elif len(message.command) == 1 and message.reply_to_message.photo: + await app.download_media( + message.reply_to_message, file_name=f"{user_id}.jpg" + ) + details = { + "type": "photo", + "time": time.time(), + "data": None, + "reason": None, + } + elif len(message.command) > 1 and message.reply_to_message.photo: + await app.download_media( + message.reply_to_message, file_name=f"{user_id}.jpg" + ) + _reason = message.text.split(None, 1)[1].strip() + details = { + "type": "photo", + "time": time.time(), + "data": None, + "reason": _reason, + } + elif len(message.command) == 1 and message.reply_to_message.sticker: + if message.reply_to_message.sticker.is_animated: + details = { + "type": "text", + "time": time.time(), + "data": None, + "reason": None, + } + else: + await app.download_media( + message.reply_to_message, file_name=f"{user_id}.jpg" + ) + details = { + "type": "photo", + "time": time.time(), + "data": None, + "reason": None, + } + elif len(message.command) > 1 and message.reply_to_message.sticker: + _reason = (message.text.split(None, 1)[1].strip())[:100] + if message.reply_to_message.sticker.is_animated: + details = { + "type": "text_reason", + "time": time.time(), + "data": None, + "reason": _reason, + } + else: + await app.download_media( + message.reply_to_message, file_name=f"{user_id}.jpg" + ) + details = { + "type": "photo", + "time": time.time(), + "data": None, + "reason": _reason, + } + else: + details = { + "type": "text", + "time": time.time(), + "data": None, + "reason": None, + } + + await add_afk(user_id, details) + await message.reply_text(f"{message.from_user.first_name} ɪs ɴᴏᴡ ᴀғᴋ!") + + + + +chat_watcher_group = 1 + + +@app.on_message( + ~filters.me & ~filters.bot & ~filters.via_bot, + group=chat_watcher_group, +) +async def chat_watcher_func(_, message): + if message.sender_chat: + return + userid = message.from_user.id + user_name = message.from_user.first_name + if message.entities: + possible = ["/afk", f"/afk@{BOT_USERNAME}"] + message_text = message.text or message.caption + for entity in message.entities: + if entity.type == MessageEntityType.BOT_COMMAND: + if (message_text[0 : 0 + entity.length]).lower() in possible: + return + + msg = "" + replied_user_id = 0 + + + + verifier, reasondb = await is_afk(userid) + if verifier: + await remove_afk(userid) + try: + afktype = reasondb["type"] + timeafk = reasondb["time"] + data = reasondb["data"] + reasonafk = reasondb["reason"] + seenago = get_readable_time((int(time.time() - timeafk))) + if afktype == "text": + msg += f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\n" + if afktype == "text_reason": + msg += f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}\n\n" + if afktype == "animation": + if str(reasonafk) == "None": + send = await message.reply_animation( + data, + caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\n", + ) + else: + send = await message.reply_animation( + data, + caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}\n\n", + ) + if afktype == "photo": + if str(reasonafk) == "None": + send = await message.reply_photo( + photo=f"downloads/{userid}.jpg", + caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\n", + ) + else: + send = await message.reply_photo( + photo=f"downloads/{userid}.jpg", + caption=f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ ᴀɴᴅ ᴡᴀs ᴀᴡᴀʏ ғᴏʀ {seenago}\n\nReason: {reasonafk}\n\n", + ) + except: + msg += f"{user_name[:25]} ɪs ʙᴀᴄᴋ ᴏɴʟɪɴᴇ\n\n" + + + if message.reply_to_message: + try: + replied_first_name = message.reply_to_message.from_user.first_name + replied_user_id = message.reply_to_message.from_user.id + verifier, reasondb = await is_afk(replied_user_id) + if verifier: + try: + afktype = reasondb["type"] + timeafk = reasondb["time"] + data = reasondb["data"] + reasonafk = reasondb["reason"] + seenago = get_readable_time((int(time.time() - timeafk))) + if afktype == "text": + msg += ( + f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n" + ) + if afktype == "text_reason": + msg += f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nReason: {reasonafk}\n\n" + if afktype == "animation": + if str(reasonafk) == "None": + send = await message.reply_animation( + data, + caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_animation( + data, + caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nReason: {reasonafk}\n\n", + ) + if afktype == "photo": + if str(reasonafk) == "None": + send = await message.reply_photo( + photo=f"downloads/{replied_user_id}.jpg", + caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_photo( + photo=f"downloads/{replied_user_id}.jpg", + caption=f"{replied_first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nReason: {reasonafk}\n\n", + ) + except Exception: + msg += f"{replied_first_name} ɪs ᴀғᴋ,\nnᴩᴀᴛᴀ ɴɪ ʙᴄ ᴋᴀʙ sᴇ\n\n" + except: + pass + + if message.entities: + entity = message.entities + j = 0 + for x in range(len(entity)): + if (entity[j].type) == MessageEntityType.MENTION: + found = re.findall("@([_0-9a-zA-Z]+)", message.text) + try: + get_user = found[j] + user = await app.get_users(get_user) + if user.id == replied_user_id: + j += 1 + continue + except: + j += 1 + continue + verifier, reasondb = await is_afk(user.id) + if verifier: + try: + afktype = reasondb["type"] + timeafk = reasondb["time"] + data = reasondb["data"] + reasonafk = reasondb["reason"] + seenago = get_readable_time((int(time.time() - timeafk))) + if afktype == "text": + msg += ( + f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n" + ) + if afktype == "text_reason": + msg += f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n" + if afktype == "animation": + if str(reasonafk) == "None": + send = await message.reply_animation( + data, + caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_animation( + data, + caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n", + ) + if afktype == "photo": + if str(reasonafk) == "None": + send = await message.reply_photo( + photo=f"downloads/{user.id}.jpg", + caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_photo( + photo=f"downloads/{user.id}.jpg", + caption=f"{user.first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n", + ) + except: + msg += f"{user.first_name[:25]} ɪs ᴀғᴋ\n\n" + elif (entity[j].type) == MessageEntityType.TEXT_MENTION: + try: + user_id = entity[j].user.id + if user_id == replied_user_id: + j += 1 + continue + first_name = entity[j].user.first_name + except: + j += 1 + continue + verifier, reasondb = await is_afk(user_id) + if verifier: + try: + afktype = reasondb["type"] + timeafk = reasondb["time"] + data = reasondb["data"] + reasonafk = reasondb["reason"] + seenago = get_readable_time((int(time.time() - timeafk))) + if afktype == "text": + msg += f"{first_name[:25]}** ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n" + if afktype == "text_reason": + msg += f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n" + if afktype == "animation": + if str(reasonafk) == "None": + send = await message.reply_animation( + data, + caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_animation( + data, + caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n", + ) + if afktype == "photo": + if str(reasonafk) == "None": + send = await message.reply_photo( + photo=f"downloads/{user_id}.jpg", + caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\n", + ) + else: + send = await message.reply_photo( + photo=f"downloads/{user_id}.jpg", + caption=f"{first_name[:25]} ɪs ᴀғᴋ sɪɴᴄᴇ {seenago}\n\nAlasan: {reasonafk}\n\n", + ) + except: + msg += f"{first_name[:25]} ɪs ᴀғᴋ\n\n" + j += 1 + if msg != "": + try: + send = await message.reply_text(msg, disable_web_page_preview=True) + except: + return diff --git a/DragMusic/plugins/tools/chatlog.py b/DragMusic/plugins/tools/chatlog.py new file mode 100644 index 0000000000000000000000000000000000000000..68c143e0a9473c4fb2d6ff13cb6cc247fa690bc3 --- /dev/null +++ b/DragMusic/plugins/tools/chatlog.py @@ -0,0 +1,56 @@ +from pyrogram import Client +from pyrogram.types import Message +from pyrogram import filters +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup +from config import LOGGER_ID as LOG_GROUP_ID +from DragMusic import app + +@app.on_message(filters.new_chat_members, group=2) +async def join_watcher(_, message): + chat = message.chat + link = await app.export_chat_invite_link(message.chat.id) + for members in message.new_chat_members: + if members.id == (await app.get_me()).id: + count = await app.get_chat_members_count(chat.id) + msg = (f" ʙᴏᴛ ᴀᴅᴅᴇᴅ ɪɴ ᴀ ɴᴇᴡ ɢʀᴏᴜᴘ \n\n" + f" ɢʀᴏᴜᴘ ɴᴀᴍᴇ ➠ {message.chat.title}\n" + f" ɢʀᴏᴜᴘ ɪᴅ ➠ {message.chat.id}\n" + f" ɢʀᴏᴜᴘ ᴜsᴇʀɴᴀᴍᴇ ➠ @{message.chat.username if message.chat.username else 'Private'}\n" + f" ɢʀᴏᴜᴘ ʟɪɴᴋ ➠ [Click Here]({link})\n" + f" ɢʀᴏᴜᴘ ᴍᴇᴍʙᴇʀs ➠ {count}\n" + f" ᴀᴅᴅᴇᴅ ʙʏ ➠ {message.from_user.mention}") + try: + await app.send_message( + LOG_GROUP_ID, + text=msg, + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton(f"sᴇᴇ ʙᴏᴛ ᴀᴅᴅᴇᴅ ɢʀᴏᴜᴘ", url=f"{link}")] + ]), + message_thread_id=12279 + ) + except Exception as e: + print(f"Error sending message: {e}") + +@app.on_message(filters.left_chat_member) +async def on_left_chat_member(_, message: Message): + if (await app.get_me()).id == message.left_chat_member.id: + remove_by = message.from_user.mention if message.from_user else "𝐔ɴᴋɴᴏᴡɴ 𝐔sᴇʀ" + title = message.chat.title + username = f"@{message.chat.username}" if message.chat.username else "𝐏ʀɪᴠᴀᴛᴇ 𝐂ʜᴀᴛ" + chat_id = message.chat.id + left = (f"ʙᴏᴛ ʟᴇғᴛ ɢʀᴏᴜᴘ \n\n" + f" ɢʀᴏᴜᴘ ɴᴀᴍᴇ ➠ {title}\n\n" + f" ɢʀᴏᴜᴘ ɪᴅ ➠ {chat_id}\n\n" + f" ʙᴏᴛ ʀᴇᴍᴏᴠᴇᴅ ʙʏ ➠ {remove_by}\n\n" + f" ʙᴏᴛ ɴᴀᴍᴇ ➠ @{(await app.get_me()).username}") + try: + await app.send_message( + LOG_GROUP_ID, + text=left, + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton(f"ᴀᴅᴅ ᴍᴇ ʟᴏᴠᴇ", url=f"https://t.me/{(await app.get_me()).username}?startgroup=true")] + ]), + message_thread_id=12279 + ) + except Exception as e: + print(f"Error sending message: {e}") diff --git a/DragMusic/plugins/tools/dev.py b/DragMusic/plugins/tools/dev.py new file mode 100644 index 0000000000000000000000000000000000000000..98515e8d8209172030e65915744e6fb98a67cb92 --- /dev/null +++ b/DragMusic/plugins/tools/dev.py @@ -0,0 +1,115 @@ +import os +import re +import subprocess +import sys +import traceback +from inspect import getfullargspec +from io import StringIO +from time import time + +from pyrogram import filters +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, CallbackQuery + +from DragMusic import app +from config import OWNER_ID + + +async def aexec(code, client, message): + exec( + "async def __aexec(client, message): " + + "".join(f"\n {a}" for a in code.split("\n")) + ) + return await locals()["__aexec"](client, message) + + +async def edit_or_reply(msg: Message, **kwargs): + func = msg.edit_text if msg.from_user.is_self else msg.reply + await func(**kwargs) + + +@app.on_message(filters.text & filters.user(OWNER_ID) & ~filters.forwarded & ~filters.via_bot) +async def executor(client: app, message: Message): + """Executes Python or shell commands based on plain text input.""" + if not message.text: + return # Prevent errors when message.text is None + + if message.text.startswith("eval"): + if len(message.text.split()) < 2: + return await edit_or_reply(message, text="ᴡʜᴀᴛ ʏᴏᴜ ᴡᴀɴɴᴀ ᴇxᴇᴄᴜᴛᴇ ʙᴀʙʏ ?") + + cmd = message.text.split(" ", maxsplit=1)[1] + t1 = time() + old_stderr, old_stdout = sys.stderr, sys.stdout + redirected_output = sys.stdout = StringIO() + redirected_error = sys.stderr = StringIO() + stdout, stderr, exc = None, None, None + + try: + await aexec(cmd, client, message) + except Exception: + exc = traceback.format_exc() + + stdout, stderr = redirected_output.getvalue(), redirected_error.getvalue() + sys.stdout, sys.stderr = old_stdout, old_stderr + + evaluation = exc or stderr or stdout or "Success" + final_output = f"⥤ ʀᴇsᴜʟᴛ :\n
{evaluation}
" + + t2 = time() + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(f"Runtime: {round(t2-t1, 3)}s", callback_data=f"runtime {round(t2-t1, 3)}"), + InlineKeyboardButton(" Close", callback_data=f"close|{message.from_user.id}"), + ] + ] + ) + + await edit_or_reply(message, text=final_output, reply_markup=keyboard) + + elif message.text.startswith("sh"): + """Executes shell commands.""" + if len(message.text.split()) < 2: + return await edit_or_reply(message, text="ᴇxᴀᴍᴩʟᴇ :\nsh git pull") + + text = message.text.split(None, 1)[1] + shell = re.split(r""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text) + + try: + t1 = time() # Ensure t1 is defined before usage + process = subprocess.Popen(shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output = process.stdout.read().decode("utf-8").strip() or "None" + except Exception as err: + exc_type, exc_obj, exc_tb = sys.exc_info() + errors = traceback.format_exception(etype=exc_type, value=exc_obj, tb=exc_tb) + return await edit_or_reply(message, text=f"ERROR :\n
{''.join(errors)}
") + + t2 = time() + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(f"Runtime: {round(t2-t1, 3)}s", callback_data=f"runtime {round(t2-t1, 3)}"), + InlineKeyboardButton(" Close", callback_data=f"close|{message.from_user.id}"), + ] + ] + ) + + await edit_or_reply(message, text=f"OUTPUT :\n
{output}
", reply_markup=keyboard) + + await message.stop_propagation() + + +@app.on_callback_query(filters.regex(r"runtime")) +async def runtime_func_cq(_, cq): + runtime = cq.data.split(None, 1)[1] + await cq.answer(runtime, show_alert=True) + + +@app.on_callback_query(filters.regex(r"close\|")) +async def close_command(_, CallbackQuery: CallbackQuery): + user_id = int(CallbackQuery.data.split("|")[1]) + if CallbackQuery.from_user.id != user_id: + return await CallbackQuery.answer(" You can't close this!", show_alert=True) + + await CallbackQuery.message.delete() + await CallbackQuery.answer() diff --git a/DragMusic/plugins/tools/invitelink.py b/DragMusic/plugins/tools/invitelink.py new file mode 100644 index 0000000000000000000000000000000000000000..fdfd567d4ccd3861249827db988a2f74854a4c36 --- /dev/null +++ b/DragMusic/plugins/tools/invitelink.py @@ -0,0 +1,74 @@ +from DragMusic import app +from pyrogram import Client, filters +from pyrogram.errors import ChatIdInvalid +from pyrogram.errors import ChatAdminRequired, ChatNotModified, ChatIdInvalid, FloodWait, InviteHashExpired, UserNotParticipant +import os +import json +from pyrogram.types import Message +from DragMusic.misc import SUDOERS + + + +# Command handler for /givelink command +@app.on_message(filters.command("givelink")) +async def give_link_command(client, message): + # Generate an invite link for the chat where the command is used + chat = message.chat.id + link = await app.export_chat_invite_link(chat) + await message.reply_text(f"Here's the invite link for this chat:\n{link}") + + +@app.on_message(filters.command(["link", "invitelink"], prefixes=["/", "!", "%", ",", "", ".", "@", "#"]) & SUDOERS) +async def link_command_handler(client: Client, message: Message): + if len(message.command) != 2: + await message.reply("Invalid usage. Correct format: /link group_id") + return + + group_id = message.command[1] + file_name = f"group_info_{group_id}.txt" + + try: + chat = await client.get_chat(int(group_id)) + + if chat is None: + await message.reply("Unable to get information for the specified group ID.") + return + + try: + invite_link = await client.export_chat_invite_link(chat.id) + except FloodWait as e: + await message.reply(f"FloodWait: {e.x} seconds. Retrying in {e.x} seconds.") + return + + group_data = { + "id": chat.id, + "type": str(chat.type), + "title": chat.title, + "members_count": chat.members_count, + "description": chat.description, + "invite_link": invite_link, + "is_verified": chat.is_verified, + "is_restricted": chat.is_restricted, + "is_creator": chat.is_creator, + "is_scam": chat.is_scam, + "is_fake": chat.is_fake, + "dc_id": chat.dc_id, + "has_protected_content": chat.has_protected_content, + } + + with open(file_name, "w", encoding="utf-8") as file: + for key, value in group_data.items(): + file.write(f"{key}: {value}\n") + + await client.send_document( + chat_id=message.chat.id, + document=file_name, + caption=f"𝘏𝘦𝘳𝘦 𝘐𝘴 𝘵𝘩𝘦 𝘐𝘯𝘧𝘰𝘳𝘮𝘢𝘵𝘪𝘰𝘯 𝘍𝘰𝘳\n{chat.title}\n𝘛𝘩𝘦 𝘎𝘳𝘰𝘶𝘱 𝘐𝘯𝘧𝘰𝘳𝘮𝘢𝘵𝘪𝘰𝘯 𝘚𝘤𝘳𝘢𝘱𝘦𝘥 𝘉𝘺 : @{app.username}" + ) + + except Exception as e: + await message.reply(f"Error: {str(e)}") + + finally: + if os.path.exists(file_name): + os.remove(file_name) diff --git a/DragMusic/plugins/tools/language.py b/DragMusic/plugins/tools/language.py new file mode 100644 index 0000000000000000000000000000000000000000..3d72b36c519b0707150fbe432d8a39db7ce6985f --- /dev/null +++ b/DragMusic/plugins/tools/language.py @@ -0,0 +1,74 @@ +from pykeyboard import InlineKeyboard +from pyrogram import filters +from pyrogram.types import InlineKeyboardButton, Message + +from DragMusic import app +from DragMusic.utils.database import get_lang, set_lang +from DragMusic.utils.decorators import ActualAdminCB, language, languageCB +from config import BANNED_USERS +from strings import get_string, languages_present + + +def lanuages_keyboard(_): + keyboard = InlineKeyboard(row_width=2) + keyboard.add( + *[ + ( + InlineKeyboardButton( + text=languages_present[i], + callback_data=f"languages:{i}", + ) + ) + for i in languages_present + ] + ) + keyboard.row( + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data=f"settingsback_helper", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data=f"close"), + ) + return keyboard + + +@app.on_message(filters.command(["lang", "setlang", "language"]) & ~BANNED_USERS) +@language +async def langs_command(client, message: Message, _): + keyboard = lanuages_keyboard(_) + await message.reply_text( + _["lang_1"], + reply_markup=keyboard, + ) + + +@app.on_callback_query(filters.regex("LG") & ~BANNED_USERS) +@languageCB +async def lanuagecb(client, CallbackQuery, _): + try: + await CallbackQuery.answer() + except: + pass + keyboard = lanuages_keyboard(_) + return await CallbackQuery.edit_message_reply_markup(reply_markup=keyboard) + + +@app.on_callback_query(filters.regex(r"languages:(.*?)") & ~BANNED_USERS) +@ActualAdminCB +async def language_markup(client, CallbackQuery, _): + langauge = (CallbackQuery.data).split(":")[1] + old = await get_lang(CallbackQuery.message.chat.id) + if str(old) == str(langauge): + return await CallbackQuery.answer(_["lang_4"], show_alert=True) + try: + _ = get_string(langauge) + await CallbackQuery.answer(_["lang_2"], show_alert=True) + except: + _ = get_string(old) + return await CallbackQuery.answer( + _["lang_3"], + show_alert=True, + ) + await set_lang(CallbackQuery.message.chat.id, langauge) + keyboard = lanuages_keyboard(_) + return await CallbackQuery.edit_message_reply_markup(reply_markup=keyboard) diff --git a/DragMusic/plugins/tools/ping.py b/DragMusic/plugins/tools/ping.py new file mode 100644 index 0000000000000000000000000000000000000000..4b0b95bdaa6c412978863d5d96cad85e65f71c48 --- /dev/null +++ b/DragMusic/plugins/tools/ping.py @@ -0,0 +1,85 @@ +from datetime import datetime +import httpx # For making HTTP requests +from pyrogram import Client, filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.utils import bot_sys_stats +from DragMusic.utils.decorators.language import language +from DragMusic.utils.inline import supp_markup +from config import BANNED_USERS, PING_IMG_URL + +# Replace with your actual API URL and Bot Token +API_URL = "https://karma-api2.vercel.app/instadl" +DOWNLOADING_STICKER_ID = ( + "CAACAgUAAxkBAAEVtNxnbAfkXOWkvCJSkfjJab2fml0AAbkAAhESAAKKWGlXKi6QQO-bOTM2BA" +) + +@app.on_message(filters.command(["ping", "alive"]) & ~BANNED_USERS) +@language +async def ping_com(client, message: Message, _): + start = datetime.now() + response = await message.reply_photo( + photo=PING_IMG_URL, + caption=_["ping_1"].format(app.mention), + ) + pytgping = await Drag.ping() + UP, CPU, RAM, DISK = await bot_sys_stats() + resp = (datetime.now() - start).microseconds / 1000 + await response.edit_text( + _["ping_2"].format(resp, app.mention, UP, RAM, CPU, DISK, pytgping), + reply_markup=supp_markup(_), + ) + +# Instagram download command handler +@app.on_message(filters.command(["ig", "instagram", "insta", "instadl"]) & ~BANNED_USERS) +@language +async def instadl_command_handler(client, message: Message, _): + if len(message.command) < 2: + await message.reply_text("Usage: /instadl [Instagram URL]") + return + + link = message.command[1] + downloading_sticker = None # Initialize the variable + + try: + # Send the downloading sticker + downloading_sticker = await message.reply_sticker(DOWNLOADING_STICKER_ID) + + # Make an asynchronous GET request to the API using httpx + async with httpx.AsyncClient() as client: + response = await client.get(API_URL, params={"url": link}) + data = response.json() + + # Check if the API request was successful + if "content_url" in data: + content_url = data["content_url"] + + # Determine content type from the URL + content_type = "video" if "video" in content_url else "photo" + + # Reply with either photo or video + if content_type == "photo": + await message.reply_photo(content_url) + elif content_type == "video": + await message.reply_video(content_url) + else: + await message.reply_text("Unsupported content type.") + else: + await message.reply_text( + "Unable to fetch content. Please check the Instagram URL or try with another Instagram link." + ) + + except Exception as e: + print(e) + await message.reply_text("An error occurred while processing the request.") + + finally: + # Only delete the sticker if it was successfully sent + if downloading_sticker: + await downloading_sticker.delete() + +# Start the Pyrogram bot +if __name__ == "__main__": + app.run() diff --git a/DragMusic/plugins/tools/queue.py b/DragMusic/plugins/tools/queue.py new file mode 100644 index 0000000000000000000000000000000000000000..2d6f43db6fe83f545661756f3ab9b5261e0736b0 --- /dev/null +++ b/DragMusic/plugins/tools/queue.py @@ -0,0 +1,269 @@ +import asyncio +import os + +from pyrogram import filters +from pyrogram.errors import FloodWait +from pyrogram.types import CallbackQuery, InputMediaPhoto, Message + +import config +from DragMusic import app +from DragMusic.misc import db +from DragMusic.utils import DragBin, get_channeplayCB, seconds_to_min +from DragMusic.utils.database import get_cmode, is_active_chat, is_music_playing +from DragMusic.utils.decorators.language import language, languageCB +from DragMusic.utils.inline import queue_back_markup, queue_markup +from config import BANNED_USERS + +basic = {} + + +def get_image(videoid): + if os.path.isfile(f"cache/{videoid}.png"): + return f"cache/{videoid}.png" + else: + return config.YOUTUBE_IMG_URL + + +def get_duration(playing): + file_path = playing[0]["file"] + if "index_" in file_path or "live_" in file_path: + return "Unknown" + duration_seconds = int(playing[0]["seconds"]) + if duration_seconds == 0: + return "Unknown" + else: + return "Inline" + + +@app.on_message( + filters.command(["queue", "cqueue", "player", "cplayer", "playing", "cplaying"]) + & filters.group + & ~BANNED_USERS +) +@language +async def get_queue(client, message: Message, _): + if message.command[0][0] == "c": + chat_id = await get_cmode(message.chat.id) + if chat_id is None: + return await message.reply_text(_["setting_7"]) + try: + await app.get_chat(chat_id) + except: + return await message.reply_text(_["cplay_4"]) + cplay = True + else: + chat_id = message.chat.id + cplay = False + if not await is_active_chat(chat_id): + return await message.reply_text(_["general_5"]) + got = db.get(chat_id) + if not got: + return await message.reply_text(_["queue_2"]) + file = got[0]["file"] + videoid = got[0]["vidid"] + user = got[0]["by"] + title = (got[0]["title"]).title() + typo = (got[0]["streamtype"]).title() + DUR = get_duration(got) + if "live_" in file: + IMAGE = get_image(videoid) + elif "vid_" in file: + IMAGE = get_image(videoid) + elif "index_" in file: + IMAGE = config.STREAM_IMG_URL + else: + if videoid == "telegram": + IMAGE = ( + config.TELEGRAM_AUDIO_URL + if typo == "Audio" + else config.TELEGRAM_VIDEO_URL + ) + elif videoid == "soundcloud": + IMAGE = config.SOUNCLOUD_IMG_URL + else: + IMAGE = get_image(videoid) + send = _["queue_6"] if DUR == "Unknown" else _["queue_7"] + cap = _["queue_8"].format(app.mention, title, typo, user, send) + upl = ( + queue_markup(_, DUR, "c" if cplay else "g", videoid) + if DUR == "Unknown" + else queue_markup( + _, + DUR, + "c" if cplay else "g", + videoid, + seconds_to_min(got[0]["played"]), + got[0]["dur"], + ) + ) + basic[videoid] = True + mystic = await message.reply_photo(IMAGE, caption=cap, reply_markup=upl) + if DUR != "Unknown": + try: + while db[chat_id][0]["vidid"] == videoid: + await asyncio.sleep(5) + if await is_active_chat(chat_id): + if basic[videoid]: + if await is_music_playing(chat_id): + try: + buttons = queue_markup( + _, + DUR, + "c" if cplay else "g", + videoid, + seconds_to_min(db[chat_id][0]["played"]), + db[chat_id][0]["dur"], + ) + await mystic.edit_reply_markup(reply_markup=buttons) + except FloodWait: + pass + else: + pass + else: + break + else: + break + except: + return + + +@app.on_callback_query(filters.regex("GetTimer") & ~BANNED_USERS) +async def quite_timer(client, CallbackQuery: CallbackQuery): + try: + await CallbackQuery.answer() + except: + pass + + +@app.on_callback_query(filters.regex("GetQueued") & ~BANNED_USERS) +@languageCB +async def queued_tracks(client, CallbackQuery: CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + callback_request = callback_data.split(None, 1)[1] + what, videoid = callback_request.split("|") + try: + chat_id, channel = await get_channeplayCB(_, what, CallbackQuery) + except: + return + if not await is_active_chat(chat_id): + return await CallbackQuery.answer(_["general_5"], show_alert=True) + got = db.get(chat_id) + if not got: + return await CallbackQuery.answer(_["queue_2"], show_alert=True) + if len(got) == 1: + return await CallbackQuery.answer(_["queue_5"], show_alert=True) + await CallbackQuery.answer() + basic[videoid] = False + buttons = queue_back_markup(_, what) + med = InputMediaPhoto( + media="https://telegra.ph//file/6f7d35131f69951c74ee5.jpg", + caption=_["queue_1"], + ) + await CallbackQuery.edit_message_media(media=med) + j = 0 + msg = "" + for x in got: + j += 1 + if j == 1: + msg += f'Streaming :\n\n✨ Title : {x["title"]}\nDuration : {x["dur"]}\nBy : {x["by"]}\n\n' + elif j == 2: + msg += f'Queued :\n\n✨ Title : {x["title"]}\nDuration : {x["dur"]}\nBy : {x["by"]}\n\n' + else: + msg += f'✨ Title : {x["title"]}\nDuration : {x["dur"]}\nBy : {x["by"]}\n\n' + if "Queued" in msg: + if len(msg) < 700: + await asyncio.sleep(1) + return await CallbackQuery.edit_message_text(msg, reply_markup=buttons) + if "✨" in msg: + msg = msg.replace("✨", "") + link = await DragBin(msg) + med = InputMediaPhoto(media=link, caption=_["queue_3"].format(link)) + await CallbackQuery.edit_message_media(media=med, reply_markup=buttons) + else: + await asyncio.sleep(1) + return await CallbackQuery.edit_message_text(msg, reply_markup=buttons) + + +@app.on_callback_query(filters.regex("queue_back_timer") & ~BANNED_USERS) +@languageCB +async def queue_back(client, CallbackQuery: CallbackQuery, _): + callback_data = CallbackQuery.data.strip() + cplay = callback_data.split(None, 1)[1] + try: + chat_id, channel = await get_channeplayCB(_, cplay, CallbackQuery) + except: + return + if not await is_active_chat(chat_id): + return await CallbackQuery.answer(_["general_5"], show_alert=True) + got = db.get(chat_id) + if not got: + return await CallbackQuery.answer(_["queue_2"], show_alert=True) + await CallbackQuery.answer(_["set_cb_5"], show_alert=True) + file = got[0]["file"] + videoid = got[0]["vidid"] + user = got[0]["by"] + title = (got[0]["title"]).title() + typo = (got[0]["streamtype"]).title() + DUR = get_duration(got) + if "live_" in file: + IMAGE = get_image(videoid) + elif "vid_" in file: + IMAGE = get_image(videoid) + elif "index_" in file: + IMAGE = config.STREAM_IMG_URL + else: + if videoid == "telegram": + IMAGE = ( + config.TELEGRAM_AUDIO_URL + if typo == "Audio" + else config.TELEGRAM_VIDEO_URL + ) + elif videoid == "soundcloud": + IMAGE = config.SOUNCLOUD_IMG_URL + else: + IMAGE = get_image(videoid) + send = _["queue_6"] if DUR == "Unknown" else _["queue_7"] + cap = _["queue_8"].format(app.mention, title, typo, user, send) + upl = ( + queue_markup(_, DUR, cplay, videoid) + if DUR == "Unknown" + else queue_markup( + _, + DUR, + cplay, + videoid, + seconds_to_min(got[0]["played"]), + got[0]["dur"], + ) + ) + basic[videoid] = True + + med = InputMediaPhoto(media=IMAGE, caption=cap) + mystic = await CallbackQuery.edit_message_media(media=med, reply_markup=upl) + if DUR != "Unknown": + try: + while db[chat_id][0]["vidid"] == videoid: + await asyncio.sleep(5) + if await is_active_chat(chat_id): + if basic[videoid]: + if await is_music_playing(chat_id): + try: + buttons = queue_markup( + _, + DUR, + cplay, + videoid, + seconds_to_min(db[chat_id][0]["played"]), + db[chat_id][0]["dur"], + ) + await mystic.edit_reply_markup(reply_markup=buttons) + except FloodWait: + pass + else: + pass + else: + break + else: + break + except: + return diff --git a/DragMusic/plugins/tools/reload.py b/DragMusic/plugins/tools/reload.py new file mode 100644 index 0000000000000000000000000000000000000000..df3ce8f16427eedc4d914df1c75ff3a7e75d483e --- /dev/null +++ b/DragMusic/plugins/tools/reload.py @@ -0,0 +1,125 @@ +import asyncio +import time + +from pyrogram import filters +from pyrogram.enums import ChatMembersFilter +from pyrogram.types import CallbackQuery, Message + +from DragMusic import app +from DragMusic.core.call import Drag +from DragMusic.misc import db +from DragMusic.utils.database import get_assistant, get_authuser_names, get_cmode +from DragMusic.utils.decorators import ActualAdminCB, AdminActual, language +from DragMusic.utils.formatters import alpha_to_int, get_readable_time +from config import BANNED_USERS, adminlist, lyrical + +rel = {} + + +@app.on_message( + filters.command(["admincache", "reload", "refresh"]) & filters.group & ~BANNED_USERS +) +@language +async def reload_admin_cache(client, message: Message, _): + try: + if message.chat.id not in rel: + rel[message.chat.id] = {} + else: + saved = rel[message.chat.id] + if saved > time.time(): + left = get_readable_time((int(saved) - int(time.time()))) + return await message.reply_text(_["reload_1"].format(left)) + adminlist[message.chat.id] = [] + async for user in app.get_chat_members( + message.chat.id, filter=ChatMembersFilter.ADMINISTRATORS + ): + if user.privileges.can_manage_video_chats: + adminlist[message.chat.id].append(user.user.id) + authusers = await get_authuser_names(message.chat.id) + for user in authusers: + user_id = await alpha_to_int(user) + adminlist[message.chat.id].append(user_id) + now = int(time.time()) + 180 + rel[message.chat.id] = now + await message.reply_text(_["reload_2"]) + except: + await message.reply_text(_["reload_3"]) + + +@app.on_message(filters.command(["reboot"]) & filters.group & ~BANNED_USERS) +@AdminActual +async def restartbot(client, message: Message, _): + mystic = await message.reply_text(_["reload_4"].format(app.mention)) + await asyncio.sleep(1) + try: + db[message.chat.id] = [] + await Drag.stop_stream_force(message.chat.id) + except: + pass + userbot = await get_assistant(message.chat.id) + try: + if message.chat.username: + await userbot.resolve_peer(message.chat.username) + else: + await userbot.resolve_peer(message.chat.id) + except: + pass + chat_id = await get_cmode(message.chat.id) + if chat_id: + try: + got = await app.get_chat(chat_id) + except: + pass + userbot = await get_assistant(chat_id) + try: + if got.username: + await userbot.resolve_peer(got.username) + else: + await userbot.resolve_peer(chat_id) + except: + pass + try: + db[chat_id] = [] + await Drag.stop_stream_force(chat_id) + except: + pass + return await mystic.edit_text(_["reload_5"].format(app.mention)) + + +@app.on_callback_query(filters.regex("close") & ~BANNED_USERS) +async def close_menu(_, query: CallbackQuery): + try: + await query.answer() + await query.message.delete() + umm = await query.message.reply_text( + f"Cʟᴏsᴇᴅ ʙʏ : {query.from_user.mention}" + ) + await asyncio.sleep(7) + await umm.delete() + except: + pass + + +@app.on_callback_query(filters.regex("stop_downloading") & ~BANNED_USERS) +@ActualAdminCB +async def stop_download(client, CallbackQuery: CallbackQuery, _): + message_id = CallbackQuery.message.id + task = lyrical.get(message_id) + if not task: + return await CallbackQuery.answer(_["tg_4"], show_alert=True) + if task.done() or task.cancelled(): + return await CallbackQuery.answer(_["tg_5"], show_alert=True) + if not task.done(): + try: + task.cancel() + try: + lyrical.pop(message_id) + except: + pass + await CallbackQuery.answer(_["tg_6"], show_alert=True) + return await CallbackQuery.edit_message_text( + _["tg_7"].format(CallbackQuery.from_user.mention) + ) + except: + return await CallbackQuery.answer(_["tg_8"], show_alert=True) + await CallbackQuery.answer(_["tg_9"], show_alert=True) diff --git a/DragMusic/plugins/tools/speedtest.py b/DragMusic/plugins/tools/speedtest.py new file mode 100644 index 0000000000000000000000000000000000000000..ad2e62d41101ec110dde75ae738522819ca72221 --- /dev/null +++ b/DragMusic/plugins/tools/speedtest.py @@ -0,0 +1,45 @@ +import asyncio + +import speedtest +from pyrogram import filters +from pyrogram.types import Message + +from DragMusic import app +from DragMusic.misc import SUDOERS +from DragMusic.utils.decorators.language import language + + +def testspeed(m, _): + try: + test = speedtest.Speedtest() + test.get_best_server() + m = m.edit_text(_["server_12"]) + test.download() + m = m.edit_text(_["server_13"]) + test.upload() + test.results.share() + result = test.results.dict() + m = m.edit_text(_["server_14"]) + except Exception as e: + return m.edit_text(f"{e}") + return result + + +@app.on_message(filters.command(["speedtest", "spt"]) & SUDOERS) +@language +async def speedtest_function(client, message: Message, _): + m = await message.reply_text(_["server_11"]) + loop = asyncio.get_event_loop() + result = await loop.run_in_executor(None, testspeed, m, _) + output = _["server_15"].format( + result["client"]["isp"], + result["client"]["country"], + result["server"]["name"], + result["server"]["country"], + result["server"]["cc"], + result["server"]["sponsor"], + result["server"]["latency"], + result["ping"], + ) + msg = await message.reply_photo(photo=result["share"], caption=output) + await m.delete() diff --git a/DragMusic/plugins/tools/stats.py b/DragMusic/plugins/tools/stats.py new file mode 100644 index 0000000000000000000000000000000000000000..9b8ef5f8d0c47117a8fbdaac0fe606fa1d447d87 --- /dev/null +++ b/DragMusic/plugins/tools/stats.py @@ -0,0 +1,158 @@ +import platform +from sys import version as pyver + +import psutil +from pyrogram import __version__ as pyrover +from pyrogram import filters +from pyrogram.errors import MessageIdInvalid +from pyrogram.types import InputMediaPhoto, Message +from pytgcalls.__version__ import __version__ as pytgver + +import config +from DragMusic import app +from DragMusic.core.userbot import assistants +from DragMusic.misc import SUDOERS, mongodb +from DragMusic.plugins import ALL_MODULES +from DragMusic.utils.database import get_served_chats, get_served_users, get_sudoers +from DragMusic.utils.decorators.language import language, languageCB +from DragMusic.utils.inline.stats import back_stats_buttons, stats_buttons +from config import BANNED_USERS, OWNER_ID + +@app.on_message(filters.command(["stats", "gstats"]) & ~BANNED_USERS) +@language +async def stats_global(client, message: Message, _): + # Allow sudo users and owner to use it from anywhere + if message.from_user.id not in SUDOERS and message.from_user.id != OWNER_ID: + # Restrict access to only the group with username @dragbackup + if message.chat.username != "dragbackup": + return await message.reply_text( + "Tʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ᴛʜᴇ @ᴅʀᴀɢʙᴀᴄᴋᴜᴘ .." + ) + + upl = stats_buttons(_, True) + await message.reply_photo( + photo=config.STATS_IMG_URL, + caption=_["gstats_2"].format(app.mention), + reply_markup=upl, + ) + + +@app.on_callback_query(filters.regex("stats_back") & ~BANNED_USERS) +@languageCB +async def home_stats(client, CallbackQuery, _): + # Allow sudo users and owner to use it from anywhere + if CallbackQuery.from_user.id not in SUDOERS and CallbackQuery.from_user.id != OWNER_ID: + # Restrict access to only the group with username @dragbackup + if CallbackQuery.message.chat.username != "dragbackup": + return await CallbackQuery.answer("Tʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ᴛʜᴇ @ᴅʀᴀɢʙᴀᴄᴋᴜᴘ ɢʀᴏᴜᴘ.", show_alert=True) + + upl = stats_buttons(_, True) + await CallbackQuery.edit_message_text( + text=_["gstats_2"].format(app.mention), + reply_markup=upl, + ) + + +@app.on_callback_query(filters.regex("TopOverall") & ~BANNED_USERS) +@languageCB +async def overall_stats(client, CallbackQuery, _): + # Allow sudo users and owner to use it from anywhere + if CallbackQuery.from_user.id not in SUDOERS and CallbackQuery.from_user.id != OWNER_ID: + # Restrict access to only the group with username @dragbackup + if CallbackQuery.message.chat.username != "dragbackup": + return await CallbackQuery.answer("Tʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ᴛʜᴇ @ᴅʀᴀɢʙᴀᴄᴋᴜᴘ ɢʀᴏᴜᴘ.", show_alert=True) + + await CallbackQuery.answer() + upl = back_stats_buttons(_) + try: + await CallbackQuery.answer() + except: + pass + await CallbackQuery.edit_message_text(_["gstats_1"].format(app.mention)) + served_chats = len(await get_served_chats()) + served_users = len(await get_served_users()) + text = _["gstats_3"].format( + app.mention, + len(assistants), + len(BANNED_USERS), + served_chats, + served_users, + len(ALL_MODULES), + len(SUDOERS), + config.AUTO_LEAVING_ASSISTANT, + config.DURATION_LIMIT_MIN, + ) + med = InputMediaPhoto(media=config.STATS_IMG_URL, caption=text) + try: + await CallbackQuery.edit_message_media(media=med, reply_markup=upl) + except MessageIdInvalid: + await CallbackQuery.message.reply_photo( + photo=config.STATS_IMG_URL, caption=text, reply_markup=upl + ) + + +@app.on_callback_query(filters.regex("bot_stats_sudo")) +@languageCB +async def bot_stats(client, CallbackQuery, _): + # Allow sudo users and owner to use it from anywhere + if CallbackQuery.from_user.id not in SUDOERS and CallbackQuery.from_user.id != OWNER_ID: + # Restrict access to only the group with username @dragbackup + if CallbackQuery.message.chat.username != "dragbackup": + return await CallbackQuery.answer("Tʜɪs ᴄᴏᴍᴍᴀɴᴅ ᴄᴀɴ ᴏɴʟʏ ʙᴇ ᴜsᴇᴅ ɪɴ ᴛʜᴇ @ᴅʀᴀɢʙᴀᴄᴋᴜᴘ ɢʀᴏᴜᴘ.", show_alert=True) + + upl = back_stats_buttons(_) + try: + await CallbackQuery.answer() + except: + pass + await CallbackQuery.edit_message_text(_["gstats_1"].format(app.mention)) + p_core = psutil.cpu_count(logical=False) + t_core = psutil.cpu_count(logical=True) + ram = str(round(psutil.virtual_memory().total / (1024.0**3))) + " ɢʙ" + try: + cpu_freq = psutil.cpu_freq().current + if cpu_freq >= 1000: + cpu_freq = f"{round(cpu_freq / 1000, 2)}ɢʜᴢ" + else: + cpu_freq = f"{round(cpu_freq, 2)}ᴍʜᴢ" + except: + cpu_freq = "ғᴀɪʟᴇᴅ ᴛᴏ ғᴇᴛᴄʜ" + hdd = psutil.disk_usage("/") + total = hdd.total / (1024.0**3) + used = hdd.used / (1024.0**3) + free = hdd.free / (1024.0**3) + call = await mongodb.command("dbstats") + datasize = call["dataSize"] / 1024 + storage = call["storageSize"] / 1024 + served_chats = len(await get_served_chats()) + served_users = len(await get_served_users()) + text = _["gstats_5"].format( + app.mention, + len(ALL_MODULES), + platform.system(), + ram, + p_core, + t_core, + cpu_freq, + pyver.split()[0], + pyrover, + pytgver, + str(total)[:4], + str(used)[:4], + str(free)[:4], + served_chats, + served_users, + len(BANNED_USERS), + len(await get_sudoers()), + str(datasize)[:6], + storage, + call["collections"], + call["objects"], + ) + med = InputMediaPhoto(media=config.STATS_IMG_URL, caption=text) + try: + await CallbackQuery.edit_message_media(media=med, reply_markup=upl) + except MessageIdInvalid: + await CallbackQuery.message.reply_photo( + photo=config.STATS_IMG_URL, caption=text, reply_markup=upl + ) diff --git a/DragMusic/plugins/tools/tgm.py b/DragMusic/plugins/tools/tgm.py new file mode 100644 index 0000000000000000000000000000000000000000..ebb7365b9e7cbe07b550897b6c9eb116ae530593 --- /dev/null +++ b/DragMusic/plugins/tools/tgm.py @@ -0,0 +1,43 @@ +import requests +from pyrogram import filters +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup +from DragMusic import app + +def upload_to_catbox(file_path): + """Uploads a file to Catbox and returns the file URL.""" + url = "https://catbox.moe/user/api.php" + with open(file_path, "rb") as file: + response = requests.post( + url, + data={"reqtype": "fileupload"}, + files={"fileToUpload": file} + ) + if response.status_code == 200: + return response.text.strip() + else: + raise Exception(f"Cᴀᴛʙᴏx ᴜᴘʟᴏᴀᴅ ғᴀɪʟᴇᴅ: {response.text}") + +@app.on_message(filters.command("tgm")) +def ul(_, message): + reply = message.reply_to_message + if not reply or not reply.media: + return message.reply("Pʟᴇᴀsᴇ ʀᴇᴘʟʏ ᴛᴏ ᴀɴ ɪᴍᴀɢᴇ ᴏʀ ᴍᴇᴅɪᴀ ᴛᴏ ᴜᴘʟᴏᴀᴅ.") + + i = message.reply("Downloading...") + path = reply.download() + + if not path: + return i.edit("Fᴀɪʟᴇᴅ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ᴛʜᴇ ғɪʟᴇ.") + + try: + # Upload to Catbox + file_url = upload_to_catbox(path) + + # Create a button with the Catbox link + button = InlineKeyboardButton("ᴄᴀᴛʙᴏx ʟɪɴᴋ", url=file_url) + markup = InlineKeyboardMarkup([[button]]) + + # Send a reply with the button + i.edit("Yᴏᴜʀ ғɪʟᴇ ʜᴀs ʙᴇᴇɴ ᴜᴘʟᴏᴀᴅᴇᴅ ᴛᴏ Cᴀᴛʙᴏx:", reply_markup=markup) + except Exception as e: + i.edit(f"An error occurred: {str(e)}") diff --git a/DragMusic/plugins/tools/welcome.py b/DragMusic/plugins/tools/welcome.py new file mode 100644 index 0000000000000000000000000000000000000000..7ab46db999def96b3dc57312d994ec5828e163ea --- /dev/null +++ b/DragMusic/plugins/tools/welcome.py @@ -0,0 +1,165 @@ +import os +from PIL import ImageDraw, Image, ImageFont, ImageChops +from pyrogram import * +from pyrogram.types import * +from logging import getLogger +from DragMusic import app + + + + + +LOGGER = getLogger(__name__) + +class WelDatabase: + def __init__(self): + self.data = {} + + async def find_one(self, chat_id): + return chat_id in self.data + + async def add_wlcm(self, chat_id): + self.data[chat_id] = {} # You can store additional information related to the chat + # For example, self.data[chat_id]['some_key'] = 'some_value' + + async def rm_wlcm(self, chat_id): + if chat_id in self.data: + del self.data[chat_id] + +wlcm = WelDatabase() + +class temp: + ME = None + CURRENT = 2 + CANCEL = False + MELCOW = {} + U_NAME = None + B_NAME = None + +# ... (rest of your code remains unchanged) + +# ... (FUCK you randi ke bacvhhe ) + +def circle(pfp, size=(500, 500)): + pfp = pfp.resize(size, Image.ANTIALIAS).convert("RGBA") + bigsize = (pfp.size[0] * 3, pfp.size[1] * 3) + mask = Image.new("L", bigsize, 0) + draw = ImageDraw.Draw(mask) + draw.ellipse((0, 0) + bigsize, fill=255) + mask = mask.resize(pfp.size, Image.ANTIALIAS) + mask = ImageChops.darker(mask, pfp.split()[-1]) + pfp.putalpha(mask) + return pfp + +def welcomepic(pic, user, chatname, id, uname): + background = Image.open("DragMusic/assets/wel2.png") + pfp = Image.open(pic).convert("RGBA") + pfp = circle(pfp) + pfp = pfp.resize((825, 824)) + draw = ImageDraw.Draw(background) + font = ImageFont.truetype('DragMusic/assets/font.ttf', size=110) + welcome_font = ImageFont.truetype('DragMusic/assets/font.ttf', size=60) + draw.text((2100, 1420), f'ID: {id}', fill=(12000, 12000, 12000), font=font) + pfp_position = (1990, 435) + background.paste(pfp, pfp_position, pfp) + background.save(f"downloads/welcome#{id}.png") + return f"downloads/welcome#{id}.png" + +# FUCK you bhosadiwale + + +@app.on_message(filters.command("wel") & ~filters.private) +async def auto_state(_, message): + usage = "**Usage:**\n⦿/wel [on|off]\n➤ᴀᴜʀ ʜᴀᴀɴ ᴋᴀɴɢᴇʀs ᴋᴀʀᴏ ᴀʙ ᴄᴏᴘʏ ʙʜᴏsᴀᴅɪᴡᴀʟᴇ\n➤sᴀʟᴏɴ ᴀᴜʀ ʜᴀᴀɴ sᴛʏʟɪsʜ ғᴏɴᴛ ɴᴏᴛ ᴀʟʟᴏᴡᴇᴅ ɪɴ ᴛʜᴇ ᴛʜᴜᴍʙɴᴀɪʟ.!\ᴀᴜʀ ʜᴀᴀɴ ᴀɢʀ ᴋʜᴜᴅ ᴋɪ ᴋᴀʀɴɪ ʜᴀɪ ᴛᴏ ɢᴀᴀɴᴅ ᴍᴀʀᴀᴏ ʙᴇᴛɪᴄʜᴏᴅ" + if len(message.command) == 1: + return await message.reply_text(usage) + chat_id = message.chat.id + user = await app.get_chat_member(message.chat.id, message.from_user.id) + if user.status in ( + enums.ChatMemberStatus.ADMINISTRATOR, + enums.ChatMemberStatus.OWNER, + ): + A = await wlcm.find_one(chat_id) + state = message.text.split(None, 1)[1].strip().lower() + if state == "on": + if A: + return await message.reply_text("Special Welcome Already Enabled") + elif not A: + await wlcm.add_wlcm(chat_id) + await message.reply_text(f"Enabled Special Welcome in {message.chat.title}") + elif state == "off": + if not A: + return await message.reply_text("Special Welcome Already Disabled") + elif A: + await wlcm.rm_wlcm(chat_id) + await message.reply_text(f"Disabled Special Welcome in {message.chat.title}") + else: + await message.reply_text(usage) + else: + await message.reply("Only Admins Can Use This Command") + +# ... (copy paster teri maa ki chut ) + +@app.on_chat_member_updated(filters.group, group=-3) +async def greet_group(_, member: ChatMemberUpdated): + chat_id = member.chat.id + A = await wlcm.find_one(chat_id) # Corrected this line + if not A: + return + if ( + not member.new_chat_member + or member.new_chat_member.status in {"banned", "left", "restricted"} + or member.old_chat_member + ): + return + user = member.new_chat_member.user if member.new_chat_member else member.from_user + try: + pic = await app.download_media( + user.photo.big_file_id, file_name=f"pp{user.id}.png" + ) + except AttributeError: + pic = "DragMusic/assets/upic.png" + if (temp.MELCOW).get(f"welcome-{member.chat.id}") is not None: + try: + await temp.MELCOW[f"welcome-{member.chat.id}"].delete() + except Exception as e: + LOGGER.error(e) + try: + welcomeimg = welcomepic( + pic, user.first_name, member.chat.title, user.id, user.username + ) + temp.MELCOW[f"welcome-{member.chat.id}"] = await app.send_photo( + member.chat.id, + photo=welcomeimg, + caption=f""" +**❀ ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ ᴛʜᴇ {member.chat.title} ɢʀᴏᴜᴘ ❀ + +๏ ɴᴀᴍᴇ ➛ {user.mention} +๏ ɪᴅ ➛ {user.id} +๏ ᴜsᴇʀɴᴀᴍᴇ ➛ @{user.username} +๏ ᴍᴀᴅᴇ ʙʏ ➛ [ʀᴏʏ-ᴇᴅɪᴛx](https://t.me/BTSChinna** +""", + reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(f"ᴀᴅᴅ ᴍᴇ ʙᴀʙʏ", url=f"https://t.me/alexaprobot?startgroup=true")]]) + ) + except Exception as e: + LOGGER.error(e) + try: + os.remove(f"downloads/welcome#{user.id}.png") + os.remove(f"downloads/pp{user.id}.png") + except Exception as e: + pass + +# ... (resfuxbk + +@app.on_message(filters.new_chat_members & filters.group, group=-1) +async def bot_wel(_, message): + for u in message.new_chat_members: + if u.id == app.me.id: + await app.send_message(LOG_CHANNEL_ID, f""" +**NEW GROUP +➖➖➖➖➖➖➖➖➖➖➖➖ +NAME: {message.chat.title} +ID: {message.chat.id} +USERNAME: @{message.chat.username} +➖➖➖➖➖➖➖➖➖➖➖➖** +""") diff --git a/DragMusic/utils/__init__.py b/DragMusic/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6208a5acfba73aa96660a9077356d84aa88d5cc0 --- /dev/null +++ b/DragMusic/utils/__init__.py @@ -0,0 +1,8 @@ +from .channelplay import * +from .database import * +from .decorators import * +from .extraction import * +from .formatters import * +from .inline import * +from .pastebin import * +from .sys import * diff --git a/DragMusic/utils/channelplay.py b/DragMusic/utils/channelplay.py new file mode 100644 index 0000000000000000000000000000000000000000..f7e4fba2c1ad7d623bcb7f813940904231f4d43f --- /dev/null +++ b/DragMusic/utils/channelplay.py @@ -0,0 +1,23 @@ +from DragMusic import app +from DragMusic.utils.database import get_cmode + + +async def get_channeplayCB(_, command, CallbackQuery): + if command == "c": + chat_id = await get_cmode(CallbackQuery.message.chat.id) + if chat_id is None: + try: + return await CallbackQuery.answer(_["setting_7"], show_alert=True) + except: + return + try: + channel = (await app.get_chat(chat_id)).title + except: + try: + return await CallbackQuery.answer(_["cplay_4"], show_alert=True) + except: + return + else: + chat_id = CallbackQuery.message.chat.id + channel = None + return chat_id, channel diff --git a/DragMusic/utils/database.py b/DragMusic/utils/database.py new file mode 100644 index 0000000000000000000000000000000000000000..7e0ca03590c92a804640294d3d2b0e7c750e64b1 --- /dev/null +++ b/DragMusic/utils/database.py @@ -0,0 +1,646 @@ +import random +from typing import Dict, List, Union + +from DragMusic import userbot +from DragMusic.core.mongo import mongodb + +authdb = mongodb.adminauth +authuserdb = mongodb.authuser +autoenddb = mongodb.autoend +assdb = mongodb.assistants +blacklist_chatdb = mongodb.blacklistChat +blockeddb = mongodb.blockedusers +chatsdb = mongodb.chats +channeldb = mongodb.cplaymode +countdb = mongodb.upcount +gbansdb = mongodb.gban +langdb = mongodb.language +onoffdb = mongodb.onoffper +playmodedb = mongodb.playmode +playtypedb = mongodb.playtypedb +skipdb = mongodb.skipmode +sudoersdb = mongodb.sudoers +usersdb = mongodb.tgusersdb + +# Shifting to memory [mongo sucks often] +active = [] +activevideo = [] +assistantdict = {} +autoend = {} +count = {} +channelconnect = {} +langm = {} +loop = {} +maintenance = [] +nonadmin = {} +pause = {} +playmode = {} +playtype = {} +skipmode = {} + + +async def get_assistant_number(chat_id: int) -> str: + assistant = assistantdict.get(chat_id) + return assistant + + +async def get_client(assistant: int): + if int(assistant) == 1: + return userbot.one + elif int(assistant) == 2: + return userbot.two + elif int(assistant) == 3: + return userbot.three + elif int(assistant) == 4: + return userbot.four + elif int(assistant) == 5: + return userbot.five + + +async def set_assistant_new(chat_id, number): + number = int(number) + await assdb.update_one( + {"chat_id": chat_id}, + {"$set": {"assistant": number}}, + upsert=True, + ) + + +async def set_assistant(chat_id): + from DragMusic.core.userbot import assistants + + ran_assistant = random.choice(assistants) + assistantdict[chat_id] = ran_assistant + await assdb.update_one( + {"chat_id": chat_id}, + {"$set": {"assistant": ran_assistant}}, + upsert=True, + ) + userbot = await get_client(ran_assistant) + return userbot + + +async def get_assistant(chat_id: int) -> str: + from DragMusic.core.userbot import assistants + + assistant = assistantdict.get(chat_id) + if not assistant: + dbassistant = await assdb.find_one({"chat_id": chat_id}) + if not dbassistant: + userbot = await set_assistant(chat_id) + return userbot + else: + got_assis = dbassistant["assistant"] + if got_assis in assistants: + assistantdict[chat_id] = got_assis + userbot = await get_client(got_assis) + return userbot + else: + userbot = await set_assistant(chat_id) + return userbot + else: + if assistant in assistants: + userbot = await get_client(assistant) + return userbot + else: + userbot = await set_assistant(chat_id) + return userbot + + +async def set_calls_assistant(chat_id): + from DragMusic.core.userbot import assistants + + ran_assistant = random.choice(assistants) + assistantdict[chat_id] = ran_assistant + await assdb.update_one( + {"chat_id": chat_id}, + {"$set": {"assistant": ran_assistant}}, + upsert=True, + ) + return ran_assistant + + +async def group_assistant(self, chat_id: int) -> int: + from DragMusic.core.userbot import assistants + + assistant = assistantdict.get(chat_id) + if not assistant: + dbassistant = await assdb.find_one({"chat_id": chat_id}) + if not dbassistant: + assis = await set_calls_assistant(chat_id) + else: + assis = dbassistant["assistant"] + if assis in assistants: + assistantdict[chat_id] = assis + assis = assis + else: + assis = await set_calls_assistant(chat_id) + else: + if assistant in assistants: + assis = assistant + else: + assis = await set_calls_assistant(chat_id) + if int(assis) == 1: + return self.one + elif int(assis) == 2: + return self.two + elif int(assis) == 3: + return self.three + elif int(assis) == 4: + return self.four + elif int(assis) == 5: + return self.five + + +async def is_skipmode(chat_id: int) -> bool: + mode = skipmode.get(chat_id) + if not mode: + user = await skipdb.find_one({"chat_id": chat_id}) + if not user: + skipmode[chat_id] = True + return True + skipmode[chat_id] = False + return False + return mode + + +async def skip_on(chat_id: int): + skipmode[chat_id] = True + user = await skipdb.find_one({"chat_id": chat_id}) + if user: + return await skipdb.delete_one({"chat_id": chat_id}) + + +async def skip_off(chat_id: int): + skipmode[chat_id] = False + user = await skipdb.find_one({"chat_id": chat_id}) + if not user: + return await skipdb.insert_one({"chat_id": chat_id}) + + +async def get_upvote_count(chat_id: int) -> int: + mode = count.get(chat_id) + if not mode: + mode = await countdb.find_one({"chat_id": chat_id}) + if not mode: + return 5 + count[chat_id] = mode["mode"] + return mode["mode"] + return mode + + +async def set_upvotes(chat_id: int, mode: int): + count[chat_id] = mode + await countdb.update_one( + {"chat_id": chat_id}, {"$set": {"mode": mode}}, upsert=True + ) + + +async def is_autoend() -> bool: + chat_id = 1234 + user = await autoenddb.find_one({"chat_id": chat_id}) + if not user: + return False + return True + + +async def autoend_on(): + chat_id = 1234 + await autoenddb.insert_one({"chat_id": chat_id}) + + +async def autoend_off(): + chat_id = 1234 + await autoenddb.delete_one({"chat_id": chat_id}) + + +async def get_loop(chat_id: int) -> int: + lop = loop.get(chat_id) + if not lop: + return 0 + return lop + + +async def set_loop(chat_id: int, mode: int): + loop[chat_id] = mode + + +async def get_cmode(chat_id: int) -> int: + mode = channelconnect.get(chat_id) + if not mode: + mode = await channeldb.find_one({"chat_id": chat_id}) + if not mode: + return None + channelconnect[chat_id] = mode["mode"] + return mode["mode"] + return mode + + +async def set_cmode(chat_id: int, mode: int): + channelconnect[chat_id] = mode + await channeldb.update_one( + {"chat_id": chat_id}, {"$set": {"mode": mode}}, upsert=True + ) + + +async def get_playtype(chat_id: int) -> str: + mode = playtype.get(chat_id) + if not mode: + mode = await playtypedb.find_one({"chat_id": chat_id}) + if not mode: + playtype[chat_id] = "Everyone" + return "Everyone" + playtype[chat_id] = mode["mode"] + return mode["mode"] + return mode + + +async def set_playtype(chat_id: int, mode: str): + playtype[chat_id] = mode + await playtypedb.update_one( + {"chat_id": chat_id}, {"$set": {"mode": mode}}, upsert=True + ) + + +async def get_playmode(chat_id: int) -> str: + mode = playmode.get(chat_id) + if not mode: + mode = await playmodedb.find_one({"chat_id": chat_id}) + if not mode: + playmode[chat_id] = "Direct" + return "Direct" + playmode[chat_id] = mode["mode"] + return mode["mode"] + return mode + + +async def set_playmode(chat_id: int, mode: str): + playmode[chat_id] = mode + await playmodedb.update_one( + {"chat_id": chat_id}, {"$set": {"mode": mode}}, upsert=True + ) + + +async def get_lang(chat_id: int) -> str: + mode = langm.get(chat_id) + if not mode: + lang = await langdb.find_one({"chat_id": chat_id}) + if not lang: + langm[chat_id] = "en" + return "en" + langm[chat_id] = lang["lang"] + return lang["lang"] + return mode + + +async def set_lang(chat_id: int, lang: str): + langm[chat_id] = lang + await langdb.update_one({"chat_id": chat_id}, {"$set": {"lang": lang}}, upsert=True) + + +async def is_music_playing(chat_id: int) -> bool: + mode = pause.get(chat_id) + if not mode: + return False + return mode + + +async def music_on(chat_id: int): + pause[chat_id] = True + + +async def music_off(chat_id: int): + pause[chat_id] = False + + +async def get_active_chats() -> list: + return active + + +async def is_active_chat(chat_id: int) -> bool: + if chat_id not in active: + return False + else: + return True + + +async def add_active_chat(chat_id: int): + if chat_id not in active: + active.append(chat_id) + + +async def remove_active_chat(chat_id: int): + if chat_id in active: + active.remove(chat_id) + + +async def get_active_video_chats() -> list: + return activevideo + + +async def is_active_video_chat(chat_id: int) -> bool: + if chat_id not in activevideo: + return False + else: + return True + + +async def add_active_video_chat(chat_id: int): + if chat_id not in activevideo: + activevideo.append(chat_id) + + +async def remove_active_video_chat(chat_id: int): + if chat_id in activevideo: + activevideo.remove(chat_id) + + +async def check_nonadmin_chat(chat_id: int) -> bool: + user = await authdb.find_one({"chat_id": chat_id}) + if not user: + return False + return True + + +async def is_nonadmin_chat(chat_id: int) -> bool: + mode = nonadmin.get(chat_id) + if not mode: + user = await authdb.find_one({"chat_id": chat_id}) + if not user: + nonadmin[chat_id] = False + return False + nonadmin[chat_id] = True + return True + return mode + + +async def add_nonadmin_chat(chat_id: int): + nonadmin[chat_id] = True + is_admin = await check_nonadmin_chat(chat_id) + if is_admin: + return + return await authdb.insert_one({"chat_id": chat_id}) + + +async def remove_nonadmin_chat(chat_id: int): + nonadmin[chat_id] = False + is_admin = await check_nonadmin_chat(chat_id) + if not is_admin: + return + return await authdb.delete_one({"chat_id": chat_id}) + + +async def is_on_off(on_off: int) -> bool: + onoff = await onoffdb.find_one({"on_off": on_off}) + if not onoff: + return False + return True + + +async def add_on(on_off: int): + is_on = await is_on_off(on_off) + if is_on: + return + return await onoffdb.insert_one({"on_off": on_off}) + + +async def add_off(on_off: int): + is_off = await is_on_off(on_off) + if not is_off: + return + return await onoffdb.delete_one({"on_off": on_off}) + + +async def is_maintenance(): + if not maintenance: + get = await onoffdb.find_one({"on_off": 1}) + if not get: + maintenance.clear() + maintenance.append(2) + return True + else: + maintenance.clear() + maintenance.append(1) + return False + else: + if 1 in maintenance: + return False + else: + return True + + +async def maintenance_off(): + maintenance.clear() + maintenance.append(2) + is_off = await is_on_off(1) + if not is_off: + return + return await onoffdb.delete_one({"on_off": 1}) + + +async def maintenance_on(): + maintenance.clear() + maintenance.append(1) + is_on = await is_on_off(1) + if is_on: + return + return await onoffdb.insert_one({"on_off": 1}) + + +async def is_served_user(user_id: int) -> bool: + user = await usersdb.find_one({"user_id": user_id}) + if not user: + return False + return True + + +async def get_served_users() -> list: + users_list = [] + async for user in usersdb.find({"user_id": {"$gt": 0}}): + users_list.append(user) + return users_list + + +async def add_served_user(user_id: int): + is_served = await is_served_user(user_id) + if is_served: + return + return await usersdb.insert_one({"user_id": user_id}) + + +async def get_served_chats() -> list: + chats_list = [] + async for chat in chatsdb.find({"chat_id": {"$lt": 0}}): + chats_list.append(chat) + return chats_list + + +async def is_served_chat(chat_id: int) -> bool: + chat = await chatsdb.find_one({"chat_id": chat_id}) + if not chat: + return False + return True + + +async def add_served_chat(chat_id: int): + is_served = await is_served_chat(chat_id) + if is_served: + return + return await chatsdb.insert_one({"chat_id": chat_id}) + + +async def blacklisted_chats() -> list: + chats_list = [] + async for chat in blacklist_chatdb.find({"chat_id": {"$lt": 0}}): + chats_list.append(chat["chat_id"]) + return chats_list + + +async def blacklist_chat(chat_id: int) -> bool: + if not await blacklist_chatdb.find_one({"chat_id": chat_id}): + await blacklist_chatdb.insert_one({"chat_id": chat_id}) + return True + return False + + +async def whitelist_chat(chat_id: int) -> bool: + if await blacklist_chatdb.find_one({"chat_id": chat_id}): + await blacklist_chatdb.delete_one({"chat_id": chat_id}) + return True + return False + + +async def _get_authusers(chat_id: int) -> Dict[str, int]: + _notes = await authuserdb.find_one({"chat_id": chat_id}) + if not _notes: + return {} + return _notes["notes"] + + +async def get_authuser_names(chat_id: int) -> List[str]: + _notes = [] + for note in await _get_authusers(chat_id): + _notes.append(note) + return _notes + + +async def get_authuser(chat_id: int, name: str) -> Union[bool, dict]: + name = name + _notes = await _get_authusers(chat_id) + if name in _notes: + return _notes[name] + else: + return False + + +async def save_authuser(chat_id: int, name: str, note: dict): + name = name + _notes = await _get_authusers(chat_id) + _notes[name] = note + + await authuserdb.update_one( + {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True + ) + + +async def delete_authuser(chat_id: int, name: str) -> bool: + notesd = await _get_authusers(chat_id) + name = name + if name in notesd: + del notesd[name] + await authuserdb.update_one( + {"chat_id": chat_id}, + {"$set": {"notes": notesd}}, + upsert=True, + ) + return True + return False + + +async def get_gbanned() -> list: + results = [] + async for user in gbansdb.find({"user_id": {"$gt": 0}}): + user_id = user["user_id"] + results.append(user_id) + return results + + +async def is_gbanned_user(user_id: int) -> bool: + user = await gbansdb.find_one({"user_id": user_id}) + if not user: + return False + return True + + +async def add_gban_user(user_id: int): + is_gbanned = await is_gbanned_user(user_id) + if is_gbanned: + return + return await gbansdb.insert_one({"user_id": user_id}) + + +async def remove_gban_user(user_id: int): + is_gbanned = await is_gbanned_user(user_id) + if not is_gbanned: + return + return await gbansdb.delete_one({"user_id": user_id}) + + +async def get_sudoers() -> list: + sudoers = await sudoersdb.find_one({"sudo": "sudo"}) + if not sudoers: + return [] + return sudoers["sudoers"] + + +async def add_sudo(user_id: int) -> bool: + sudoers = await get_sudoers() + sudoers.append(user_id) + await sudoersdb.update_one( + {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True + ) + return True + + +async def remove_sudo(user_id: int) -> bool: + sudoers = await get_sudoers() + sudoers.remove(user_id) + await sudoersdb.update_one( + {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True + ) + return True + + +async def get_banned_users() -> list: + results = [] + async for user in blockeddb.find({"user_id": {"$gt": 0}}): + user_id = user["user_id"] + results.append(user_id) + return results + + +async def get_banned_count() -> int: + users = blockeddb.find({"user_id": {"$gt": 0}}) + users = await users.to_list(length=100000) + return len(users) + + +async def is_banned_user(user_id: int) -> bool: + user = await blockeddb.find_one({"user_id": user_id}) + if not user: + return False + return True + + +async def add_banned_user(user_id: int): + is_gbanned = await is_banned_user(user_id) + if is_gbanned: + return + return await blockeddb.insert_one({"user_id": user_id}) + + +async def remove_banned_user(user_id: int): + is_gbanned = await is_banned_user(user_id) + if not is_gbanned: + return + return await blockeddb.delete_one({"user_id": user_id}) diff --git a/DragMusic/utils/decorators/__init__.py b/DragMusic/utils/decorators/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c1e9ec3f1b6e7a9b181df44d5389b67b191c0b29 --- /dev/null +++ b/DragMusic/utils/decorators/__init__.py @@ -0,0 +1,2 @@ +from .admins import * +from .language import * diff --git a/DragMusic/utils/decorators/admins.py b/DragMusic/utils/decorators/admins.py new file mode 100644 index 0000000000000000000000000000000000000000..fcf2380c9904b0b4e1b95a977bffbaea1ee59215 --- /dev/null +++ b/DragMusic/utils/decorators/admins.py @@ -0,0 +1,203 @@ +from pyrogram.enums import ChatType +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +from DragMusic import app +from DragMusic.misc import SUDOERS, db +from DragMusic.utils.database import ( + get_authuser_names, + get_cmode, + get_lang, + get_upvote_count, + is_active_chat, + is_maintenance, + is_nonadmin_chat, + is_skipmode, +) +from config import SUPPORT_CHAT, adminlist, confirmer +from strings import get_string + +from ..formatters import int_to_alpha + + +def AdminRightsCheck(mystic): + async def wrapper(client, message): + if await is_maintenance() is False: + if message.from_user.id not in SUDOERS: + return await message.reply_text( + text=f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + disable_web_page_preview=True, + ) + + try: + await message.delete() + except: + pass + + try: + language = await get_lang(message.chat.id) + _ = get_string(language) + except: + _ = get_string("en") + if message.sender_chat: + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ʜᴏᴡ ᴛᴏ ғɪx ?", + callback_data="DragmousAdmin", + ), + ] + ] + ) + return await message.reply_text(_["general_3"], reply_markup=upl) + if message.command[0][0] == "c": + chat_id = await get_cmode(message.chat.id) + if chat_id is None: + return await message.reply_text(_["setting_7"]) + try: + await app.get_chat(chat_id) + except: + return await message.reply_text(_["cplay_4"]) + else: + chat_id = message.chat.id + if not await is_active_chat(chat_id): + return await message.reply_text(_["general_5"]) + is_non_admin = await is_nonadmin_chat(message.chat.id) + if not is_non_admin: + if message.from_user.id not in SUDOERS: + admins = adminlist.get(message.chat.id) + if not admins: + return await message.reply_text(_["admin_13"]) + else: + if message.from_user.id not in admins: + if await is_skipmode(message.chat.id): + upvote = await get_upvote_count(chat_id) + text = f"""ᴀᴅᴍɪɴ ʀɪɢʜᴛs ɴᴇᴇᴅᴇᴅ + +ʀᴇғʀᴇsʜ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ᴠɪᴀ : /reload + +» {upvote} ᴠᴏᴛᴇs ɴᴇᴇᴅᴇᴅ ғᴏʀ ᴘᴇʀғᴏʀᴍɪɴɢ ᴛʜɪs ᴀᴄᴛɪᴏɴ.""" + + command = message.command[0] + if command[0] == "c": + command = command[1:] + if command == "speed": + return await message.reply_text(_["admin_14"]) + MODE = command.title() + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ᴠᴏᴛᴇ", + callback_data=f"ADMIN UpVote|{chat_id}_{MODE}", + ), + ] + ] + ) + if chat_id not in confirmer: + confirmer[chat_id] = {} + try: + vidid = db[chat_id][0]["vidid"] + file = db[chat_id][0]["file"] + except: + return await message.reply_text(_["admin_14"]) + senn = await message.reply_text(text, reply_markup=upl) + confirmer[chat_id][senn.id] = { + "vidid": vidid, + "file": file, + } + return + else: + return await message.reply_text(_["admin_14"]) + + return await mystic(client, message, _, chat_id) + + return wrapper + + +def AdminActual(mystic): + async def wrapper(client, message): + if await is_maintenance() is False: + if message.from_user.id not in SUDOERS: + return await message.reply_text( + text=f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + disable_web_page_preview=True, + ) + + try: + await message.delete() + except: + pass + + try: + language = await get_lang(message.chat.id) + _ = get_string(language) + except: + _ = get_string("en") + if message.sender_chat: + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ʜᴏᴡ ᴛᴏ ғɪx ?", + callback_data="DragmousAdmin", + ), + ] + ] + ) + return await message.reply_text(_["general_3"], reply_markup=upl) + if message.from_user.id not in SUDOERS: + try: + member = ( + await app.get_chat_member(message.chat.id, message.from_user.id) + ).privileges + except: + return + if not member.can_manage_video_chats: + return await message.reply(_["general_4"]) + return await mystic(client, message, _) + + return wrapper + + +def ActualAdminCB(mystic): + async def wrapper(client, CallbackQuery): + if await is_maintenance() is False: + if CallbackQuery.from_user.id not in SUDOERS: + return await CallbackQuery.answer( + f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + show_alert=True, + ) + try: + language = await get_lang(CallbackQuery.message.chat.id) + _ = get_string(language) + except: + _ = get_string("en") + if CallbackQuery.message.chat.type == ChatType.PRIVATE: + return await mystic(client, CallbackQuery, _) + is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) + if not is_non_admin: + try: + a = ( + await app.get_chat_member( + CallbackQuery.message.chat.id, + CallbackQuery.from_user.id, + ) + ).privileges + except: + return await CallbackQuery.answer(_["general_4"], show_alert=True) + if not a.can_manage_video_chats: + if CallbackQuery.from_user.id not in SUDOERS: + token = await int_to_alpha(CallbackQuery.from_user.id) + _check = await get_authuser_names(CallbackQuery.from_user.id) + if token not in _check: + try: + return await CallbackQuery.answer( + _["general_4"], + show_alert=True, + ) + except: + return + return await mystic(client, CallbackQuery, _) + + return wrapper diff --git a/DragMusic/utils/decorators/language.py b/DragMusic/utils/decorators/language.py new file mode 100644 index 0000000000000000000000000000000000000000..00ce1e41f467f641c17697f48724870d63bfecf8 --- /dev/null +++ b/DragMusic/utils/decorators/language.py @@ -0,0 +1,59 @@ +from strings import get_string + +from DragMusic import app +from DragMusic.misc import SUDOERS +from config import SUPPORT_CHAT +from DragMusic.utils.database import get_lang, is_maintenance + + +def language(mystic): + async def wrapper(_, message, **kwargs): + if await is_maintenance() is False: + if message.from_user.id not in SUDOERS: + return await message.reply_text( + text=f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + disable_web_page_preview=True, + ) + try: + await message.delete() + except: + pass + + try: + language = await get_lang(message.chat.id) + language = get_string(language) + except: + language = get_string("en") + return await mystic(_, message, language) + + return wrapper + + +def languageCB(mystic): + async def wrapper(_, CallbackQuery, **kwargs): + if await is_maintenance() is False: + if CallbackQuery.from_user.id not in SUDOERS: + return await CallbackQuery.answer( + f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + show_alert=True, + ) + try: + language = await get_lang(CallbackQuery.message.chat.id) + language = get_string(language) + except: + language = get_string("en") + return await mystic(_, CallbackQuery, language) + + return wrapper + + +def LanguageStart(mystic): + async def wrapper(_, message, **kwargs): + try: + language = await get_lang(message.chat.id) + language = get_string(language) + except: + language = get_string("en") + return await mystic(_, message, language) + + return wrapper diff --git a/DragMusic/utils/decorators/play.py b/DragMusic/utils/decorators/play.py new file mode 100644 index 0000000000000000000000000000000000000000..685aaae4084e79e24781a03dce2ef1d720a06776 --- /dev/null +++ b/DragMusic/utils/decorators/play.py @@ -0,0 +1,195 @@ +import asyncio + +from pyrogram.enums import ChatMemberStatus +from pyrogram.errors import ( + ChatAdminRequired, + InviteRequestSent, + UserAlreadyParticipant, + UserNotParticipant, +) +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +from DragMusic import YouTube, app +from DragMusic.misc import SUDOERS +from DragMusic.utils.database import ( + get_assistant, + get_cmode, + get_lang, + get_playmode, + get_playtype, + is_active_chat, + is_maintenance, +) +from DragMusic.utils.inline import botplaylist_markup +from config import PLAYLIST_IMG_URL, SUPPORT_CHAT, adminlist +from strings import get_string + +links = {} + + +def PlayWrapper(command): + async def wrapper(client, message): + language = await get_lang(message.chat.id) + _ = get_string(language) + if message.sender_chat: + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="ʜᴏᴡ ᴛᴏ ғɪx ?", + callback_data="DragmousAdmin", + ), + ] + ] + ) + return await message.reply_text(_["general_3"], reply_markup=upl) + + if await is_maintenance() is False: + if message.from_user.id not in SUDOERS: + return await message.reply_text( + text=f"{app.mention} ɪs ᴜɴᴅᴇʀ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ, ᴠɪsɪᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ ғᴏʀ ᴋɴᴏᴡɪɴɢ ᴛʜᴇ ʀᴇᴀsᴏɴ.", + disable_web_page_preview=True, + ) + + try: + await message.delete() + except: + pass + + audio_telegram = ( + (message.reply_to_message.audio or message.reply_to_message.voice) + if message.reply_to_message + else None + ) + video_telegram = ( + (message.reply_to_message.video or message.reply_to_message.document) + if message.reply_to_message + else None + ) + url = await YouTube.url(message) + if audio_telegram is None and video_telegram is None and url is None: + if len(message.command) < 2: + if "stream" in message.command: + return await message.reply_text(_["str_1"]) + buttons = botplaylist_markup(_) + return await message.reply_photo( + photo=PLAYLIST_IMG_URL, + caption=_["play_18"], + reply_markup=InlineKeyboardMarkup(buttons), + ) + if message.command[0][0] == "c": + chat_id = await get_cmode(message.chat.id) + if chat_id is None: + return await message.reply_text(_["setting_7"]) + try: + chat = await app.get_chat(chat_id) + except: + return await message.reply_text(_["cplay_4"]) + channel = chat.title + else: + chat_id = message.chat.id + channel = None + playmode = await get_playmode(message.chat.id) + playty = await get_playtype(message.chat.id) + if playty != "Everyone": + if message.from_user.id not in SUDOERS: + admins = adminlist.get(message.chat.id) + if not admins: + return await message.reply_text(_["admin_13"]) + else: + if message.from_user.id not in admins: + return await message.reply_text(_["play_4"]) + if message.command[0][0] == "v": + video = True + else: + if "-v" in message.text: + video = True + else: + video = True if message.command[0][1] == "v" else None + if message.command[0][-1] == "e": + if not await is_active_chat(chat_id): + return await message.reply_text(_["play_16"]) + fplay = True + else: + fplay = None + + if not await is_active_chat(chat_id): + userbot = await get_assistant(chat_id) + try: + try: + get = await app.get_chat_member(chat_id, userbot.id) + except ChatAdminRequired: + return await message.reply_text(_["call_1"]) + if ( + get.status == ChatMemberStatus.BANNED + or get.status == ChatMemberStatus.RESTRICTED + ): + return await message.reply_text( + _["call_2"].format( + app.mention, userbot.id, userbot.name, userbot.username + ) + ) + except UserNotParticipant: + if chat_id in links: + invitelink = links[chat_id] + else: + if message.chat.username: + invitelink = message.chat.username + try: + await userbot.resolve_peer(invitelink) + except: + pass + else: + try: + invitelink = await app.export_chat_invite_link(chat_id) + except ChatAdminRequired: + return await message.reply_text(_["call_1"]) + except Exception as e: + return await message.reply_text( + _["call_3"].format(app.mention, type(e).__name__) + ) + + if invitelink.startswith("https://t.me/+"): + invitelink = invitelink.replace( + "https://t.me/+", "https://t.me/joinchat/" + ) + myu = await message.reply_text(_["call_4"].format(app.mention)) + try: + await asyncio.sleep(1) + await userbot.join_chat(invitelink) + except InviteRequestSent: + try: + await app.approve_chat_join_request(chat_id, userbot.id) + except Exception as e: + return await message.reply_text( + _["call_3"].format(app.mention, type(e).__name__) + ) + await asyncio.sleep(3) + await myu.edit(_["call_5"].format(app.mention)) + except UserAlreadyParticipant: + pass + except Exception as e: + return await message.reply_text( + _["call_3"].format(app.mention, type(e).__name__) + ) + + links[chat_id] = invitelink + + try: + await userbot.resolve_peer(chat_id) + except: + pass + + return await command( + client, + message, + _, + chat_id, + video, + channel, + playmode, + url, + fplay, + ) + + return wrapper diff --git a/DragMusic/utils/exceptions.py b/DragMusic/utils/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..c28414d73415baf1ce1e93068e5a8edcdbbcafbe --- /dev/null +++ b/DragMusic/utils/exceptions.py @@ -0,0 +1,3 @@ +class AssistantErr(Exception): + def __init__(self, errr: str): + super().__init__(errr) diff --git a/DragMusic/utils/extraction.py b/DragMusic/utils/extraction.py new file mode 100644 index 0000000000000000000000000000000000000000..1b22ccddc56b9b2feeb565468553a285bcdfd0b9 --- /dev/null +++ b/DragMusic/utils/extraction.py @@ -0,0 +1,17 @@ +from pyrogram.enums import MessageEntityType +from pyrogram.types import Message, User + +from DragMusic import app + + +async def extract_user(m: Message) -> User: + if m.reply_to_message: + return m.reply_to_message.from_user + msg_entities = m.entities[1] if m.text.startswith("/") else m.entities[0] + return await app.get_users( + msg_entities.user.id + if msg_entities.type == MessageEntityType.TEXT_MENTION + else int(m.command[1]) + if m.command[1].isdecimal() + else m.command[1] + ) diff --git a/DragMusic/utils/formatters.py b/DragMusic/utils/formatters.py new file mode 100644 index 0000000000000000000000000000000000000000..c0077e5ca959c6323a2aea356a101d41a2377006 --- /dev/null +++ b/DragMusic/utils/formatters.py @@ -0,0 +1,185 @@ +import json +import subprocess + + +def get_readable_time(seconds: int) -> str: + count = 0 + ping_time = "" + time_list = [] + time_suffix_list = ["s", "ᴍ", "ʜ", "ᴅᴀʏs"] + while count < 4: + count += 1 + if count < 3: + remainder, result = divmod(seconds, 60) + else: + remainder, result = divmod(seconds, 24) + if seconds == 0 and remainder == 0: + break + time_list.append(int(result)) + seconds = int(remainder) + for i in range(len(time_list)): + time_list[i] = str(time_list[i]) + time_suffix_list[i] + if len(time_list) == 4: + ping_time += time_list.pop() + ", " + time_list.reverse() + ping_time += ":".join(time_list) + return ping_time + + +def convert_bytes(size: float) -> str: + """humanize size""" + if not size: + return "" + power = 1024 + t_n = 0 + power_dict = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} + while size > power: + size /= power + t_n += 1 + return "{:.2f} {}B".format(size, power_dict[t_n]) + + +async def int_to_alpha(user_id: int) -> str: + alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] + text = "" + user_id = str(user_id) + for i in user_id: + text += alphabet[int(i)] + return text + + +async def alpha_to_int(user_id_alphabet: str) -> int: + alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] + user_id = "" + for i in user_id_alphabet: + index = alphabet.index(i) + user_id += str(index) + user_id = int(user_id) + return user_id + + +def time_to_seconds(time): + stringt = str(time) + return sum(int(x) * 60**i for i, x in enumerate(reversed(stringt.split(":")))) + + +def seconds_to_min(seconds): + if seconds is not None: + seconds = int(seconds) + d, h, m, s = ( + seconds // (3600 * 24), + seconds // 3600 % 24, + seconds % 3600 // 60, + seconds % 3600 % 60, + ) + if d > 0: + return "{:02d}:{:02d}:{:02d}:{:02d}".format(d, h, m, s) + elif h > 0: + return "{:02d}:{:02d}:{:02d}".format(h, m, s) + elif m > 0: + return "{:02d}:{:02d}".format(m, s) + elif s > 0: + return "00:{:02d}".format(s) + return "-" + + +def speed_converter(seconds, speed): + if str(speed) == str("0.5"): + seconds = seconds * 2 + if str(speed) == str("0.75"): + seconds = seconds + ((50 * seconds) // 100) + if str(speed) == str("1.5"): + seconds = seconds - ((25 * seconds) // 100) + if str(speed) == str("2.0"): + seconds = seconds - ((50 * seconds) // 100) + collect = seconds + if seconds is not None: + seconds = int(seconds) + d, h, m, s = ( + seconds // (3600 * 24), + seconds // 3600 % 24, + seconds % 3600 // 60, + seconds % 3600 % 60, + ) + if d > 0: + convert = "{:02d}:{:02d}:{:02d}:{:02d}".format(d, h, m, s) + return convert, collect + elif h > 0: + convert = "{:02d}:{:02d}:{:02d}".format(h, m, s) + return convert, collect + elif m > 0: + convert = "{:02d}:{:02d}".format(m, s) + return convert, collect + elif s > 0: + convert = "00:{:02d}".format(s) + return convert, collect + return "-" + + +def check_duration(file_path): + command = [ + "ffprobe", + "-loglevel", + "quiet", + "-print_format", + "json", + "-show_format", + "-show_streams", + file_path, + ] + + pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + out, err = pipe.communicate() + _json = json.loads(out) + + if "format" in _json: + if "duration" in _json["format"]: + return float(_json["format"]["duration"]) + + if "streams" in _json: + for s in _json["streams"]: + if "duration" in s: + return float(s["duration"]) + + return "Unknown" + + +formats = [ + "webm", + "mkv", + "flv", + "vob", + "ogv", + "ogg", + "rrc", + "gifv", + "mng", + "mov", + "avi", + "qt", + "wmv", + "yuv", + "rm", + "asf", + "amv", + "mp4", + "m4p", + "m4v", + "mpg", + "mp2", + "mpeg", + "mpe", + "mpv", + "m4v", + "svi", + "3gp", + "3g2", + "mxf", + "roq", + "nsv", + "flv", + "f4v", + "f4p", + "f4a", + "f4b", +] diff --git a/DragMusic/utils/inline/__init__.py b/DragMusic/utils/inline/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0e5871b91d513b6ea3aa284b3a7f8ab5ac4c726f --- /dev/null +++ b/DragMusic/utils/inline/__init__.py @@ -0,0 +1,7 @@ +from .extras import * +from .help import * +from .play import * +from .queue import * +from .settings import * +from .speed import * +from .start import * diff --git a/DragMusic/utils/inline/extras.py b/DragMusic/utils/inline/extras.py new file mode 100644 index 0000000000000000000000000000000000000000..7156033f4cfd0dcf5012cb1870ca56a0e84430f6 --- /dev/null +++ b/DragMusic/utils/inline/extras.py @@ -0,0 +1,41 @@ +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +from config import SUPPORT_CHAT + + +def botplaylist_markup(_): + buttons = [ + [ + InlineKeyboardButton(text=_["S_B_9"], url=SUPPORT_CHAT), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def close_markup(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ] + ] + ) + return upl + + +def supp_markup(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["S_B_9"], + url=SUPPORT_CHAT, + ), + ] + ] + ) + return upl diff --git a/DragMusic/utils/inline/help.py b/DragMusic/utils/inline/help.py new file mode 100644 index 0000000000000000000000000000000000000000..07381345214fdc1df10a3af6b5a3a648f407d495 --- /dev/null +++ b/DragMusic/utils/inline/help.py @@ -0,0 +1,118 @@ +from typing import Union + +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + +from DragMusic import app + + +def help_pannel(_, START: Union[bool, int] = None): + first = [InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data=f"close")] + second = [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data=f"settingsback_helper", + ), + ] + mark = second if START else first + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["H_B_1"], + callback_data="help_callback hb1", + ), + InlineKeyboardButton( + text=_["H_B_2"], + callback_data="help_callback hb2", + ), + InlineKeyboardButton( + text=_["H_B_3"], + callback_data="help_callback hb3", + ), + ], + [ + InlineKeyboardButton( + text=_["H_B_4"], + callback_data="help_callback hb4", + ), + InlineKeyboardButton( + text=_["H_B_5"], + callback_data="help_callback hb5", + ), + InlineKeyboardButton( + text=_["H_B_6"], + callback_data="help_callback hb6", + ), + ], + [ + InlineKeyboardButton( + text=_["H_B_7"], + callback_data="help_callback hb7", + ), + InlineKeyboardButton( + text=_["H_B_8"], + callback_data="help_callback hb8", + ), + InlineKeyboardButton( + text=_["H_B_9"], + callback_data="help_callback hb9", + ), + ], + [ + InlineKeyboardButton( + text=_["H_B_10"], + callback_data="help_callback hb10", + ), + InlineKeyboardButton( + text=_["H_B_11"], + callback_data="help_callback hb11", + ), + InlineKeyboardButton( + text=_["H_B_12"], + callback_data="help_callback hb12", + ), + ], + [ + InlineKeyboardButton( + text=_["H_B_13"], + callback_data="help_callback hb13", + ), + InlineKeyboardButton( + text=_["H_B_14"], + callback_data="help_callback hb14", + ), + InlineKeyboardButton( + text=_["H_B_15"], + callback_data="help_callback hb15", + ), + ], + mark, + ] + ) + return upl + + +def help_back_markup(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data=f"settings_back_helper", + ), + ] + ] + ) + return upl + + +def private_help_panel(_): + buttons = [ + [ + InlineKeyboardButton( + text=_["S_B_4"], + url=f"https://t.me/{app.username}?start=help", + ), + ], + ] + return buttons diff --git a/DragMusic/utils/inline/play.py b/DragMusic/utils/inline/play.py new file mode 100644 index 0000000000000000000000000000000000000000..b20d06c0f1af72ad8ed484b90aaa5a884c116c1e --- /dev/null +++ b/DragMusic/utils/inline/play.py @@ -0,0 +1,156 @@ +import math + +from pyrogram.types import InlineKeyboardButton + +from DragMusic.utils.formatters import time_to_seconds + + +def track_markup(_, videoid, user_id, channel, fplay): + buttons = [ + [ + InlineKeyboardButton( + text=_["P_B_1"], + callback_data=f"MusicStream {videoid}|{user_id}|a|{channel}|{fplay}", + ), + InlineKeyboardButton( + text=_["P_B_2"], + callback_data=f"MusicStream {videoid}|{user_id}|v|{channel}|{fplay}", + ), + ], + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data=f"forceclose {videoid}|{user_id}", + ) + ], + ] + return buttons + + +def stream_markup_timer(_, chat_id, played, dur): + played_sec = time_to_seconds(played) + duration_sec = time_to_seconds(dur) + percentage = (played_sec / duration_sec) * 100 + umm = math.floor(percentage) + if 0 < umm <= 10: + bar = "◉—————————" + elif 10 < umm < 20: + bar = "—◉————————" + elif 20 <= umm < 30: + bar = "——◉———————" + elif 30 <= umm < 40: + bar = "———◉——————" + elif 40 <= umm < 50: + bar = "————◉—————" + elif 50 <= umm < 60: + bar = "—————◉————" + elif 60 <= umm < 70: + bar = "——————◉———" + elif 70 <= umm < 80: + bar = "———————◉——" + elif 80 <= umm < 95: + bar = "————————◉—" + else: + bar = "—————————◉" + buttons = [ + [ + InlineKeyboardButton(text="▷", callback_data=f"ADMIN Resume|{chat_id}"), + InlineKeyboardButton(text="II", callback_data=f"ADMIN Pause|{chat_id}"), + InlineKeyboardButton(text="↻", callback_data=f"ADMIN Replay|{chat_id}"), + InlineKeyboardButton(text="‣‣I", callback_data=f"ADMIN Skip|{chat_id}"), + InlineKeyboardButton(text="▢", callback_data=f"ADMIN Stop|{chat_id}"), + ], + [ + InlineKeyboardButton( + text=f"{played} {bar} {dur}", + callback_data="GetTimer", + ) + ], + [InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close")], + ] + return buttons + + +def stream_markup(_, chat_id): + buttons = [ + [ + InlineKeyboardButton(text="▷", callback_data=f"ADMIN Resume|{chat_id}"), + InlineKeyboardButton(text="II", callback_data=f"ADMIN Pause|{chat_id}"), + InlineKeyboardButton(text="↻", callback_data=f"ADMIN Replay|{chat_id}"), + InlineKeyboardButton(text="‣‣I", callback_data=f"ADMIN Skip|{chat_id}"), + InlineKeyboardButton(text="▢", callback_data=f"ADMIN Stop|{chat_id}"), + ], + [InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close")], + ] + return buttons + + +def playlist_markup(_, videoid, user_id, ptype, channel, fplay): + buttons = [ + [ + InlineKeyboardButton( + text=_["P_B_1"], + callback_data=f"DragPlaylists {videoid}|{user_id}|{ptype}|a|{channel}|{fplay}", + ), + InlineKeyboardButton( + text=_["P_B_2"], + callback_data=f"DragPlaylists {videoid}|{user_id}|{ptype}|v|{channel}|{fplay}", + ), + ], + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data=f"forceclose {videoid}|{user_id}", + ), + ], + ] + return buttons + + +def livestream_markup(_, videoid, user_id, mode, channel, fplay): + buttons = [ + [ + InlineKeyboardButton( + text=_["P_B_3"], + callback_data=f"LiveStream {videoid}|{user_id}|{mode}|{channel}|{fplay}", + ), + ], + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data=f"forceclose {videoid}|{user_id}", + ), + ], + ] + return buttons + + +def slider_markup(_, videoid, user_id, query, query_type, channel, fplay): + query = f"{query[:20]}" + buttons = [ + [ + InlineKeyboardButton( + text=_["P_B_1"], + callback_data=f"MusicStream {videoid}|{user_id}|a|{channel}|{fplay}", + ), + InlineKeyboardButton( + text=_["P_B_2"], + callback_data=f"MusicStream {videoid}|{user_id}|v|{channel}|{fplay}", + ), + ], + [ + InlineKeyboardButton( + text="◁", + callback_data=f"slider B|{query_type}|{query}|{user_id}|{channel}|{fplay}", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data=f"forceclose {query}|{user_id}", + ), + InlineKeyboardButton( + text="▷", + callback_data=f"slider F|{query_type}|{query}|{user_id}|{channel}|{fplay}", + ), + ], + ] + return buttons diff --git a/DragMusic/utils/inline/playlist.py b/DragMusic/utils/inline/playlist.py new file mode 100644 index 0000000000000000000000000000000000000000..96f17f968b1902ca7b4fa79bf12dd19f65916eae --- /dev/null +++ b/DragMusic/utils/inline/playlist.py @@ -0,0 +1,107 @@ +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + + +def botplaylist_markup(_): + buttons = [ + [ + InlineKeyboardButton( + text=_["PL_B_1"], + callback_data="get_playlist_playmode", + ), + ], + [ + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def top_play_markup(_): + buttons = [ + [InlineKeyboardButton(text=_["PL_B_9"], callback_data="SERVERTOP global")], + [InlineKeyboardButton(text=_["PL_B_10"], callback_data="SERVERTOP chat")], + [InlineKeyboardButton(text=_["PL_B_11"], callback_data="SERVERTOP user")], + [ + InlineKeyboardButton(text=_["BACK_BUTTON"], callback_data="get_playmarkup"), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def get_playlist_markup(_): + buttons = [ + [ + InlineKeyboardButton(text=_["P_B_1"], callback_data="play_playlist a"), + InlineKeyboardButton(text=_["P_B_2"], callback_data="play_playlist v"), + ], + [ + InlineKeyboardButton(text=_["BACK_BUTTON"], callback_data="home_play"), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def top_play_markup(_): + buttons = [ + [InlineKeyboardButton(text=_["PL_B_9"], callback_data="SERVERTOP Global")], + [InlineKeyboardButton(text=_["PL_B_10"], callback_data="SERVERTOP Group")], + [InlineKeyboardButton(text=_["PL_B_11"], callback_data="SERVERTOP Personal")], + [ + InlineKeyboardButton(text=_["BACK_BUTTON"], callback_data="get_playmarkup"), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def failed_top_markup(_): + buttons = [ + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="get_top_playlists", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def warning_markup(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["PL_B_7"], + callback_data="delete_whole_playlist", + ), + ], + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="del_back_playlist", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ], + ] + ) + return upl + + +def close_markup(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ] + ] + ) + return upl diff --git a/DragMusic/utils/inline/queue.py b/DragMusic/utils/inline/queue.py new file mode 100644 index 0000000000000000000000000000000000000000..15180b1d19d91d58755480e34058705bdad58f06 --- /dev/null +++ b/DragMusic/utils/inline/queue.py @@ -0,0 +1,75 @@ +from typing import Union + +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + + +def queue_markup( + _, + DURATION, + CPLAY, + videoid, + played: Union[bool, int] = None, + dur: Union[bool, int] = None, +): + not_dur = [ + [ + InlineKeyboardButton( + text=_["QU_B_1"], + callback_data=f"GetQueued {CPLAY}|{videoid}", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ] + ] + dur = [ + [ + InlineKeyboardButton( + text=_["QU_B_2"].format(played, dur), + callback_data="GetTimer", + ) + ], + [ + InlineKeyboardButton( + text=_["QU_B_1"], + callback_data=f"GetQueued {CPLAY}|{videoid}", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ], + ] + upl = InlineKeyboardMarkup(not_dur if DURATION == "Unknown" else dur) + return upl + + +def queue_back_markup(_, CPLAY): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data=f"queue_back_timer {CPLAY}", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ] + ] + ) + return upl + + +def aq_markup(_, chat_id): + buttons = [ + [ + InlineKeyboardButton(text="▷", callback_data=f"ADMIN Resume|{chat_id}"), + InlineKeyboardButton(text="II", callback_data=f"ADMIN Pause|{chat_id}"), + InlineKeyboardButton(text="‣‣I", callback_data=f"ADMIN Skip|{chat_id}"), + InlineKeyboardButton(text="▢", callback_data=f"ADMIN Stop|{chat_id}"), + ], + ] + return buttons diff --git a/DragMusic/utils/inline/settings.py b/DragMusic/utils/inline/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e1de69512ea0a43e8b6c2612a973102837aca5 --- /dev/null +++ b/DragMusic/utils/inline/settings.py @@ -0,0 +1,112 @@ +from typing import Union + +from pyrogram.types import InlineKeyboardButton + + +def setting_markup(_): + buttons = [ + [ + InlineKeyboardButton(text=_["ST_B_1"], callback_data="AU"), + InlineKeyboardButton(text=_["ST_B_3"], callback_data="LG"), + ], + [ + InlineKeyboardButton(text=_["ST_B_2"], callback_data="PM"), + ], + [ + InlineKeyboardButton(text=_["ST_B_4"], callback_data="VM"), + ], + [ + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def vote_mode_markup(_, current, mode: Union[bool, str] = None): + buttons = [ + [ + InlineKeyboardButton(text="Vᴏᴛɪɴɢ ᴍᴏᴅᴇ ➜", callback_data="VOTEANSWER"), + InlineKeyboardButton( + text=_["ST_B_5"] if mode == True else _["ST_B_6"], + callback_data="VOMODECHANGE", + ), + ], + [ + InlineKeyboardButton(text="-2", callback_data="FERRARIUDTI M"), + InlineKeyboardButton( + text=f"ᴄᴜʀʀᴇɴᴛ : {current}", + callback_data="ANSWERVOMODE", + ), + InlineKeyboardButton(text="+2", callback_data="FERRARIUDTI A"), + ], + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="settings_helper", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def auth_users_markup(_, status: Union[bool, str] = None): + buttons = [ + [ + InlineKeyboardButton(text=_["ST_B_7"], callback_data="AUTHANSWER"), + InlineKeyboardButton( + text=_["ST_B_8"] if status == True else _["ST_B_9"], + callback_data="AUTH", + ), + ], + [ + InlineKeyboardButton(text=_["ST_B_1"], callback_data="AUTHLIST"), + ], + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="settings_helper", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons + + +def playmode_users_markup( + _, + Direct: Union[bool, str] = None, + Group: Union[bool, str] = None, + Playtype: Union[bool, str] = None, +): + buttons = [ + [ + InlineKeyboardButton(text=_["ST_B_10"], callback_data="SEARCHANSWER"), + InlineKeyboardButton( + text=_["ST_B_11"] if Direct == True else _["ST_B_12"], + callback_data="MODECHANGE", + ), + ], + [ + InlineKeyboardButton(text=_["ST_B_13"], callback_data="AUTHANSWER"), + InlineKeyboardButton( + text=_["ST_B_8"] if Group == True else _["ST_B_9"], + callback_data="CHANNELMODECHANGE", + ), + ], + [ + InlineKeyboardButton(text=_["ST_B_14"], callback_data="PLAYTYPEANSWER"), + InlineKeyboardButton( + text=_["ST_B_8"] if Playtype == True else _["ST_B_9"], + callback_data="PLAYTYPECHANGE", + ), + ], + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="settings_helper", + ), + InlineKeyboardButton(text=_["CLOSE_BUTTON"], callback_data="close"), + ], + ] + return buttons diff --git a/DragMusic/utils/inline/speed.py b/DragMusic/utils/inline/speed.py new file mode 100644 index 0000000000000000000000000000000000000000..fa4997d8cf7353a4191d76d52d32570a3a67becb --- /dev/null +++ b/DragMusic/utils/inline/speed.py @@ -0,0 +1,41 @@ +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + + +def speed_markup(_, chat_id): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🕒 0.5x", + callback_data=f"SpeedUP {chat_id}|0.5", + ), + InlineKeyboardButton( + text="🕓 0.75x", + callback_data=f"SpeedUP {chat_id}|0.75", + ), + ], + [ + InlineKeyboardButton( + text=_["P_B_4"], + callback_data=f"SpeedUP {chat_id}|1.0", + ), + ], + [ + InlineKeyboardButton( + text="🕤 1.5x", + callback_data=f"SpeedUP {chat_id}|1.5", + ), + InlineKeyboardButton( + text="🕛 2.0x", + callback_data=f"SpeedUP {chat_id}|2.0", + ), + ], + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ], + ] + ) + return upl diff --git a/DragMusic/utils/inline/start.py b/DragMusic/utils/inline/start.py new file mode 100644 index 0000000000000000000000000000000000000000..a75412f36bae217dfd800b33076c30e9f40bf1c0 --- /dev/null +++ b/DragMusic/utils/inline/start.py @@ -0,0 +1,33 @@ +from pyrogram.types import InlineKeyboardButton + +import config +from DragMusic import app + + +def start_panel(_): + buttons = [ + [ + InlineKeyboardButton( + text=_["S_B_1"], url=f"https://t.me/{app.username}?startgroup=true" + ), + InlineKeyboardButton(text=_["S_B_2"], url=config.SUPPORT_CHAT), + ], + ] + return buttons + + +def private_panel(_): + buttons = [ + [ + InlineKeyboardButton( + text=_["S_B_3"], + url=f"https://t.me/{app.username}?startgroup=true", + ) + ], + [InlineKeyboardButton(text=_["S_B_4"], callback_data="settings_back_helper")], + [ + InlineKeyboardButton(text=_["S_B_5"], user_id=config.OWNER_ID), + InlineKeyboardButton(text=_["S_B_6"], url=config.SUPPORT_CHANNEL), + ], + ] + return buttons diff --git a/DragMusic/utils/inline/stats.py b/DragMusic/utils/inline/stats.py new file mode 100644 index 0000000000000000000000000000000000000000..8bed88089ef601bd95a7bcb8a3819e799940c039 --- /dev/null +++ b/DragMusic/utils/inline/stats.py @@ -0,0 +1,50 @@ +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + + +def stats_buttons(_, status): + not_sudo = [ + InlineKeyboardButton( + text=_["SA_B_1"], + callback_data="TopOverall", + ) + ] + sudo = [ + InlineKeyboardButton( + text=_["SA_B_2"], + callback_data="bot_stats_sudo", + ), + InlineKeyboardButton( + text=_["SA_B_3"], + callback_data="TopOverall", + ), + ] + upl = InlineKeyboardMarkup( + [ + sudo if status else not_sudo, + [ + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ], + ] + ) + return upl + + +def back_stats_buttons(_): + upl = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=_["BACK_BUTTON"], + callback_data="stats_back", + ), + InlineKeyboardButton( + text=_["CLOSE_BUTTON"], + callback_data="close", + ), + ], + ] + ) + return upl diff --git a/DragMusic/utils/inlinequery.py b/DragMusic/utils/inlinequery.py new file mode 100644 index 0000000000000000000000000000000000000000..d86e06b163ac9af0074d02cf379f70e7b6a1ee74 --- /dev/null +++ b/DragMusic/utils/inlinequery.py @@ -0,0 +1,44 @@ +from pyrogram.types import InlineQueryResultArticle, InputTextMessageContent + +answer = [] + +answer.extend( + [ + InlineQueryResultArticle( + title="Pᴀᴜsᴇ", + description=f"ᴩᴀᴜsᴇ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/pause"), + ), + InlineQueryResultArticle( + title="Rᴇsᴜᴍᴇ", + description=f"ʀᴇsᴜᴍᴇ ᴛʜᴇ ᴩᴀᴜsᴇᴅ sᴛʀᴇᴀᴍ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/resume"), + ), + InlineQueryResultArticle( + title="Sᴋɪᴩ", + description=f"sᴋɪᴩ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ ᴀɴᴅ ᴍᴏᴠᴇs ᴛᴏ ᴛʜᴇ ɴᴇxᴛ sᴛʀᴇᴀᴍ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/skip"), + ), + InlineQueryResultArticle( + title="Eɴᴅ", + description="ᴇɴᴅ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/end"), + ), + InlineQueryResultArticle( + title="Sʜᴜғғʟᴇ", + description="sʜᴜғғʟᴇ ᴛʜᴇ ǫᴜᴇᴜᴇᴅ sᴏɴɢs ɪɴ ᴩʟᴀʏʟɪsᴛ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/shuffle"), + ), + InlineQueryResultArticle( + title="Lᴏᴏᴩ", + description="ʟᴏᴏᴩ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ ᴛʀᴀᴄᴋ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.", + thumb_url="https://telegra.ph/file/c5952790fa8235f499749.jpg", + input_message_content=InputTextMessageContent("/loop 3"), + ), + ] +) diff --git a/DragMusic/utils/logger.py b/DragMusic/utils/logger.py new file mode 100644 index 0000000000000000000000000000000000000000..b1dacedcd1247976d87cde44947a3c684a455091 --- /dev/null +++ b/DragMusic/utils/logger.py @@ -0,0 +1,30 @@ +from pyrogram.enums import ParseMode +from DragMusic import app +from DragMusic.utils.database import is_on_off +from config import LOGGER_ID + +async def play_logs(message, streamtype): + if await is_on_off(2): + logger_text = f""" +
{app.mention} ᴘʟᴀʏ ʟᴏɢ
+
ᴄʜᴀᴛ ɪᴅ : {message.chat.id} +ᴄʜᴀᴛ ɴᴀᴍᴇ : {message.chat.title} +ᴄʜᴀᴛ ᴜsᴇʀɴᴀᴍᴇ : @{message.chat.username}
+
ᴜsᴇʀ ɪᴅ : {message.from_user.id} +ɴᴀᴍᴇ : {message.from_user.mention} +ᴜsᴇʀɴᴀᴍᴇ : @{message.from_user.username}
+
ǫᴜᴇʀʏ : {message.text.split(None, 1)[1]} +sᴛʀᴇᴀᴍᴛʏᴘᴇ : {streamtype}
""" + + if message.chat.id != LOGGER_ID: + try: + await app.send_message( + chat_id=LOGGER_ID, + text=logger_text, + parse_mode=ParseMode.HTML, + disable_web_page_preview=True, + message_thread_id=12294 # Send to the specific thread + ) + except Exception as e: + print(f"Error sending log message: {e}") # Log the error for debugging + return diff --git a/DragMusic/utils/pastebin.py b/DragMusic/utils/pastebin.py new file mode 100644 index 0000000000000000000000000000000000000000..ada4b8de4ee88803498da2e276ed1b96428ed3c0 --- /dev/null +++ b/DragMusic/utils/pastebin.py @@ -0,0 +1,21 @@ +import aiohttp + +BASE = "https://batbin.me/" + + +async def post(url: str, *args, **kwargs): + async with aiohttp.ClientSession() as session: + async with session.post(url, *args, **kwargs) as resp: + try: + data = await resp.json() + except Exception: + data = await resp.text() + return data + + +async def DragBin(text): + resp = await post(f"{BASE}api/v2/paste", data=text) + if not resp["success"]: + return + link = BASE + resp["message"] + return link diff --git a/DragMusic/utils/stream/autoclear.py b/DragMusic/utils/stream/autoclear.py new file mode 100644 index 0000000000000000000000000000000000000000..92c8104634be834d711be84f4a88720ce617d8c5 --- /dev/null +++ b/DragMusic/utils/stream/autoclear.py @@ -0,0 +1,18 @@ +import os + +from config import autoclean + + +async def auto_clean(popped): + try: + rem = popped["file"] + autoclean.remove(rem) + count = autoclean.count(rem) + if count == 0: + if "vid_" not in rem or "live_" not in rem or "index_" not in rem: + try: + os.remove(rem) + except: + pass + except: + pass diff --git a/DragMusic/utils/stream/queue.py b/DragMusic/utils/stream/queue.py new file mode 100644 index 0000000000000000000000000000000000000000..bb5a2c4ca6139b557a26a1f59633fe32f575f425 --- /dev/null +++ b/DragMusic/utils/stream/queue.py @@ -0,0 +1,91 @@ +import asyncio +from typing import Union + +from DragMusic.misc import db +from DragMusic.utils.formatters import check_duration, seconds_to_min +from config import autoclean, time_to_seconds + + +async def put_queue( + chat_id, + original_chat_id, + file, + title, + duration, + user, + vidid, + user_id, + stream, + forceplay: Union[bool, str] = None, +): + title = title.title() + try: + duration_in_seconds = time_to_seconds(duration) - 3 + except: + duration_in_seconds = 0 + put = { + "title": title, + "dur": duration, + "streamtype": stream, + "by": user, + "user_id": user_id, + "chat_id": original_chat_id, + "file": file, + "vidid": vidid, + "seconds": duration_in_seconds, + "played": 0, + } + if forceplay: + check = db.get(chat_id) + if check: + check.insert(0, put) + else: + db[chat_id] = [] + db[chat_id].append(put) + else: + db[chat_id].append(put) + autoclean.append(file) + + +async def put_queue_index( + chat_id, + original_chat_id, + file, + title, + duration, + user, + vidid, + stream, + forceplay: Union[bool, str] = None, +): + if "20.212.146.162" in vidid: + try: + dur = await asyncio.get_event_loop().run_in_executor( + None, check_duration, vidid + ) + duration = seconds_to_min(dur) + except: + duration = "ᴜʀʟ sᴛʀᴇᴀᴍ" + dur = 0 + else: + dur = 0 + put = { + "title": title, + "dur": duration, + "streamtype": stream, + "by": user, + "chat_id": original_chat_id, + "file": file, + "vidid": vidid, + "seconds": dur, + "played": 0, + } + if forceplay: + check = db.get(chat_id) + if check: + check.insert(0, put) + else: + db[chat_id] = [] + db[chat_id].append(put) + else: + db[chat_id].append(put) diff --git a/DragMusic/utils/stream/stream.py b/DragMusic/utils/stream/stream.py new file mode 100644 index 0000000000000000000000000000000000000000..b4fbbb2dcdea7da20b684e0c9c1d2ed339c6608a --- /dev/null +++ b/DragMusic/utils/stream/stream.py @@ -0,0 +1,420 @@ +import os +from random import randint +from typing import Union + +from pyrogram.types import InlineKeyboardMarkup + +import config +from DragMusic import Carbon, YouTube, app +from DragMusic.core.call import Drag +from DragMusic.misc import db +from DragMusic.utils.database import add_active_video_chat, is_active_chat +from DragMusic.utils.exceptions import AssistantErr +from DragMusic.utils.inline import aq_markup, close_markup, stream_markup +from DragMusic.utils.pastebin import DragBin +from DragMusic.utils.stream.queue import put_queue, put_queue_index +from DragMusic.utils.thumbnails import get_thumb + + +async def stream( + _, + mystic, + user_id, + result, + chat_id, + user_name, + original_chat_id, + video: Union[bool, str] = None, + streamtype: Union[bool, str] = None, + spotify: Union[bool, str] = None, + forceplay: Union[bool, str] = None, +): + if not result: + return + if forceplay: + await Drag.force_stop_stream(chat_id) + if streamtype == "playlist": + msg = f"{_['play_19']}\n\n" + count = 0 + for search in result: + if int(count) == config.PLAYLIST_FETCH_LIMIT: + continue + try: + ( + title, + duration_min, + duration_sec, + thumbnail, + vidid, + ) = await YouTube.details(search, False if spotify else True) + except: + continue + if str(duration_min) == "None": + continue + if duration_sec > config.DURATION_LIMIT: + continue + if await is_active_chat(chat_id): + await put_queue( + chat_id, + original_chat_id, + f"vid_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + ) + position = len(db.get(chat_id)) - 1 + count += 1 + msg += f"{count}. {title[:70]}\n" + msg += f"{_['play_20']} {position}\n\n" + else: + if not forceplay: + db[chat_id] = [] + status = True if video else None + try: + file_path, direct = await YouTube.download( + vidid, mystic, video=status, videoid=True + ) + except: + raise AssistantErr(_["play_14"]) + await Drag.join_call( + chat_id, + original_chat_id, + file_path, + video=status, + image=thumbnail, + ) + await put_queue( + chat_id, + original_chat_id, + file_path if direct else f"vid_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + forceplay=forceplay, + ) + img = await get_thumb(vidid) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{vidid}", + title[:23], + duration_min, + user_name, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + if count == 0: + return + else: + link = await DragBin(msg) + lines = msg.count("\n") + if lines >= 17: + car = os.linesep.join(msg.split(os.linesep)[:17]) + else: + car = msg + carbon = await Carbon.generate(car, randint(100, 10000000)) + upl = close_markup(_) + return await app.send_photo( + original_chat_id, + photo=carbon, + caption=_["play_21"].format(position, link), + reply_markup=upl, + ) + elif streamtype == "youtube": + link = result["link"] + vidid = result["vidid"] + title = (result["title"]).title() + duration_min = result["duration_min"] + thumbnail = result["thumb"] + status = True if video else None + try: + file_path, direct = await YouTube.download( + vidid, mystic, videoid=True, video=status + ) + except: + raise AssistantErr(_["play_14"]) + if await is_active_chat(chat_id): + await put_queue( + chat_id, + original_chat_id, + file_path if direct else f"vid_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + ) + position = len(db.get(chat_id)) - 1 + button = aq_markup(_, chat_id) + await app.send_message( + chat_id=original_chat_id, + text=_["queue_4"].format(position, title[:27], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + else: + if not forceplay: + db[chat_id] = [] + await Drag.join_call( + chat_id, + original_chat_id, + file_path, + video=status, + image=thumbnail, + ) + await put_queue( + chat_id, + original_chat_id, + file_path if direct else f"vid_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + forceplay=forceplay, + ) + img = await get_thumb(vidid) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{vidid}", + title[:23], + duration_min, + user_name, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "stream" + elif streamtype == "soundcloud": + file_path = result["filepath"] + title = result["title"] + duration_min = result["duration_min"] + if await is_active_chat(chat_id): + await put_queue( + chat_id, + original_chat_id, + file_path, + title, + duration_min, + user_name, + streamtype, + user_id, + "audio", + ) + position = len(db.get(chat_id)) - 1 + button = aq_markup(_, chat_id) + await app.send_message( + chat_id=original_chat_id, + text=_["queue_4"].format(position, title[:27], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + else: + if not forceplay: + db[chat_id] = [] + await Drag.join_call(chat_id, original_chat_id, file_path, video=None) + await put_queue( + chat_id, + original_chat_id, + file_path, + title, + duration_min, + user_name, + streamtype, + user_id, + "audio", + forceplay=forceplay, + ) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=config.SOUNCLOUD_IMG_URL, + caption=_["stream_1"].format( + config.SUPPORT_CHAT, title[:23], duration_min, user_name + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif streamtype == "telegram": + file_path = result["path"] + link = result["link"] + title = (result["title"]).title() + duration_min = result["dur"] + status = True if video else None + if await is_active_chat(chat_id): + await put_queue( + chat_id, + original_chat_id, + file_path, + title, + duration_min, + user_name, + streamtype, + user_id, + "video" if video else "audio", + ) + position = len(db.get(chat_id)) - 1 + button = aq_markup(_, chat_id) + await app.send_message( + chat_id=original_chat_id, + text=_["queue_4"].format(position, title[:27], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + else: + if not forceplay: + db[chat_id] = [] + await Drag.join_call(chat_id, original_chat_id, file_path, video=status) + await put_queue( + chat_id, + original_chat_id, + file_path, + title, + duration_min, + user_name, + streamtype, + user_id, + "video" if video else "audio", + forceplay=forceplay, + ) + if video: + await add_active_video_chat(chat_id) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=config.TELEGRAM_VIDEO_URL if video else config.TELEGRAM_AUDIO_URL, + caption=_["stream_1"].format(link, title[:23], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif streamtype == "live": + link = result["link"] + vidid = result["vidid"] + title = (result["title"]).title() + thumbnail = result["thumb"] + duration_min = "Live Track" + status = True if video else None + if await is_active_chat(chat_id): + await put_queue( + chat_id, + original_chat_id, + f"live_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + ) + position = len(db.get(chat_id)) - 1 + button = aq_markup(_, chat_id) + await app.send_message( + chat_id=original_chat_id, + text=_["queue_4"].format(position, title[:27], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + else: + if not forceplay: + db[chat_id] = [] + n, file_path = await YouTube.video(link) + if n == 0: + raise AssistantErr(_["str_3"]) + await Drag.join_call( + chat_id, + original_chat_id, + file_path, + video=status, + image=thumbnail if thumbnail else None, + ) + await put_queue( + chat_id, + original_chat_id, + f"live_{vidid}", + title, + duration_min, + user_name, + vidid, + user_id, + "video" if video else "audio", + forceplay=forceplay, + ) + img = await get_thumb(vidid) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=img, + caption=_["stream_1"].format( + f"https://t.me/{app.username}?start=info_{vidid}", + title[:23], + duration_min, + user_name, + ), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + elif streamtype == "index": + link = result + title = "ɪɴᴅᴇx ᴏʀ ᴍ3ᴜ8 ʟɪɴᴋ" + duration_min = "00:00" + if await is_active_chat(chat_id): + await put_queue_index( + chat_id, + original_chat_id, + "index_url", + title, + duration_min, + user_name, + link, + "video" if video else "audio", + ) + position = len(db.get(chat_id)) - 1 + button = aq_markup(_, chat_id) + await mystic.edit_text( + text=_["queue_4"].format(position, title[:27], duration_min, user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + else: + if not forceplay: + db[chat_id] = [] + await Drag.join_call( + chat_id, + original_chat_id, + link, + video=True if video else None, + ) + await put_queue_index( + chat_id, + original_chat_id, + "index_url", + title, + duration_min, + user_name, + link, + "video" if video else "audio", + forceplay=forceplay, + ) + button = stream_markup(_, chat_id) + run = await app.send_photo( + original_chat_id, + photo=config.STREAM_IMG_URL, + caption=_["stream_2"].format(user_name), + reply_markup=InlineKeyboardMarkup(button), + ) + db[chat_id][0]["mystic"] = run + db[chat_id][0]["markup"] = "tg" + await mystic.delete() diff --git a/DragMusic/utils/sys.py b/DragMusic/utils/sys.py new file mode 100644 index 0000000000000000000000000000000000000000..6f89ca60e2fc3e7c4f89702739d017f66a1ed356 --- /dev/null +++ b/DragMusic/utils/sys.py @@ -0,0 +1,15 @@ +import time + +import psutil + +from DragMusic.misc import _boot_ +from DragMusic.utils.formatters import get_readable_time + + +async def bot_sys_stats(): + bot_uptime = int(time.time() - _boot_) + UP = f"{get_readable_time(bot_uptime)}" + CPU = f"{psutil.cpu_percent(interval=0.5)}%" + RAM = f"{psutil.virtual_memory().percent}%" + DISK = f"{psutil.disk_usage('/').percent}%" + return UP, CPU, RAM, DISK diff --git a/DragMusic/utils/thumbnails.py b/DragMusic/utils/thumbnails.py new file mode 100644 index 0000000000000000000000000000000000000000..9ee788982cee4eef25f8747731524f60ab288896 --- /dev/null +++ b/DragMusic/utils/thumbnails.py @@ -0,0 +1,121 @@ +import os +import re + +import aiofiles +import aiohttp +from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont +from unidecode import unidecode +from youtubesearchpython.__future__ import VideosSearch + +from DragMusic import app +from config import YOUTUBE_IMG_URL + + +def changeImageSize(maxWidth, maxHeight, image): + widthRatio = maxWidth / image.size[0] + heightRatio = maxHeight / image.size[1] + newWidth = int(widthRatio * image.size[0]) + newHeight = int(heightRatio * image.size[1]) + newImage = image.resize((newWidth, newHeight)) + return newImage + + +def clear(text): + list = text.split(" ") + title = "" + for i in list: + if len(title) + len(i) < 60: + title += " " + i + return title.strip() + + +async def get_thumb(videoid): + if os.path.isfile(f"cache/{videoid}.png"): + return f"cache/{videoid}.png" + + url = f"https://www.youtube.com/watch?v={videoid}" + try: + results = VideosSearch(url, limit=1) + for result in (await results.next())["result"]: + try: + title = result["title"] + title = re.sub("\W+", " ", title) + title = title.title() + except: + title = "Unsupported Title" + try: + duration = result["duration"] + except: + duration = "Unknown Mins" + thumbnail = result["thumbnails"][0]["url"].split("?")[0] + try: + views = result["viewCount"]["short"] + except: + views = "Unknown Views" + try: + channel = result["channel"]["name"] + except: + channel = "Unknown Channel" + + async with aiohttp.ClientSession() as session: + async with session.get(thumbnail) as resp: + if resp.status == 200: + f = await aiofiles.open(f"cache/thumb{videoid}.png", mode="wb") + await f.write(await resp.read()) + await f.close() + + youtube = Image.open(f"cache/thumb{videoid}.png") + image1 = changeImageSize(1280, 720, youtube) + image2 = image1.convert("RGBA") + background = image2.filter(filter=ImageFilter.BoxBlur(10)) + enhancer = ImageEnhance.Brightness(background) + background = enhancer.enhance(0.5) + draw = ImageDraw.Draw(background) + arial = ImageFont.truetype("DragMusic/assets/font2.ttf", 30) + font = ImageFont.truetype("DragMusic/assets/font.ttf", 30) + draw.text((1110, 8), unidecode(app.name), fill="white", font=arial) + draw.text( + (55, 560), + f"{channel} | {views[:23]}", + (255, 255, 255), + font=arial, + ) + draw.text( + (57, 600), + clear(title), + (255, 255, 255), + font=font, + ) + draw.line( + [(55, 660), (1220, 660)], + fill="white", + width=5, + joint="curve", + ) + draw.ellipse( + [(918, 648), (942, 672)], + outline="white", + fill="white", + width=15, + ) + draw.text( + (36, 685), + "00:00", + (255, 255, 255), + font=arial, + ) + draw.text( + (1185, 685), + f"{duration[:23]}", + (255, 255, 255), + font=arial, + ) + try: + os.remove(f"cache/thumb{videoid}.png") + except: + pass + background.save(f"cache/{videoid}.png") + return f"cache/{videoid}.png" + except Exception as e: + print(e) + return YOUTUBE_IMG_URL diff --git a/Procfile b/Procfile new file mode 100644 index 0000000000000000000000000000000000000000..36ad736e105f3ef6956470806a835b0019c975eb --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +worker: bash start diff --git a/Security.md b/Security.md new file mode 100644 index 0000000000000000000000000000000000000000..034e848032092eaf8ef96eac731b6ed5961987f3 --- /dev/null +++ b/Security.md @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +Use this section to tell people how to report a vulnerability. + +Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc. diff --git a/app.json b/app.json new file mode 100644 index 0000000000000000000000000000000000000000..5340340662c8d4e1c936e07206732abcaca6a7b9 --- /dev/null +++ b/app.json @@ -0,0 +1,73 @@ +{ + "name": "DRAGON", + "description": "A Telegram Music Player Bot, written in Python with Pyrogram and Py-Tgcalls.", + "logo": "https://telegra.ph/file/0ec34774fcb33d12ce8be.jpg", + "keywords": [ + "python3", + "telegram", + "bot", + "AnonX", + "MusicBot", + "telegram-bot", + "pyrogram" + ], + "env": { + "API_ID": { + "description": "Get this value from https://my.telegram.org", + "value": "", + "required": true + }, + "API_HASH": { + "description": "Get this value from https://my.telegram.org", + "value": "", + "required": true + }, + "BOT_TOKEN": { + "description": "A Bot's token from Botfather", + "value": "", + "required": true + }, + "MONGO_DB_URI": { + "description": "Get a mongodb url from https://cloud.mongodb.com.", + "value": "", + "required": true + }, + "OWNER_ID": { + "description": "The user id of user whom you would like to add as OWNER.", + "value": "", + "required": true + }, + "STRING_SESSION": { + "description": "A Pyrogram v2 String Session from @StringFatherBot on Telegram.", + "value": "", + "required": true + }, + "HEROKU_API_KEY": { + "description": "Your Heroku account's API key", + "value": "", + "required": false + }, + "HEROKU_APP_NAME": { + "description": "Your heroku app name", + "value": "", + "required": false + }, + "LOGGER_ID": { + "description": "Your Log Group ID, add your bot and promote as an admin with full rights!. Channel ki id mat daal dena bsdk.", + "value": "", + "required": true + } + }, + "buildpacks": [ + { + "url": "heroku/python" + }, + { + "url": "heroku/nodejs" + }, + { + "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git" + } + ], + "stack": "container" + } diff --git a/config.py b/config.py new file mode 100644 index 0000000000000000000000000000000000000000..7612a174d47c6c3e6d9cde6d888d6bad543ff9f0 --- /dev/null +++ b/config.py @@ -0,0 +1,117 @@ +import re +from os import getenv + +from dotenv import load_dotenv +from pyrogram import filters + +load_dotenv() + +# Get this value from my.telegram.org/apps +API_ID = int(getenv("API_ID")) +API_HASH = getenv("API_HASH") +BOT_USERNAME = "@dragxmusicbot" +# Get your token from @BotFather on Telegram.main +BOT_TOKEN = getenv("BOT_TOKEN") + +# Get your mongo url from cloud.mongodb.com +MONGO_DB_URI = getenv("MONGO_DB_URI") + +DURATION_LIMIT_MIN = int(getenv("DURATION_LIMIT", 200)) + +SERVER_PLAYLIST_LIMIT = 300 # Set your desired limit here + +API_URL = getenv("API_URL", 'https://api.thequickearn.xyz') #youtube song url +API_KEY = getenv("API_KEY", None) # youtube song api key, get it from https://t.me/RahulTC + +# Chat id of a group for logging bot's activities +LOGGER_ID = int(getenv("LOGGER_ID", )) + +# Get this value from @FallenxBot on Telegram by /id +OWNER_ID = int(getenv("OWNER_ID", )) + +## Fill these variables if you're deploying on heroku. +# Your heroku app name +HEROKU_APP_NAME = getenv("HEROKU_APP_NAME") +# Get it from http://dashboard.heroku.com/account +HEROKU_API_KEY = getenv("HEROKU_API_KEY") + +UPSTREAM_REPO = getenv( + "UPSTREAM_REPO", + "https://github.com/taslim19/musicxdrag", +) +UPSTREAM_BRANCH = getenv("UPSTREAM_BRANCH", "main") +GIT_TOKEN = getenv( + "GIT_TOKEN", None +) # Fill this variable if your upstream repository is private + +SUPPORT_CHANNEL = getenv("SUPPORT_CHANNEL", "https://t.me/haatsoja") +SUPPORT_CHAT = getenv("SUPPORT_CHAT", "https://t.me/dragbackup") + +# Set this to True if you want the assistant to automatically leave chats after an interval +AUTO_LEAVING_ASSISTANT = bool(getenv("AUTO_LEAVING_ASSISTANT", False)) + + +# Get this credentials from https://developer.spotify.com/dashboard +SPOTIFY_CLIENT_ID = getenv("SPOTIFY_CLIENT_ID", "48037b43459c4bacbce6c61be2575ade") +SPOTIFY_CLIENT_SECRET = getenv("SPOTIFY_CLIENT_SECRET", "103c89540301422aa880a462ca556416") + + +# Maximum limit for fetching playlist's track from youtube, spotify, apple links. +PLAYLIST_FETCH_LIMIT = int(getenv("PLAYLIST_FETCH_LIMIT", 300)) + + +# Telegram audio and video file size limit (in bytes) +TG_AUDIO_FILESIZE_LIMIT = int(getenv("TG_AUDIO_FILESIZE_LIMIT", 1610612736)) +TG_VIDEO_FILESIZE_LIMIT = int(getenv("TG_VIDEO_FILESIZE_LIMIT", 1610612736)) +# Checkout https://www.gbmb.org/mb-to-bytes for converting mb to bytes + + +# Get your pyrogram v2 session from @StringFatherBot on Telegram +STRING1 = getenv("STRING_SESSION", None) +STRING2 = getenv("STRING_SESSION2", None) +STRING3 = getenv("STRING_SESSION3", None) +STRING4 = getenv("STRING_SESSION4", None) +STRING5 = getenv("STRING_SESSION5", None) + + +BANNED_USERS = filters.user() +adminlist = {} +lyrical = {} +votemode = {} +autoclean = [] +confirmer = {} + + +START_IMG_URL = getenv("START_IMG_URL", "https://files.catbox.moe/8rwzc8.jpeg") +PING_IMG_URL = getenv("PING_IMG_URL", "https://files.catbox.moe/uopqdn.jpg") +PLAYLIST_IMG_URL ="https://telegra.ph/file/8d7b534e34e13316a7dd2.jpg" +STATS_IMG_URL = "https://files.catbox.moe/nge71y.jpg" +TELEGRAM_AUDIO_URL = "https://te.legra.ph/file/6298d377ad3eb46711644.jpg" +TELEGRAM_VIDEO_URL = "https://te.legra.ph/file/6298d377ad3eb46711644.jpg" +STREAM_IMG_URL = "https://te.legra.ph/file/bd995b032b6bd263e2cc9.jpg" +SOUNCLOUD_IMG_URL = "https://te.legra.ph/file/bb0ff85f2dd44070ea519.jpg" +YOUTUBE_IMG_URL = "https://te.legra.ph/file/6298d377ad3eb46711644.jpg" +SPOTIFY_ARTIST_IMG_URL = "https://te.legra.ph/file/37d163a2f75e0d3b403d6.jpg" +SPOTIFY_ALBUM_IMG_URL = "https://te.legra.ph/file/b35fd1dfca73b950b1b05.jpg" +SPOTIFY_PLAYLIST_IMG_URL = "https://te.legra.ph/file/95b3ca7993bbfaf993dcb.jpg" + + +def time_to_seconds(time): + stringt = str(time) + return sum(int(x) * 60**i for i, x in enumerate(reversed(stringt.split(":")))) + + +DURATION_LIMIT = int(time_to_seconds(f"{DURATION_LIMIT_MIN}:0")) + + +if SUPPORT_CHANNEL: + if not re.match("(?:http|https)://", SUPPORT_CHANNEL): + raise SystemExit( + "[ERROR] - Your SUPPORT_CHANNEL url is wrong. Please ensure that it starts with https://" + ) + +if SUPPORT_CHAT: + if not re.match("(?:http|https)://", SUPPORT_CHAT): + raise SystemExit( + "[ERROR] - Your SUPPORT_CHAT url is wrong. Please ensure that it starts with https://" +) diff --git a/cookies.txt b/cookies.txt new file mode 100644 index 0000000000000000000000000000000000000000..ccc558d88a0630338699bb9ce40cac9a0237d4f9 --- /dev/null +++ b/cookies.txt @@ -0,0 +1,17 @@ +# Netscape HTTP Cookie File +# http://curl.haxx.se/rfc/cookie_spec.html +# This file was generated by Cookie-Editor +#HttpOnly_.youtube.com TRUE / TRUE 1742921152 YTSESSION-1b ANPz9Kij0V5aPjAttfZnRD4suOkGNjcz71q/xU0sngZqCq6hloIsSWAFbPEQs27oatdAAu+UOnVdqHYpAHAX/sazeOPD+W6qV1UK1w4= +#HttpOnly_.youtube.com TRUE / TRUE 1777481033 __Secure-3PSID g.a000vAg8Bwo4A5fv1NfvT2I_Xqfi4q1nb9NAILFCge0h-2Cy7HusWTyvvIa4FO4BSmdbR6CFxwACgYKAaISARYSFQHGX2MijMXK3BV7jH8exWDuhU97choVAUF8yKobdzO11tjJBgWksmpx0h9L0076 +#HttpOnly_.youtube.com TRUE / TRUE 1742922832 GPS 1 +#HttpOnly_.youtube.com TRUE / TRUE 1774457033 __Secure-1PSIDTS sidts-CjEB7pHptSAYHEZy5rb_OuZ_7NBWl8AzZVFx7tIFEB4aNPNKlP715S5LMgfhdD5n2_MtEAA +.youtube.com TRUE / TRUE 1777481033 SAPISID 3GQv2sj-2w3zrw2J/AvZHeLBzSCg3geUBk +#HttpOnly_.youtube.com TRUE / TRUE 1774457132 __Secure-1PSIDCC AKEyXzUwvFFY1fEphh9h5DcjJ_qi4A81tMwebn_aCgQ8FAyahMtFeczYZvw7wMv5e4tlO9W9Sw +#HttpOnly_.youtube.com TRUE / TRUE 1777481033 SSID ALdDq3hPOhryHiBTk +.youtube.com TRUE / TRUE 1777481033 __Secure-1PAPISID 3GQv2sj-2w3zrw2J/AvZHeLBzSCg3geUBk +#HttpOnly_.youtube.com TRUE / TRUE 1777481033 __Secure-1PSID g.a000vAg8Bwo4A5fv1NfvT2I_Xqfi4q1nb9NAILFCge0h-2Cy7HusUywUecfgnF11rqmsMWsLsQACgYKAb0SARYSFQHGX2MiwbMAvy-q6FczWi2M0wMoQhoVAUF8yKrzvMeeJByv6o9DZGxhhH4n0076 +.youtube.com TRUE / TRUE 1777481033 __Secure-3PAPISID 3GQv2sj-2w3zrw2J/AvZHeLBzSCg3geUBk +#HttpOnly_.youtube.com TRUE / TRUE 1774457132 __Secure-3PSIDCC AKEyXzXj1GiFMV5Umszk5kRXg8j6dmUEDJdjkv_ty12JJm5zood-XieGGKljVfqEVo5Xncd0Pw +#HttpOnly_.youtube.com TRUE / TRUE 1774457033 __Secure-3PSIDTS sidts-CjEB7pHptSAYHEZy5rb_OuZ_7NBWl8AzZVFx7tIFEB4aNPNKlP715S5LMgfhdD5n2_MtEAA +#HttpOnly_.youtube.com TRUE / TRUE 1777481033 LOGIN_INFO AFmmF2swRQIgdcJU8AlPASy-JQuMIAgtjaemwSB4uvrzaeU9T-xHuqgCIQCov2OFYIGh9LQtaoKwDe6g3_ByZU_YtmBIQTRCNsSEBw:QUQ3MjNmejlhUTh1bkNYMkRod2t6akFMVHNaV0M5UEFGSkZXbEQ5Qy01Rkp0X25wTkw3NU5ra1lSdTZDZ0h1akxJdlpQU2wtaEo4Y3NCVk9kV1VkYm9Lblp5RmFfQXYzcUE5UGdfbm1jdXM2TEc5U3Q5OV94NXE3N05GYXBTVDVOMzdIcmFEckVzQmN0cl9OSzhDemJPb1lIT2lkZkk0MUln +.youtube.com TRUE / TRUE 1777481036 PREF tz=Asia.Calcutta diff --git a/cookies/cookies.txt b/cookies/cookies.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/cookies/cookies.txt @@ -0,0 +1 @@ + diff --git a/heroku.yml b/heroku.yml new file mode 100644 index 0000000000000000000000000000000000000000..252dbe1042e579955463c8df9d3cf1f7a98bf0bf --- /dev/null +++ b/heroku.yml @@ -0,0 +1,5 @@ +build: + docker: + worker: Dockerfile +run: + worker: bash start diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..2632740690d239a74669a9c7b52bbc984ce5ac4b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,41 @@ +telethon==1.33.1 +aiofiles +apscheduler +aiohttp==3.9.3 +asyncio==3.4.3 +gTTS +dnspython==2.3.0 +hachoir +heroku3 +motor +psutil +wget +qrcode +future==0.18.3 +search_engine_parser +speedtest-cli +py-tgcalls==1.2.9 +MukeshAPI +ntgcalls==1.1.2 +gitpython +pykeyboard +python-dotenv +pyyaml==6.0.1 +tgcrypto +telegraph==2.2.0 +yt-dlp +lexica-api==1.4.7 +httpx==0.25.2 +lyricsgenius +spotipy +SafoneAPI +youtube_search +youtube-search-python +googlesearch-python +unidecode +#git+https://github.com/joetats/youtube_search@master +#git+https://github.com/alexmercerind/youtube-search-python@main +https://github.com/KurimuzonAkuma/pyrogram/archive/v2.1.23.zip +git+https://github.com/AsmSafone/SafoneAPI +bing_image_downloader +openai==0.28 diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000000000000000000000000000000000000..431fc7e8c3a5b3737349a7ad0a8d0d4fc233b52b --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.11.4 diff --git a/sample.env b/sample.env new file mode 100644 index 0000000000000000000000000000000000000000..4ab941d548a72b0bd4ca01da6f457f21acbaab9e --- /dev/null +++ b/sample.env @@ -0,0 +1,7 @@ +API_ID= +API_HASH= +BOT_TOKEN= +LOGGER_ID= +MONGO_DB_URI= +OWNER_ID= +STRING_SESSION= diff --git a/setup b/setup new file mode 100644 index 0000000000000000000000000000000000000000..ea0067c0fbca88b1750dc2c4fba5e7e15e7ab843 --- /dev/null +++ b/setup @@ -0,0 +1,126 @@ +#!/bin/bash + +pprint (){ + cred='\033[0;31m' + cgreen='\033[0;32m' + cyellow='\033[0;33m' + cblue='\033[0;34m' + cpurple='\033[0;35m' + eval "export color='$cpurple'" + [ ! -z $2 ] && eval "export color=\"\$$2\"" + printf "$color $1" +} + +color_reset(){ printf '\033[0;37m';} + +yesnoprompt(){ + old_stty_cfg=$(stty -g) + stty raw -echo ; answer=$(head -c 1) + stty $old_stty_cfg + echo "$answer" | grep -iq "^y" +} + +update() { + pprint "\n\nUpdating package list.. " + sudo apt update 2>&1 | grep "can be upgraded" &>/dev/null + if [ $? -eq 0 ]; then + pprint "UPDATE AVAILABLE" "cgreen" + pprint "\n\nDo you want to automatically upgrade (y/n)?" + if yesnoprompt; then + pprint "\n\nUpgrading packages.. " + sudo apt upgrade -y &>/dev/null && + pprint "DONE!\n\n" "cgreen" || (pprint "FAIL.\n\n" "cred"; exit 1) + else + echo + fi + else + pprint "ALREADY UP TO DATE\n\n" "cgreen" + fi +} + +packages(){ + if ! command -v pip &>/dev/null; then + pprint "Couldn't found pip, installing now..." + sudo apt install python3-pip -y 2>pypilog.txt 1>/dev/null && + pprint "SUCCESS.\n\n" "cgreen" || (pprint "FAIL.\n\n" "cred"; exit 1) + fi + + if ! command -v ffmpeg &>/dev/null; then + pprint "Couldn't found ffmpeg, installing now..." + if sudo apt install ffmpeg -y &>/dev/null;then + pprint "SUCCESS.\n\n" "cgreen" + else + pprint "FAIL.\n\n" "cred" + pprint "You need to install ffmpeg manually in order to deploy DragMusic, exiting...\n" "cblue" + exit 1 + fi + fi + + # Check ffmpeg version and warn user if necessary. + fv=$(grep -Po 'version (3.*?) ' <<< $(ffmpeg -version)) && + pprint "Playing live streams not going to work since you have ffmpeg $fv, live streams are supported by version 4+.\n" "cblue" +} + + +node(){ + command -v npm &>/dev/null && return + pprint "Installing Nodejs and Npm.. " + curl -fssL https://deb.nodesource.com/setup_19.x | sudo -E bash - &>nodelog.txt && + sudo apt install -y nodejs &>>nodelog.txt && + sudo npm i -g npm &>>nodelog.txt && + pprint "SUCCESS!\n" "cgreen" || (pprint "FAIL.\n" "cred"; exit 1) +} + + +installation(){ + pprint "\n\nUpgrading pip and installing dependency packages..." + pip3 install -U pip &>>pypilog.txt && + pip3 install -U -r requirements.txt &>>pypilog.txt && + pprint "DONE.\n" "cgreen" && return + pprint "FAIL.\n" "cred" + exit 1 +} + +clear +pprint "Welcome to DragMusic Setup Installer\n\n" +pprint "If you see any error during Installation Process, Please refer to these files for logs: " +pprint "\nFor node js errors , Checkout nodelog.txt" +pprint "\nFor pypi packages errors , Checkout pypilog.txt" +sleep 1 +pprint "\n\nScript needs sudo privileges in order to update & install packages.\n" +sudo test + +update +packages +node +installation +pprint "\n\n\n\n\nDragMusic Installation Completed !" "cgreen" +sleep 1 +clear + +pprint "\nEnter Your Values Below\n\n\n" +pprint "API ID: "; color_reset; read api_id +pprint "\nAPI HASH: "; color_reset; read api_hash +pprint "\nBOT TOKEN: "; color_reset; read bot_token +pprint "\nOWNER ID:"; color_reset; read ownid +pprint "\nMONGO DB URI: "; color_reset; read mongo_db +pprint "\nLOG GROUP ID: "; color_reset; read logger +pprint "\nSTRING SESSION: "; color_reset; read string_session + +pprint "\n\nProcessing your vars, wait a while !" "cgreen" + +if [ -f .env ]; then + rm .env +fi + +echo """API_ID = $api_id +API_HASH = $api_hash +BOT_TOKEN = $bot_token +MONGO_DB_URI = $mongo_db +LOGGER_ID = $logger +STRING_SESSION = $string_session +OWNER_ID = $ownid""" > .env +clear + +pprint "\n\n\nThanks for using DragMusic installer, your vars have been saved successfully ! \nIf you wanna add more variables add them in your env by : vi .env" +pprint "\n\nNow you can start the bot by : bash start\n\n" diff --git a/start b/start new file mode 100644 index 0000000000000000000000000000000000000000..abbb831cd470083aa0011c0a42596ab192a1194c --- /dev/null +++ b/start @@ -0,0 +1 @@ +python3 -m DragMusic diff --git a/strings/__init__.py b/strings/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..00c9c007fb1da9e7cdcf7af2c2cd0138ca08405d --- /dev/null +++ b/strings/__init__.py @@ -0,0 +1,34 @@ +import os +from typing import List + +import yaml + +languages = {} +languages_present = {} + + +def get_string(lang: str): + return languages[lang] + + +for filename in os.listdir(r"./strings/langs/"): + if "en" not in languages: + languages["en"] = yaml.safe_load( + open(r"./strings/langs/en.yml", encoding="utf8") + ) + languages_present["en"] = languages["en"]["name"] + if filename.endswith(".yml"): + language_name = filename[:-4] + if language_name == "en": + continue + languages[language_name] = yaml.safe_load( + open(r"./strings/langs/" + filename, encoding="utf8") + ) + for item in languages["en"]: + if item not in languages[language_name]: + languages[language_name][item] = languages["en"][item] + try: + languages_present[language_name] = languages[language_name]["name"] + except: + print("There is some issue with the language file inside bot.") + exit() diff --git a/strings/helpers.py b/strings/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..f06bd5e11a4e8bb1892302f7741fea78cc100844 --- /dev/null +++ b/strings/helpers.py @@ -0,0 +1,160 @@ +HELP_1 = """ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs : + +ᴊᴜsᴛ ᴀᴅᴅ ɪɴ ᴛʜᴇ sᴛᴀʀᴛɪɴɢ ᴏғ ᴛʜᴇ ᴄᴏᴍᴍᴀɴᴅs ᴛᴏ ᴜsᴇ ᴛʜᴇᴍ ғᴏʀ ᴄʜᴀɴɴᴇʟ. + + +/pause : ᴩᴀᴜsᴇ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ. + +/resume : ʀᴇsᴜᴍᴇ ᴛʜᴇ ᴩᴀᴜsᴇᴅ sᴛʀᴇᴀᴍ. + +/skip : sᴋɪᴩ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ ᴀɴᴅ sᴛᴀʀᴛ sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ɴᴇxᴛ ᴛʀᴀᴄᴋ ɪɴ ǫᴜᴇᴜᴇ. + +/end ᴏʀ /stop : ᴄʟᴇᴀʀs ᴛʜᴇ ǫᴜᴇᴜᴇ ᴀɴᴅ ᴇɴᴅ ᴛʜᴇ ᴄᴜʀʀᴇɴᴛ ᴩʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ. + +/player : ɢᴇᴛ ᴀ ɪɴᴛᴇʀᴀᴄᴛɪᴠᴇ ᴩʟᴀʏᴇʀ ᴩᴀɴᴇʟ. + +/queue : sʜᴏᴡs ᴛʜᴇ ǫᴜᴇᴜᴇᴅ ᴛʀᴀᴄᴋs ʟɪsᴛ. +""" + +HELP_2 = """ +ᴀᴜᴛʜ ᴜsᴇʀs : + +ᴀᴜᴛʜ ᴜsᴇʀs ᴄᴀɴ ᴜsᴇ ᴀᴅᴍɪɴ ʀɪɢʜᴛs ɪɴ ᴛʜᴇ ʙᴏᴛ ᴡɪᴛʜᴏᴜᴛ ᴀᴅᴍɪɴ ʀɪɢʜᴛs ɪɴ ᴛʜᴇ ᴄʜᴀᴛ. + +/auth [ᴜsᴇʀɴᴀᴍᴇ/ᴜsᴇʀ_ɪᴅ] : ᴀᴅᴅ ᴀ ᴜsᴇʀ ᴛᴏ ᴀᴜᴛʜ ʟɪsᴛ ᴏғ ᴛʜᴇ ʙᴏᴛ. +/unauth [ᴜsᴇʀɴᴀᴍᴇ/ᴜsᴇʀ_ɪᴅ] : ʀᴇᴍᴏᴠᴇ ᴀ ᴀᴜᴛʜ ᴜsᴇʀs ғʀᴏᴍ ᴛʜᴇ ᴀᴜᴛʜ ᴜsᴇʀs ʟɪsᴛ. +/authusers : sʜᴏᴡs ᴛʜᴇ ʟɪsᴛ ᴏғ ᴀᴜᴛʜ ᴜsᴇʀs ᴏғ ᴛʜᴇ ɢʀᴏᴜᴩ. +""" + +HELP_3 = """ +ʙʀᴏᴀᴅᴄᴀsᴛ ғᴇᴀᴛᴜʀᴇ [ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs] : + +/broadcast [ᴍᴇssᴀɢᴇ ᴏʀ ʀᴇᴩʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ] : ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ sᴇʀᴠᴇᴅ ᴄʜᴀᴛs ᴏғ ᴛʜᴇ ʙᴏᴛ. + +ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ ᴍᴏᴅᴇs : +-pin : ᴩɪɴs ʏᴏᴜʀ ʙʀᴏᴀᴅᴄᴀsᴛᴇᴅ ᴍᴇssᴀɢᴇs ɪɴ sᴇʀᴠᴇᴅ ᴄʜᴀᴛs. +-pinloud : ᴩɪɴs ʏᴏᴜʀ ʙʀᴏᴀᴅᴄᴀsᴛᴇᴅ ᴍᴇssᴀɢᴇ ɪɴ sᴇʀᴠᴇᴅ ᴄʜᴀᴛs ᴀɴᴅ sᴇɴᴅ ɴᴏᴛɪғɪᴄᴀᴛɪᴏɴ ᴛᴏ ᴛʜᴇ ᴍᴇᴍʙᴇʀs. +-user : ʙʀᴏᴀᴅᴄᴀsᴛs ᴛʜᴇ ᴍᴇssᴀɢᴇ ᴛᴏ ᴛʜᴇ ᴜsᴇʀs ᴡʜᴏ ʜᴀᴠᴇ sᴛᴀʀᴛᴇᴅ ʏᴏᴜʀ ʙᴏᴛ. +-assistant : ʙʀᴏᴀᴅᴄᴀsᴛ ʏᴏᴜʀ ᴍᴇssᴀɢᴇ ғʀᴏᴍ ᴛʜᴇ ᴀssɪᴛᴀɴᴛ ᴀᴄᴄᴏᴜɴᴛ ᴏғ ᴛʜᴇ ʙᴏᴛ. +-nobot : ғᴏʀᴄᴇs ᴛʜᴇ ʙᴏᴛ ᴛᴏ ɴᴏᴛ ʙʀᴏᴀᴅᴄᴀsᴛ ᴛʜᴇ ᴍᴇssᴀɢᴇ.. + +ᴇxᴀᴍᴩʟᴇ: /broadcast -user -assistant -pin ᴛᴇsᴛɪɴɢ ʙʀᴏᴀᴅᴄᴀsᴛ +""" + +HELP_4 = """ᴄʜᴀᴛ ʙʟᴀᴄᴋʟɪsᴛ ғᴇᴀᴛᴜʀᴇ : [ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs] + +ʀᴇsᴛʀɪᴄᴛ sʜɪᴛ ᴄʜᴀᴛs ᴛᴏ ᴜsᴇ ᴏᴜʀ ᴘʀᴇᴄɪᴏᴜs ʙᴏᴛ. + +/blacklistchat [ᴄʜᴀᴛ ɪᴅ] : ʙʟᴀᴄᴋʟɪsᴛ ᴀ ᴄʜᴀᴛ ғʀᴏᴍ ᴜsɪɴɢ ᴛʜᴇ ʙᴏᴛ. +/whitelistchat [ᴄʜᴀᴛ ɪᴅ] : ᴡʜɪᴛᴇʟɪsᴛ ᴛʜᴇ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛ. +/blacklistedchat : sʜᴏᴡs ᴛʜᴇ ʟɪsᴛ ᴏғ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛs. +""" + +HELP_5 = """ +ʙʟᴏᴄᴋ ᴜsᴇʀs: [ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs] + +sᴛᴀʀᴛs ɪɢɴᴏʀɪɴɢ ᴛʜᴇ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴜsᴇʀ, sᴏ ᴛʜᴀᴛ ʜᴇ ᴄᴀɴ'ᴛ ᴜsᴇ ʙᴏᴛ ᴄᴏᴍᴍᴀɴᴅs. + +/block [ᴜsᴇʀɴᴀᴍᴇ ᴏʀ ʀᴇᴩʟʏ ᴛᴏ ᴀ ᴜsᴇʀ] : ʙʟᴏᴄᴋ ᴛʜᴇ ᴜsᴇʀ ғʀᴏᴍ ᴏᴜʀ ʙᴏᴛ. +/unblock [ᴜsᴇʀɴᴀᴍᴇ ᴏʀ ʀᴇᴩʟʏ ᴛᴏ ᴀ ᴜsᴇʀ] : ᴜɴʙʟᴏᴄᴋs ᴛʜᴇ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀ. +/blockedusers : sʜᴏᴡs ᴛʜᴇ ʟɪsᴛ ᴏғ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs. +""" + +HELP_6 = """ +ᴄʜᴀɴɴᴇʟ ᴩʟᴀʏ ᴄᴏᴍᴍᴀɴᴅs: + +ʏᴏᴜ ᴄᴀɴ sᴛʀᴇᴀᴍ ᴀᴜᴅɪᴏ/ᴠɪᴅᴇᴏ ɪɴ ᴄʜᴀɴɴᴇʟ. + +/cplay : sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴀᴜᴅɪᴏ ᴛʀᴀᴄᴋ ᴏɴ ᴄʜᴀɴɴᴇʟ's ᴠɪᴅᴇᴏᴄʜᴀᴛ. +/cvplay : sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴠɪᴅᴇᴏ ᴛʀᴀᴄᴋ ᴏɴ ᴄʜᴀɴɴᴇʟ's ᴠɪᴅᴇᴏᴄʜᴀᴛ. +/cplayforce or /cvplayforce : sᴛᴏᴩs ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ ᴀɴᴅ sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴛʀᴀᴄᴋ. + +/channelplay [ᴄʜᴀᴛ ᴜsᴇʀɴᴀᴍᴇ ᴏʀ ɪᴅ] ᴏʀ [ᴅɪsᴀʙʟᴇ] : ᴄᴏɴɴᴇᴄᴛ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴀ ɢʀᴏᴜᴩ ᴀɴᴅ sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʀᴀᴄᴋs ʙʏ ᴛʜᴇ ʜᴇʟᴩ ᴏғ ᴄᴏᴍᴍᴀɴᴅs sᴇɴᴛ ɪɴ ɢʀᴏᴜᴩ. +""" + +HELP_7 = """ +ɢʟᴏʙᴀʟ ʙᴀɴ ғᴇᴀᴛᴜʀᴇ [ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs] : + +/gban [ᴜsᴇʀɴᴀᴍᴇ ᴏʀ ʀᴇᴩʟʏ ᴛᴏ ᴀ ᴜsᴇʀ] : ɢʟᴏʙᴀʟʟʏ ʙᴀɴs ᴛʜᴇ ᴄʜᴜᴛɪʏᴀ ғʀᴏᴍ ᴀʟʟ ᴛʜᴇ sᴇʀᴠᴇᴅ ᴄʜᴀᴛs ᴀɴᴅ ʙʟᴀᴄᴋʟɪsᴛ ʜɪᴍ ғʀᴏᴍ ᴜsɪɴɢ ᴛʜᴇ ʙᴏᴛ. +/ungban [ᴜsᴇʀɴᴀᴍᴇ ᴏʀ ʀᴇᴩʟʏ ᴛᴏ ᴀ ᴜsᴇʀ] : ɢʟᴏʙᴀʟʟʏ ᴜɴʙᴀɴs ᴛʜᴇ ɢʟᴏʙᴀʟʟʏ ʙᴀɴɴᴇᴅ ᴜsᴇʀ. +/gbannedusers : sʜᴏᴡs ᴛʜᴇ ʟɪsᴛ ᴏғ ɢʟᴏʙᴀʟʟʏ ʙᴀɴɴᴇᴅ ᴜsᴇʀs. +""" + +HELP_8 = """ +ʟᴏᴏᴘ sᴛʀᴇᴀᴍ : + +sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ ɪɴ ʟᴏᴏᴘ + +/loop [enable/disable] : ᴇɴᴀʙʟᴇs/ᴅɪsᴀʙʟᴇs ʟᴏᴏᴘ ғᴏʀ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ +/loop [1, 2, 3, ...] : ᴇɴᴀʙʟᴇs ᴛʜᴇ ʟᴏᴏᴘ ғᴏʀ ᴛʜᴇ ɢɪᴠᴇɴ ᴠᴀʟᴜᴇ. +""" + +HELP_9 = """ +ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ [ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs] : + +/logs : ɢᴇᴛ ʟᴏɢs ᴏғ ᴛʜᴇ ʙᴏᴛ. + +/logger [ᴇɴᴀʙʟᴇ/ᴅɪsᴀʙʟᴇ] : ʙᴏᴛ ᴡɪʟʟ sᴛᴀʀᴛ ʟᴏɢɢɪɴɢ ᴛʜᴇ ᴀᴄᴛɪᴠɪᴛɪᴇs ʜᴀᴩᴩᴇɴ ᴏɴ ʙᴏᴛ. + +/maintenance [ᴇɴᴀʙʟᴇ/ᴅɪsᴀʙʟᴇ] : ᴇɴᴀʙʟᴇ ᴏʀ ᴅɪsᴀʙʟᴇ ᴛʜᴇ ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ ᴏғ ʏᴏᴜʀ ʙᴏᴛ. +""" + +HELP_10 = """ +ᴘɪɴɢ & sᴛᴀᴛs : + +/start : sᴛᴀʀᴛs ᴛʜᴇ ᴍᴜsɪᴄ ʙᴏᴛ. +/help : ɢᴇᴛ ʜᴇʟᴩ ᴍᴇɴᴜ ᴡɪᴛʜ ᴇxᴩʟᴀɴᴀᴛɪᴏɴ ᴏғ ᴄᴏᴍᴍᴀɴᴅs. + +/ping : sʜᴏᴡs ᴛʜᴇ ᴩɪɴɢ ᴀɴᴅ sʏsᴛᴇᴍ sᴛᴀᴛs ᴏғ ᴛʜᴇ ʙᴏᴛ. + +/stats : sʜᴏᴡs ᴛʜᴇ ᴏᴠᴇʀᴀʟʟ sᴛᴀᴛs ᴏғ ᴛʜᴇ ʙᴏᴛ. +""" + +HELP_11 = """ +ᴩʟᴀʏ ᴄᴏᴍᴍᴀɴᴅs : + +v : sᴛᴀɴᴅs ғᴏʀ ᴠɪᴅᴇᴏ ᴩʟᴀʏ. +force : sᴛᴀɴᴅs ғᴏʀ ғᴏʀᴄᴇ ᴩʟᴀʏ. + +/play ᴏʀ /vplay : sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴛʀᴀᴄᴋ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ. + +/playforce ᴏʀ /vplayforce : sᴛᴏᴩs ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ ᴀɴᴅ sᴛᴀʀᴛs sᴛʀᴇᴀᴍɪɴɢ ᴛʜᴇ ʀᴇǫᴜᴇsᴛᴇᴅ ᴛʀᴀᴄᴋ. +""" + +HELP_12 = """ +sʜᴜғғʟᴇ ᴏ̨ᴜᴇᴜᴇ : + +/shuffle : sʜᴜғғʟᴇ's ᴛʜᴇ ᴏ̨ᴜᴇᴜᴇ. +/queue : sʜᴏᴡs ᴛʜᴇ sʜᴜғғʟᴇᴅ ᴏ̨ᴜᴇᴜᴇ. +""" + +HELP_13 = """ +sᴇᴇᴋ sᴛʀᴇᴀᴍ : + +/seek [ᴅᴜʀᴀᴛɪᴏɴ ɪɴ sᴇᴄᴏɴᴅs] : sᴇᴇᴋ ᴛʜᴇ sᴛʀᴇᴀᴍ ᴛᴏ ᴛʜᴇ ɢɪᴠᴇɴ ᴅᴜʀᴀᴛɪᴏɴ. +/seekback [ᴅᴜʀᴀᴛɪᴏɴ ɪɴ sᴇᴄᴏɴᴅs] : ʙᴀᴄᴋᴡᴀʀᴅ sᴇᴇᴋ ᴛʜᴇ sᴛʀᴇᴀᴍ ᴛᴏ ᴛʜᴇ ᴛʜᴇ ɢɪᴠᴇɴ ᴅᴜʀᴀᴛɪᴏɴ. +""" + +HELP_14 = """ +sᴏɴɢ ᴅᴏᴡɴʟᴏᴀᴅ + +/song [sᴏɴɢ ɴᴀᴍᴇ/ʏᴛ ᴜʀʟ] : ᴅᴏᴡɴʟᴏᴀᴅ ᴀɴʏ ᴛʀᴀᴄᴋ ғʀᴏᴍ ʏᴏᴜᴛᴜʙᴇ ɪɴ ᴍᴘ3 ᴏʀ ᴍᴘ4 ғᴏʀᴍᴀᴛs. +""" + +HELP_15 = """ +sᴘᴇᴇᴅ ᴄᴏᴍᴍᴀɴᴅs : + +ʏᴏᴜ ᴄᴀɴ ᴄᴏɴᴛʀᴏʟ ᴛʜᴇ ᴘʟᴀʏʙᴀᴄᴋ sᴘᴇᴇᴅ ᴏғ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ. [ᴀᴅᴍɪɴs ᴏɴʟʏ] + +/speed or /playback : ғᴏʀ ᴀᴅᴊᴜsᴛɪɴɢ ᴛʜᴇ ᴀᴜᴅɪᴏ ᴘʟᴀʏʙᴀᴄᴋ sᴘᴇᴇᴅ ɪɴ ɢʀᴏᴜᴘ. +/cspeed or /cplayback : ғᴏʀ ᴀᴅᴊᴜsᴛɪɴɢ ᴛʜᴇ ᴀᴜᴅɪᴏ ᴘʟᴀʏʙᴀᴄᴋ sᴘᴇᴇᴅ ɪɴ ᴄʜᴀɴɴᴇʟ. +""" +HELP_16 = """ + CHATGPT COMMANDS : + +USE CHATGPT USING THESE FOLLOWING COMMANDS +/ASK,/CHATGPT,/GPT +TO RESET THE CONVERSTION USE /RESET +TO SET THE ROLE FOR CHATGPT USE /SETROLE +""" + diff --git a/strings/langs/ar.yml b/strings/langs/ar.yml new file mode 100644 index 0000000000000000000000000000000000000000..9571535e36f2538880b6c04eb8c39c818652c7b5 --- /dev/null +++ b/strings/langs/ar.yml @@ -0,0 +1,320 @@ +name : 🇦🇪 عربي + + +general_1 : "» قم بالرد على رسالة المستخدم أو قم بتقديم اسم المستخدم / معرف المستخدم." +general_2 : "» حدث خطأ ما أثناء معالجة استعلامك.\n\nاستثناء: {0}" +general_3 : "أنت مشرف مجهول في هذه الدردشة، عد إلى حساب المستخدم لاستخدامي." +general_4 : "» ليس لديك الصلاحيات لإدارة مكالمات الفيديو.\n\nقم بإعادة تحميل ذاكرة التخزين المؤقت للمشرفين عبر /reload" +general_5 : "» البوت لا يقوم ببث مكالمات الفيديو." + +tg_1 : "{0} مُنزِّل\n\nحجم الملف: {1}\nاكتمل: {2}\nالنسبة المئوية: {3}%\n\nالسرعة: {4}/ث\nالتقدير الزمني: {5}" +tg_2 : "تم التنزيل بنجاح، جاري معالجة الملف...\n\nالوقت المستغرق: {0}" +tg_3 : "فشل في تنزيل الوسائط من تليجرام، يرجى المحاولة مرة أخرى..." +tg_4 : "» تم تنزيل العنصر بالفعل." +tg_5 : "» تم تنزيل العنصر بالفعل أو تم الإلغاء." +tg_6 : "» تم إلغاء التنزيل." +tg_7 : "» تم إلغاء التنزيل بواسطة: {0}" +tg_8 : "فشل في إيقاف التنزيل." +tg_9 : "فشل في الحصول على مهمة التنزيل الجارية..." + +call_1 : "» البوت يحتاج إذن دعوة المستخدمين عبر الرابط لدعوة المساعد إلى محادثتك." +call_2 : "تم حظر مساعد {0} في مجموعتك/قناتك.\n\nالمعرّف : {1}\nالاسم : {2}\nاسم المستخدم : @{3}\n\nيرجى إلغاء حظر المساعد والمحاولة مرة أخرى." +call_3 : "فشل في دعوة مساعد {0} إلى محادثتك.\n\nالسبب : {1}" +call_4 : "يرجى الانتظار...\n\nجاري دعوة مساعد {0} إلى محادثتك..." +call_5 : "تم انضمام مساعد {0} بنجاح.\n\nمحاولة بدء التشغيل..." +call_6 : "» فشل في التبديل إلى البث، يُرجى استخدام /skip لتغيير المسار مرة أخرى." +call_7 : "» جاري تنزيل المسار التالي من قائمة الانتظار.\n\nيرجى الانتظار..." +call_8 : "لم يتم العثور على دردشة فيديو نشطة.\n\nيرجى بدء دردشة فيديو في مجموعتك/قناتك والمحاولة مرة أخرى." +call_9 : "المساعد بالفعل في دردشة فيديو.\n\nإذا لم يكن المساعد في دردشة فيديو، يرجى إرسال /reboot ثم اللعب مرة أخرى." +call_10 : "خطأ في الخادم التيليجرام\n\nالتيليجرام يواجه مشكلات داخلية، يرجى المحاولة مرة أخرى أو إعادة تشغيل دردشة الفيديو في مجموعتك/قناتك." + +auth_1 : "» يمكنك فقط أن تمتلك 25 مستخدمًا مُصرَّحًا في مجموعتك." +auth_2 : "» تمت إضافة {0} إلى قائمة المستخدمين المُصرَّح بهم." +auth_3 : "{0} موجود بالفعل في قائمة المستخدمين المُصرَّح بهم." +auth_4 : "» تمت إزالة {0} من قائمة المستخدمين المُصرَّح بهم." +auth_5 : "{0} غير موجود في قائمة المستخدمين المُصرَّح بهم." +auth_6 : "» جاري استرداد قائمة المستخدمين المُصرَّح بهم..." +auth_7 : "» قائمة المستخدمين المُصرَّح بهم في {0}:\n\n" +auth_8 : "↬ تمت الإضافة بواسطة:" + +reload_1 : "» يمكنك تحديث ذاكرة التخزين المؤقت للمشرفين فقط مرة واحدة كل 3 دقائق.\n\nيرجى المحاولة بعد {0}." +reload_2 : "» تم تحديث ذاكرة التخزين المؤقت للمشرفين بنجاح." +reload_3 : "» فشل في تحديث ذاكرة التخزين المؤقت للمشرفين، تأكد من أن البوت مشرف في محادثتك." +reload_4 : "» يُرجى الانتظار...\n\nإعادة تشغيل {0} لمحادثتك." +reload_5 : "تم إعادة تشغيل {0} بنجاح لمحادثتك.\n\nابدأ اللعب مرة أخرى..." + +admin_1 : "هل تذكر أنك استأنفت البث؟" +admin_2 : "➻ تم إيقاف البث مؤقتًا 🎄\n│ \n└بواسطة: {0} 🥀" +admin_3 : "هل تذكر أنك قمت بإيقاف البث؟" +admin_4 : "➻ تم استئناف البث 🎄\n│ \n└بواسطة: {0} 🥀" +admin_5 : "➻ انتهى/تم إيقاف البث 🎄\n│ \n└بواسطة: {0} 🥀" +admin_6 : "➻ تم تخطي البث 🎄\n│ \n└بواسطة: {0} 🥀\n\n» لا توجد مقاطع في قائمة الانتظار في {1}، سأغادر الدردشة الفيديوية." +admin_7 : "خطأ أثناء تغيير البث إلى {0}." +admin_8 : "» يرجى تعطيل التكرار الدائري عبر /loop disable ثم حاول الانتقال مرة أخرى." +admin_9 : "يرجى استخدام أرقام محددة للانتقال، مثل 1، 2، 4..." +admin_10 : "مطلوب على الأقل مقطعين في قائمة الانتظار للانتقال إلى المقطع المحدد.\n\nتحقق من قائمة الانتظار عبر: /queue" +admin_11 : "» ليس هناك مقاطع كافية في قائمة الانتظار للانتقال إلى المقطع المحدد.\n\nيرجى الانتقال بين المقاطع من 1 إلى {0}" +admin_12 : "» فشل في الانتقال إلى المقطع المحدد.\n\nتحقق من المقاطع المتبقية في قائمة الانتظار عبر: /queue" +admin_13 : "» يرجى إعادة تحميل ذاكرة التخزين المؤقت للمشرف عبر: /reload" +admin_14 : "» ليس لديك صلاحيات لإدارة دردشات الفيديو.\n\nيرجى إعادة تحميل ذاكرة التخزين المؤقت للمشرف عبر: /reload" +admin_15 : "» فشل في عملية الخلط.\n\nتحقق من قائمة الانتظار عبر: /queue" +admin_16 : "» تم خلط قائمة الانتظار بواسطة {0}.\n\nتحقق من قائمة الانتظار المختلطة عبر: /queue" +admin_17 : "مثال:\n\n/loop enable/disable\n/loop 10/9/8/7" +admin_18 : "» تم تمكين الحلقة لعدد {0} مرات بواسطة: {1}." +admin_19 : "» تم تعطيل تشغيل الحلقة بواسطة: {0}." +admin_20 : "مثال:\n\n/seek or /seekback [المدة بالثواني]" +admin_21 : "» يرجى استخدام أرقام رقمية لعملية البحث بالثواني." +admin_22 : "» لا يمكن تغيير مكان بث الفيديو المباشر." +admin_23 : "» حاول التحكم في البحث بمدة أقل.\n\nتم تشغيل {0} من أصل {1} دقيقة." +admin_24 : "جارِ البحث...\n\nيرجى الانتظار..." +admin_25 : "» تم تغيير مكان البث بنجاح.\n\nالمدة: {0} دقيقة\nبواسطة: {1}" +admin_26 : "فشل في تغيير المكان." +admin_27 : "» يمكن التحكم حالياً فقط في سرعة بث اليوتيوب." +admin_28 : "لوحة تحكم سرعة {0}\n\nانقر على الأزرار أدناه لتغيير سرعة البث الحالي في دردشة الفيديو." +admin_29 : "» البوت يعمل بالفعل بسرعة عادية." +admin_30 : "» يرجى الانتظار...\n\nهناك شخص آخر يحاول تغيير سرعة البث." +admin_31 : "جارِ تغيير السرعة..." +admin_32 : "» يتم محاولة تغيير سرعة البث الحالي...\n\nطلب بواسطة: {0}" +admin_33 : "» فشل في تغيير سرعة البث الحالي." +admin_34 : "» تم تغيير سرعة البث الحالي إلى {0}x\n\nطلب بواسطة: {1}" +admin_35 : "انتهت عملية التصويت لأن المقطع الذي تم تقديم التصويت له قد انتهى." +admin_36 : "فشل في تنفيذ هذا الإجراء لأن المقطع الذي تم تقديم التصويت له قد انتهى أو تم إيقافه." +admin_37 : "تم الحصول بنجاح على {0} تصويت إيجابي." +admin_38 : "» تمت إضافة تصويت إيجابي واحد." +admin_39 : "» تمت إزالة تصويت إيجابي واحد." +admin_40 : "تم التصويت بإيجابية." + +start_1 : "{0} على قيد الحياة يا صغيري.\n\n✫ وقت التشغيل : {1}" +start_2 : "هلا {0}، 🥀\n\n๏ هذا هو {1} !\n\n➻ بوت تشغيل موسيقى سريع وقوي على تليجرام مع ميزات رائعة.\n\nالمنصات المدعومة: يوتيوب، سبوتيفاي، ريسو، آبل ميوزيك وساوندكلاود.\n──────────────────\n๏ انقر على زر المساعدة للحصول على معلومات حول وحداتي وأوامري." +start_3 : "هلا {0}،\nهذا {1}\n\nشكرًا لإضافتي في {2}، {3} الآن يمكنه تشغيل الأغاني في هذه الدردشة." +start_4 : "🎄 المطلوب سوبر جروب 🎄\n\nيرجى تحويل المجموعة الخاصة بك إلى سوبر جروب ثم أضفني مرة أخرى.\n\nكيفية جعلها سوبر جروب؟\n- اجعل تاريخ الدردشة الخاصة بمجموعتك مرئيًا مرة واحدة." +start_5 : "↝ الدردشة في القائمة السوداء ↜\n\nتم إدراج هذه الدردشة في قاعدة بيانات {0} كدردشة في القائمة السوداء.\nقدم طلبًا لمستخدم سودو لإزالة الدردشة من القائمة السوداء أو قم بزيارة دردشة الدعم." +start_6 : "😲 معلومات المقطع 😲\n\n📌 العنوان : {0}\n\n⏳ المدة : {1} دقيقة\n👀 المشاهدات : {2}\n⏰ نشر في : {3}\n📎 القناة : {5}\n\n🥀 البحث مدعوم من قبل {6}" + +queue_1 : "» جاري جلب قائمة الانتظار...\n\nيرجى الانتظار..." +queue_2 : "» قائمة الانتظار فارغة." +queue_3 : "» انقر هنا للتحقق من قائمة المقاطع في الانتظار : هنا" +queue_4 : "➲ تمت إضافته إلى قائمة الانتظار في الموقع رقم #{0}\n\n‣ العنوان : {1}\n‣ المدة : {2} دقيقة\n‣ طلب بواسطة : {3}" +queue_5 : "هناك مقطع واحد فقط في قائمة الانتظار.\n\nأضف المزيد من المقاطع للتحقق من القائمة." +queue_6 : "🕚 المدة : مدة البث غير معروفة\n\nانقر على الزر أدناه للحصول على قائمة الانتظار بالكامل." +queue_7 : "\nانقر على الزر أدناه للحصول على قائمة الانتظار بالكامل." +queue_8 : "مشغل {0}\n\n🎄 يتم البث حاليًا لـ : {1}\n\n🔗 نوع البث : {2}\n🥀 طلب بواسطة : {3}\n{4}" + +stream_1 : "➲ بدء البث |\n\n‣ العنوان : {1}\n‣ المدة : {2} دقيقة\n‣ طلب بواسطة : {3}" +stream_2 : "➲ بدء البث |\n\n‣ نوع البث : بث مباشر [الرابط]\n‣ طلب بواسطة : {0}" + +help_1 : "اختر الفئة التي ترغب في الحصول على المساعدة لها.\nاستفسر عن شكواك في دردشة الدعم\n\nيمكن استخدام جميع الأوامر مع : /" +help_2 : "انقر على الزر أدناه للحصول على قائمة المساعدة في رسائلك الخاصة." + +lang_1 : "» يُرجى اختيار اللغة التي ترغب في تعيينها كلغة افتراضية لهذه المجموعة:" +lang_2 : "تم تغيير اللغة بنجاح." +lang_3 : "فشل في تغيير اللغة." +lang_4 : "أنت بالفعل على نفس اللغة." + +setting_1 : "لوحة إعدادات {0}\n\nمعرّف الدردشة : {1}\nعنوان الدردشة : {2}\n\nانقر على الأزرار أدناه لتغيير الإعدادات." +setting_2 : "» مباشر : يشغل عمليات البحث مباشرةً.\n\n» مضمن : يعيد زرًا مضمنًا للاختيار بين الفيديو والصوت." +setting_3 : "» الجميع : يمكن لأي شخص استخدام أوامر المشرف [تخطي، إيقاف مؤقت، استئناف وما إلى ذلك] في هذه المجموعة.\n\n» المشرفون فقط : يمكن فقط للمشرفين والمستخدمين المصرح لهم استخدام أوامر المشرف." +setting_4 : "» لم يتم العثور على مستخدمين مصرح لهم." +setting_5 : "» مجموعة : يشغل الموسيقى في المجموعة التي تم إعطاء الأمر فيها.\n\n» قناة : يشغل الموسيقى في القناة التي تريدها. قم بتعيين معرّف القناة عبر /channelplay" +setting_6 : "» الجميع : يمكن لأي شخص حاضر في هذه المجموعة تشغيل الموسيقى هنا.\n\n» المشرفون فقط : يمكن فقط للمشرفين تشغيل الموسيقى في هذه المجموعة." +setting_7 : "» يرجى تعريف معرف القناة عبر /channelplay" +setting_8 : "عند تمكين هذا الوضع، يمكن للأشخاص الذين ليس لديهم صلاحيات المشرف استخدام أوامر المشرف بعد عدد معين من التصويتات." +setting_9 : "التصويتات الحالية المطلوبة لاستخدام أوامر المشرف هي : {0}" +setting_10 : "تم تعطيل وضع التصويت." +setting_11 : "أدنى عدد للتصويتات يمكن أن يكون 2. لا يمكنك تعيينه أقل من 2" +setting_12 : "أعلى عدد للتصويتات يمكن أن يكون 15. لا يمكنك تعيينه أعلى من 15" + +set_cb_1 : "جارٍ الحصول على لوحة مستخدمي المصرح لهم..." +set_cb_2 : "جارٍ الحصول على لوحة وضع التشغيل..." +set_cb_3 : "جاري تغيير الإعدادات..." +set_cb_4 : "» جاري الحصول على قائمة المستخدمين المصرح لهم..." +set_cb_5 : "» الرجاء الانتظار..." + +gstats_1 : "جارٍ الحصول على إحصائيات ومعلومات {0}...\n\nقد يستغرق الأمر بعض الوقت، يرجى الانتظار..." +gstats_2 : "انقر على الأزرار أدناه للتحقق من إحصائيات {0}." +gstats_3 : "إحصائيات ومعلومات {0} :\n\nالمساعدين : {1}\nالمحظورون : {2}\nالدردشات : {3}\nالمستخدمون : {4}\nالوحدات : {5}\nالمشرفون : {6}\n\nمغادرة تلقائية للمساعدين : {7}\nحدود مدة التشغيل : {8} دقائق" +gstats_4 : "هذا الزر مخصص للمشرفين فقط." +gstats_5 : "إحصائيات ومعلومات {0} :\n\nالوحدات : {1}\nالمنصة : {2}\nالذاكرة (RAM) : {3}\nالنوى الفعلية : {4}\nإجمالي النوى : {5}\nتردد وحدة المعالجة المركزية : {6}\n\nبيثون : {7}\nPyrogram : {8}\nPy-TgCalls : {9}\n\nالتخزين المتاح : {10} جيبايت\nالتخزين المستخدم : {11} جيبايت\nالتخزين المتبقي : {12} جيبايت\n\nالدردشات المخدومة : {13}\nالمستخدمون المخدومون : {14}\nالمستخدمون المحظورون : {15}\nمستخدمو sudo : {16}\n\nحجم قاعدة البيانات الإجمالي : {17} ميجابايت\nسعة تخزين قاعدة البيانات الإجمالية : {18} ميجابايت\nإجمالي مجموعات بيانات قاعدة البيانات : {19}\nإجمالي مفاتيح قاعدة البيانات : {20}" + +playcb_1 : "» آه، هذا ليس لك يا حبيبي." +playcb_2 : "» جاري الحصول على النتيجة التالية،\n\nالرجاء الانتظار..." + +cplay_1 : "» يمكنك تشغيل الموسيقى في القنوات من {0} إلى أي قناة أخرى أو القناة المرتبطة بالدردشة.\n\nللقناة المرتبطة :\n/channelplay linked\n\nلأي قناة أخرى :\n/channelplay [معرف القناة]" +cplay_2 : "» هذه الدردشة ليس لديها أي قناة مرتبطة." +cplay_3 : "» تم تعيين القناة إلى {0}.\nمعرف القناة : {1}" +cplay_4 : "» فشل في الحصول على القناة.\n\nتأكد من أنك قمت بإضافة البوت إلى القناة وترقيته كمشرف." +cplay_5 : "القنوات فقط مدعومة." +cplay_6 : "» يجب أن تكون المالك للقناة {0} لتربطها بالمجموعة هذه.\nمالك القناة : @{1}\n\nبديلاً يمكنك ربط مجموعتك بتلك القناة ومن ثم محاولة الاتصال باستخدام /channelplay linked" +cplay_7 : "» تم تعطيل تشغيل القناة." + +play_1 : "🔎" +play_2 : "➻ وضع تشغيل القناة\n\nجاري المعالجة، يرجى الانتظار...\n\nالقناة المرتبطة : {0}" +play_3 : "» فشل في معالجة الاستعلام." +play_4 : "تشغيل للمسؤولين فقط\nيُسمح فقط لمسؤولي هذه الدردشة بالتشغيل\n\nقم بتغيير وضع التشغيل عبر /playmode" +play_5 : "» فشل في معالجة ملف الصوت.\n\nحجم ملف الصوت أكبر من الحد المحدد." +play_6 : "» البث أطول من {0} غير مسموح بتشغيله على {1}" +play_7 : "» ليس ملحق ملف فيديو صالح.\n\nالملحقات المدعومة : {0}" +play_8 : "» يجب أن يكون حجم ملف الفيديو أقل من 1 جيجابايت." +play_9 : "ميزة قائمة تشغيل يوتيوب\n\nحدد الوضع الذي تريد تشغيل قائمة تشغيل يوتيوب كاملة فيه." +play_10 : "العنوان : {0}\nالمدة : {1} دقيقة" +play_11 : "مشغل سبوتيفاي {0}\n\nالطلب من قِبل : {1}" +play_12 : "مشغل أبل ميوزك {0}\n\nالطلب من قِبل : {1}" +play_13 : "» تم الكشف عن بث مباشر.\n\nهل أنت متأكد أنك تريد تشغيل هذا البث المباشر؟" +play_14 : "فشل في جلب تفاصيل المسار.\n\nجرب تشغيل أي مسار آخر." +play_15 : "» فشل في معالجة الاستعلام.\n\nأستطيع فقط تشغيل مسارات سبوتيفاي والبومات وفنانين وقوائم تشغيل." +play_16 : "لا يوجد دردشة صوتية نشطة.\n\nلاستخدام التشغيل القسري، يجب أن يكون هناك دردشة صوتية نشطة." +play_17 : "يرجى تشغيل دردشة الفيديو، لا يمكنني تشغيل عناوين URL." +play_18 : "الاستخدام: /play [اسم الأغنية/عنوان يوتيوب/الرد على ملف صوتي/فيديو]" +play_19 : "قائمة التشغيل في الانتظار:" +play_20 : "الموقف في قائمة الانتظار -" +play_21 : "تمت إضافة {0} مسارات إلى القائمة في الانتظار.\n\nالتحقق: انقر هنا" +play_22 : "حدد الوضع الذي تريد تشغيل الاستعلامات به داخل مجموعتك: {0}" + +str_1 : "يرجى تقديم روابط m3u8 أو index." +str_2 : "➻ تم التحقق من البث الصالح.\n\nجاري المعالجة..." +str_3 : "فشل في بث بث مباشر من يوتيوب، لم يتم العثور على تنسيق بث مباشر." + +ping_1 : "يتم عمل بينغ لـ {0}..." +ping_2 : "🏓 البونج : {0}ms\n\n{1} إحصائيات النظام :\n\n↬ وقت التشغيل : {2}\n↬ الذاكرة العشوائية (RAM) : {3}\n↬ المعالج (CPU) : {4}\n↬ القرص الصلب (Disk) : {5}\n↬ Py-TgCalls : {6}ms" + +queue_1 : "» جاري جلب قائمة الانتظار...\n\nيرجى الانتظار..." +queue_2 : "» قائمة الانتظار فارغة." +queue_3 : "» انقر هنا للتحقق من قائمة المقاطع في الانتظار : هنا" +queue_4 : "➲ تمت إضافته إلى قائمة الانتظار في الموقع رقم #{0}\n\n‣ العنوان : {1}\n‣ المدة : {2} دقيقة\n‣ طلب بواسطة : {3}" +queue_5 : "هناك مقطع واحد فقط في قائمة الانتظار.\n\nأضف المزيد من المقاطع للتحقق من القائمة." +queue_6 : "🕚 المدة : مدة البث غير معروفة\n\nانقر على الزر أدناه للحصول على قائمة الانتظار بالكامل." +queue_7 : "\nانقر على الزر أدناه للحصول على قائمة الانتظار بالكامل." +queue_8 : "مشغل {0}\n\n🎄 يتم البث حاليًا لـ : {1}\n\n🔗 نوع البث : {2}\n🥀 طلب بواسطة : {3}\n{4}" + +stream_1 : "➲ بدء البث |\n\n‣ العنوان : {1}\n‣ المدة : {2} دقيقة\n‣ طلب بواسطة : {3}" +stream_2 : "➲ بدء البث |\n\n‣ نوع البث : بث مباشر [الرابط]\n‣ طلب بواسطة : {0}" + +CLOSE_BUTTON : "إغلاق" +BACK_BUTTON : "رجوع" + +S_B_1 : "أضفني" +S_B_2 : "الدعم" +S_B_3 : "أضفني في مجموعتك" +S_B_4 : "المساعدة والأوامر" +S_B_5 : "المطور" +S_B_6 : "القناة" +S_B_7 : "الشيفرة المصدرية" +S_B_8 : "👀 يوتيوب 👀" +S_B_9 : "🥀 الدعم 🥀" + +H_B_1 : "أدمن" +H_B_2 : "أوث" +H_B_3 : "بث" +H_B_4 : "بل-دردشة" +H_B_5 : "بل-مستخدم" +H_B_6 : "تشغيل-عشوائي" +H_B_7 : "حظر-جماعي" +H_B_8 : "تكرار" +H_B_9 : "صيانة" +H_B_10 : "بنج" +H_B_11 : "تشغيل" +H_B_12 : "تبديل-عشوائي" +H_B_13 : "بحث" +H_B_14 : "أغنية" +H_B_15 : "سرعة" + +P_B_1 : "صوتي" +P_B_2 : "فيديو" +P_B_3 : "بث مباشر" +P_B_4 : "عادي" + +ST_B_1 : "مستخدمين مصرح لهم" +ST_B_2 : "وضع التشغيل" +ST_B_3 : "اللغة" +ST_B_4 : "وضع التصويت" +ST_B_5 : "مشغل" +ST_B_6 : "معطل" +ST_B_7 : "مستخدمين مصرح لهم ➜" +ST_B_8 : "مسؤولون" +ST_B_9 : "الجميع" +ST_B_10 : "وضع البحث ➜" +ST_B_11 : "مباشر" +ST_B_12 : "داخلي" +ST_B_13 : "أوامر المسؤول ➜" +ST_B_14 : "نوع التشغيل ➜" + +SA_B_1 : "إحصائيات عامة" +SA_B_2 : "عام" +SA_B_3 : "عامة" + +QU_B_1 : "قائمة الانتظار" +QU_B_2 : " {0} —————————— {1}" + +sudo_1 : "» {0} موجود بالفعل في قائمة مستخدمي sudo." +sudo_2 : "» تمت إضافة {0} إلى قائمة مستخدمي sudo." +sudo_3 : "» {0} غير موجود في قائمة مستخدمي sudo." +sudo_4 : "» تمت إزالة {0} من قائمة مستخدمي sudo." +sudo_5 : "🥀 المالك :\n" +sudo_6 : "\n✨ مستخدمو sudo :\n" +sudo_7 : "» لا توجد مستخدمين sudo." +sudo_8 : "فشل." + +block_1 : "» {0} محظور بالفعل من البوت." +block_2 : "» تمت إضافة {0} إلى قائمة المستخدمين المحظورين." +block_3 : "» {0} غير موجود في قائمة المستخدمين المحظورين." +block_4 : "» تمت إزالة {0} من قائمة المستخدمين المحظورين." +block_5 : "» لا توجد مستخدمين محظورين." +block_6 : "» جاري الحصول على قائمة المستخدمين المحظورين..." +block_7 : "😫 المستخدمون المحظورون :\n\n" + +black_1 : "مثال :\n\n/blacklistchat [معرّف الدردشة]" +black_2 : "» هذه الدردشة محظورة بالفعل." +black_3 : "» تمت إضافتها بنجاح إلى قائمة الدردشات المحظورة." +black_4 : "مثال :\n\n/whitelistchat [معرّف الدردشة]" +black_5 : "» هذه الدردشة غير محظورة." +black_6 : "» تمت إزالتها بنجاح من قائمة الدردشات المحظورة." +black_7 : "» قائمة الدردشات المحظورة :\n\n" +black_8 : "» لا توجد دردشات محظورة على {0}." +black_9 : "» حدث خطأ ما." + +maint_1 : "مثال :\n/maintenance [تمكين | تعطيل]" +maint_2 : "» تم تمكين وضع الصيانة {0}." +maint_3 : "» تم تعطيل وضع الصيانة {0}." +maint_4 : "» وضع الصيانة مُمكّن بالفعل." +maint_5 : "» وضع الصيانة مُعطّل بالفعل." + +log_1 : "مثال :\n/logger [تمكين | تعطيل]" +log_2 : "تم تمكين تسجيل البيانات." +log_3 : "تم تعطيل تسجيل البيانات." + +broad_1 : "» بدء البث..." +broad_2 : "مثال :\n\n/broadcast [الرسالة أو الرد على رسالة]" +broad_3 : "» تم بث الرسالة إلى {0} دردشة مع {1} تثبيتًا من البوت." +broad_4 : "» تم بث الرسالة إلى {0} مستخدمين." +broad_5 : "» بدء بث المساعد..." +broad_6 : "➻ بث المساعد :\n\n" +broad_7 : "↬ تم بث المساعد {0} في {1} دردشة." +broad_8 : "» يُرجى تقديم نص للبث." + +server_1 : "» فشل في الحصول على السجلات." +server_2 : "يرجى التأكد من تكوين مفتاح API هيروكو الخاص بك واسم التطبيق بشكل صحيح." +server_3 : "التحقق من وجود تحديثات متاحة..." +server_4 : "خطأ في أمر git." +server_5 : "مستودع Git غير صالح." +server_6 : "» البوت محدث." +server_7 : "» تم تحديث البوت بنجاح! انتظر بضع دقائق حتى يتم إعادة تشغيل البوت ودمج التغييرات!" +server_8 : "جاري إعادة تشغيل {0}...\n\nيمكنك البدء في التشغيل مرة أخرى بعد 15-20 ثانية." +server_9 : "حدث خطأ ما، يُرجى التحقق من السجلات." +server_10 : "حدث استثناء في #مُحدّث بسبب : {0}" +server_11 : "» جاري إجراء اختبار سرعة..." +server_12 : "⇆ جاري اختبار سرعة التنزيل..." +server_13 : "⇆ جاري اختبار سرعة الرفع..." +server_14 : "↻ مشاركة نتائج اختبار السرعة..." +server_15 : "✯ نتائج اختبار السرعة ✯\n\nالعميل :\n» عنوان IP : {0}\n» البلد : {1}\n\nالخادم :\n» الاسم : {2}\n» البلد : {3}, {4}\n» الراعي : {5}\n» التأخير : {6}\n» التأخير في الشبكة : {7}" +gban_1 : "» لماذا تريد حظر نفسك يا صغيري؟" +gban_2 : "» لماذا يجب أن أحظر نفسي؟" +gban_3 : "» لا يمكنك حظر المستخدمين المصرح لهم." +gban_4 : "» تم حظر {0} بالفعل على مستوى البوت." +gban_5 : "» جاري تنفيذ حظر عالمي على {0}.\n\nالزمن المتوقع: {1}" +gban_6 : "حظر عالمي جديد على {0}:\n\nمنبعه من : {1} [{2}]\nالمستخدم : {3}\nمعرّف المستخدم : {4}\n\nتم الحظر بواسطة : {5}\nالدردشات : {6}" +gban_7 : "» {0} ليس محظورًا على مستوى البوت." +gban_8 : "» رفع الحظر العالمي عن {0}.\n\nالزمن المتوقع : {1}" +gban_9 : "» تم رفع الحظر العالمي عن {0}.\n\nتم إلغاء الحظر في {1} دردشة." +gban_10 : "» لا يوجد أي مستخدم محظور على مستوى البوت." +gban_11 : "» جاري جلب قائمة المستخدمين المحظورين على مستوى البوت..." +gban_12 : "🙂 قائمة المستخدمين المحظورين عالميًا :\n\n" diff --git a/strings/langs/en.yml b/strings/langs/en.yml new file mode 100644 index 0000000000000000000000000000000000000000..b6f1814f43814c048a147be2f69bec1bd17b710b --- /dev/null +++ b/strings/langs/en.yml @@ -0,0 +1,344 @@ +name : 🇺🇸 English + + +general_1: "ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴜsᴇʀ'ѕ ᴍᴇssᴀɢᴇ ᴏʀ ɢɪᴠᴇ ᴜsᴇʀɴᴀᴍᴇ/ᴜsᴇʀ ɪᴅ." +general_2: "» sᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ ᴡʜɪʟᴇ ᴘʀᴏᴄᴇssɪɴɢ ʏᴏᴜʀ ǫᴜᴇʀʏ.\n\nᴇxᴄᴇᴘᴛɪᴏɴ : {0}" +general_3: "ʏᴏᴜ'ʀᴇ ᴀɴ ᴀɴᴏɴʏᴍᴏᴜs ᴀᴅᴍɪɴ ɪɴ ᴛʜɪs ᴄʜᴀᴛ, ʀᴇᴠᴇʀᴛ ʙᴀᴄᴋ ᴛᴏ ᴜsᴇʀ ᴀᴄᴄᴏᴜɴᴛ ғᴏʀ ᴜsɪɴɢ ᴍᴇ." +general_4: "» ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴs ᴛᴏ ᴍᴀɴᴀɢᴇ ᴠɪᴅᴇᴏ ᴄʜᴀᴛs.\n\nʀᴇʟᴏᴀᴅ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ᴠɪᴀ /reload" +general_5: "» ʙᴏᴛ ɪsɴ'ᴛ sᴛʀᴇᴀᴍɪɴɢ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ." + +#Playlist Buttons +PL_B_1 : "ᴘʟᴀʏ ᴘʟᴀʏʟɪsᴛ" +PL_B_2 : "ᴀᴅᴅ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ" +PL_B_3 : "ᴍᴏʀᴇ" +PL_B_4 : "ᴘʟᴀʏ ᴍᴏᴅᴇ" +PL_B_5 : "ᴅᴇʟ ᴀʟʟ ᴘʟᴀʏʟɪsᴛ" +PL_B_6 : "ᴅᴇʟ ᴘʟᴀʏʟɪsᴛ" +PL_B_7 : "ʏᴇs ɪ ᴀᴍ sᴜʀᴇ." +PL_B_8 : "ᴘʟᴀʏ ᴛᴏᴘ 10" +PL_B_9 : "ᴘʟᴀʏ ɢʟᴏʙᴀʟ ᴛᴏᴘ 10" +PL_B_10 : "ᴘʟᴀʏ ɢʀᴏᴜᴘ ᴛᴏᴘ 10" +PL_B_11 : "ᴘʟᴀʏ ᴘᴇʀsᴏɴᴀʟ ᴛᴏᴘ 10" + +#Playlist +playlist_1 : "ᴜsᴀɢᴇ: /ᴘʟᴀʏ [ᴍᴜsɪᴄ ɴᴀᴍᴇ ᴏʀ ʏᴏᴜᴛᴜʙᴇ ʟɪɴᴋ ᴏʀ ʀᴇᴘʟʏ ᴛᴏ ᴀᴜᴅɪᴏ]\n\n ɪғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴘʟᴀʏ ʙᴏᴛ's sᴇʀᴠᴇʀ ᴘʟᴀʏʟɪsᴛ! ᴛʏᴘᴇ /ᴘʟᴀʏ ᴀɴᴅ ᴘʀᴇss ᴏɴ ᴘʟᴀʏ ᴘʟᴀʏʟɪsᴛ ʙᴜᴛᴛᴏɴ.." +playlist_2 : "ɢᴇᴛᴛɪɴɢ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..." +playlist_3 : "➻ ʏᴏᴜ ʜᴀᴠᴇ ɴᴏ ᴘʟᴀʏʟɪsᴛ ᴏɴ ʙᴏᴛ's sᴇʀᴠᴇʀ.\n\n➥ ᴛᴏ ᴀᴅᴅ ᴀ sᴏɴɢ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ,ᴊᴜsᴛ ᴛʏᴘᴇ » /ᴀᴅᴅᴘʟᴀʏʟɪsᴛ [ sᴏɴɢ ɴᴀᴍᴇ / sᴏɴɢ ʟɪɴᴋ / YᴏᴜTᴜʙᴇ ᴘʟᴀʏʟɪsᴛ ʟɪɴᴋ ] \n\n➥ ʟɪᴋᴇ » /ᴀᴅᴅᴘʟᴀʏʟɪsᴛ DJ ʙᴀʟᴀ ʙᴀʙᴜ" +playlist_4 : "➻ ғᴇᴛᴄʜᴇᴅ ᴘʟᴀʏʟɪsᴛ:\n\n➥" +playlist_5 : "Duration- {0} Mins" +playlist_6 : "Contact me in PM for deletion of Playlists." +playlist_7 : "➻ ᴛʀᴀᴄᴋs ɪɴsɪᴅᴇ ᴘʟᴀʏʟɪsᴛ: {0} \n\n ᴘʀᴇss ᴛʜᴇ ʙᴜᴛᴛᴏɴs ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴛʀᴀᴄᴋ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ.\n\n ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴡʜᴏʟᴇ ᴘʟᴀʏʟɪsᴛ: ᴘʀᴇss ᴅᴇʟ ᴡʜᴏʟᴇ ᴘʟᴀʏʟɪsᴛ ʙᴜᴛᴛᴏɴ." +playlist_8 : "➻ ᴛʜɪs sᴏɴɢ ɪs ᴀʟʀᴇᴀᴅʏ ᴀᴅᴅᴇᴅ ɪɴ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ.\n\n➥ ᴛʀʏ ᴀɴᴏᴛʜᴇʀ sᴏɴɢ ɴᴀᴍᴇ ᴛᴏ ᴀᴅᴅ ᴍᴏʀʀ sᴏɴɢs.\n\n➥ ᴄʜᴇᴄᴋ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ ʙʏ » /playlists \n\n ➥ ᴅᴇʟᴇᴛᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ » /delplaylist**" +playlist_9 : "sᴏʀʀʏ! ʏᴏᴜ ᴄᴀɴ ᴏɴʟʏ ʜᴀᴠᴇ {0} ᴍᴜsɪᴄ ɪɴ ᴀ ᴘʟᴀʏʟɪsᴛ." +playlist_10 : "ᴘʟᴀʏʟɪsᴛ ᴀᴅᴅɪᴛɪᴏɴ\n\n{0}\nᴀᴅᴅᴇᴅ ᴛᴏ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ." +playlist_11 : "➻ sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴇʟᴇᴛᴇᴅ ʏᴏᴜʀ sᴏɴɢ ғʀᴏᴍ ᴘʟᴀʏʟɪsᴛ." +playlist_12 : "➻ ғᴀɪʟᴇᴅ ᴛᴏ ᴅᴇʟᴇᴛᴇ ʏᴏᴜʀ sᴏɴɢ." +playlist_13 : "➻ ᴅᴇʟᴇᴛᴇᴅ ʏᴏᴜʀ ᴀʟʟ sᴏɴɢs ғʀᴏᴍ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ " +playlist_14 : "ᴀʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴅᴇʟᴇᴛᴇ ʏᴏᴜʀ ᴀʟʟ sᴏɴɢs ғʀᴏᴍ ᴘʟᴀʏʟɪsᴛ? \n\n ʏᴏᴜ'll ʟᴏsᴛ ʏᴏᴜʀ ᴘʟᴀʏʟɪsᴛ ᴀɴᴅ ᴛʜɪs ᴄᴀɴ'ᴛ ʙᴇ ʀᴇᴄᴏᴠᴇʀᴇᴅ ʟᴀᴛᴇʀ." +playlist_15 : "ᴄʜᴇᴄᴋᴏᴜᴛ ᴡʜᴏʟᴇ ᴘʟᴀʏʟɪsᴛ ʙʏ ᴄʟɪᴄᴋ ʜᴇʀᴇ » [ sᴇᴇ ᴘʟᴀʏʟɪsᴛ ]({0})" +playlist_16 : "ǫᴜᴇᴜᴇᴅ ᴘʟᴀʏʟɪsᴛ:" +playlist_17 : "ǫᴜᴇᴜᴇᴅ ᴘᴏsɪᴛɪᴏɴ-" +playlist_18 : "➻ [ᴄʜᴇᴄᴋᴏᴜᴛ ᴡʜᴏʟᴇ ǫᴜᴇᴜᴇᴅ ᴘʟᴀʏʟɪsᴛ]({0})\n\n➥ ʟᴀsᴛ ǫᴜᴇᴜᴇᴅ ᴘᴏsɪᴛɪᴏɴ : {1}" + + +tg_1 : "{0} ᴅᴏᴡɴʟᴏᴀᴅᴇʀ\n\nғɪʟᴇ sɪᴢᴇ : {1}\nᴄᴏᴍᴘʟᴇᴛᴇᴅ : {2}\nᴘᴇʀᴄᴇɴᴛᴀɢᴇ : {3}%\n\nsᴘᴇᴇᴅ : {4}/s\nᴇᴛᴀ : {5}" +tg_2 : "sᴜᴄᴄᴇssғᴜʟʟʏ ᴅᴏᴡɴʟᴏᴀᴅᴇᴅ, ᴘʀᴏᴄᴇssɪɴɢ ғɪʟᴇ...\n\nᴛɪᴍᴇ ᴇʟᴀᴘsᴇᴅ : {0}" +tg_3 : "ғᴀɪʟᴇᴅ ᴛᴏ ᴅᴏᴡɴʟᴏᴀᴅ ᴍᴇᴅɪᴀ ғʀᴏᴍ ᴛᴇʟᴇɢʀᴀᴍ, ᴘʟᴇᴀsᴇ ᴛʀʏ ᴀɢᴀɪɴ..." +tg_4 : "» ᴅᴏᴡɴʟᴏᴀᴅ ᴀʟʀᴇᴀᴅʏ ᴄᴏᴍᴘʟᴇᴛᴇᴅ." +tg_5 : "» ᴅᴏᴡɴʟᴏᴀᴅ ᴀʟʀᴇᴀᴅʏ ᴄᴏᴍᴘʟᴇᴛᴇᴅ ᴏʀ ᴄᴀɴᴄᴇʟʟᴇᴅ." +tg_6 : "» ᴅᴏᴡɴʟᴏᴀᴅ ᴄᴀɴᴄᴇʟʟᴇᴅ." +tg_7 : "» ᴅᴏᴡɴʟᴏᴀᴅ ᴄᴀɴᴄᴇʟʟᴇᴅ ʙʏ : {0}" +tg_8 : "ғᴀɪʟᴇᴅ ᴛᴏ sᴛᴏᴘ ᴛʜᴇ ᴅᴏᴡɴʟᴏᴀᴅ." +tg_9 : "ғᴀɪʟᴇᴅ ᴛᴏ ɢᴇᴛ ᴛʜᴇ ᴏɴɢᴏɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅ ᴛᴀsᴋ..." + +call_1 : "» ʙᴏᴛ ʀᴇǫᴜɪʀᴇs ɪɴᴠɪᴛᴇ ᴜsᴇʀs ᴠɪᴀ ʟɪɴᴋ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ ɪɴᴠɪᴛᴇ ᴀssɪsᴛᴀɴᴛ ᴛᴏ ʏᴏᴜʀ ᴄʜᴀᴛ." +call_2 : "{0} ᴀssɪsᴛᴀɴᴛ ɪs ʙᴀɴɴᴇᴅ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ/ᴄʜᴀɴɴᴇʟ.\n\nɪᴅ : {1}\nɴᴀᴍᴇ : {2}\nᴜsᴇʀɴᴀᴍᴇ : @{3}\n\nᴘʟᴇᴀsᴇ ᴜɴʙᴀɴ ᴛʜᴇ ᴀssɪsᴛᴀɴᴛ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ." +call_3 : "ғᴀɪʟᴇᴅ ᴛᴏ ɪɴᴠɪᴛᴇ {0} ᴀssɪsᴛᴀɴᴛ ᴛᴏ ʏᴏᴜʀ ᴄʜᴀᴛ.\n\nʀᴇᴀsᴏɴ : {1}" +call_4 : "ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ...\n\nɪɴᴠɪᴛɪɴɢ {0} ᴀssɪsᴛᴀɴᴛ ᴛᴏ ʏᴏᴜʀ ᴄʜᴀᴛ..." +call_5 : "{0} ᴀssɪsᴛᴀɴᴛ ᴊᴏɪɴᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ.\n\nᴛʀʏɪɴɢ ᴛᴏ sᴛᴀʀᴛ sᴛʀᴇᴀᴍ..." +call_6 : "» ғᴀɪʟᴇᴅ ᴛᴏ sᴡɪᴛᴄʜ sᴛʀᴇᴀᴍ, ᴘʟᴇᴀsᴇ ᴜsᴇ /skip ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʜᴇ ᴛʀᴀᴄᴋ ᴀɢᴀɪɴ." +call_7 : "» ᴅᴏᴡɴʟᴏᴀᴅɪɴɢ ɴᴇxᴛ ᴛʀᴀᴄᴋ ғʀᴏᴍ ǫᴜᴇᴜᴇ.\n\nᴘʟᴇᴀsᴇ ʜᴏʟᴅ ᴏɴ..." +call_8 : "Nᴏ ᴀᴄᴛɪᴠᴇ ᴠɪᴅᴇᴏᴄʜᴀᴛ ғᴏᴜɴᴅ.\n\nPʟᴇᴀsᴇ sᴛᴀʀᴛ ᴠɪᴅᴇᴏᴄʜᴀᴛ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ/ᴄʜᴀɴɴᴇʟ ᴀɴᴅ ᴛʀʏ ᴀɢᴀɪɴ." +call_9 : "Assɪsᴛᴀɴᴛ ᴀʟʀᴇᴀᴅʏ ɪɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ.\n\nɪғ ᴀssɪsᴛᴀɴᴛ ɪs ɴᴏᴛ ɪɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ, ᴘʟᴇᴀsᴇ sᴇɴᴅ /reboot ᴀɴᴅ ᴘʟᴀʏ ᴀɢᴀɪɴ." +call_10 : "Tᴇʟᴇɢʀᴀᴍ sᴇʀᴠᴇʀ ᴇʀʀᴏʀ\n\nᴛᴇʟᴇɢʀᴀᴍ ɪs ʜᴀᴠɪɴɢ sᴏᴍᴇ ɪɴᴛᴇʀɴᴀʟ ᴘʀᴏʙʟᴇᴍs, ᴘʟᴇᴀsᴇ ᴛʀʏ ᴘʟᴀʏɪɴɢ ᴀɢᴀɪɴ ᴏʀ ʀᴇsᴛᴀʀᴛ ᴛʜᴇ ᴠɪᴅᴇᴏᴄʜᴀᴛ ᴏғ ʏᴏᴜʀ ɢʀᴏᴜᴘ." + +auth_1 : "» ʏᴏᴜ ᴄᴀɴ ᴏɴʟʏ ʜᴀᴠᴇ 25 ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ." +auth_2 : "» ᴀᴅᴅᴇᴅ {0} ᴛᴏ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +auth_3 : "{0} ɪs ᴀʟʀᴇᴀᴅʏ ɪɴ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +auth_4 : "» ʀᴇᴍᴏᴠᴇᴅ {0} ғʀᴏᴍ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +auth_5 : "{0} ɪs ɴᴏᴛ ɪɴ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +auth_6 : "» ғᴇᴛᴄʜɪɴɢ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ..." +auth_7 : "» ʟɪsᴛ ᴏғ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ɪɴ {0} :\n\n" +auth_8 : "↬ ᴀᴅᴅᴇᴅ ʙʏ :" + +reload_1 : "» ʏᴏᴜ ᴄᴀɴ ᴏɴʟʏ ʀᴇғʀᴇsʜ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ᴏɴᴄᴇ ɪɴ 3 ᴍɪɴᴜᴛᴇs.\n\nᴘʟᴇᴀsᴇ ᴛʀʏ ᴀғᴛᴇʀ {0}." +reload_2 : "» ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ʀᴇғʀᴇsʜᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ." +reload_3 : "» ғᴀɪʟᴇᴅ ᴛᴏ ʀᴇʟᴏᴀᴅ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ, ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜᴀᴛ ᴛʜᴇ ʙᴏᴛ ɪs ᴀᴅᴍɪɴ ɪɴ ʏᴏᴜʀ ᴄʜᴀᴛ." +reload_4 : "» ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ...\n\nʀᴇʙᴏᴏᴛɪɴɢ {0} ғᴏʀ ʏᴏᴜʀ ᴄʜᴀᴛ." +reload_5 : "sᴜᴄᴄᴇssғᴜʟʟʏ ʀᴇʙᴏᴏᴛᴇᴅ {0} ғᴏʀ ʏᴏᴜʀ ᴄʜᴀᴛ.\n\nsᴛᴀʀᴛ ᴘʟᴀʏɪɴɢ ᴀɢᴀɪɴ..." + +admin_1 : "» ᴅɪᴅ ʏᴏᴜ ʀᴇᴍᴇᴍʙᴇʀ ᴛʜᴀᴛ ʏᴏᴜ'ᴠᴇ ʀᴇsᴜᴍᴇᴅ ᴛʜᴇ sᴛʀᴇᴀᴍ ?" +admin_2 : "➻ sᴛʀᴇᴀᴍ ᴘᴀᴜsᴇᴅ \n│ \n└ʙʏ : {0} " +admin_3 : "» ᴅɪᴅ ʏᴏᴜ ʀᴇᴍᴇᴍʙᴇʀ ᴛʜᴀᴛ ʏᴏᴜ'ᴠᴇ ᴘᴀᴜsᴇᴅ ᴛʜᴇ sᴛʀᴇᴀᴍ ?" +admin_4 : "➻ sᴛʀᴇᴀᴍ ʀᴇsᴜᴍᴇᴅ \n│ \n└ʙʏ : {0} " +admin_5 : "➻ sᴛʀᴇᴀᴍ ᴇɴᴅᴇᴅ/sᴛᴏᴩᴩᴇᴅ \n│ \n└ʙʏ : {0} " +admin_6 : "➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ \n│ \n└ʙʏ : {0} \n\n» ɴᴏ ᴍᴏʀᴇ ǫᴜᴇᴜᴇᴅ ᴛʀᴀᴄᴋs ɪɴ {1}, ʟᴇᴀᴠɪɴɢ ᴠɪᴅᴇᴏᴄʜᴀᴛ." +admin_7 : "ᴇʀʀᴏʀ ᴡʜɪʟᴇ ᴄʜᴀɴɢɪɴɢ sᴛʀᴇᴀᴍ ᴛᴏ {0}." +admin_8 : "» ᴘʟᴇᴀsᴇ ᴅɪsᴀʙʟᴇ ʟᴏᴏᴘ ᴘʟᴀʏ ᴠɪᴀ /loop disable ᴀɴᴅ ᴛʜᴇɴ ᴛʀʏ ᴛᴏ sᴋɪᴘ ᴀɢᴀɪɴ." +admin_9 : "ᴘʟᴇᴀsᴇ ᴜsᴇ sᴘᴇᴄɪғɪᴄ ɴᴜᴍʙᴇʀs ғᴏʀ sᴋɪᴘ, ʟɪᴋᴇ 1, 2, 4..." +admin_10 : "ᴀᴛʟᴇᴀsᴛ 2 ᴛʀᴀᴄᴋs ɴᴇᴇᴅᴇᴅ ɪɴ ǫᴜᴇᴜᴇ ғᴏʀ sᴘᴇᴄɪғɪᴄ sᴋɪᴘ.\n\nᴄʜᴇᴄᴋ ᴛʜᴇ ǫᴜᴇᴜᴇ ʙʏ : /queue" +admin_11 : "» ɴᴏᴛ ᴇɴᴏᴜɢʜ ᴛʀᴀᴄᴋs ɪɴ ǫᴜᴇᴜᴇ ғᴏʀ sᴘᴇᴄɪғɪᴄ sᴋɪᴘ.\n\nᴘʟᴇᴀsᴇ sᴋɪᴘ ʙᴇᴛᴡᴇᴇɴ 1 ᴀɴᴅ {0}" +admin_12 : "» ғᴀɪʟᴇᴅ ᴛᴏ sᴋɪᴘ ᴛᴏ sᴘᴇᴄɪғɪᴄ ᴛʀᴀᴄᴋ.\n\nᴄʜᴇᴄᴋ ʟᴇғᴛ ǫᴜᴇᴜᴇ ʙʏ : /queue" +admin_13 : "» ᴘʟᴇᴀsᴇ ʀᴇʟᴏᴀᴅ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ᴠɪᴀ : /reload" +admin_14 : "» ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴘᴇʀᴍɪssɪᴏɴs ᴛᴏ ᴍᴀɴᴀɢᴇ ᴠɪᴅᴇᴏ ᴄʜᴀᴛs.\n\nʀᴇʟᴏᴀᴅ ᴀᴅᴍɪɴ ᴄᴀᴄʜᴇ ᴠɪᴀ : /reload" +admin_15 : "» ғᴀɪʟᴇᴅ ᴛᴏ sʜᴜғғʟᴇ.\n\nᴄʜᴇᴄᴋ ǫᴜᴇᴜᴇ ʙʏ : /queue" +admin_16 : "» ǫᴜᴇᴜᴇ sʜᴜғғʟᴇᴅ ʙʏ {0}.\n\nᴄʜᴇᴄᴋ sʜᴜғғʟᴇᴅ ǫᴜᴇᴜᴇ ʙʏ : /queue" +admin_17 : "ᴇxᴀᴍᴘʟᴇ :\n\n/loop enable/disable\n/loop 10/9/8/7" +admin_18 : "» ʟᴏᴏᴘ ᴇɴᴀʙʟᴇᴅ ғᴏʀ {0} ᴛɪᴍᴇs ʙʏ : {1}." +admin_19 : "» ʟᴏᴏᴘ ᴘʟᴀʏ ʜᴀs ʙᴇᴇɴ ᴅɪsᴀʙʟᴇᴅ ʙʏ : {0}." +admin_20 : "ᴇxᴀᴍᴘʟᴇ :\n\n/seek ᴏʀ /seekback [ᴅᴜʀᴀᴛɪᴏɴ ɪɴ sᴇᴄᴏɴᴅs]" +admin_21 : "» ᴘʟᴇᴀsᴇ ᴜsᴇ ɴᴜᴍᴇʀɪᴄ ᴅɪɢɪᴛs ғᴏʀ sᴇᴇᴋɪɴɢ ɪɴ sᴇᴄᴏɴᴅs." +admin_22 : "» ʟɪᴠᴇ sᴛʀᴇᴀᴍs ᴄᴀɴ'ᴛ ʙᴇ sᴇᴇᴋᴇᴅ." +admin_23 : "» ᴛʀʏ sᴇᴇᴋɪɴɢ ᴡɪᴛʜ ᴀ ʟᴏᴡᴇʀ ᴅᴜʀᴀᴛɪᴏɴ.\n\nᴘʟᴀʏᴇᴅ {0} ᴏᴜᴛ ᴏғ {1} ᴍɪɴᴜᴛᴇs." +admin_24 : "sᴇᴇᴋɪɴɢ...\n\nᴘʟᴇᴀsᴇ ʜᴏʟᴅ ᴏɴ..." +admin_25 : "» sᴛʀᴇᴀᴍ sᴜᴄᴄᴇssғᴜʟʟʏ sᴇᴇᴋᴇᴅ.\n\nᴅᴜʀᴀᴛɪᴏɴ : {0} ᴍɪɴᴜᴛᴇs\nʙʏ : {1}" +admin_26 : "ғᴀɪʟᴇᴅ ᴛᴏ sᴇᴇᴋ." +admin_27 : "» ᴏɴʟʏ ʏᴏᴜᴛᴜʙᴇ sᴛʀᴇᴀᴍ's sᴘᴇᴇᴅ ᴄᴀɴ ʙᴇ ᴄᴏɴᴛʀᴏʟʟᴇᴅ ᴄᴜʀʀᴇɴᴛʟʏ." +admin_28 : "{0} sᴘᴇᴇᴅ ᴄᴏɴᴛʀᴏʟ ᴘᴀɴᴇʟ\n\nᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴜᴛᴛᴏɴs ʙᴇʟᴏᴡ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʜᴇ sᴘᴇᴇᴅ ᴏғ ᴄᴜʀʀᴇɴᴛʟʏ ᴘʟᴀʏɪɴɢ sᴛʀᴇᴀᴍ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ." +admin_29 : "» ʙᴏᴛ ɪs ᴀʟʀᴇᴀᴅʏ ᴘʟᴀʏɪɴɢ ᴏɴ ɴᴏʀᴍᴀʟ sᴘᴇᴇᴅ." +admin_30 : "» ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ...\n\nsᴏᴍᴇᴏɴᴇ ᴇʟsᴇ ɪs ᴛʀʏɪɴɢ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʜᴇ sᴘᴇᴇᴅ ᴏғ ᴛʜᴇ sᴛʀᴇᴀᴍ." +admin_31 : "ᴄʜᴀɴɢɪɴɢ sᴘᴇᴇᴅ..." +admin_32 : "» ᴛʀʏɪɴɢ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʜᴇ sᴘᴇᴇᴅ ᴏғ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ...\n\nʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {0}" +admin_33 : "» ғᴀɪʟᴇᴅ ᴛᴏ ᴄʜᴀɴɢᴇ ᴛʜᴇ sᴘᴇᴇᴅ ᴏғ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ." +admin_34 : "» ᴄʜᴀɴɢᴇᴅ ᴛʜᴇ sᴘᴇᴇᴅ ᴏғ ᴛʜᴇ ᴏɴɢᴏɪɴɢ sᴛʀᴇᴀᴍ ᴛᴏ {0}x\n\nʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {1}" +admin_35 : "ᴛʜᴇ ᴠᴏᴛɪɴɢ ʜᴀs ᴇɴᴅᴇᴅ ʙᴇᴄᴀᴜsᴇ ᴛʜᴇ ᴛʀᴀᴄᴋ ʜᴀs ᴇɴᴅᴇᴅ ғᴏʀ ᴡʜɪᴄʜ ᴛʜᴇ ᴠᴏᴛɪɴɢ ᴡᴀs ᴘʀᴏᴠɪᴅᴇᴅ." +admin_36 : "ғᴀɪʟᴇᴅ ᴛᴏ ᴘᴇʀғᴏʀᴍ ᴛʜɪs ᴀᴄᴛɪᴏɴ ʙᴇᴄᴀᴜsᴇ ғᴏʀ ᴡʜɪᴄʜ ᴛʀᴀᴄᴋ ᴛʜᴇ ᴠᴏᴛɪɴɢ ᴡᴀs ᴘʀᴏᴠɪᴅᴇᴅ ɪs ᴇɪᴛʜᴇʀ ᴇɴᴅᴇᴅ ᴏʀ sᴛᴏᴘᴘᴇᴅ." +admin_37 : "sᴜᴄᴄᴇssғᴜʟʟʏ ɢᴏᴛ {0} ᴜᴘᴠᴏᴛᴇs." +admin_38 : "» ᴀᴅᴅᴇᴅ 1 ᴜᴘᴠᴏᴛᴇ." +admin_39 : "» ʀᴇᴍᴏᴠᴇᴅ 1 ᴜᴘᴠᴏᴛᴇ." +admin_40 : "ᴜᴘᴠᴏᴛᴇᴅ." + +start_1 : "ᴛʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴜsɪɴɢ ᴍᴇ ɪɴ \n ᴄʜᴀᴛ » {0}\n\n ɪғ ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇʀɪᴇs \n ʜᴀᴠᴇ ᴀɴʏ ǫᴜᴇʀɪᴇs ᴛʜᴇɴ ᴇxᴘʟᴀɪɴ ᴛᴏ ᴜs .\n\n Jᴏɪɴ ᴏᴜʀ [ᴜᴘᴅᴀᴛᴇs]\n ғᴏʀ ɢᴇᴛᴛɪɴɢ ɴᴇᴡ ᴜᴘᴅᴀᴛᴇs ..." +start_2 : "ᴡᴇʟᴄᴏᴍᴇ ᴛᴏ {0}\n\n I Aᴍ Aɴ Aᴅᴠᴀɴᴄᴇᴅ Aɴᴅ Sᴜᴘᴇʀғᴀsᴛ VC Pʟᴀʏᴇʀ Bᴏᴛ Wɪᴛʜ Mᴀɴʏ Fᴀɴᴛᴀsᴛɪᴄ Fᴇᴀᴛᴜʀᴇs..\n\n Aᴅᴅ Mᴇ Iɴ Yᴏᴜʀ Gʀᴏᴜᴘ Tᴏ EɴJᴏʏ Sᴜᴘᴇʀ Hɪɢʜ Qᴜᴀʟɪᴛʏ Aᴜᴅɪᴏ Aɴᴅ Vɪᴅᴇᴏ.➪\n \n🎧sɪɴɢᴇʀ ᴍᴜsɪᴄ ᴠᴇʀsɪᴏɴ ➪ ᴠ𝟸.𝟶𝟶" +start_3 : "ᴛʜᴀɴᴋ ʏᴏᴜ ғᴏʀ ᴜsɪɴɢ ᴍᴇ ɪɴ \n ʏᴏᴜʀ ᴄʜᴀᴛs ɢʀᴏᴜᴘ ...\n\n ᴀ ᴜsᴇʀɴᴀᴍᴇ › @{1}\n ᴀssɪsᴛᴀɴᴛ ɪᴅ : {2}\n\n Jᴏɪɴ ᴏᴜʀ [ᴜᴘᴅᴀᴛᴇs] ғᴏʀ ɢᴇᴛᴛɪɴɢ ɴᴇᴡ ᴜᴘᴅᴀᴛᴇs ..." +start_4 : "❰DRAG❱ 💿 ᴏᴡɴᴇʀ [{1}] ʜᴀs Jᴜsᴛ Jᴏɪɴᴇᴅ ʏᴏᴜʀ ᴄʜᴀᴛ." +start_5 : "ᴛʜᴇ sᴜᴅᴏ ᴜsᴇʀ ᴏғ {0}, [{1}] Jᴜsᴛ Jᴏɪɴᴇᴅ ʏᴏᴜʀ ᴄʜᴀᴛ ." +start_6 : "sᴜᴘᴇʀɢʀᴏᴜᴘ ɴᴇᴇᴅᴇᴅ \n\nᴘʟᴇᴀsᴇ ᴄᴏɴᴠᴇʀᴛ ʏᴏᴜʀ ɢʀᴏᴜᴘ ᴛᴏ sᴜᴘᴇʀɢʀᴏᴜᴘ ᴀɴᴅ ᴛʜᴇɴ ᴀᴅᴅ ᴍᴇ ʙᴀᴄᴋ.\n\nʜᴏᴡ ᴛᴏ ᴍᴀᴋᴇ sᴜᴘᴇʀɢʀᴏᴜᴘ ?\n ᴍᴀᴋᴇ ʏᴏᴜʀ ɢʀᴏᴜᴘ's ᴄʜᴀᴛ ʜɪsᴛᴏʀʏ ᴠɪsɪʙʟᴇ ᴏɴᴄᴇ." +start_7 : "ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛ\n\nᴛʜɪs ᴄʜᴀᴛ ɪs ʙʟᴀᴄᴋʟɪsᴛ ғᴏʀ ᴜsɪɴɢ ᴛʜᴇ ʙᴏᴛ. ʀᴇǫᴜᴇsᴛ ᴀ sᴜᴅᴏ ᴜsᴇʀ ᴛᴏ ᴡʜɪᴛᴇʟɪsᴛ ʏᴏᴜʀ ᴄʜᴀᴛ, sᴜᴅᴏ ᴜsᴇʀs [ʟɪsᴛ]({0}) , ᴇʟsᴇ ғᴜ*ᴋ ᴏғғ." + +help_1 : "ᴄʜᴏᴏsᴇ ᴛʜᴇ ᴄᴀᴛᴇɢᴏʀʏ ғᴏʀ ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴɴᴀ ɢᴇᴛ ʜᴇʟᴩ.\nᴀsᴋ ʏᴏᴜʀ ᴅᴏᴜʙᴛs ᴀᴛ sᴜᴘᴘᴏʀᴛ ᴄʜᴀᴛ\n\nᴀʟʟ ᴄᴏᴍᴍᴀɴᴅs ᴄᴀɴ ʙᴇ ᴜsᴇᴅ ᴡɪᴛʜ : /" +help_2 : "ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ɢᴇᴛ ᴍʏ ʜᴇʟᴘ ᴍᴇɴᴜ ɪɴ ʏᴏᴜʀ ᴘᴍ." + +lang_1 : "» ᴘʟᴇᴀsᴇ ᴄʜᴏᴏsᴇ ᴛʜᴇ ʟᴀɴɢᴜᴀɢᴇ ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴɴᴀ sᴇᴛ ᴀs ᴛʜɪs ɢʀᴏᴜᴘ's ᴅᴇғᴀᴜʟᴛ ʟᴀɴɢᴜᴀɢᴇ :" +lang_2 : "ʟᴀɴɢᴜᴀɢᴇ ᴄʜᴀɴɢᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ." +lang_3 : "ғᴀɪʟᴇᴅ ᴛᴏ ᴄʜᴀɴɢᴇ ʟᴀɴɢᴜᴀɢᴇ." +lang_4 : "Yᴏᴜ'ʀᴇ ᴀʟʀᴇᴀᴅʏ ᴏɴ ᴛʜᴇ sᴀᴍᴇ ʟᴀɴɢᴜᴀɢᴇ." + +setting_1 : "{0} sᴇᴛᴛɪɴɢs ᴘᴀɴᴇʟ\n\nᴄʜᴀᴛ ɪᴅ : {1}\nᴄʜᴀᴛ ᴛɪᴛʟᴇ : {2}\n\nᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴜᴛᴛᴏɴs ʙᴇʟᴏᴡ ғᴏʀ ᴄʜᴀɴɢɪɴɢ sᴇᴛᴛɪɴɢs." +setting_2 : "» ᴅɪʀᴇᴄᴛ : ᴘʟᴀʏs sᴇᴀʀᴄʜ ǫᴜᴇʀɪᴇs ᴅɪʀᴇᴄᴛʟʏ.\n\n» ɪɴʟɪɴᴇ : ʀᴇᴛᴜʀɴs ɪɴʟɪɴᴇ ʙᴜᴛᴛᴏɴs ꜰᴏʀ ᴄʜᴏᴏsɪɴɢ ʙᴇᴛᴡᴇᴇɴ ᴠɪᴅᴇᴏ & ᴀᴜᴅɪᴏ." +setting_3 : "» ᴇᴠᴇʀʏᴏɴᴇ : ᴀɴʏᴏɴᴇ ᴄᴀɴ ᴜsᴇ ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs [sᴋɪᴘ, ᴘᴀᴜsᴇ, ʀᴇsᴜᴍᴇ ᴇᴛᴄ.] ᴘʀᴇsᴇɴᴛ ɪɴ ᴛʜɪs ɢʀᴏᴜᴘ.\n\n» ᴀᴅᴍɪɴ ᴏɴʟʏ : ᴏɴʟʏ ᴀᴅᴍɪɴs ᴀɴᴅ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ᴄᴀɴ ᴜsᴇ ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs." +setting_4 : "» ɴᴏ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ꜰᴏᴜɴᴅ." +setting_5 : "» ɢʀᴏᴜᴘ : ᴘʟᴀʏs ᴍᴜsɪᴄ ɪɴ ᴛʜᴇ ɢʀᴏᴜᴘ ᴡʜᴇʀᴇ ᴛʜᴇ ᴄᴏᴍᴍᴀɴᴅ ɪs ɢɪᴠᴇɴ.\n\n» ᴄʜᴀɴɴᴇʟ : ᴘʟᴀʏs ᴍᴜsɪᴄ ɪɴ ᴛʜᴇ ᴄʜᴀɴɴᴇʟ ʏᴏᴜ ᴡᴀɴᴛ. sᴇᴛ ᴄʜᴀɴɴᴇʟ ɪᴅ ᴠɪᴀ /channelplay" +setting_6 : "» ᴇᴠᴇʀʏᴏɴᴇ : ᴀɴʏᴏɴᴇ ᴘʀᴇsᴇɴᴛ ɪɴ ᴛʜɪs ɢʀᴏᴜᴘ ᴄᴀɴ ᴘʟᴀʏ ᴍᴜsɪᴄ ʜᴇʀᴇ.\n\n» ᴀᴅᴍɪɴ ᴏɴʟʏ: ᴏɴʟʏ ᴀᴅᴍɪɴs ᴄᴀɴ ᴘʟᴀʏ ᴛʜᴇ ᴍᴜsɪᴄ ɪɴ ᴛʜɪs ɢʀᴏᴜᴘ." +setting_7 : "» ᴘʟᴇᴀsᴇ ᴅᴇғɪɴᴇ ᴄʜᴀɴɴᴇʟ ɪᴅ ᴠɪᴀ /channelplay" +setting_8 : "ᴡʜᴇɴ ᴛʜɪs ᴍᴏᴅᴇ ɪs ᴇɴᴀʙʟᴇᴅ, ᴘᴇᴏᴘʟᴇ ᴡɪᴛʜᴏᴜᴛ ᴀᴅᴍɪɴ ʀɪɢʜᴛs ᴄᴀɴ ᴜsᴇ ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs ᴀғᴛᴇʀ ᴀ ᴄᴇʀᴛᴀɪɴ ᴀᴍᴏᴜɴᴛ ᴏғ ᴠᴏᴛᴇs." +setting_9 : "ᴄᴜʀʀᴇɴᴛ ᴜᴘᴠᴏᴛᴇs ʀᴇǫᴜɪʀᴇᴅ ғᴏʀ ᴜsɪɴɢ ᴀᴅᴍɪɴ ᴄᴏᴍᴍᴀɴᴅs ᴀʀᴇ : {0}" +setting_10 : "ᴠᴏᴛɪɴɢ ᴍᴏᴅᴇ ɪs ᴅɪsᴀʙʟᴇᴅ." +setting_11 : "ʟᴏᴡᴇsᴛ ᴜᴘᴠᴏᴛᴇs ᴄᴏᴜɴᴛ ᴄᴀɴ ʙᴇ 2. ʏᴏᴜ ᴄᴀɴ'ᴛ sᴇᴛ ʙᴇʟᴏᴡ 2" +setting_12 : "ʜɪɢʜᴇsᴛ ᴜᴘᴠᴏᴛᴇs ᴄᴏᴜɴᴛ ᴄᴀɴ ʙᴇ 15. ʏᴏᴜ ᴄᴀɴ'ᴛ sᴇᴛ ᴀʙᴏᴠᴇ 15" + +set_cb_1 : "ɢᴇᴛᴛɪɴɢ ᴀᴜᴛʜ ᴜsᴇʀs ᴩᴀɴᴇʟ..." +set_cb_2 : "ɢᴇᴛᴛɪɴɢ ᴩʟᴀʏ ᴍᴏᴅᴇ ᴩᴀɴᴇʟ..." +set_cb_3 : "sᴇᴛᴛɪɴɢ ᴜᴩ ᴄʜᴀɴɢᴇs..." +set_cb_4 : "» ғᴇᴛᴄʜɪɴɢ ᴀᴜᴛʜᴏʀɪᴢᴇᴅ ᴜsᴇʀs ʟɪsᴛ..." +set_cb_5 : "» ɢᴇᴛᴛɪɴɢ ʙᴀᴄᴋ..." + +gstats_1 : "ɢᴇᴛᴛɪɴɢ {0} sᴛᴀᴛs ᴀɴᴅ ɪɴғᴏʀᴍᴀᴛɪᴏɴ...\n\nɪᴛ ᴍᴀʏ ᴛᴀᴋᴇ ᴀ ᴡʜɪʟᴇ, ᴘʟᴇᴀsᴇ ʜᴏʟᴅ ᴏɴ..." +gstats_2 : "ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ʙᴜᴛᴛᴏɴs ʙᴇʟᴏᴡ ᴛᴏ ᴄʜᴇᴄᴋ ᴛʜᴇ sᴛᴀᴛs ᴏғ {0}." +gstats_3 : "{0} sᴛᴀᴛs ᴀɴᴅ ɪɴғᴏʀᴍᴀᴛɪᴏɴ :\n\nᴀssɪsᴛᴀɴᴛs : {1}\nʙʟᴏᴄᴋᴇᴅ : {2}\nᴄʜᴀᴛs: {3}\nᴜsᴇʀs : {4}\nᴍᴏᴅᴜʟᴇs : {5}\nsᴜᴅᴏᴇʀs : {6}\n\nᴀᴜᴛᴏ ʟᴇᴀᴠɪɴɢ ᴀssɪsᴛᴀɴᴛ : {7}\nᴘʟᴀʏ ᴅᴜʀᴀᴛɪᴏɴ ʟɪᴍɪᴛ : {8} ᴍɪɴᴜᴛᴇs" +gstats_4 : "ᴛʜɪs ʙᴜᴛᴛᴏɴ ɪs ᴏɴʟʏ ғᴏʀ sᴜᴅᴏᴇʀs." +gstats_5 : "{0} sᴛᴀᴛs ᴀɴᴅ ɪɴғᴏʀᴍᴀᴛɪᴏɴ :\n\nᴍᴏᴅᴜʟᴇs : {1}\nᴘʟᴀᴛғᴏʀᴍ : {2}\nʀᴀᴍ : {3}\nᴘʜʏsɪᴄᴀʟ ᴄᴏʀᴇs : {4}\nᴛᴏᴛᴀʟ ᴄᴏʀᴇs : {5}\nᴄᴘᴜ ғʀᴇǫᴜᴇɴᴄʏ : {6}\n\nᴘʏᴛʜᴏɴ : {7}\nᴘʏʀᴏɢʀᴀᴍ : {8}\nᴘʏ-ᴛɢᴄᴀʟʟs : {9}\n\nsᴛᴏʀᴀɢᴇ ᴀᴠᴀɪʟᴀʙʟᴇ : {10} ɢɪʙ\nsᴛᴏʀᴀɢᴇ ᴜsᴇᴅ : {11} ɢɪʙ\nsᴛᴏʀᴀɢᴇ ʟᴇғᴛ : {12} ɢɪʙ\n\nsᴇʀᴠᴇᴅ ᴄʜᴀᴛs : {13}\nsᴇʀᴠᴇᴅ ᴜsᴇʀs : {14}\nʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs : {15}\nsᴜᴅᴏ ᴜsᴇʀs : {16}\n\nᴛᴏᴛᴀʟ ᴅʙ sɪᴢᴇ : {17} ᴍʙ\nᴛᴏᴛᴀʟ ᴅʙ sᴛᴏʀᴀɢᴇ : {18} ᴍʙ\nᴛᴏᴛᴀʟ ᴅʙ ᴄᴏʟʟᴇᴄᴛɪᴏɴs : {19}\nᴛᴏᴛᴀʟ ᴅʙ ᴋᴇʏs : {20}" + +playcb_1 : "» ᴀᴡᴡ, ᴛʜɪs ɪs ɴᴏᴛ ғᴏʀ ʏᴏᴜ ʙᴀʙʏ." +playcb_2 : "» ɢᴇᴛᴛɪɴɢ ɴᴇxᴛ ʀᴇsᴜʟᴛ,\n\nᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..." + +cplay_1 : "» ʏᴏᴜ ᴄᴀɴ ᴘʟᴀʏ ᴍᴜsɪᴄ ɪɴ ᴄʜᴀɴɴᴇʟs ғʀᴏᴍ {0} ᴛᴏ ᴀɴʏ ᴄʜᴀɴɴᴇʟ ᴏʀ ʏᴏᴜʀ ᴄʜᴀᴛ's ʟɪɴᴋᴇᴅ ᴄʜᴀɴɴᴇʟ.\n\nғᴏʀ ʟɪɴᴋᴇᴅ ᴄʜᴀɴɴᴇʟ :\n/channelplay linked\n\nғᴏʀ ᴀɴʏ ᴏᴛʜᴇʀ ᴄʜᴀɴɴᴇʟ :\n/channelplay [ᴄʜᴀɴɴᴇʟ ɪᴅ]" +cplay_2 : "» ᴛʜɪs ᴄʜᴀᴛ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴀɴʏ ʟɪɴᴋᴇᴅ ᴄʜᴀɴɴᴇʟ." +cplay_3 : "» ᴄʜᴀɴɴᴇʟ ᴅᴇғɪɴᴇᴅ ᴛᴏ {0}.\nᴄʜᴀɴɴᴇʟ ɪᴅ : {1}" +cplay_4 : "» ғᴀɪʟᴇᴅ ᴛᴏ ɢᴇᴛ ᴄʜᴀɴɴᴇʟ.\n\nᴍᴀᴋᴇ sᴜʀᴇ ʏᴏᴜ'ᴠᴇ ᴀᴅᴅᴇᴅ ᴛʜᴇ ʙᴏᴛ ɪɴ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ᴀɴᴅ ᴘʀᴏᴍᴏᴛᴇᴅ ᴀs ᴀᴅᴍɪɴ." +cplay_5 : "ᴏɴʟʏ ᴄʜᴀɴɴᴇʟs ᴀʀᴇ sᴜᴘᴘᴏʀᴛᴇᴅ." +cplay_6 : "» ʏᴏᴜ ɴᴇᴇᴅ ᴛᴏ ʙᴇ ᴛʜᴇ ᴏᴡɴᴇʀ ᴏғ ᴛʜᴇ ᴄʜᴀɴɴᴇʟ {0} ᴛᴏ ᴄᴏɴɴᴇᴄᴛ ɪᴛ ᴡɪᴛʜ ᴛʜɪs ɢʀᴏᴜᴘ.\nᴄʜᴀɴɴᴇʟ's ᴏᴡɴᴇʀ : @{1}\n\nᴀʟᴛᴇʀɴᴀᴛɪᴠᴇʟʏ ʏᴏᴜ ᴄᴀɴ ʟɪɴᴋ ʏᴏᴜʀ ɢʀᴏᴜᴘ ᴛᴏ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ ᴀɴᴅ ᴛʜᴇɴ ᴛʀʏ ᴄᴏɴɴɴᴇᴄᴛɪɴɢ ᴡɪᴛʜ /channelplay linked" +cplay_7 : "» ᴄʜᴀɴɴᴇʟ ᴘʟᴀʏ ᴅɪsᴀʙʟᴇᴅ." + +play_1 : "🍓" +play_2 : "➻ ᴄʜᴀɴɴᴇʟ ᴘʟᴀʏ ᴍᴏᴅᴇ\n\nᴘʀᴏᴄᴇssɪɴɢ, ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ...\n\nʟɪɴᴋᴇᴅ ᴄʜᴀɴɴᴇʟ : {0}" +play_3 : "» ғᴀɪʟᴇᴅ ᴛᴏ ᴘʀᴏᴄᴇss ǫᴜᴇʀʏ." +play_4 : "ᴀᴅᴍɪɴs ᴏɴʟʏ ᴘʟᴀʏ\nᴏɴʟʏ ᴀᴅᴍɪɴs ᴏғ ᴛʜɪs ᴄʜᴀᴛ ᴀʀᴇ ᴀʟʟᴏᴡᴇᴅ ᴛᴏ ᴘʟᴀʏ\n\nᴄʜᴀɴɢᴇ ᴘʟᴀʏ ᴍᴏᴅᴇ ᴠɪᴀ /playmode" +play_5 : "» ғᴀɪʟᴇᴅ ᴛᴏ ᴘʀᴏᴄᴇss ᴀᴜᴅɪᴏ ғɪʟᴇ.\n\nᴀᴜᴅɪᴏ ғɪʟᴇ sɪᴢᴇ ɪs ʟᴀʀɢᴇʀ ᴛʜᴀɴ ᴛʜᴇ ᴅᴇғɪɴᴇᴅ ʟɪᴍɪᴛ." +play_6 : "» sᴛʀᴇᴀᴍ's ʟᴏɴɢᴇʀ ᴛʜᴀɴ {0} ᴀʀᴇɴ'ᴛ ᴀʟʟᴏᴡᴇᴅ ᴛᴏ ᴘʟᴀʏ ᴏɴ {1}" +play_7 : "» ɴᴏᴛ ᴀ ᴠᴀʟɪᴅ ᴠɪᴅᴇᴏ ғɪʟᴇ ᴇxᴛᴇɴsɪᴏɴ.\n\nsᴜᴘᴘᴏʀᴛᴇᴅ ᴇxᴛᴇɴsɪᴏɴs : {0}" +play_8 : "» ᴠɪᴅᴇᴏ ғɪʟᴇ sɪᴢᴇ sʜᴏᴜʟᴅ ʙᴇ ʟᴇss ᴛʜᴀɴ 1ɢɪʙ." +play_9 : "ʏᴏᴜᴛᴜʙᴇ ᴘʟᴀʏʟɪsᴛ ғᴇᴀᴛᴜʀᴇ\n\nsᴇʟᴇᴄᴛ ᴛʜᴇ ᴍᴏᴅᴇ ɪɴ ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴘʟᴀʏ ᴡʜᴏʟᴇ ʏᴏᴜᴛᴜʙᴇ ᴘʟᴀʏʟɪsᴛ." +play_10 : "ᴛɪᴛʟᴇ : {0}\nᴅᴜʀᴀᴛɪᴏɴ : {1} ᴍɪɴᴜᴛᴇs" +play_11 : "{0} sᴘᴏᴛɪғʏ ᴘʟᴀʏᴇʀ\n\nʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {1}" +play_12 : "{0} ᴀᴘᴘʟᴇ ᴘʟᴀʏᴇʀ\n\nʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {1}" +play_13 : "» ʟɪᴠᴇ sᴛʀᴇᴀᴍ ᴅᴇᴛᴇᴄᴛᴇᴅ.\n\nᴀʀᴇ ʏᴏᴜ sᴜʀᴇ ᴛʜᴀᴛ ʏᴏᴜ ᴡᴀɴɴᴀ ᴘʟᴀʏ ᴛʜɪs ʟɪᴠᴇ sᴛʀᴇᴀᴍ ?" +play_14 : "ꜰᴀɪʟᴇᴅ ᴛᴏ ꜰᴇᴛᴄʜ ᴛʀᴀᴄᴋ ᴅᴇᴛᴀɪʟs.\n\nᴛʀʏ ᴘʟᴀʏɪɴɢ ᴀɴʏ ᴏᴛʜᴇʀ." +play_15 : "» ғᴀɪʟᴇᴅ ᴛᴏ ᴘʀᴏᴄᴇss ǫᴜᴇʀʏ.\n\nɪ ᴄᴀɴ ᴏɴʟʏ ᴘʟᴀʏ sᴘᴏᴛɪғʏ ᴛʀᴀᴄᴋs, ᴀʟʙᴜᴍs, ᴀʀᴛɪsᴛs ᴀɴᴅ ᴘʟᴀʏʟɪsᴛs." +play_16 : "ɴᴏ ᴀᴄᴛɪᴠᴇ ᴠᴏɪᴄᴇ ᴄʜᴀᴛ.\n\nᴛᴏ ᴜsᴇ ғᴏʀᴄᴇ ᴩʟᴀʏ, ᴛʜᴇʀᴇ ᴍᴜsᴛ ʙᴇ ᴀɴ ᴀᴄᴛɪᴠᴇ ᴠᴏɪᴄᴇᴄʜᴀᴛ." +play_17 : "ᴘʟᴇᴀsᴇ ᴛᴜʀɴ ᴏɴ ᴠɪᴅᴇᴏᴄʜᴀᴛ, ɪ'ᴍ ᴜɴᴀʙʟᴇ ᴛᴏ sᴛʀᴇᴀᴍ ᴜʀʟs." +play_18 : "ᴜsᴀɢᴇ : /play [sᴏɴɢ ɴᴀᴍᴇ/ʏᴏᴜᴛᴜʙᴇ ᴜʀʟ/ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴀᴜᴅɪᴏ/ᴠɪᴅᴇᴏ ғɪʟᴇ]" +play_19 : "Queued Playlist :" +play_20 : "Queued Position-" +play_21 : "ᴀᴅᴅᴇᴅ {0} ᴛʀᴀᴄᴋs ᴛᴏ ǫᴜᴇᴜᴇ.\n\nᴄʜᴇᴄᴋ : ᴄʟɪᴄᴋ ʜᴇʀᴇ" +play_22 : "sᴇʟᴇᴄᴛ ᴛʜᴇ ᴍᴏᴅᴇ ɪɴ ᴡʜɪᴄʜ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ᴘʟᴀʏ ᴛʜᴇ ǫᴜᴇʀɪᴇs ɪɴsɪᴅᴇ ʏᴏᴜʀ ɢʀᴏᴜᴘ : {0}" + +str_1 : "ᴘʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴍ3ᴜ8 ᴏʀ ɪɴᴅᴇx ʟɪɴᴋs." +str_2 : "➻ ᴠᴀʟɪᴅ sᴛʀᴇᴀᴍ ᴠᴇʀɪғɪᴇᴅ.\n\nᴘʀᴏᴄᴇssɪɴɢ..." +str_3 : "ғᴀɪʟᴇᴅ ᴛᴏ sᴛʀᴇᴀᴍ ʏᴏᴜᴛᴜʙᴇ ʟɪᴠᴇ sᴛʀᴇᴀᴍ, ɴᴏ ʟɪᴠᴇ ꜰᴏʀᴍᴀᴛ ꜰᴏᴜɴᴅ." + +ping_1 : "{0} ɪs ᴘɪɴɢɪɴɢ..." +ping_2 : "🏓 ᴩᴏɴɢ : {0}ᴍs\n\n{1} sʏsᴛᴇᴍ sᴛᴀᴛs :\n\n↬ ᴜᴩᴛɪᴍᴇ : {2}\n↬ ʀᴀᴍ : {3}\n↬ ᴄᴩᴜ : {4}\n↬ ᴅɪsᴋ : {5}\n↬ ᴩʏ-ᴛɢᴄᴀʟʟs : {6}ᴍs" + +queue_1 : " ғᴇᴛᴄʜɪɴɢ ǫᴜᴇᴜᴇ...\n\n๏ ᴘʟᴇᴀsᴇ ᴡᴀɪᴛ..." +queue_2 : " ǫᴜᴇᴜᴇ ᴇᴍᴘᴛʏ." +queue_3 : " ᴄʟɪᴄᴋ ʜᴇʀᴇ ᴛᴏ ᴄʜᴇᴄᴋ ᴛʜᴇ ʟɪsᴛ ᴏғ ᴛʜᴇ ǫᴜᴇᴜᴇᴅ ᴛʀᴀᴄᴋs ➠ ʜᴇʀᴇ" +queue_4 : " ᴀᴅᴅᴇᴅ ᴛᴏ ǫᴜᴇᴜᴇ ᴀᴛ sɪɴɢᴇʀ ᴍᴜsɪᴄ #{0}\n\n ᴛɪᴛʟᴇ ➠ {1}\n ᴅᴜʀᴀᴛɪᴏɴ ➠ {2} ᴍɪɴᴜᴛᴇs\n ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ ➠ {3}\n\n ᴍᴀᴅᴇ ʙʏ ➛ @haatsoja" +queue_5 : " ᴛʜᴇʀᴇ's ᴏɴʟʏ ᴏɴᴇ ǫᴜᴇᴜᴇᴅ ᴛʀᴀᴄᴋ ɪɴ ᴘʟᴀʏʟɪsᴛ.\n\n ᴀᴅᴅ ᴍᴏʀᴇ ᴛʀᴀᴄᴋs ᴛᴏ ᴄʜᴇᴄᴋ ʟɪsᴛ." +queue_6 : " ᴅᴜʀᴀᴛɪᴏɴ ➠ ᴜɴᴋɴᴏᴡɴ ᴅᴜʀᴀᴛɪᴏɴ sᴛʀᴇᴀᴍ\n\n ᴄʟɪᴄᴋ ᴏɴ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ɢᴇᴛ ᴡʜᴏʟᴇ ǫᴜᴇᴜᴇᴅ ʟɪsᴛ." +queue_7 : "\n ᴄʟɪᴄᴋ ᴏɴ ʙᴜᴛᴛᴏɴ ʙᴇʟᴏᴡ ᴛᴏ ɢᴇᴛ ᴡʜᴏʟᴇ ǫᴜᴇᴜᴇᴅ ʟɪsᴛ." +queue_8 : " {0} ᴘʟᴀʏᴇʀ\n\n sᴛʀᴇᴀᴍɪɴɢ ➠ {1}\n\n sᴛʀᴇᴀᴍ ᴛʏᴘᴇ ➠ {2}\n ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ ➠ {3}\n{4}" + +stream_1 : " sɪɴɢᴇʀ ᴍᴜsɪᴄ Sᴛᴀʀᴛᴇᴅ Sᴛʀᴇᴀᴍɪɴɢ \n\n‣ Tɪᴛʟᴇ : {1}\n‣ Dᴜʀᴀᴛɪᴏɴ : {2} ᴍɪɴᴜᴛᴇs\n‣ Rᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {3}" +stream_2 : " sɪɴɢᴇʀ ᴍᴜsɪᴄ Sᴛᴀʀᴛᴇᴅ Sᴛʀᴇᴀᴍɪɴɢ \n\n‣ Sᴛʀᴇᴀᴍ ᴛʏᴘᴇ : ʟɪᴠᴇ sᴛʀᴇᴀᴍ [ᴜʀʟ]\n‣ Rᴇǫᴜᴇsᴛᴇᴅ ʙʏ : {0}" + +CLOSE_BUTTON : "ᴄʟᴏsᴇ" +BACK_BUTTON : "ʙᴀᴄᴋ" + +S_B_1 : "𝑨𝑫𝑫 𝑴𝑬 𝑳𝑶𝑽𝑬" +S_B_2 : "sᴜᴘᴘᴏʀᴛ" +S_B_3 : "𝑨𝑫𝑫 𝑴𝑬 𝑳𝑶𝑽𝑬" +S_B_4 : "ᴄᴏᴍᴍᴀɴᴅs" +S_B_5 : "ᴅᴇᴠ" +S_B_6 : "ᴄʜᴀɴɴᴇʟ" +S_B_8 : "ʏᴏᴜᴛᴜʙᴇ" +S_B_9 : "sᴜᴩᴩᴏʀᴛ" + +H_B_1 : "❤️Aᴅᴍɪɴ❤️" +H_B_2 : "❤️Aᴜᴛʜ❤️" +H_B_3 : "❤️Bʀᴏᴀᴅᴄᴀsᴛ❤️" +H_B_4 : "❤️Bʟ-Cʜᴀᴛ❤️" +H_B_5 : "❤️Bʟ-Usᴇʀ❤️" +H_B_6 : "❤️C-Pʟᴀʏ❤️" +H_B_7 : "❤️G-Bᴀɴ❤️" +H_B_8 : "❤️Lᴏᴏᴘ❤️" +H_B_9 : "❤️Mᴀɪɴᴛᴇɴᴀɴᴄᴇ❤️" +H_B_10 : "❤️Pɪɴɢ❤️" +H_B_11 : "❤️Pʟᴀʏ❤️" +H_B_12 : "❤️Sʜᴜғғʟᴇ❤️" +H_B_13 : "❤️Sᴇᴇᴋ❤️" +H_B_14 : "❤️Sᴏɴɢ❤️" +H_B_15 : "❤️Sᴘᴇᴇᴅ❤️" +H_B_16 : "❤️GPT❤️" + +P_B_1 : "ᴀᴜᴅɪᴏ" +P_B_2 : "ᴠɪᴅᴇᴏ" +P_B_3 : "ʟɪᴠᴇ sᴛʀᴇᴀᴍ" +P_B_4 : "ɴᴏʀᴍᴀʟ" + +ST_B_1 : "Aᴜᴛʜ ᴜsᴇʀs" +ST_B_2 : "Pʟᴀʏ ᴍᴏᴅᴇ" +ST_B_3 : "Lᴀɴɢᴜᴀɢᴇ" +ST_B_4 : "Vᴏᴛɪɴɢ ᴍᴏᴅᴇ" +ST_B_5 : "ᴏɴ" +ST_B_6 : "ᴏғғ" +ST_B_7 : "Aᴜᴛʜ ᴜsᴇʀs ➜" +ST_B_8 : "ᴀᴅᴍɪɴs" +ST_B_9 : "ᴇᴠᴇʀʏᴏɴᴇ" +ST_B_10 : "Sᴇᴀʀᴄʜ ᴍᴏᴅᴇ ➜" +ST_B_11 : "ᴅɪʀᴇᴄᴛ" +ST_B_12 : "ɪɴʟɪɴᴇ" +ST_B_13 : "Aᴅᴍɪɴ ᴄᴍᴅs ➜" +ST_B_14 : "Pʟᴀʏ ᴛʏᴘᴇ ➜" + +SA_B_1 : "ᴏᴠᴇʀᴀʟʟ sᴛᴀᴛs" +SA_B_2 : "ɢᴇɴᴇʀᴀʟ" +SA_B_3 : "ᴏᴠᴇʀᴀʟʟ" + +QU_B_1 : "ǫᴜᴇᴜᴇ" +QU_B_2 : " {0} —————————— {1}" + +sudo_1 : "» {0} ɪs ᴀʟʀᴇᴀᴅʏ ɪɴ PRO ᴜsᴇʀs ʟɪsᴛ." +sudo_2 : "» ᴀᴅᴅᴇᴅ {0} ᴛᴏ PRO ᴜsᴇʀs ʟɪsᴛ." +sudo_3 : "» {0} ɪs ɴᴏᴛ ɪɴ PRO ᴜsᴇʀs ʟɪsᴛ." +sudo_4 : "» ʀᴇᴍᴏᴠᴇᴅ {0} ғʀᴏᴍ PRO ᴜsᴇʀs ʟɪsᴛ." +sudo_5 : "🥰 ᴏᴡɴᴇʀ :\n" +sudo_6 : "\n 🤫 PRO ᴜsᴇʀs :\n" +sudo_7 : "» ɴᴏ PRO ᴜsᴇʀs ғᴏᴜɴᴅ." +sudo_8 : "ғᴀɪʟᴇᴅ." + +block_1 : "» {0} ɪs ᴀʟʀᴇᴀᴅʏ ʙʟᴏᴄᴋᴇᴅ ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ." +block_2 : "» ᴀᴅᴅᴇᴅ {0} ᴛᴏ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +block_3 : "» {0} ɪs ɴᴏᴛ ɪɴ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +block_4 : "» ʀᴇᴍᴏᴠᴇᴅ {0} ғʀᴏᴍ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs ʟɪsᴛ." +block_5 : "» ɴᴏ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs ғᴏᴜɴᴅ." +block_6 : "» ɢᴇᴛᴛɪɴɢ ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs ʟɪsᴛ..." +block_7 : "😫 ʙʟᴏᴄᴋᴇᴅ ᴜsᴇʀs :\n\n" + +black_1 : "ᴇxᴀᴍᴘʟᴇ :\n\n/blacklistchat [ᴄʜᴀᴛ ɪᴅ]" +black_2 : "» ᴛʜɪs ᴄʜᴀᴛ ɪs ᴀʟʀᴇᴀᴅʏ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ." +black_3 : "» sᴜᴄᴄᴇssғᴜʟʟʏ ᴀᴅᴅᴇᴅ ᴛᴏ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛs." +black_4 : "ᴇxᴀᴍᴘʟᴇ :\n\n/whitelistchat [ᴄʜᴀᴛ ɪᴅ]" +black_5 : "» ᴛʜɪs ᴄʜᴀᴛ ɪs ɴᴏᴛ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ." +black_6 : "» sᴜᴄᴄᴇssғᴜʟʟʏ ʀᴇᴍᴏᴠᴇᴅ ғʀᴏᴍ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛs." +black_7 : "» ʟɪsᴛ ᴏғ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛs :\n\n" +black_8 : "» ɴᴏ ʙʟᴀᴄᴋʟɪsᴛᴇᴅ ᴄʜᴀᴛs ᴏɴ {0}." +black_9 : "» sᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ." + +maint_1 : "ᴇxᴀᴍᴘʟᴇ :\n/maintenance [ᴇɴᴀʙʟᴇ | ᴅɪsᴀʙʟᴇ]" +maint_2 : "» {0} ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ ᴇɴᴀʙʟᴇᴅ." +maint_3 : "» {0} ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ ᴅɪsᴀʙʟᴇᴅ." +maint_4 : "» ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ ɪs ᴀʟʀᴇᴀᴅʏ ᴇɴᴀʙʟᴇᴅ." +maint_5 : "» ᴍᴀɪɴᴛᴇɴᴀɴᴄᴇ ᴍᴏᴅᴇ ɪs ᴀʟʀᴇᴀᴅʏ ᴅɪsᴀʙʟᴇᴅ." + +log_1 : "ᴇxᴀᴍᴘʟᴇ :\n/logger [ᴇɴᴀʙʟᴇ | ᴅɪsᴀʙʟᴇ]" +log_2 : "ᴇɴᴀʙʟᴇᴅ ʟᴏɢɢɪɴɢ." +log_3 : "ᴅɪsᴀʙʟᴇᴅ ʟᴏɢɢɪɴɢ." + +broad_1 : "» sᴛᴀʀᴛᴇᴅ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ..." +broad_2 : "ᴇxᴀᴍᴘʟᴇ :\n\n/broadcast [ᴍᴇssᴀɢᴇ ᴏʀ ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ]" +broad_3 : "» ʙʀᴏᴀᴅᴄᴀsᴛᴇᴅ ᴍᴇssᴀɢᴇ ᴛᴏ {0} ᴄʜᴀᴛs ᴡɪᴛʜ {1} ᴘɪɴs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ." +broad_4 : "» ʙʀᴏᴀᴅᴄᴀsᴛᴇᴅ ᴍᴇssᴀɢᴇ ᴛᴏ {0} ᴜsᴇʀs." +broad_5 : "» sᴛᴀʀᴛɪɴɢ ᴀssɪsᴛᴀɴᴛ ʙʀᴏᴀᴅᴄᴀsᴛ..." +broad_6 : "➻ ᴀssɪsᴛᴀɴᴛ ʙʀᴏᴀᴅᴄᴀsᴛ :\n\n" +broad_7 : "↬ ᴀssɪsᴛᴀɴᴛ {0} ʙʀᴏᴀᴅᴄᴀsᴛᴇᴅ ɪɴ {1} ᴄʜᴀᴛs." +broad_8 : "» ᴘʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ sᴏᴍᴇ ᴛᴇxᴛ ᴛᴏ ʙʀᴏᴀᴅᴄᴀsᴛ." + +server_1 : "» ғᴀɪʟᴇᴅ ᴛᴏ ɢᴇᴛ ʟᴏɢs." +server_2 : "ᴘʟᴇᴀsᴇ ᴍᴀᴋᴇ sᴜʀᴇ ᴛʜᴀᴛ ʏᴏᴜʀ ʜᴇʀᴏᴋᴜ ᴀᴘɪ ᴋᴇʏ ᴀɴᴅ ᴀᴘᴘ ɴᴀᴍᴇ ᴀʀᴇ ᴄᴏɴғɪɢᴜʀᴇᴅ ᴄᴏʀʀᴇᴄᴛʟʏ." +server_3 : "ᴄʜᴇᴄᴋɪɴɢ ꜰᴏʀ ᴀᴠᴀɪʟᴀʙʟᴇ ᴜᴘᴅᴀᴛᴇs..." +server_4 : "ɢɪᴛ ᴄᴏᴍᴍᴀɴᴅ ᴇʀʀᴏʀ." +server_5 : "ɪɴᴠᴀʟɪᴅ ɢɪᴛ ʀᴇᴘsɪᴛᴏʀʏ." +server_6 : "» ʙᴏᴛ ɪs ᴜᴘ-ᴛᴏ-ᴅᴀᴛᴇ." +server_7 : "» ʙᴏᴛ ᴜᴩᴅᴀᴛᴇᴅ sᴜᴄᴄᴇssғᴜʟʟʏ ! ɴᴏᴡ ᴡᴀɪᴛ ғᴏʀ ғᴇᴡ ᴍɪɴᴜᴛᴇs ᴜɴᴛɪʟ ᴛʜᴇ ʙᴏᴛ ʀᴇsᴛᴀʀᴛs ᴀɴᴅ ᴩᴜsʜ ᴄʜᴀɴɢᴇs !" +server_8 : "{0} ɪs ʀᴇsᴛᴀʀᴛɪɴɢ...\n\nʏᴏᴜ ᴄᴀɴ sᴛᴀʀᴛ ᴩʟᴀʏɪɴɢ ᴀɢᴀɪɴ ᴀғᴛᴇʀ 15-20 sᴇᴄᴏɴᴅs." +server_9 : "sᴏᴍᴇᴛʜɪɴɢ ᴡᴇɴᴛ ᴡʀᴏɴɢ, ᴩʟᴇᴀsᴇ ᴄʜᴇᴄᴋ ʟᴏɢs." +server_10 : "ᴀɴ ᴇxᴄᴇᴩᴛɪᴏɴ ᴏᴄᴄᴜʀᴇᴅ ᴀᴛ #ᴜᴩᴅᴀᴛᴇʀ ᴅᴜᴇ ᴛᴏ : {0}" +server_11 : "» ʀᴜɴɴɪɴɢ ᴀ sᴘᴇᴇᴅᴛᴇsᴛ..." +server_12 : "⇆ ʀᴜɴɴɪɴɢ ᴅᴏᴡɴʟᴏᴀᴅ sᴩᴇᴇᴅᴛᴇsᴛ..." +server_13 : "⇆ ʀᴜɴɴɪɴɢ ᴜᴩʟᴏᴀᴅ sᴩᴇᴇᴅᴛᴇsᴛ..." +server_14 : "↻ sʜᴀʀɪɴɢ sᴩᴇᴇᴅᴛᴇsᴛ ʀᴇsᴜʟᴛs..." +server_15 : "✯ sᴩᴇᴇᴅᴛᴇsᴛ ʀᴇsᴜʟᴛs ✯\n\nᴄʟɪᴇɴᴛ :\n» ɪsᴩ : {0}\n» ᴄᴏᴜɴᴛʀʏ : {1}\n\nsᴇʀᴠᴇʀ :\n» ɴᴀᴍᴇ : {2}\n» ᴄᴏᴜɴᴛʀʏ : {3}, {4}\n» sᴩᴏɴsᴏʀ : {5}\n» ʟᴀᴛᴇɴᴄʏ : {6}\n» ᴩɪɴɢ : {7}" + +gban_1 : "» ᴡʜʏ ᴅɪᴅ ʏᴏᴜ ᴡᴀɴɴᴀ ɢʙᴀɴ ʏᴏᴜʀsᴇʟғ ʙᴀʙʏ ?" +gban_2 : "» ᴡʜʏ sʜᴏᴜʟᴅ ɪ ɢʙᴀɴ ᴍʏsᴇʟғ ?" +gban_3 : "» ʏᴏᴜ ᴄᴀɴ'ᴛ ɢʙᴀɴ ᴍʏ sᴜᴅᴏᴇʀs." +gban_4 : "» {0} ɪs ᴀʟʀᴇᴀᴅʏ ɢʟᴏʙᴀʟʟʏ ʙᴀɴɴᴇᴅ ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ." +gban_5 : "» ɪɴɪᴛɪᴀʟɪᴢɪɴɢ ɢʟᴏʙᴀʟ ʙᴀɴ ᴏɴ {0}.\n\nᴛɪᴍᴇ ᴇxᴘᴇᴄᴛᴇᴅ : {1}" +gban_6 : "ɴᴇᴡ ɢʟᴏʙᴀʟ ʙᴀɴ ᴏɴ {0} :\n\nᴏʀɪɢɪɴᴀᴛᴇᴅ ғʀᴏᴍ : {1} [{2}]\nᴜsᴇʀ : {3}\nᴜsᴇʀ ɪᴅ : {4}\n\nʙᴀɴɴᴇᴅ ʙʏ : {5}\nᴄʜᴀᴛs : {6}" +gban_7 : "» {0} ɪs ɴᴏᴛ ɢʙᴀɴɴᴇᴅ ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ." +gban_8 : "» ʟɪғᴛɪɴɢ ɢʟᴏʙᴀʟ ʙᴀɴ ғʀᴏᴍ {0}.\n\nᴇxᴘᴇᴄᴛᴇᴅ ᴛɪᴍᴇ : {1}" +gban_9 : "» ʟɪғᴛᴇᴅ ɢʟᴏʙᴀʟ ʙᴀɴ ғʀᴏᴍ {0}.\n\nᴜɴʙᴀɴɴᴇᴅ ɪɴ {1} ᴄʜᴀᴛs." +gban_10 : "» ɴᴏ ᴏɴᴇ ɪs ɢʟᴏʙᴀʟʟʏ ʙᴀɴɴᴇᴅ ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ." +gban_11 : "» ғᴇᴛᴄʜɪɴɢ ɢʙᴀɴɴᴇᴅ ᴜsᴇʀs ʟɪsᴛ..." +gban_12 : "🙂ɢʟᴏʙᴀʟʟʏ ʙᴀɴɴᴇᴅ ᴜsᴇʀs :\n\n" diff --git a/strings/langs/hi.yml b/strings/langs/hi.yml new file mode 100644 index 0000000000000000000000000000000000000000..8eb192126c8618133b5824fc47ea01ee0e41200f --- /dev/null +++ b/strings/langs/hi.yml @@ -0,0 +1,306 @@ +name : 🇮🇳 हिंदी + + +general_1: "» एक उपयोगकर्ता के संदेश का उत्तर दें या उपयोगकर्ता नाम / उपयोगकर्ता ID दें।" +general_2: "» कुछ गड़बड़ हो गई थी आपके क्वेरी को प्रोसेस करते समय।\n\nअपवाद: {0}" +general_3: "आप इस चैट में एक गुमनाम व्यवस्थापक हैं, मुझे उपयोग करने के लिए उपयोगकर्ता खाता पर वापस लौटें।" +general_4: "» आपकी अनुमतियाँ वीडियो चैट प्रबंधित करने के लिए नहीं हैं।\n\nव्यवस्थापक कैश को पुनः लोड करें /reload के माध्यम से" +general_5: "» बॉट वीडियोचैट पर स्ट्रीमिंग नहीं कर रहा है।" + +tg_1: "{0} डाउनलोडर\n\nफ़ाइल का आकार : {1}\nपूर्ण हो गया : {2}\nप्रतिशत : {3}%\n\nगति : {4}/s\nETA : {5}" +tg_2: "सफलतापूर्वक डाउनलोड किया गया, फ़ाइल प्रोसेस की जा रही है...\n\nसमय गुजरा : {0}" +tg_3: "मीडिया टेलीग्राम से डाउनलोड करने में विफल, कृपया पुनः प्रयास करें..." +tg_4: "» पहले से ही डाउनलोड पूरा हो गया है।" +tg_5: "» डाउनलोड पहले से ही पूरा हो गया है या रद्द किया गया है।" +tg_6: "» डाउनलोड रद्द कर दिया गया है।" +tg_7: "» डाउनलोड रद्द किया गया है द्वारा : {0}" +tg_8: "डाउनलोड रोकने में विफल।" +tg_9: "चल रहे डाउनलोड कार्य प्राप्त करने में विफल।" + +call_1: "» बोट को लिंक के माध्यम से उपयोगकर्ताओं को आमंत्रित करने की अनुमति की आवश्यकता होती है ताकि सहायक को आपकी चैट में आमंत्रित किया जा सके।" +call_2: "{0} सहायक आपके समूह/चैनल में प्रतिबंधित है।\n\nआईडी : {1}\nनाम : {2}\nउपयोगकर्ता नाम : @{3}\n\nकृपया सहायक को अनबैन करें और पुनः प्रयास करें।" +call_3: "सहायक को आपकी चैट में आमंत्रित करने में विफल।\n\nकारण : {1}" +call_4: "कृपया प्रतीक्षा करें...\n\n{0} सहायक को आपकी चैट में आमंत्रित किया जा रहा है..." +call_5: "{0} सहायक सफलतापूर्वक शामिल हो गया।\n\nप्रसारण शुरू करने का प्रयास किया जा रहा है..." +call_6: "» प्रसारण स्विच करने में विफल। कृपया पुनः /skip का उपयोग करके ट्रैक को फिर से बदलें।" +call_7: "» अगले ट्रैक को कतार से डाउनलोड किया जा रहा है।\n\nकृपया प्रतीक्षा करें..." +call_8: "↬ द्वारा जोड़ा गया :" + +auth_1: "» आपके समूह में केवल 25 प्रमाणित उपयोगकर्ताएँ हो सकती हैं।" +auth_2: "» {0} को प्रमाणित उपयोगकर्ताओं की सूची में जोड़ दिया गया है।" +auth_3: "{0} पहले से ही प्रमाणित उपयोगकर्ताओं की सूची में है।" +auth_4: "» {0} को प्रमाणित उपयोगकर्ताओं की सूची से हटा दिया गया है।" +auth_5: "{0} प्रमाणित उपयोगकर्ताओं की सूची में नहीं है।" +auth_6: "» प्रमाणित उपयोगकर्ताओं की सूची को पुनर्प्राप्त किया जा रहा है..." +auth_7: "» {0} की प्रमाणित उपयोगकर्ताओं की सूची में :\n\n" +auth_8: "↬ द्वारा जोड़ा गया :" + +reload_1: "» आपको केवल 3 मिनट में एक बार व्यवस्थापक कैश को ताज़ा करने की अनुमति होती है।\n\nकृपया {0} के बाद पुनः प्रयास करें।" +reload_2: "» व्यवस्थापक कैश सफलतापूर्वक ताज़ा किया गया।" +reload_3: "» व्यवस्थापक कैश को ताज़ा करने में विफल, सुनिश्चित करें कि बोट आपकी चैट में व्यवस्थापक है।" +reload_4: "» कृपया प्रतीक्षा करें...\n\n{0} को आपकी चैट के लिए दोबारा शुरू किया जा रहा है।" +reload_5: "{0} को आपकी चैट के लिए सफलतापूर्वक दोबारा आरंभ किया गया।\n\nफिर से प्रारंभ करने का प्रयास किया जा रहा है..." + +admin_1: "» क्या आपको याद है कि आपने प्रसारण को पुनः आरंभ किया था?" +admin_2: "➻ प्रसारण ठहरा दिया 🎄\n│ \n└द्वारा : {0} 🥀" +admin_3: "» क्या आपको याद है कि आपने प्रसारण को ठहराया था?" +admin_4: "➻ प्रसारण पुनः आरंभ 🎄\n│ \n└द्वारा : {0} 🥀" +admin_5: "➻ प्रसारण समाप्त/रोक दिया 🎄\n│ \n└द्वारा : {0} 🥀" +admin_6: "➻ प्रसारण रोका 🎄\n│ \n└द्वारा : {0} 🥀\n\n» {1} में अब कोई और ट्रैक कतार में नहीं है, वीडियोचैट छोड़ रहे हैं।" +admin_7: "स्ट्रीम {0} को बदलते समय त्रुटि।" +admin_8: "» कृपया लूप प्ले को अक्षम करें और फिर से स्किप का प्रयास करें। /loop disable के माध्यम से लूप प्ले को अक्षम करें।" +admin_9: "कृपया स्किप के लिए विशिष्ट संख्याएँ उपयोग करें, जैसे 1, 2, 4..." +admin_10: "कम से कम 2 ट्रैक्स की आवश्यकता होती है विशिष्ट स्किप के लिए।\n\nकृपया ट्रैक कतार देखें: /queue" +admin_11: "» ट्रैक्स कतार में पर्याप्त नहीं है विशिष्ट स्किप के लिए।\n\nकृपया 1 और {0} के बीच स्किप करें।" +admin_12: "» विशिष्ट ट्रैक पर स्किप करने में विफल।\n\nकृपया बचे हुए कतार की जाँच करें: /queue" +admin_13: "» कृपया व्यवस्थापक कैश को ताज़ा करें: /reload" +admin_14: "» वीडियो चैट प्रबंधित करने की अनुमति नहीं है।\n\nकृपया व्यवस्थापक कैश को ताज़ा करें: /reload" +admin_15: "» शफल करने में विफल।\n\nकतार देखें: /queue" +admin_16: "» कतार को शफल किया गया है {0} द्वारा।\n\nशफल किया गया कतार देखें: /queue" +admin_17: "{0} स्पीड नियंत्रण पैनल\n\nकर्रेंट प्लेइंग स्ट्रीम की स्पीड बदलने के लिए नीचे दिए गए बटन पर क्लिक करें।" +admin_18: "» {0} के लिए स्पीड चालू की गई है।\n\nद्वारा : {1}।" +admin_19: "» स्पीड कंट्रोल बंद किया गया है।\n\nद्वारा : {0}।" +admin_20: "उदाहरण:\n\n/seek या /seekback [सेकंड में अवधि]" +admin_21: "» कृपया सेकंड में अवधि के लिए केवल न्यूमेरिक डिजिट्स का उपयोग करें।" +admin_22: "» लाइव स्ट्रीम्स को सीक नहीं किया जा सकता।" +admin_23: "» कृपया कम अवधि में सीक करने का प्रयास करें।\n\n{0} मिनटों में प्ले हुआ, {1} मिनटों की क़तार से।" +admin_24: "सीक किया जा रहा है...\n\nकृपया प्रतीक्षा करें..." +admin_25: "» स्पीड के साथ सफलतापूर्वक सीक किया गया।\n\nअवधि : {0} मिनटों\nद्वारा : {1}" +admin_26: "सीक में विफल।" +admin_27: "» केवल यूट्यूब स्ट्रीम की स्पीड को वर्तमान में नियंत्रित किया जा सकता है।" +admin_28: "{0} स्पीड नियंत्रण पैनल\n\nकृपया वीडियो चैट पर प्लेइंग स्ट्रीम की स्पीड बदलने के लिए नीचे दिए गए बटनों पर क्लिक करें।" +admin_29: "» बॉट पहले से ही सामान्य स्पीड पर प्ले कर रहा है।" +admin_30: "» कृपया प्रतीक्षा करें...\n\nकोई अन्य व्यक्ति स्ट्रीम की स्पीड बदलने का प्रयास कर रहा है।" +admin_31: "स्पीड बदल रहा है..." +admin_32: "» चल रहे स्ट्रीम की स्पीड सफलतापूर्वक बदली गई।\n\nअनुरोधकर्ता : {0}" +admin_33: "» चल रहे स्ट्रीम की स्पीड बदलने में विफल।" +admin_34: "» चल रहे स्ट्रीम की स्पीड सफलतापूर्वक {0}x की गई।\n\nअनुरोधकर्ता : {1}" +admin_35: "मतदान समाप्त हो गया है क्योंकि वोटिंग प्रदान किए जाने वाले ट्रैक के लिए समाप्त हो गया है।" +admin_36: "इस क्रिया को करने में विफल क्योंकि वोटिंग प्रदान किए जाने वाले ट्रैक के लिए समाप्त हो गया है या वो रुका हुआ है।" +admin_37: "सफलतापूर्वक {0} अपवोट प्राप्त किए गए।" +admin_38: "» 1 अपवोट जोड़ा गया।" +admin_39: "» 1 अपवोट हटा दिया गया।" +admin_40: "अपवोट किया गया।" + +start_1 : "{0} जिंदा है बेबी।\n\n✫ उपकाल : {1}" +start_2 : "हे {0}, 🥀\n\n๏ यह {1} है !\n\n➻ एक तेज़ और शक्तिशाली टेलीग्राम संगीत प्लेयर बॉट जिसमें कुछ शानदार सुविधाएँ हैं।\n\nसमर्थित प्लेटफ़ॉर्म्स : यूट्यूब, स्पॉटिफ़ाई, रेसो, एप्पल म्यूज़िक और साउंडक्लाउड।\n──────────────────\n๏ मेरे मॉड्यूल्स और कमांड्स के बारे में जानकारी प्राप्त करने के लिए हेल्प बटन पर क्लिक करें।" +start_3 : "हे {0},\nयह {1} है\n\nआपके द्वारा {2} में मुझे जोड़ने के लिए धन्यवाद, {3} अब इस चैट में गाने बजा सकता है।" +start_4 : "🎄 सुपरग्रुप की आवश्यकता है 🎄\n\nकृपया अपने ग्रुप को सुपरग्रुप में बदलें और फिर मुझे फिर से जोड़ें।\n\nसुपरग्रुप कैसे बनाएं ?\n- अपने ग्रुप की चैट इतिहास को दृश्यमान बनाएं।" +start_5 : "↝ ब्लैकलिस्ट की गई चैट ↜\n\nयह चैट {0} डेटाबेस पर ब्लैकलिस्ट है।\nअपनी चैट को अनब्लैकलिस्ट करने के लिए सुडो उपयोगकर्ता से अनुरोध करें या समर्थन चैट पर जाएं।" +start_6 : "😲 ट्रैक जानकारी 😲\n\n📌 शीर्षक : {0}\n\n⏳ अवधि : {1} मिनट\n👀 दृश्य : {2}\n⏰ प्रकाशित हुआ : {3}\n📎 चैनल : {5}\n\n🥀 सर्च पावर्ड बाय {6}" + +help_1 : "इस ग्रुप के लिए उपयोगकर्ता की मदद के लिए कृपया उपयोगकर्ता जाति को चुनें।\nअपने संदेहों को पूछें समर्थन चैट में\n\nसभी कमांड्स का उपयोग करने के लिए : /" +help_2 : "अपने प्राइवेट में मेरे मदद मेनू प्राप्त करने के लिए कृपया नीचे दिए गए बटन पर क्लिक करें।" + +lang_1 : "» कृपया ग्रुप की डिफ़ॉल्ट भाषा के रूप में सेट करने के लिए भाषा चुनें :" +lang_2 : "भाषा सफलतापूर्वक बदल दी गई।" +lang_3 : "भाषा बदलने में विफल।" +lang_4 : "आप पहले से ही वही भाषा में हैं।" + +setting_1 : "{0} सेटिंग्स पैनल\n\nचैट आईडी : {1}\nचैट टाइटल : {2}\n\nसेटिंग्स बदलने के लिए नीचे दिए गए बटनों पर क्लिक करें." +setting_2 : "» डायरेक्ट: सीधे सर्च क्वेरी को चलाता है।\n\n» इनलाइन: वीडियो और ऑडियो के बीच चयन करने के लिए इनलाइन बटन्स प्रदान करता है।" +setting_3 : "» सभी: किसी भी व्यक्ति को इस ग्रुप में एडमिन कमांड्स [स्किप, पॉज, रिज्यूम आदि] का उपयोग करने की अनुमति है।\n\n» केवल एडमिन: केवल एडमिन और अधिकृत उपयोगकर्ता एडमिन कमांड्स का उपयोग कर सकते हैं।" +setting_4 : "» कोई अधिकृत उपयोगकर्ता नहीं मिले." +setting_5 : "» ग्रुप: ग्रुप में संगीत बजाता है जहां कमांड दी जाती है।\n\n» चैनल: वह चैनल चुनें जिसमें संगीत बजना है। /channelplay के माध्यम से चैनल आईडी सेट करें" +setting_6 : "» सभी: किसी भी व्यक्ति को इस ग्रुप में संगीत बजाने की अनुमति है।\n\n» केवल एडमिन: केवल एडमिन्स ही इस ग्रुप में संगीत बजा सकते हैं।" +setting_7 : "» कृपया /channelplay के माध्यम से चैनल आईडी सेट करें" +setting_8 : "जब यह मोड सक्षम होता है, तो वे लोग भी एडमिन कमांड्स का उपयोग कर सकते हैं जिनके पास एडमिन अधिकार नहीं होते हैं, एक निश्चित संख्या में वोट के बाद।" +setting_9 : "वर्तमान उपवोट्स की आवश्यकता जो एडमिन कमांड्स का उपयोग करने के लिए हैं : {0}" +setting_10 : "वोटिंग मोड अक्षम है।" +setting_11 : "न्यूनतम उपवोट्स की गिनती 2 हो सकती है। आप 2 से कम नहीं सेट कर सकते" +setting_12 : "अधिकतम उपवोट्स की गिनती 15 हो सकती है। आप 15 से अधिक नहीं सेट कर सकते" + +set_cb_1 : "आधीकृत उपयोगकर्ताओं का पैनल प्राप्त किया जा रहा है..." +set_cb_2 : "प्ले मोड पैनल प्राप्त किया जा रहा है..." +set_cb_3 : "सेटिंग्स बदल रहे हैं..." +set_cb_4 : "» आधीकृत उपयोगकर्ता सूची प्राप्त की जा रही है..." +set_cb_5 : "» पीछे जा रहे हैं..." + +gstats_1: "गेटिंग {0} स्टैट्स और इनफ़ोर्मेशन...\n\nइसमें समय लग सकता है, कृपया होल्ड ऑन..." +gstats_2: "क्लिक ऑन थे बट्टन्स बेलोव तो चेक थे स्टैट्स ऑफ {0}." +gstats_3: "{0} स्टैट्स और इनफ़ोर्मेशन :\n\nअसिस्टंट्स : {1}\nब्लॉक्ड : {2}\nचैट्स: {3}\nयूज़र्स : {4}\nमॉड्यूल्स : {5}\nसुडोएर्स : {6}\n\nऑटो लीविंग असिस्टंट : {7}\nप्ले दुरातिओन लिमिट : {8} मिनट्स" +gstats_4: "इस बट्टन इस ओनली फॉर सुडोएर्स." +gstats_5: "{0} स्टैट्स और इनफ़ोर्मेशन :\n\nमॉड्यूल्स : {1}\nप्लैटफॉर्म : {2}\nरैम : {3}\nफिजिकल कोर्स : {4}\nटोटल कोर्स : {5}\nसीपीयू फ़्रेक्वेंसी : {6}\n\nपायथन : {7}\nपायरोग्राम : {8}\nपाय-टीजीकैल्स : {9}\n\nस्टोरेज अवेलेबल : {10} गीब\nस्टोरेज यूज़्ड : {11} गीब\nस्टोरेज लेफ्ट : {12} गीब\n\nसर्व्ह्ड चैट्स : {13}\nसर्व्ह्ड यूज़र्स : {14}\nब्लॉक्ड यूज़र्स : {15}\nसुडो यूज़र्स : {16}\n\nटोटल डीबी साइज़ : {17} एम्बी\nटोटल डीबी स्टोरेज : {18} एम्बी\nटोटल डीबी कलेक्शन्स : {19}\nटोटल डीबी कीज़ : {20}" + +playcb_1: "» अव्व, थिस इस नोट फ़ॉर यू बेबी." +playcb_2: "» गेटिंग नेक्स्ट रेसुल्ट,\n\nप्लीज़ वेट..." + +cplay_1: "» यू कैन प्ले म्यूज़िक इन चैनल्स फ्रोम {0} तो अन्य चैनल और योर चैट्स लिंकेड चैनल.\n\nफ़ॉर लिंकेड चैनल :\n/channelplay linked\n\nफ़ॉर अन्य चैनल :\n/channelplay [चैनल आईडी]" +cplay_2: "» थिस चैट डोन'ट हेव अन्य लिंकेड चैनल." +cplay_3: "» चैनल डिफ़ाइन्ड टू {0}.\nचैनल आईडी : {1}" +cplay_4: "» फ़ेल्ड टो गेट चैनल.\n\nमेक सुरे यू'वे अद्देड थे बोट इन योर चैनल एंड प्रोमोटेड अस अद्मिन." +cplay_5: "ओन्ली चैनल्स आरे सुप्पोर्टेड." +cplay_6: "» यू नीड टो बी थे ओव्नर ऑफ थे चैनल {0} टो कन्नेक्ट इट विथ थिस ग्रूप.\nचैनल'स ओव्नर : @{1}\n\nआल्टरनटिवली यू कैन लिंक योर ग्रूप टो थाट चैनल एंड थेन ट्राई कन्नेक्टिंग विथ /channelplay linked" +cplay_7: "» चैनल प्लेय डिसअब्लेड." + +play_1: "🔎" +play_2: "➻ चैनल प्लेय मोड\n\nप्रोसेसिंग, प्लीज़ वेट...\n\nलिंकेड चैनल : {0}" +play_3: "» फ़ेल्ड टो प्रोसेस क़ुएरी." +play_4: "एड्मिन्स ओनली प्लेय\nओन्ली एड्मिन्स ऑफ थिस चैट आरे अल्लोवेड टो प्लेय\n\nचेंगे प्लेय मोड विआ /playmode" +play_5: "» फ़ेल्ड टो प्रोसेस ऑडियो फ़िले.\n\nऑडियो फ़िले सिज़े इस लार्जर थान थे डिफ़ाइन्ड लिमिट." +play_6: "» स्ट्रीम'स लोंगेर थान {0} आरें'ट अल्लोवेड टो प्लेय ऑन {1}" +play_7: "» नोट अ वैलिड विडियो फ़िले एक्सटेंशन.\n\nसुप्पोर्टेड एक्सटेंशन्स : {0}" +play_8: "» विडियो फ़िले सिज़े शोल्ड बी लेस थान 1गीब." +play_9: "यूट्यूब प्लेयलिस्ट फीचर\n\nसेलेक्ट थे मोड इन व्हिच यू वॉन्ट टो प्लेय होले यूट्यूब प्लेयलिस्ट." +play_10: "टाइटल : {0}\nड्युरेशन : {1} मिनट्स" +play_11: "{0} स्पोटिफ़ाई प्लेयर\n\nरिक्वेस्टेड बाय : {1}" +play_12: "{0} अप्प्ले प्लेयर\n\nरिक्वेस्टेड बाय : {1}" +play_13: "» लाइव स्ट्रीम डिटेक्टेड.\n\nआरे यू सुरे थाट यू वॉन्ट टो प्लेय लाइव स्ट्रीम इन थिस चैनल?" +play_14: "ट्रैक डिटेल्स प्राप्त करने में विफल।\n\nकृपया कोई अन्य ट्रैक प्ले करने का प्रयास करें।" +play_15: "» क्वेरी प्रोसेस करने में विफल।\n\nमैं केवल स्पॉटिफाई ट्रैक्स, एल्बम्स, कलाकारों और प्लेलिस्ट्स प्ले कर सकता हूँ।" +play_16: "कोई सक्रिय वॉयस चैट नहीं।\n\nफोर्स प्ले का उपयोग करने के लिए किसी सक्रिय वॉयस चैट होनी चाहिए।" +play_17: "कृपया वीडियो चैट ऑन करें, मैं URL्स को स्ट्रीम करने में असमर्थ हूँ।" +play_18: "उपयोग: /play [गाने का नाम/YouTube URL/ऑडियो/वीडियो फ़ाइल का उत्तर]" +play_19: "कतार में जोड़ा गया प्लेलिस्ट:" +play_20: "कतार में स्थिति-" +play_21: "{0} ट्रैक्स को कतार में जोड़ा गया।\n\nजाँच करें: यहाँ क्लिक करें" +play_22: "आपके ग्रुप के अंदर क्यूइड सूचियों को प्ले करने के लिए आपके द्वारा चुने गए मोड: {0}" + +str_1 : "कृपया m3u8 या इंडेक्स लिंक्स प्रदान करें।" +str_2 : "➻ मान्य स्ट्रीम सत्यापित।\n\nप्रोसेसिंग..." +str_3 : "यूट्यूब लाइव स्ट्रीम प्ले करने में विफल। कोई लाइव प्रारूप नहीं मिला।" + +ping_1 : "{0} पिंग कर रहा है..." +ping_2 : "🏓 पोंग : {0}ms\n\n{1} सिस्टम स्थिति :\n\n↬ अपटाइम : {2}\n↬ रैम : {3}\n↬ सीपीयू : {4}\n↬ डिस्क : {5}\n↬ पायथन-टीजीसीएल : {6}ms" + +queue_1 : "» कतार प्राप्त हो रही है...\n\nकृपया प्रतीक्षा करें..." +queue_2 : "» कतार खाली है।" +queue_3 : "» कतार में ट्रैकों की सूची देखने के लिए यहाँ क्लिक करें : यहाँ" +queue_4 : "➲ कतार में जोड़ा गया #{0}\n\n‣ शीर्षक : {1}\n‣ अवधि : {2} मिनट\n‣ द्वारा अनुरोधित : {3}" +queue_5 : "केवल एक कतार में ट्रैक है।\n\nलिस्ट देखने के लिए अधिक ट्रैक जोड़ें।" +queue_6 : "🕚 अवधि : अज्ञात स्ट्रीम\n\nपूरी कतार की सूची प्राप्त करने के लिए नीचे बटन पर क्लिक करें।" +queue_7 : "\nनीचे बटन पर क्लिक करें।" +queue_8 : "{0} प्लेयर\n\n🎄 स्ट्रीमिंग : {1}\n\n🔗 स्ट्रीम प्रकार : {2}\n🥀 अनुरोधक : {3}\n{4}" + +stream_1 : "➲ स्ट्रीमिंग शुरू की गई |\n\n‣ शीर्षक : {1}\n‣ अवधि : {2} मिनट\n‣ द्वारा अनुरोधित : {3}" +stream_2 : "➲ स्ट्रीमिंग शुरू की गई |\n\n‣ स्ट्रीम प्रकार : लाइव स्ट्रीम [URL]\n‣ द्वारा अनुरोधित : {0}" + +CLOSE_BUTTON : "बंद करें" +BACK_BUTTON : "वापस" + +S_B_1 : "मुझे जोड़ें" +S_B_2 : "समर्थन" +S_B_3 : "मुझे अपने समूह में जोड़ें" +S_B_4 : "मदद और कमांड्स" +S_B_5 : "डेवलपर" +S_B_6 : "चैनल" +S_B_7 : "स्रोत कोड" +S_B_8 : "👀 YouTube 👀" +S_B_9 : "🥀 समर्थन 🥀" + +H_B_1 : "एडमिन" +H_B_2 : "ऑथ" +H_B_3 : "ब्रॉडकास्ट" +H_B_4 : "ब्लैकलिस्ट" +H_B_5 : "ब्लॉक" +H_B_6 : "चैनल प्ले" +H_B_7 : "जी-बैन" +H_B_8 : "लूप" +H_B_9 : "सुडो" +H_B_10 : "पिंग" +H_B_11 : "प्ले" +H_B_12 : "शफल" +H_B_13 : "सीक-बैक" +H_B_14 : "गाना" +H_B_15 : "गति" + +P_B_1 : "ऑडियो" +P_B_2 : "वीडियो" +P_B_3 : "लाइव स्ट्रीम" +P_B_4 : "नॉर्मल" + +ST_B_1 : "ऑथ उपयोगकर्ता" +ST_B_2 : "प्ले मोड" +ST_B_3 : "भाषा" +ST_B_4 : "वोटिंग मोड" +ST_B_5 : "चालू" +ST_B_6 : "बंद" +ST_B_7 : "ऑथ उपयोगकर्ता ➜" +ST_B_8 : "व्यवस्थापक" +ST_B_9 : "सभी" +ST_B_10 : "खोज मोड ➜" +ST_B_11 : "प्रत्यक्ष" +ST_B_12 : "इनलाइन" +ST_B_13 : "व्यवस्थापक कमांड ➜" +ST_B_14 : "प्ले प्रकार ➜" + +SA_B_1 : "कुल स्थितियाँ" +SA_B_2 : "सामान्य" +SA_B_3 : "कुल" + +QU_B_1 : "कतार" +QU_B_2 : " {0} —————————— {1}" + +sudo_1 : "» {0} पहले से ही सुडो उपयोगकर्ताओं की सूची में है।" +sudo_2 : "» {0} को सुडो उपयोगकर्ताओं की सूची में जोड़ दिया गया।" +sudo_3 : "» {0} सुडो उपयोगकर्ताओं की सूची में नहीं है।" +sudo_4 : "» {0} को सुडो उपयोगकर्ताओं की सूची से हटा दिया गया।" +sudo_5 : "🥀 मालिक :\n" +sudo_6 : "\n✨ सुडो उपयोगकर्ताएँ :\n" +sudo_7 : "» सुडो उपयोगकर्ताएँ नहीं मिलीं।" +sudo_8 : "विफल।" + +block_1 : "» {0} पहले से ही ब्लॉक किया गया है।" +block_2 : "» {0} को ब्लॉक की सूची में जोड़ दिया गया।" +block_3 : "» {0} ब्लॉक की सूची में नहीं है।" +block_4 : "» {0} को ब्लॉक की सूची से हटा दिया गया।" +block_5 : "» ब्लॉक की सूची में कोई उपयोगकर्ता नहीं मिला।" +block_6 : "» ब्लॉक की सूची मिल रही है..." +block_7 : "😫 ब्लॉक की सूची :\n\n" + +black_1 : "उदाहरण :\n\n/blacklistchat [चैट आईडी]" +black_2 : "» यह चैट पहले से ही ब्लैकलिस्ट की सूची में है।" +black_3 : "» सफलतापूर्वक ब्लैकलिस्ट में जोड़ दिया गया।" +black_4 : "उदाहरण :\n\n/whitelistchat [चैट आईडी]" +black_5 : "» यह चैट ब्लैकलिस्ट की सूची में नहीं है।" +black_6 : "» सफलतापूर्वक ब्लैकलिस्ट से हटा दिया गया।" +black_7 : "» ब्लैकलिस्ट की सूची :\n\n" +black_8 : "» {0} के ऊपर कोई चैट ब्लैकलिस्ट की सूची में नहीं है।" +black_9 : "» कुछ गड़बड़ हो गई।" + +maint_1 : "उदाहरण :\n/maintenance [on|off]" +maint_2 : "» {0} ने मेंटेनेंस मोड सक्रिय किया।" +maint_3 : "» {0} ने मेंटेनेंस मोड अक्षम किया।" +maint_4 : "» मेंटेनेंस मोड पहले से ही सक्रिय है।" +maint_5 : "» मेंटेनेंस मोड पहले से ही अक्षम है।" + +log_1 : "उदाहरण :\n/logger [on|off]" +log_2 : "लॉगिंग सक्रिय किया" + +broad_1 : "» प्रसारण शुरू किया जा रहा है..." +broad_2 : "उदाहरण :\n\n/broadcast [संदेश या किसी संदेश के उत्तर में]" +broad_3 : "» संदेश को {0} चैट्स में प्रसारित किया गया, {1} पिन से बोट से।" +broad_4 : "» संदेश को {0} उपयोगकर्ताओं को प्रसारित किया गया।" +broad_5 : "» सहायक प्रसारण शुरू कर रहा है..." +broad_6 : "➻ सहायक प्रसारण :\n\n" +broad_7 : "↬ सहायक ने {0} चैटों में प्रसारित किया, {1} से।" +broad_8 : "» कृपया प्रसारित करने के लिए कुछ टेक्स्ट प्रदान करें।" + +server_1 : "» लॉग्स प्राप्त करने में विफल हुआ।" +server_2 : "कृपया सुनिश्चित करें कि आपका Heroku API कुंजी और ऐप का नाम सही रूप से कॉन्फ़िगर किए गए हैं।" +server_3 : "उपलब्ध अपडेटों की जांच की जा रही है..." +server_4 : "git कमांड त्रुटि।" +server_5 : "अमान्य git रिपॉजिटरी।" +server_6 : "» बोट अप-टू-डेट है।" +server_7 : "» बोट को सफलतापूर्वक अपडेट किया गया! अब कुछ मिनटों तक प्रतीक्षा करें जब तक बोट पुनरारंभ और परिवर्तनों को पुश नहीं करता है!" +server_8 : "{0} रीस्टार्ट हो रहा है...\n\n15-20 सेकंड के बाद आप फिर से खेलना शुरू कर सकते हैं।" +server_9 : "कुछ गलत हो गया, कृपया लॉग जांचें।" +server_10 : "{0} पर एक अपवाद हुआ #अपडेटर में : {0}" +server_11 : "» एक स्पीड टेस्ट चल रहा है..." +server_12 : "⇆ डाउनलोड स्पीड टेस्ट चल रहा है..." +server_13 : "⇆ अपलोड स्पीड टेस्ट चल रहा है..." +server_14 : "↻ स्पीड टेस्ट परिणाम साझा किए जा रहे हैं..." +server_15 : "✯ स्पीड टेस्ट परिणाम ✯\n\nग्राहक :\n» आईपी : {0}\n» देश : {1}\n\nसर्वर :\n» नाम : {2}\n» देश : {3}, {4}\nस्पॉन्सर : {5}\nलैटेंसी : {6}\nपिंग : {7}" + +gban_1 : "» तुमने क्यों खुद को ग्लोबल बैन करना चाहा बेबी?" +gban_2 : "» मैं क्यों खुद को ग्लोबल बैन करूँ?" +gban_3 : "» तुम मेरे सुडोएर्स को ग्लोबल बैन नहीं कर सकते।" +gban_4 : "» {0} पहले से ही बोट से ग्लोबल बैन है।" +gban_5 : "» {0} पर ग्लोबल बैन को आरंभ किया जा रहा है।\n\nप्रत्याशित समय: {1}" +gban_6 : "नया ग्लोबल बैन {0} पर:\n\nमूल श्रोत से: {1} [{2}]\nउपयोगकर्ता: {3}\nउपयोगकर्ता आईडी: {4}\n\nद्वारा बैन किया गया: {5}\nचैट्स: {6}" +gban_7 : "» {0} बोट से ग्लोबल बैन नहीं है।" +gban_8 : "» {0} से ग्लोबल बैन को हटाया जा रहा है।\n\nप्रत्याशित समय: {1}" +gban_9 : "» {0} से ग्लोबल बैन हटाया गया है।\n\n{1} चैट्स में अनबैन हो गया है।" +gban_10 : "» किसी भी उपयोगकर्ता को बोट से ग्लोबल बैन नहीं किया गया है।" +gban_11 : "» ग्लोबल बैन उपयोगकर्ता सूची प्राप्त की जा रही है..." +gban_12 : "🙂 ग्लोबल बैन उपयोगकर्ता :\n\n" diff --git a/strings/langs/pa.yml b/strings/langs/pa.yml new file mode 100644 index 0000000000000000000000000000000000000000..7f57c32150915a9f42f117b70e93e37a76980030 --- /dev/null +++ b/strings/langs/pa.yml @@ -0,0 +1,308 @@ +name : 🇮🇳 ਪੰਜਾਬੀ + +general_1 : "» ਉਪਭੋਗਤਾ ਦੇ ਸੁਨੇਹੇ ਦਾ ਜਵਾਬ ਦਿਓ ਜਾਂ ਉਪਭੋਗਤਾ ਨਾਮ/ਉਪਭੋਗਤਾ ਆਈਡੀ ਦਿਓ।" +general_2 : "» ਤੁਹਾਡੀ ਪੁੱਛਗਿੱਛ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਦੇ ਸਮੇਂ ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ।\n\nਅਪਵਾਦ : {0}" +general_3 : "ਤੁਸੀਂ ਇੱਥੇ ਏਕ ਗੁਮਾਨ ਕੰਪਨੀ ਦੇ ਗੁਮਾਨਸ਼ੀਨ ਪ੍ਰਸ਼ਾਸਕ ਹੋ, ਆਪਣੇ ਉਪਭੋਗਤਾ ਖਾਤੇ ਦੇ ਉਪਯੋਗ ਲਈ ਮੁੜ ਵਾਪਸ ਯਤਨ ਕਰੋ." +general_4 : "» ਤੁਹਾਨੂੰ ਵੀਡੀਓ ਚੈਟਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰਨ ਦਾ ਅਨੁਮਤੀਆਂ ਨਹੀਂ ਹਨ.\n\nਐਡਮਿਨ ਕੈਸ਼ ਨੂੰ ਮੁੜ ਲੋਡ ਕਰੋ ਪਰਮੀਸ਼ਨ /reload ਦੁਆਰਾ" +general_5 : "» ਬੋਟ ਵੀਡੀਓ ਚੈਟ 'ਤੇ ਸਟ੍ਰੀਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਹੈ." + +tg_1 : "{0} ਡਾਉਨਲੋਡਰ\n\nਫਾਇਲ ਆਕਾਰ : {1}\nਪੂਰਾ ਹੋ ਗਿਆ : {2}\nਪ੍ਰਤੀਸ਼ਤ : {3}%\n\nਵੇਗ : {4}/ਸ\nਈਟਾ : {5}" +tg_2 : "ਸਫਲਤਾਪੂਰਕ ਡਾਊਨਲੋਡ ਹੋ ਗਿਆ ਹੈ, ਫਾਇਲ ਪ੍ਰੋਸੈਸਿੰਗ ਹੋ ਰਹੀ ਹੈ...\n\nਗੁਜਰੇ ਸਮੇਂ : {0}" +tg_3 : "ਟੈਲੀਗ੍ਰਾਮ ਤੋਂ ਮੀਡੀਆ ਡਾਊਨਲੋਡ ਕਰਨ 'ਚ ਅਸਫਲ, ਕਿਰਪਾ ਕਰਕੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ..." +tg_4 : "» ਡਾਊਨਲੋਡ ਪਹਿਲਾਂ ਹੀ ਪੂਰਾ ਹੋ ਗਿਆ ਹੈ." +tg_5 : "» ਡਾਊਨਲੋਡ ਪਹਿਲਾਂ ਹੀ ਪੂਰਾ ਹੋ ਗਿਆ ਹੈ ਜਾਂ ਰੱਦ ਕਿਤਾ ਗਿਆ ਹੈ." +tg_6 : "» ਡਾਊਨਲੋਡ ਰੱਦ ਕਿਤਾ ਗਿਆ ਹੈ." +tg_7 : "» ਡਾਊਨਲੋਡ ਰੱਦ ਕਰਨਵਾਲਾ: {0}" +tg_8 : "ਡਾਊਨਲੋਡ ਰੋਕਣ ਵਿੱਚ ਅਸਫਲ ਰਹਿਾ ਹੈ." +tg_9 : "ਚੱਲਦੇ ਡਾਊਨਲੋਡ ਕੰਮ ਦੀ ਜਾਂਚ ਕਰਨ 'ਚ ਅਸਫਲ ਰਹਿਆ ਹੈ..." + +call_1 : "» ਬੋਟ ਲਈ ਲਿੰਕ ਰਾਹੀਂ ਯੂਜ਼ਰਾਂ ਨੂੰ ਸੱਦਣ ਦੀ ਇਜ਼ਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ ਤਾਂ ਕਿ ਬੋਟ ਨੂੰ ਤੁਹਾਡੇ ਚੈਟ 'ਚ ਸ਼ਾਮਲ ਕਰ ਸਕੇ." +call_2 : "{0} ਸਹਾਇਕ ਤੁਹਾਡੇ ਗਰੁੱਪ/ਚੈਨਲ 'ਚ ਪਾਬੰਦ ਹੈ.\n\nਆਈਡੀ : {1}\nਨਾਮ : {2}\nਯੂਜ਼ਰਨੇਮ : @{3}\n\nਕਿਰਪਾ ਕਰਕੇ ਸਹਾਇਕ ਦੇ ਪ੍ਰਤਿਬੰਧ ਖੋਲ੍ਹੋ ਅਤੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ." +call_3 : "{0} ਸਹਾਇਕ ਨੂੰ ਤੁਹਾਡੇ ਚੈਟ 'ਚ ਸੱਦਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਅਸਫਲ ਹੋ ਗਈ ਹੈ.\n\nਕਾਰਨ : {1}" +call_4 : "ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕੋ...\n\n{0} ਸਹਾਇਕ ਨੂੰ ਤੁਹਾਡੇ ਚੈਟ 'ਚ ਸੱਦਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." +call_5 : "{0} ਸਹਾਇਕ ਨੂੰ ਸਫਲਤਾਪੂਰਕ ਸੱਦਣ ਲਈ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ.\n\nਸਟਰੀਮ ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." +call_6 : "» ਸਟਰੀਮ ਬਦਲਣ 'ਚ ਅਸਫਲ ਹੋਇਆ, ਕਿਰਪਾ ਕਰਕੇ /skip ਵਰਤੋਂ ਕਰੋ ਜੀ ਤੁਸੀਂ ਫਿਰ ਗੀਤ ਤਬਦੀਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ." +call_7 : "» ਅਗਲੇ ਗੀਤ ਨੂੰ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ.\n\nਕਿਰਪਾ ਕਰਕੇ ਧੈਰਯ ਰੱਖੋ..." +call_8 : "ਕੋਈ ਚਾਲਤੀ ਵੀਡੀਓਚੈਟ ਨਹੀਂ ਮਿਲੀ.\n\nਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਗਰੁੱਪ/ਚੈਨਲ ਵਿੱਚ ਵੀਡੀਓਚੈਟ ਸ਼ੁਰੂ ਕਰੋ ਅਤੇ ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ." +call_9 : "ਸਹਾਇਕ ਹੀ ਪਹਿਲਾਂ ਵੀਡੀਓਚੈਟ ਵਿੱਚ ਹੈ.\n\nਜੇ ਸਹਾਇਕ ਵੀਡੀਓਚੈਟ ਵਿੱਚ ਨਹੀਂ ਹੈ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ /reboot ਭੇਜੋ ਅਤੇ ਫਿਰ ਖੇਡੋ." +call_10 : "ਟੈਲੀਗ੍ਰਾਮ ਸਰਵਰ ਗਲਤੀ\n\nਟੈਲੀਗ੍ਰਾਮ ਵਿੱਚ ਕੁਝ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆਵਾਂ ਹਨ, ਕਿਰਪਾ ਕਰਕੇ ਫੇਰ ਖੇਡੋ ਜਾਂ ਆਪਣੇ ਗਰੁੱਪ ਦੀ ਵੀਡੀਓਚੈਟ ਨੂੰ ਮੁੜ ਚਾਲਾਓ." + +auth_1 : "» ਤੁਸੀਂ ਆਪਣੇ ਗਰੁੱਪ 'ਚ ਸਿਰਫ 25 ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਰੱਖ ਸਕਦੇ ਹੋ." +auth_2 : "» {0} ਨੂੰ ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ." +auth_3 : "{0} ਪਹਿਲਾਂ ਹੀ ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਸੂਚੀ 'ਚ ਹੈ." +auth_4 : "» {0} ਨੂੰ ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਸੂਚੀ ਤੋਂ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ." +auth_5 : "{0} ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਸੂਚੀ 'ਚ ਨਹੀਂ ਹੈ." +auth_6 : "» ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਸੂਚੀ ਲਵਾ ਰਹੀ ਹੈ..." +auth_7 : "» ਮੰਜੂਰ ਉਪਭੋਗਤਾਵਾਂ ਦੀ ਸੂਚੀ {0} ਵਿੱਚ:\n\n" +auth_8 : "↬ ਦੁਆਰਾ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ :" + +reload_1 : "» ਤੁਸੀਂ ਕੇਵਲ 3 ਮਿੰਟਾਂ 'ਚ ਇੱਕ ਵਾਰ ਐਡਮਿਨ ਕੈਸ਼ ਰੀਫ੍ਰੈਸ਼ ਕਰ ਸਕਦੇ ਹੋ.\n\nਕਿਰਪਾ ਕਰਕੇ {0} ਤੋਂ ਬਾਅਦ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ." +reload_2 : "» ਐਡਮਿਨ ਕੈਸ਼ ਸਫਲਤਾਪੂਰਕ ਰੀਫ੍ਰੈਸ਼ ਹੋ ਗਈ ਹੈ." +reload_3 : "» ਐਡਮਿਨ ਕੈਸ਼ ਰੀਫ੍ਰੈਸ਼ ਕਰਨ 'ਚ ਅਸਫਲ ਹੋ ਗਈ ਹੈ, ਕ੍ਰਿਪਾ ਕਰਕੇ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਬੋਟ ਤੁਹਾਡੇ ਚੈਟ ਵਿੱਚ ਐਡਮਿਨ ਹੈ." +reload_4 : "» ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕੋ...\n\n{0} ਨੂੰ ਮੁੜ ਚਾਲਾਉਣ ਲਈ ਰੀਬੂਟ ਹੋ ਰਿਹਾ ਹੈ." +reload_5 : "{0} ਨੂੰ ਤੁਹਾਡੇ ਚੈਟ ਲਈ ਸਫਲਤਾਪੂਰਕ ਮੁੜ ਚਾਲਾ ਦਿੱਤਾ ਗਿਆ ਹੈ.\n\nਮੁੜ ਖੇਡਣਾ ਸ਼ੁਰੂ ਕਰੋ..." + +admin_1 : "» ਕੀ ਤੁਸੀਂ ਯਾਦ ਰੱਖਦੇ ਹੋ ਕਿ ਤੁਸੀਂ ਸਟ੍ਰੀਮ ਨੂੰ ਚਲਾਇਆ ਸੀ?" +admin_2 : "➻ ਸਟ੍ਰੀਮ ਰੋਕੀ ਗਈ 🎄\n│ \n└ਦੁਆਰਾ : {0} 🥀" +admin_3 : "» ਕੀ ਤੁਸੀਂ ਯਾਦ ਰੱਖਦੇ ਹੋ ਕਿ ਤੁਸੀਂ ਸਟ੍ਰੀਮ ਰੋਕੀ ਸੀ?" +admin_4 : "➻ ਸਟ੍ਰੀਮ ਚਾਲੀ ਗਈ 🎄\n│ \n└ਦੁਆਰਾ : {0} 🥀" +admin_5 : "➻ ਸਟ੍ਰੀਮ ਮੁੱਕ ਗਈ/ਰੋਕੀ ਗਈ 🎄\n│ \n└ਦੁਆਰਾ : {0} 🥀" +admin_6 : "➻ ਸਟ੍ਰੀਮ ਛੱਡ ਦਿੱਤੀ 🎄\n│ \n└ਦੁਆਰਾ : {0} 🥀\n\n» {1} ਵਿੱਚ ਹੋਰ ਕੁਈ ਕਤਾਰ 'ਚ ਹੋਰ ਕੋਈ ਟਰੈਕ ਨਹੀਂ ਬਚੇ, ਵੀਡੀਓਚੈਟ ਤੋਂ ਬਾਹਰ ਆ ਰਿਹਾ ਹੈ." +admin_7 : "ਸਟ੍ਰੀਮ ਨੂੰ {0} 'ਤੇ ਤਬਦੀਲ ਕਰਨ 'ਚ ਗਲਤੀ." +admin_8 : "» ਕਿਰਪਾ ਕਰਕੇ /loop disable ਦੀ ਸਹਾਇਤਾ ਨਾਲ ਲੂਪ ਪਲੇ ਨੂੰ ਬੰਦ ਕਰੋ ਅਤੇ ਫਿਰ ਸਕਿਪ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ." +admin_9 : "ਕਿਰਪਾ ਕਰਕੇ ਸਕਿਪ ਲਈ ਵਿਸ਼ਿਸ਼ ਨੰਬਰ ਵਰਤੋ, ਜਿਵੇਂ 1, 2, 4..." +admin_10 : "ਕਮ ਤੋਂ ਕਮ 2 ਟ੍ਰੈਕਾਂ ਦੀ ਜ਼ਰੂਰਤ ਹੈ ਜੋ ਵਿਸ਼ਿਸ਼ ਸਕਿਪ ਲਈ ਲੱਗੇ।\n\nਕਤਾਰ ਚੈੱਕ ਕਰੋ : /queue" +admin_11 : "» ਕਤਾਰ 'ਚ ਵਿਸ਼ਿਸ਼ ਸਕਿਪ ਲਈ ਕੋਈ ਟ੍ਰੈਕ ਨਹੀਂ ਹੈ।\n\nਕਿਰਪਾ ਕਰਕੇ 1 ਅਤੇ {0} ਵਿੱਚ ਸਕਿਪ ਕਰੋ" +admin_12 : "» ਵਿਸ਼ਿਸ਼ ਟ੍ਰੈਕ ਤੇ ਸਕਿਪ ਨਹੀਂ ਕੀਤਾ ਗਿਆ।\n\nਬਾਕੀ ਕਤਾਰ ਚੈੱਕ ਕਰੋ : /queue" +admin_13 : "» ਕਿਰਪਾ ਕਰਕੇ ਏਡਮਿਨ ਕੈਸ਼ ਨੂੰ ਰੀਲੋਡ ਕਰੋ : /reload" +admin_14 : "» ਤੁਹਾਡੇ ਕੋਲ ਵੀਡੀਓ ਚੈੱਟ ਪ੍ਰਬੰਧਿਤ ਕਰਨ ਦੀ ਅਨੁਮਤੀ ਨਹੀਂ ਹੈ।\n\nਕਿਰਪਾ ਕਰਕੇ ਏਡਮਿਨ ਕੈਸ਼ ਨੂੰ ਰੀਲੋਡ ਕਰੋ : /reload" +admin_15 : "» ਸ਼ੁੱਧੀ ਨਹੀਂ ਹੋ ਰਹੀ।\n\nਕਤਾਰ ਦੇ ਅੱਪਰ ਚੈੱਕ ਕਰੋ : /queue" +admin_16 : "» ਕਤਾਰ ਸ਼ੁੱਧੀ ਹੋ ਗਈ ਹੈ {0} ਵੱਲੋਂ।\n\nਸ਼ੁੱਧੀ ਕਤਾਰ ਚੈੱਕ ਕਰੋ : /queue" +admin_17 : "ਉਦਾਹਰਣ :\n\n/loop enable/disable\n/loop 10/9/8/7" +admin_18 : "» ਲੂਪ {0} ਸਮੇਂ ਲਈ ਚਾਲੀ ਗਈ ਹੈ {1} ਵੱਲੋਂ।" +admin_19 : "» ਲੂਪ ਪਲੇ ਬੰਦ ਕੀਤੀ ਗਈ ਹੈ {0} ਵੱਲੋਂ।" +admin_20 : "ਉਦਾਹਰਣ :\n\n/seek ਜਾਂ /seekback [ਸਮਾਂ ਸਕਿਅੰਤਾ ਸਕਿੰਟਾਂ ਵਿੱਚ]" +admin_21 : "» ਕਿਰਪਾ ਕਰਕੇ ਸਕੀਨਗ ਲਈ ਨੰਬਰੀਕ ਅੰਕ ਵਰਤੋ." +admin_22 : "» ਲਾਈਵ ਸਟਰੀਮ ਨੂੰ ਸੀਕ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ." +admin_23 : "» ਘੱਟ ਮੁਦਾਂ ਨਾਲ ਸੀਕ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\n\n{0} ਵਿੱਚ ਖੇਡਿਆ {1} ਮਿੰਟਾਂ ਤੱਕ." +admin_24 : "ਸੀਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...\n\nਕਿਰਪਾ ਕਰਕੇ ਬਾਹਰ ਜਾਣ ਵਾਲੇ ਨਾਲ ਵਾਜਾ ਕਰੋ..." +admin_25 : "» ਸਟਰੀਮ ਸਫਲਤਾਪੂਰਕ ਸੀਕ ਕੀਤੀ ਗਈ ਹੈ।\n\nਮੁਦਾਂ : {0} ਮਿੰਟ\nਵਾਲੇ : {1}" +admin_26 : "ਸੀਕ ਨਹੀਂ ਕੀਤੀ।" +admin_27 : "» ਸਿਰਫ ਯੂਟਿਊਬ ਸਟਰੀਮ ਦੀ ਗਤੀ ਹੁਣੇ ਤੱਕ ਨਿਯੰਤਰਿਤ ਨਹੀਂ ਹੋ ਸਕਦੀ।" +admin_28 : "{0} ਗਤੀ ਨਿਯੰਤਰਣ ਪੈਨਲ\n\nਮੌਜੂਦਾ ਚੱਲਦੇ ਸਟਰੀਮ ਦੀ ਗਤੀ ਬਦਲਣ ਲਈ ਹੇਠਲੀਆਂ ਬਟਨਾਂ 'ਤੇ ਕਲਿਕ ਕਰੋ।" +admin_29 : "» ਬੋਟ ਪਹਿਲਾਂ ਹੀ ਸਧਾਰਨ ਗਤੀ 'ਤੇ ਚੱਲਦਾ ਹੈ।" +admin_30 : "» ਕਿਰਪਾ ਕਰਕੇ ਇੰਤਜ਼ਾਰ ਕਰੋ...\n\nਕੋਈ ਹੋਰ ਵੀ ਮੁਦਾਂ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ।" +admin_31 : "ਗਤੀ ਬਦਲੀ ਜਾ ਰਹੀ ਹੈ..." +admin_32 : "» ਮੌਜੂਦਾ ਚੱਲ ਰਹੇ ਮੁਦੇ ਦੀ ਗਤੀ ਬਦਲਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ...\n\nਨੇਤਾਂ ਦੀ ਬੇਨਤੀ: {0}" +admin_33 : "» ਸਟ੍ਰੀਮ ਦੀ ਵੇਗ ਬਦਲਣ ਵਿੱਚ ਅਸਫਲ ਹੋਇਆ।" +admin_34 : "» ਚਲਦੇ ਸਟ੍ਰੀਮ ਦੀ ਵੇਗ ਬਦਲੀ ਗਈ ਹੈ {0}x\n\nਬਾਇਰਲੇਨਾਂ : {1}" +admin_35 : "ਵੋਟਿੰਗ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ ਕਿਉਂਕਿ ਵੋਟਿੰਗ ਦੀ ਆਪੋਸ਼ਣ ਦੇ ਹੋਈ ਹੈ ਜਿਸ ਸੰਗੀਤ ਲਈ ਵੋਟਿੰਗ ਦਿੱਤੀ ਗਈ ਸੀ।" +admin_36 : "ਇਸ ਕ੍ਰਿਆ ਨੂੰ ਪੂਰਾ ਕਰਨ ਵਿੱਚ ਅਸਫਲ ਹੋਇਆ ਕਿਉਂਕਿ ਵੋਟਿੰਗ ਲਈ ਮਿਲਦੇ ਹੋਏ ਸੰਗੀਤ ਵਿੱਚ ਮੁੱਖ ਸਿਖਰ ਵਾਰਤਾਂ ਦੀ ਬੰਦੋਬਸ਼ਤ ਹੈ ਜੋ ਇਥੇ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ ਜਾਂ ਰੁਕੀ ਹੋਈ ਹੈ।" +admin_37 : "ਸੰਗੀਤ ਵਿੱਚ {0} ਵੋਟਿੰਗਾਂ ਪ੍ਰਾਪਤ ਹੋਈਆਂ ਹਨ।" +admin_38 : "» 1 ਵੋਟ ਜੋੜਿਆ ਗਿਆ ਹੈ।" +admin_39 : "» 1 ਵੋਟ ਹਟਾਇਆ ਗਿਆ ਹੈ।" +admin_40 : "ਵੋਟ ਦਿੱਤਾ ਗਿਆ ਹੈ।" + +start_1 : "{0} ਜੀ ਜਿੰਦਾ ਹੈ ਵੀ.\n\n✫ ਅਪਟਾਈਮ : {1}" +start_2 : "ਹੇਲੋ {0}, 🥀\n\n๏ ਇਹ {1} ਹੈ !\n\n➻ ਇੱਕ ਤੇਜ਼ ਅਤੇ ਤਾਕਤਵਰ ਟੈਲੀਗ੍ਰਾਮ ਸੰਗੀਤ ਪਲੇਅਰ ਬੋਟ ਜਿਸ ਵਿੱਚ ਕੁਝ ਸ਼ਾਨਦਾਰ ਵੈਬਸਾਇਟਾਂ ਹਨ।\n\nਸਮਰਥਿਤ ਪਲੈਟਫਾਰਮ : ਯੂਟਿਊਬ, ਸਪੋਟੀਫਾਈ, ਰੈਸੋ, ਐਪਲ ਮਿਊਜ਼ਿਕ ਅਤੇ ਸਾਊਂਡਕਲੌਡ।\n──────────────────\n๏ ਮੇਰੀ ਮੋਡਿਊਲਾਂ ਅਤੇ ਕੰਮਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਲਈ ਮੱਦਦ ਬਟਨ ਤੇ ਕਲਿਕ ਕਰੋ।" +start_3 : "ਹੇਲੋ {0},\nਇਹ {1} ਹੈ\n\nਧੰਨਵਾਦ {2} ਵਿਚ ਮੈਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, {3} ਹੁਣ ਇਸ ਗੱਲ ਦਾ ਪਾਲਣ ਕਰ ਸਕਦੇ ਹਨ ਕਿ ਆਪ ਵੀਡੀਓ ਵਿੱਚ ਗੀਤ ਪਲੇ ਕਰ ਸਕਦੇ ਹੋ।" +start_4 : "🎄 ਸੁਪਰਗਰੂਪ ਦੀ ਲੋੜ ਹੈ 🎄\n\nਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਗਰੁੱਪ ਨੂੰ ਸੁਪਰਗਰੂਪ ਵਿੱਚ ਤਬਦੀਲ ਕਰੋ ਅਤੇ ਫਿਰ ਮੈਨੂੰ ਮੁੜ ਸ਼ਾਮਲ ਕਰੋ।\n\nਸੁਪਰਗਰੂਪ ਬਣਾਉਣ ਲਈ ਕਿਵੇਂ ?\n- ਆਪਣੇ ਗਰੁੱਪ ਚੈਟ ਦੀ ਇਤਿਹਾਸ ਨੂੰ ਏਕ ਵਾਰ ਦਿੱਖਤਾ ਬਣਾਓ।" +start_5 : "↝ ਬਲੈਕਲਿਸਟਡ ਚੈਟ ↜\n\nਇਹ ਚੈਟ {0} ਡੇਟਾਬੇਸ 'ਤੇ ਬਲੈਕਲਿਸਟ ਹੈ।\nਤੁਹਾਨੂੰ ਕਿਸੇ ਦੂਜੇ ਸੂਡੋ ਯੂਜ਼ਰ ਦੀ ਵੇਬਸਾਈਟ ਵੀਜ਼ਿਟ ਕਰਨ ਲਈ ਅਨੁਰੋਧ ਕਰਦਾ ਹੈ, ਜਾਂ ਸੁਪੋਰਟ ਚੈਟ 'ਤੇ ਜਾਓ।" +start_6 : "😲 ਟ੍ਰੈਕ ਜਾਣਕਾਰੀ 😲\n\n📌 ਸ਼ੀਰਸ਼ਕ : {0}\n\n⏳ ਮੁਦਤ : {1} ਮਿੰਟ\n👀 ਵੇਖੇ ਗਏ : {2}\n⏰ ਪ੍ਰਕਾਸ਼ਿਤ ਹੋਇਆ ਸਮਾਂ : {3}\n📎 ਚੈਨਲ : {5}\n\n🥀 ਖੋਜ ਸ਼ਕਤੀਵਾਨ ਬਣਾਇਆ ਗਿਆ ਹੈ {6}" + +help_1 : "ਸੰਮਰਥਨ ਲਈ ਕੈਟੇਗਰੀ ਚੁਣੋ ਜਿਸ ਵਿੱਚ ਤੁਸੀਂ ਮਦਦ ਪ੍ਰਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ। ਆਪਣੇ ਸਸਪੈਂਟ ਨੂੰ ਪੂਛੋ ਸੰਮਰਥਨ ਚੈਟ\n\nਸਭ ਕੰਮਾਂਡਾਂ / ਨਾਲ ਵਰਤੀ ਜਾ ਸਕਦੀਆਂ ਹਨ।" +help_2 : "ਆਪਣੇ ਪ੍ਰਾਈਵੇਟ ਚੈਟ ਵਿੱਚ ਮੇਰੇ ਮਦਦ ਮੀਨੂ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਹੇਲਪ ਮੇਨੂ ਉੱਤੇ ਦਿੱਤੇ ਗਏ ਬਟਨ 'ਤੇ ਕਲਿਕ ਕਰੋ।" + +lang_1 : "» ਮੈਂਨੂੰ ਜੇ ਕਿਸੇ ਸਮੂਹ ਦੀ ਮੂਲ ਭਾ਷ਾ ਬਣਾਉਣੀ ਹੈ, ਤਾਂ ਕਿਰਪਾ ਕਰਕੇ ਉਸ ਸਮੂਹ ਦੀ ਭਾ਷ਾ ਚੁਣੋ :" +lang_2 : "ਭਾਸ਼ਾ ਸਫ਼ਲਤਾਪੂਰਕ ਬਦਲੀ ਗਈ ਹੈ।" +lang_3 : "ਭਾਸ਼ਾ ਬਦਲਣ ਵਿੱਚ ਅਸਫਲ ਹੋਇਆ।" +lang_4 : "ਤੁਸੀਂ ਹੀ ਉਸੇ ਭਾਸ਼ਾ 'ਤੇ ਹੋ।" + +setting_1 : "{0} ਸੈਟਿੰਗਾਂ ਪੈਨਲ\n\nਚੈਟ ਆਈਡੀ : {1}\nਚੈਟ ਨਾਂ : {2}\n\nਸੈਟਿੰਗਾਂ ਬਦਲਣ ਲਈ ਹੇਠਾਂ 'ਤੇ ਬਟਨਾਂ 'ਤੇ ਕਲਿਕ ਕਰੋ।" +setting_2 : "» ਡਾਇਰੈਕਟ: ਖੋਜ ਪੁੱਛ ਤੇ ਖੋਜ ਜ਼ਿਦਾ ਸਵਰੂਪੋ 'ਤੇ ਸੀਧਾ ਚੱਲਦੀ ਹੈ।\n\n» ਇਨਲਾਈਨ: ਵੀਡੀਓ ਅਤੇ ਆਡੀਓ ਵਿੱਚ ਚੁਣਨ ਲਈ ਇਨਲਾਈਨ ਬਟਨ ਪ੍ਰਦਾਨ ਕਰਦੇ ਹਨ।" +setting_3 : "» ਹਰ ਕੋਈ: ਇਸ ਸਮੂਹ ਵਿੱਚ ਹਰ ਕੋਈ ਐਡਮਿਨ ਕੰਮਾਂਡਾਂ [ਸਕਿਪ, ਪੌਜ, ਰੀਜ਼ਿਊਮ ਆਦਿ] ਵਰਤ ਸਕਦਾ ਹੈ।\n\n» ਸਿਰਫ ਐਡਮਿਨ: ਸਿਰਫ ਐਡਮਿਨਾਂ ਅਤੇ ਮਨਜ਼ੂਰ ਯੂਜ਼ਰ ਐਡਮਿਨ ਕੰਮਾਂਡਾਂ ਵਰਤ ਸਕਦੇ ਹਨ।" +setting_4 : "» ਕੋਈ ਮਨਜ਼ੂਰ ਯੂਜ਼ਰ ਨਹੀਂ ਮਿਲੇ।" +setting_5 : "» ਗਰੁੱਪ: ਉਸ ਗਰੁੱਪ ਵਿੱਚ ਸੰਗੀਤ ਚਲਾਉਂਦਾ ਹੈ ਜਿੱਥੇ ਆਦੇਸ਼ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ।\n\n» ਚੈਨਲ: ਉਸ ਚੈਨਲ 'ਚ ਸੰਗੀਤ ਚਲਾਉਂਦਾ ਹੈ ਜਿਥੇ ਤੁਸੀਂ ਚਾਹੁੰਦੇ ਹੋ। /channelplay ਦੁਆਰਾ ਚੈਨਲ ਆਈਡੀ ਸੈਟ ਕਰੋ" +setting_6 : "» ਹਰ ਕੋਈ : ਇਸ ਗਰੁੱਪ ਵਿੱਚ ਹਾਜ਼ਰ ਕੋਈ ਵੀ ਮਿਊਜ਼ਿਕ ਚਲਾ ਸਕਦਾ ਹੈ।\n\n» ਸਿਰਫ ਐਡਮਿਨ : ਇਸ ਗਰੁੱਪ ਵਿੱਚ ਮਿਊਜ਼ਿਕ ਸਿਰਫ ਐਡਮਿਨਸ ਵੀ ਚਲਾ ਸਕਦੀ ਹੈ।" +setting_7 : "» ਕਿਰਪਾ ਕਰਕੇ /channelplay ਦੁਆਰਾ ਚੈਨਲ ਆਈਡੀ ਨੂੰ ਨਿਰਧਾਰਿਤ ਕਰੋ" +setting_8 : "ਜਦੋਂ ਇਹ ਮੋਡ ਸਮਰੱਥਿਤ ਹੁੰਦਾ ਹੈ, ਤਾਂ ਬਿਨਾ ਐਡਮਿਨ ਹੱਕਾਂ ਵਾਲੇ ਲੋਕ ਕੁਝ ਸਮੇਂ ਬਾਅਦ ਐਡਮਿਨ ਕਮਾਂਡ ਵਰਤ ਸਕਦੇ ਹਨ." +setting_9 : "ਮੌਜੂਦਾ ਅੱਪਵੋਟਾਂ ਦੀ ਗਿਣਤੀ ਜੋ ਐਡਮਿਨ ਕਮਾਂਡ ਵਰਤਣ ਲਈ ਦੀ ਜ਼ਰੂਰੀ ਹੈ: {0}" +setting_10 : "ਵੋਟਿੰਗ ਮੋਡ ਬੰਦ ਹੈ." +setting_11 : "ਸਭ ਤੋਂ ਘੱਟ ਅੱਪਵੋਟ ਗਿਣਤੀ 2 ਹੋ ਸਕਦੀ ਹੈ। ਤੁਸੀਂ 2 ਤੋਂ ਘੱਟ ਸੈਟ ਨਹੀਂ ਕਰ ਸਕਦੇ" +setting_12 : "ਸਭ ਤੋਂ ਵੱਧ ਅੱਪਵੋਟ ਗਿਣਤੀ 15 ਹੋ ਸਕਦੀ ਹੈ। ਤੁਸੀਂ 15 ਤੋਂ ਵੱਧ ਸੈਟ ਨਹੀਂ ਕਰ ਸਕਦੇ" + +set_cb_1 : "ਪ੍ਰਾਪਤ ਕਰ ਰਹੇ ਹਨ ਮਨਜੂਰ ਯੂਜ਼ਰਾਂ ਪੈਨਲ..." +set_cb_2 : "ਪ੍ਰਾਪਤ ਕਰ ਰਹੇ ਹਨ ਪਲੇ ਮੋਡ ਪੈਨਲ..." +set_cb_3 : "ਸੈੱਟਿੰਗ ਅੱਪ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." +set_cb_4 : "» ਮੰਜੂਰ ਕੀਤੇ ਗਏ ਯੂਜ਼ਰਾਂ ਦੀ ਲਿਸਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." +set_cb_5 : "» ਵਾਪਸ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..." + +gstats_1 : "ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ {0} ਸਟੈਟਸ ਅਤੇ ਜਾਣਕਾਰੀ...\n\nਇਹ ਥੋੜੇ ਸਮੇਂ ਲਗ ਸਕਦਾ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਰੁਕੋ..." +gstats_2 : "ਨੀਚੇ ਦਿੱਤੇ ਗਏ ਬਟਨਾਂ 'ਤੇ ਕਲਿਕ ਕਰੋ ਤਾਂ {0} ਦੀ ਸਟੈਟਸ ਦੇਖੋ." +gstats_3 : "{0} ਸਟੈਟਸ ਅਤੇ ਜਾਣਕਾਰੀ :\n\nਅਸਿਸਟੈਂਟਾਂ : {1}\nਬਲੌਕ : {2}\nਚੈਟਾਂ : {3}\nਯੂਜ਼ਰ : {4}\nਮੋਡਿਊਲਾਂ : {5}\nਸੁਡੋਅਰ : {6}\n\nਆਟੋ ਛੱਡਣ ਵਾਲਾ ਅਸਿਸਟੈਂਟ : {7}\nਪਲੇ ਦੀ ਮਿਆਦ ਸੀਮਾ : {8} ਮਿੰਟਾਂ" +gstats_4 : "ਇਹ ਬਟਨ ਸਿਰਫ ਸੁਡੋਅਰਾਂ ਲਈ ਹੈ." +gstats_5 : "{0} ਸਟੈਟਸ ਅਤੇ ਜਾਣਕਾਰੀ :\n\nਮੋਡਿਊਲਾਂ : {1}\nਪਲੈਟਫਾਰਮ : {2}\nਰੈਮ : {3}\nਫਿਜਿਕਲ ਕੋਰਸ : {4}\nਕੁੱਲ ਕੋਰਸ : {5}\nਸੀਪੀਯੂ ਫ਼ਰੀਕਵੈਂਸੀ : {6}\n\nਪਾਇਥਨ : {7}\nਪਾਇਥਾਂ : {8}\nਪਾਇਥਾਂ-ਟੀਜੀਕਾਲਾ : {9}\n\nਸਟੋਰੇਜ ਉਪਲੱਬਧ : {10} ਗੀਬੀ\nਸਟੋਰੇਜ ਵਰਤੇ : {11} ਗੀਬੀ\nਸਟੋਰੇਜ ਬਾਕੀ : {12} ਗੀਬੀ\n\nਸੇਵਿਆਂ ਦੀਆਂ ਚੈਟਾਂ : {13}\nਸੇਵਿਆਂ ਦੇ ਯੂਜ਼ਰ : {14}\nਬਲੌਕ ਕੀਤੇ ਯੂਜ਼ਰ : {15}\nਸੁਡੋ ਯੂਜ਼ਰ : {16}\n\nਕੁੱਲ ਡੀਬੀ ਆਕਾਰ : {17} ਐਮਬੀ\nਕੁੱਲ ਡੀਬੀ ਸਟੋਰੇਜ : {18} ਐਮਬੀ\nਕੁੱਲ ਡੀਬੀ ਕਲੈਕਸ਼ਨ : {19}\nਕੁੱਲ ਡੀਬੀ ਕੀਜ : {20}" + +playcb_1 : "» ਆਓ, ਇਹ ਤੁਹਾਡੇ ਵਾਸਤੇ ਨਹੀਂ ਹੈ ਮੇਰੇ ਮਨਾਣ ਦੇ ਅਨੁਸਾਰ." +playcb_2 : "» ਅਗਲੇ ਨਤੀਜੇ ਪ੍ਰਾਪਤ ਕੀਤੇ ਜਾ ਰਹੇ ਹਨ,\n\nਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕ ਕਰੋ..." + +cplay_1 : "» ਤੁਸੀਂ {0} ਤੋਂ ਕਿਸੇ ਵੀ ਚੈਨਲ 'ਤੇ ਗੀਤ ਖੇਡ ਸਕਦੇ ਹੋ ਜਾਂ ਤੁਹਾਡੇ ਚੈਟ ਦੇ ਲਿੰਕ ਦਿੱਤੇ ਚੈਨਲ 'ਤੇ।\n\nਲਿੰਕ ਦਿੱਤੇ ਚੈਨਲ ਲਈ:\n/channelplay linked\n\nਕਿਸੇ ਹੋਰ ਚੈਨਲ ਲਈ:\n/channelplay [ਚੈਨਲ ਆਈਡੀ]" +cplay_2 : "» ਇਸ ਚੈਟ ਦੇ ਕੋਈ ਵੀ ਲਿੰਕ ਦਿੱਤੇ ਚੈਨਲ ਨਹੀਂ ਹਨ।" +cplay_3 : "» ਚੈਨਲ ਨੂੰ {0} ਲਈ ਨਿਰਧਾਰਤ ਕੀਤਾ ਗਿਆ ਹੈ।\nਚੈਨਲ ਆਈਡੀ : {1}" +cplay_4 : "» ਚੈਨਲ ਨੂੰ ਪ੍ਰਾਪਤ ਕਰਨ 'ਚ ਅਸਫ਼ਲ ਹੋਇਆ।\n\nਮੁੱਖਬੂਟੀ ਬਣਾਓ ਕਿ ਤੁਸੀਂ ਆਪਣੇ ਚੈਨਲ ਵਿੱਚ ਬੋਟ ਸ਼ਾਮਲ ਕਰ ਚੁੱਕੇ ਹੋ ਅਤੇ ਉਸ ਨੂੰ ਐਡਮਿਨ ਬਣਾ ਦਿੳੁ।" +cplay_5 : "ਸਿਰਫ਼ ਚੈਨਲਾਂ ਦਾ ਸਮਰਥਨ ਕੀਤਾ ਗਿਆ ਹੈ।" +cplay_6 : "» ਤੁਹਾਨੂੰ ਚੈਨਲ {0} ਦਾ ਮਾਲਕ ਹੋਣ ਦੀ ਲੋੜ ਹੈ ਇਸ ਨੂੰ ਇਸ ਗਰੁਪ ਨਾਲ ਮੇਲਾਓ।\nਚੈਨਲ ਦਾ ਮਾਲਕ : @{1}\n\nਵਿਕਲਪ ਤੌਰ 'ਤੇ, ਤੁਸੀਂ ਆਪਣੇ ਗਰੁਪ ਨੂੰ ਉਹ ਚੈਨਲ ਦੇ ਸਥਾਨ 'ਤੇ ਲਿੰਕ ਕਰ ਸਕਦੇ ਹੋ ਅਤੇ ਫਿਰ /channelplay linked ਨਾਲ ਜੁੜਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰੋ।" +cplay_7 : "» ਚੈਨਲ ਪਲੇ ਅਸਮਰਥ ਕੀਤਾ ਗਿਆ ਹੈ।" + +play_1 : "🔍" +play_2 : "➻ ਚੈਨਲ ਪਲੇ ਮੋਡ\n\nਪ੍ਰੋਸੈਸਿੰਗ, ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕੋ...\n\nਲਿੰਕ ਕੀਤਾ ਚੈਨਲ : {0}" +play_3 : "» ਪ੍ਰੋਸੈਸ਼ ਕਰਨ ਵਿੱਚ ਅਸਫ਼ਲ ਹੋਇਆ।" +play_4 : "ਕੇਵਲ ਐਡਮਿਨ ਪਲੇ\nਇਸ ਚੈਟ ਦੇ ਐਡਮਿਨ ਹੀ ਖੇਡ ਸਕਦੇ ਹਨ\n\n/playmode ਰਾਹੀਂ ਖੇਡਣ ਦਾ ਮੋਡ ਬਦਲੋ" +play_5 : "» ਆਡੀਓ ਫਾਇਲ ਦੀ ਪ੍ਰੋਸੈਸ਼ਿੰਗ ਵਿੱਚ ਅਸਫ਼ਲ ਹੋਇਆ।\n\nਆਡੀਓ ਫਾਇਲ ਦਾ ਆਕਾਰ ਨੀਚੇ ਦਿੱਤੇ ਸੀਮਤ ਤੋਂ ਵੱਡਾ ਹੈ।" +play_6 : "» ਸਟ੍ਰੀਮ {0} ਤੋਂ ਲੰਬਾ ਹੈ ਅਤੇ {1} 'ਤੇ ਖੇਡਣ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ" +play_7 : "» ਮਾਨਿਆ ਵਿਡੀਓ ਫਾਇਲ ਐਕਸ਼ਟੇਸ਼ਨ ਨਹੀਂ ਹੈ।\n\nਸਹਾਇਕ ਐਕਸ਼ਟੇਸ਼ਨ: {0}" +play_8 : "» ਵੀਡੀਓ ਫਾਇਲ ਦਾ ਆਕਾਰ 1ਜੀਬੀ ਤੋਂ ਘੱਟ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ." +play_9 : "YouTube ਪਲੇਲਿਸਟ ਫੀਚਰ\n\nਪੂਰੀ YouTube ਪਲੇਲਿਸਟ ਨੂੰ ਖੇਡਣ ਲਈ ਮੋਡ ਚੁਣੋ।" +play_10 : "ਸਿਰਲੇਖ : {0}\nਮਿੰਟਾਂ ਦੀ ਮੁਦਤ : {1}" +play_11 : "{0} Spotify ਪਲੇਅਰ\n\nਦੁਆਰਾ ਮੰਗਿਆ ਗਿਆ : {1}" +play_12 : "{0} Apple ਪਲੇਅਰ\n\nਦੁਆਰਾ ਮੰਗਿਆ ਗਿਆ : {1}" +play_13 : "» ਲਾਈਵ ਸਟ੍ਰੀਮ ਪਕਡ਼ਿਆ ਗਿਆ ਹੈ।\n\nਕੀ ਤੁਸੀਂ ਯਕੀਨਾਂ ਹੈਂ ਕਿ ਤੁਸੀਂ ਇਸ ਲਾਈਵ ਸਟ੍ਰੀਮ ਨੂੰ ਚੱਲਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?" +play_14 : "ਟ੍ਰੈਕ ਦੇਤਾਇਲਾਂ ਦੀ ਵੱਖਰੀ ਕਰਨਾ ਅਸਫ਼ਲ ਹੋਇਆ।\n\nਕਿਸੇ ਹੋਰ ਨੂੰ ਖੇਡੋ ਕੋਈ ਹੋਰ ਟ੍ਰੈਕ।" +play_15 : "» ਪੁਰਜ਼ਾ ਦਾ ਇੱਛਰਾ ਕਰਨ ਵਿੱਚ ਅਸਫ਼ਲ ਹੋਇਆ।\n\nਮੈਂ ਕੇਵਲ Spotify ਟ੍ਰੈਕਾਂ, ਐਲਬਮਾਂ, ਕਲਾਕਾਰਾਂ ਅਤੇ ਪਲੇਲਿਸਟ ਖੇਡ ਸਕਦਾ ਹਾਂ।" +play_16 : "ਕੋਈ ਸਰਗਰਮ ਆਵਾਜ਼ ਚੈਟ ਨਹੀਂ ਹੈ।\n\nਫੋਰਸ ਖੇਡਣ ਲਈ, ਸਰਗਰਮ ਆਵਾਜ਼ ਚੈਟ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ।" +play_17 : "ਕਿਰਪਾ ਕਰਕੇ ਵੀਡੀਓ ਚੈਟ ਚਾਲੀਏ, ਮੈਂ URL ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਲਈ ਅਸਮਰੱਥ ਹਾਂ।" +play_18 : "ਉਪਯੋਗ : /play [ਗੀਤ ਦਾ ਨਾਮ/YouTube URL/ਆਡੀਓ/ਵੀਡੀਓ ਫਾਇਲ ਦੇ ਪ੍ਰਤੀਕ ਉੱਤਰ]" +play_19 : "ਕਤਾਰ ਦੀ ਪਲੇਲਿਸਟ:" +play_20 : "ਕਤਾਰ ਦੀ ਥਾਂ -" +play_21 : "ਕੱਢੀਆ ਗਿਆ {0} ਟਰੈਕਾਂ ਨੂੰ ਕਤਾਰ ਵਿੱਚ.\n\nਚੈਕ: ਇੱਥੇ ਕਲਿਕ ਕਰੋ" +play_22 : "ਸਮੱਗਰੀ ਨੂੰ ਉਸ ਤਰੀਕੇ ਨਾਲ ਖੇਡਣ ਦੇ ਮੋਡ ਨੂੰ ਚੁਣੋ ਜਿਸ ਵਿੱਚ ਤੁਸੀਂ ਆਪਣੇ ਗਰੁੱਪ ਵਿੱਚ ਕਤਾਰਾ ਲੱਗਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ: {0}" + +str_1 : "ਕਿਰਪਾ ਕਰਕੇ m3u8 ਜਾਂ ਇੰਡੈਕਸ ਲਿੰਕ ਪ੍ਰਦਾਨ ਕਰੋ." +str_2 : "➻ ਵੈਲੀਡ ਸਟਰੀਮ ਪੁਸ਼ਟੀ ਕੀਤੀ।\n\nਪ੍ਰੋਸੈਸਿੰਗ..." +str_3 : "ਯੂਟਿਊਬ ਲਾਈਵ ਸਟਰੀਮ ਚਲਾਉਣ 'ਚ ਅਸਫ਼ਲ ਹੋਇਆ, ਕੋਈ ਲਾਈਵ ਫਾਰਮੈਟ ਨਹੀਂ ਲੱਭਿਆ।" + +ping_1 : "{0} ਪਿੰਗ ਲੱਗਾ ਰਿਹਾ ਹੈ..." +ping_2 : "🏓 ਪੌਂਗ: {0}ਮਿਲੀਸਕਿੰਡ\n\n{1} ਸਿਸਟਮ ਸਟੈਟਸ:\n\n↬ ਅਪਟਾਇਮ: {2}\n↬ ਰੈਮ: {3}\n↬ ਸੀ.ਪੀ.ਯੂ: {4}\n↬ ਡਿਸਕ: {5}\n↬ ਪਾਈ-ਟੀਜੀ-ਕਾਲਜ: {6}ਮਿਲੀਸਕਿੰਡ" + +queue_1 : "» Ǫᴜᴇᴜᴇ ਲੱਭ ਰਿਹਾ ਹੈ...\n\nਕਿਰਪਾ ਕਰਕੇ ਇੰਤਜ਼ਾਰ ਕਰੋ..." +queue_2 : "» Ǫᴜᴇᴜᴇ ਖਾਲੀ ਹੈ." +queue_3 : "» ਕਿਰਪਾ ਕਰਕੇ ਯੋਧਾਂ ਦੀ ਸੂਚੀ ਜਾਂਚਣ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ : ਇੱਥੇ" +queue_4 : "➲ ਕਤਾਰ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ #{0}\n\n‣ ਸਿਰਲੇਖ : {1}\n‣ ਅੰਤਰਾਲ : {2} ਮਿੰਟ\n‣ ਬੇਨਕਾਰਨ ਕੇਵਲ : {3}" +queue_5 : "ਇੱਥੇ ਪਲੇਅਲਿਸਟ ਵਿੱਚ ਸਿਰਫ ਇੱਕ ਕਤਾਰ ਵਾਲਾ ਗੀਤ ਹੈ.\n\nਇੱਕ ਹੋਰ ਗੀਤ ਸ਼ਾਮਲ ਕਰੋ ਸੂਚੀ ਜਾਂਚਣ ਲਈ." +queue_6 : "🕚 ਅੰਤਰਾਲ : ਅਣਜਾਣ ਸ਼੍ਰੇਣੀ ਦੀ ਅਵਧੀ\n\nਪੂਰੀ ਕਤਾਰ ਦੀ ਸੂਚੀ ਲੱਭਣ ਲਈ ਹੇਠਾਂ ਦਿੱਤੇ ਬਟਨ 'ਤੇ ਕਲਿਕ ਕਰੋ." +queue_7 : "\nਪੂਰੀ ਕਤਾਰ ਦੀ ਸੂਚੀ ਲੱਭਣ ਲਈ ਹੇਠਾਂ ਦਿੱਤੇ ਬਟਨ 'ਤੇ ਕਲਿਕ ਕਰੋ." +queue_8 : "{0} ਪਲੇਅਰ\n\n🎄 ਸਟ੍ਰੀਮਿੰਗ : {1}\n\n🔗 ਸਟ੍ਰੀਮ ਕਿਸਮ : {2}\n🥀 ਬੇਨਕਾਰਨ ਕੇਵਲ : {3}\n{4}" + +stream_1 : "➲ ਸਟਰਟੇਡ ਸਟਰੀਮਿੰਗ |\n\n‣ ਟਾਈਟਲ : {1}\n‣ ਮੁੱਦਤ : {2} ਮਿੰਟ\n‣ ਬੇਨਕਾਰਨ ਕੇਵਲ : {3}" +stream_2 : "➲ ਸਟਰਟੇਡ ਸਟਰੀਮਿੰਗ |\n\n‣ ਸਟਰੀਮ ਕਿਸਮ : ਲਾਈਵ ਸਟਰੀਮ [ਯੂਆਰਐਲ]\n‣ ਬੇਨਕਾਰਨ ਕੇਵਲ : {0}" + +CLOSE_BUTTON : "ਬੰਦ ਕਰੋ" +BACK_BUTTON : "ਵਾਪਸ" + +S_B_1 : "ਮੈਨੂੰ ਸ਼ਾਮਲ ਕਰੋ" +S_B_2 : "ਸਹਿਯੋਗ" +S_B_3 : "ਮੇਰੇ ਗਰੁੱਪ ਵਿੱਚ ਮੈਨੂੰ ਸ਼ਾਮਲ ਕਰੋ" +S_B_4 : "ਮਦਦ ਅਤੇ ਕਮਾਂਡਾਂ" +S_B_5 : "ਡੈਵੇਲਪਰ" +S_B_6 : "ਚੈਨਲ" +S_B_7 : "ਸਰੋਤ ਕੋਡ" +S_B_8 : "👀 ਯੂਟਿਊਬ 👀" +S_B_9 : "🥀 ਸਹਿਯੋਗ 🥀" + +H_B_1 : "ਐਡਮਿਨ" +H_B_2 : "ਆਥ" +H_B_3 : "ਬ੍ਰੋਡਕਾਸਟ" +H_B_4 : "ਬਲ-ਚੈਟ" +H_B_5 : "ਬਲ-ਯੂਜ਼ਰ" +H_B_6 : "ਸੀ-ਪਲੇ" +H_B_7 : "ਜੀ-ਬੈਨ" +H_B_8 : "ਲੂਪ" +H_B_9 : "ਮੈਂਟੀਨੈਂਸ" +H_B_10 : "ਪਿੰਗ" +H_B_11 : "ਪਲੇ" +H_B_12 : "ਸ਼ਫਲ" +H_B_13 : "ਸੀਕ" +H_B_14 : "ਗੀਤ" +H_B_15 : "ਸਪੀਡ" + +P_B_1 : "ਆਡੀਓ" +P_B_2 : "ਵੀਡੀਓ" +P_B_3 : "ਲਾਈਵ ਸਟ੍ਰੀਮ" +P_B_4 : "ਨਾਰਮਲ" + +ST_B_1 : "ਆਥ ਯੂਜ਼ਰ" +ST_B_2 : "ਪਲੇ ਮੋਡ" +ST_B_3 : "ਭਾਸ਼ਾ" +ST_B_4 : "ਵੋਟਿੰਗ ਮੋਡ" +ST_B_5 : "ਚਾਲੂ" +ST_B_6 : "ਬੰਦ" +ST_B_7 : "ਆਥ ਯੂਜ਼ਰ ➜" +ST_B_8 : "ਐਡਮਿਨ" +ST_B_9 : "ਹਰ ਕੋਈ" +ST_B_10 : "ਸਰਚ ਮੋਡ ➜" +ST_B_11 : "ਸਿੱਧਾ" +ST_B_12 : "ਇਨਲਾਇਨ" +ST_B_13 : "ਐਡਮਿਨ ਕੰਮਾਂਡ ➜" +ST_B_14 : "ਪਲੇ ਟਾਈਪ ➜" + +SA_B_1 : "ਸੰਪੂਰਨ ਸਥਿਤੀ" +SA_B_2 : "ਆਮ" +SA_B_3 : "ਸੰਪੂਰਨ" + +QU_B_1 : "ਕਤਾਰ" +QU_B_2 : " {0} —————————— {1}" + +sudo_1 : "» {0} ਪਹਿਲਾਂ ਹੀ ਸੁਡੋ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਹੈ." +sudo_2 : "» {0} ਨੂੰ ਸੁਡੋ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ." +sudo_3 : "» {0} ਸੁਡੋ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਹੈ." +sudo_4 : "» {0} ਨੂੰ ਸੁਡੋ ਯੂਜ਼ਰ ਸੂਚੀ ਤੋਂ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ." +sudo_5 : "🥀 ਮਾਲਕ :\n" +sudo_6 : "\n✨ ਸੁਡੋ ਯੂਜ਼ਰ :\n" +sudo_7 : "» ਕੋਈ ਸੁਡੋ ਯੂਜ਼ਰ ਨਹੀਂ ਮਿਲਿਆ." +sudo_8 : "ਅਸਫਲ." + +block_1 : "» {0} ਪਹਿਲਾਂ ਹੀ ਬਲਾਕ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਹੈ." +block_2 : "» {0} ਨੂੰ ਬਲਾਕ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ." +block_3 : "» {0} ਬਲਾਕ ਯੂਜ਼ਰ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਹੈ." +block_4 : "» {0} ਨੂੰ ਬਲਾਕ ਯੂਜ਼ਰ ਸੂਚੀ ਤੋਂ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ." +block_5 : "» ਕੋਈ ਬਲਾਕ ਯੂਜ਼ਰ ਨਹੀਂ ਮਿਲਿਆ." +block_6 : "» ਬਲਾਕ ਯੂਜ਼ਰ ਸੂਚੀ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..." +block_7 : "😫 ਬਲਾਕ ਯੂਜ਼ਰ :\n\n" + +black_1 : "ਉਦਾਹਰਨ:\n\n/blacklistchat [ਚੈਟ ਆਈਡੀ]" +black_2 : "» ਇਹ ਚੈਟ ਪਹਿਲਾਂ ਹੀ ਬਲੈਕਲਿਸਟ 'ਤੇ ਹੈ।" +black_3 : "» ਸਫਲਤਾਪੂਰਕ ਤੌਰ 'ਤੇ ਬਲੈਕਲਿਸਟ 'ਤੇ ਚੈਟਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ।" +black_4 : "ਉਦਾਹਰਨ:\n\n/whitelistchat [ਚੈਟ ਆਈਡੀ]" +black_5 : "» ਇਹ ਚੈਟ ਬਲੈਕਲਿਸਟ 'ਤੇ ਨਹੀਂ ਹੈ।" +black_6 : "» ਸਫਲਤਾਪੂਰਕ ਤੌਰ 'ਤੇ ਚੈਟ ਨੂੰ ਬਲੈਕਲਿਸਟ ਤੋਂ ਹਟਾ ਦਿੱਤਾ ਗਿਆ ਹੈ।" +black_7 : "» ਬਲੈਕਲਿਸਟ 'ਤੇ ਚੈਟਾਂ ਦੀ ਸੂਚੀ:\n\n" +black_8 : "» {0} 'ਤੇ ਕੋਈ ਬਲੈਕਲਿਸਟ 'ਤੇ ਨਹੀਂ ਹੈ।" +black_9 : "» ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ ਸੀ।" + +maint_1 : "ਉਦਾਹਰਨ:\n/maintenance [ਚਾਲੂ | ਬੰਦ]" +maint_2 : "» {0} ਮੈਂਟੀਨੈਂਸ ਮੋਡ ਚਾਲੂ ਹੋ ਗਿਆ ਹੈ." +maint_3 : "» {0} ਮੈਂਟੀਨੈਸ ਮੋਡ ਬੰਦ ਹੋ ਗਿਆ ਹੈ." +maint_4 : "» ਮੈਂਟੀਨੈਸ ਮੋਡ ਹੀ ਚਾਲੂ ਹੈ." +maint_5 : "» ਮੈਂਟੀਨੈਸ ਮੋਡ ਹੀ ਬੰਦ ਹੈ." + +log_1 : "ਉਦਾਹਰਨ:\n/logger [ਚਾਲੂ | ਬੰਦ]" +log_2 : "ਲਾਗਰ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਹੈ." +log_3 : "ਲਾਗਰ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ." + +broad_1 : "» ਬਰੋਡਕਾਸਟਿੰਗ ਸ਼ੁਰੂ ਹੋ ਗਈ ਹੈ..." +broad_2 : "ਉਦਾਹਰਨ:\n\n/broadcast [ਸੁਨੇਹਾ ਜਾਂ ਉਤਤਰ ਦੇਣ ਲਈ ਇੱਕ ਸੁਨੇਹਾ]" +broad_3 : "» {0} ਸੁਨੇਹਿਆਂ ਨੂੰ {1} ਪਿੰਸ ਨਾਲ ਚੈਟਾਂ ਵਿੱਚ ਬ੍ਰੋਡਕਾਸਟ ਕੀਤਾ ਗਿਆ ਹੈ." +broad_4 : "» {0} ਯੂਜ਼ਰਾਂ ਨੂੰ ਸੁਨੇਹਾ ਮੁੱਕਾਬਲਾ ਕੀਤਾ ਗਿਆ ਹੈ." +broad_5 : "» ਅਸਿਸਟੈਂਟ ਬਰੋਡਕਾਸਟ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ..." +broad_6 : "➻ ਅਸਿਸਟੈਂਟ ਬਰੋਡਕਾਸਟ :\n\n" +broad_7 : "↬ ਅਸਿਸਟੈਂਟ ਨੇ {0} ਬਰੋਡਕਾਸਟ ਕੀਤਾ {1} ਚੈਟਾਂ ਵਿੱਚ." +broad_8 : "» ਕਿਰਪਾ ਕਰਕੇ ਬਰੋਡਕਾਸਟ ਕਰਨ ਲਈ ਕੁਝ ਟੈਕਸਟ ਪ੍ਰਦਾਨ ਕਰੋ." + +server_1 : "» ਲੋਗਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਅਸਫਲ ਹੋਇਆ।" +server_2 : "ਕ੍ਰਿਪਾ ਕਰਕੇ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡੀ Heroku API ਕੀ ਅਤੇ ਐਪ ਨਾਮ ਠੀਕ ਤਰ੍ਹਾ ਸੰਰਚਿਤ ਹਨ।" +server_3 : "ਉਪਲਬਧ ਅੱਪਡੇਟਾਂ ਦੀ ਜਾਂਚ ਹੋ ਰਹੀ ਹੈ..." +server_4 : "Git ਕੰਮਾਂਡ ਦਾ ਤਰਾਂਗ ਹੋਇਆ ਹੈ।" +server_5 : "ਅਮਾਨਤ ਨਾਂ ਦੀ ਅਮਾਨਤ ਨਹੀਂ ਹੈ।" +server_6 : "» ਬੋਟ ਅੱਪ-ਟੁ-ਡੇਟ ਹੈ।" +server_7 : "» ਬੋਟ ਨੂੰ ਸਫਲਤਾਪੂਰਵਕ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ ਹੈ! ਹੁਣ ਕੁਝ ਮਿੰਟ ਬਾਅਦ ਬੋਟ ਨੂੰ ਮੁੜ-ਆਰੰਭ ਹੋਣ ਦੀ ਪ੍ਰਤੀਕਰਤਾ ਕਰੋ ਅਤੇ ਤਬਦੀਲੀਆਂ ਨੂੰ ਪੁੱਸ਼ ਕਰੋ!" +server_8 : "{0} ਮੁੜ-ਆਰੰਭ ਹੋ ਰਿਹਾ ਹੈ...\n\n15-20 ਸਕਿੰਟਾਂ ਬਾਅਦ ਤੁਸੀਂ ਮਾਜੂਦਾ ਖੇਡਣਾ ਸ਼ੁਰੂ ਕਰ ਸਕਦੇ ਹੋ।" +server_9 : "ਕੁਝ ਗਲਤੀ ਹੋਈ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਲੋਗ ਜਾਂਚੋ।" +server_10 : "ਕਿਸੇ ਕਾਰਣਵਾਂ, #ਅੱਪਡੇਟਰ 'ਤੇ ਇੱਕ ਅਸਮਾਨ ਵਾਰੀ ਆਯੋਜਨ ਹੋ ਗਿਆ ਹੈ: {0}" +server_11 : "» ਸਪੀਡਟੈਸਟ ਚੱਲ ਰਿਹਾ ਹੈ..." +server_12 : "⇆ ਡਾਊਨਲੋਡ ਸਪੀਡਟੈਸਟ ਚੱਲ ਰਿਹਾ ਹੈ..." +server_13 : "⇆ ਅੱਪਲੋਡ ਸਪੀਡਟੈਸਟ ਚੱਲ ਰਿਹਾ ਹੈ..." +server_14 : "↻ ਸਪੀਡਟੈਸਟ ਨਤੀਜਿਆਂ ਨੂੰ ਸਾਂਝਾ ਕਰ ਰਿਹਾ ਹੈ..." +server_15 : "✯ ਸਪੀਡਟੈਸਟ ਨਤੀਜੇ ✯\n\nਗਾਹਕ :\n» ਆਈਪੀ : {0}\n» ਦੇਸ਼ : {1}\n\nਸਰਵਰ :\n» ਨਾਮ : {2}\n» ਦੇਸ਼ : {3}, {4}\n» ਸਪਾਂਸਰ : {5}\n» ਲੈਟੈਂਸੀ : {6}\n» ਪਿੰਗ : {7}" + +gban_1 : "» ਕਿਉਂ ਤੁਸੀਂ ਆਪਣੇ ਆਪ ਨੂੰ gban ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?" +gban_2 : "» ਕਿਉਂ ਮੈਂ ਆਪਣੇ ਆਪ ਨੂੰ gban ਕਰਨਾ ਚਾਹੁੰਦਾ ਹਾਂ?" +gban_3 : "» ਤੁਸੀਂ ਮੇਰੀ sudoers ਨੂੰ gban ਨਹੀਂ ਕਰ ਸਕਦੇ." +gban_4 : "» {0} ਹੀ ਪਹਿਲਾਂ ਹੀ ਬੋਟ ਤੋਂ ਗਲੋਬਲ ਤੌਰ 'ਤੇ ਬੈਨ ਹੈ।" +gban_5 : "» {0} 'ਤੇ ਗਲੋਬਲ ਬੈਨ ਸ਼ੁਰੂ ਹੋ ਰਿਹਾ ਹੈ।\n\nਉਮੀਦਵਾਰ ਸਮਾਂ: {1}" +gban_6 : "{0} 'ਤੇ ਨਵਾਂ ਗਲੋਬਲ ਬੈਨ:\n\nਉੱਤਪਤਤ: {1} [{2}]\nਯੂਜ਼ਰ: {3}\nਯੂਜ਼ਰ ਆਈਡੀ: {4}\n\nਬੈਨ ਕਰਨ ਵਾਲਾ: {5}\nਚੈਟਸ: {6}" +gban_7 : "» {0} ਬੋਟ ਤੋਂ ਗਲੋਬਲ ਤੌਰ 'ਤੇ ਬੈਨ ਨਹੀਂ ਹੈ।" +gban_8 : "» {0} 'ਤੋਂ ਗਲੋਬਲ ਬੈਨ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n\nਉਮੀਦਵਾਰ ਸਮਾਂ: {1}" +gban_9 : "» {0} 'ਤੋਂ ਗਲੋਬਲ ਬੈਨ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਜਾ ਰਿਹਾ ਹੈ।\n\n{1} ਚੈਟਾਂ ਵਿਚ ਵਾਪਸ ਆ ਸਕਦਾ ਹੈ।" +gban_10 : "» ਕੋਈ ਵੀ ਬੋਟ ਤੋਂ ਗਲੋਬਲ ਤੌਰ 'ਤੇ ਬੈਨ ਨਹੀਂ ਹੈ।" +gban_11 : "» ਗਲੋਬਲ ਬੈਨ ਕਿਏ ਗਏ ਯੂਜ਼ਰਾਂ ਦੀ ਸੂਚੀ ਲਵੋ ਰਹੀ ਹੈ..." +gban_12 : "🙂 ਗਲੋਬਲ ਬੈਨ ਕੀਤੇ ਗਏ ਯੂਜ਼ਰ:\n\n"