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"