├── search ├── y └── __init__.py ├── Music ├── converter │ ├── y │ ├── __init__.py │ └── converter.py ├── helpers │ ├── y │ └── errors.py ├── Plugins │ ├── __main__.py │ ├── cleaners.py │ ├── ping.py │ ├── maintenance.py │ ├── speedtest.py │ ├── inlinesearch.py │ ├── restart.py │ ├── alive.py │ ├── allow.py │ ├── stats.py │ ├── lyrics.py │ ├── sudo.py │ ├── db.py │ ├── auth.py │ ├── playlist.py │ ├── start.py │ ├── gbanmusic.py │ ├── essentials.py │ ├── admins.py │ ├── stream.py │ ├── vadmins.py │ └── song.py ├── MusicUtilities │ ├── database │ │ ├── y │ │ ├── onoff.py │ │ ├── blacklistchat.py │ │ ├── functions.py │ │ ├── sudo.py │ │ ├── theme.py │ │ ├── gbanned.py │ │ ├── chats.py │ │ ├── changers.py │ │ ├── assistant.py │ │ ├── queue.py │ │ ├── playlist.py │ │ └── auth.py │ ├── helpers │ │ ├── __init__.py │ │ ├── ytdl.py │ │ ├── heroku.py │ │ ├── filters.py │ │ ├── time.py │ │ ├── formatter.py │ │ ├── logger.py │ │ ├── paste.py │ │ ├── administrator.py │ │ ├── tasks.py │ │ ├── decorators.py │ │ ├── gets.py │ │ ├── thumbnails.py │ │ ├── chattitle.py │ │ ├── admins.py │ │ └── inline.py │ └── tgcallsrun │ │ ├── __init__.py │ │ ├── downloader.py │ │ ├── convert.py │ │ ├── queues.py │ │ ├── video.py │ │ └── music.py ├── config.py ├── __main__.py └── __init__.py ├── cache ├── __init__.py ├── x.raw ├── IMG.png ├── Red.png ├── Audio.png ├── Black.png ├── Blue.png ├── Green.png ├── Grey.png ├── IMG_2.png ├── Purple.png ├── Lightred.png ├── Lightblue.png ├── finalfont.ttf ├── 20211024_083909.jpg ├── IMG_20211231_003953_527.jpg └── 398d955e9424deaf0f0c14da92ffc80b.jpg ├── Procfile ├── heroku.yml ├── .dockerignore ├── .gitignore ├── Dockerfile ├── requirements.txt ├── env ├── .github └── workflows │ ├── python-app.yml │ └── main.yml ├── app.json └── README.md /search/y: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Music/converter/y: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Music/helpers/y: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /cache/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /search/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Music/Plugins/__main__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/y: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python3 -m Music 2 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | -------------------------------------------------------------------------------- /cache/x.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/x.raw -------------------------------------------------------------------------------- /cache/IMG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/IMG.png -------------------------------------------------------------------------------- /cache/Red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Red.png -------------------------------------------------------------------------------- /cache/Audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Audio.png -------------------------------------------------------------------------------- /cache/Black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Black.png -------------------------------------------------------------------------------- /cache/Blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Blue.png -------------------------------------------------------------------------------- /cache/Green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Green.png -------------------------------------------------------------------------------- /cache/Grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Grey.png -------------------------------------------------------------------------------- /cache/IMG_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/IMG_2.png -------------------------------------------------------------------------------- /cache/Purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Purple.png -------------------------------------------------------------------------------- /cache/Lightred.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Lightred.png -------------------------------------------------------------------------------- /cache/Lightblue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/Lightblue.png -------------------------------------------------------------------------------- /cache/finalfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/finalfont.ttf -------------------------------------------------------------------------------- /cache/20211024_083909.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/20211024_083909.jpg -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .env 2 | *.log 3 | .git/ 4 | .idea/ 5 | downloads/ 6 | raw_files/ 7 | .gitignore 8 | __pycache__/ 9 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/__init__.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client 2 | from Music.config import API_ID, API_HASH 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.session 2 | *.session-journal 3 | .env 4 | __pycache__ 5 | .idea 6 | .vscode 7 | raw_files 8 | downloads 9 | -------------------------------------------------------------------------------- /cache/IMG_20211231_003953_527.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/IMG_20211231_003953_527.jpg -------------------------------------------------------------------------------- /Music/helpers/errors.py: -------------------------------------------------------------------------------- 1 | class DurationLimitError(Exception): 2 | pass 3 | 4 | 5 | class FFmpegReturnCodeError(Exception): 6 | pass 7 | -------------------------------------------------------------------------------- /cache/398d955e9424deaf0f0c14da92ffc80b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ridho17-ind/SkyzoMusicBot/HEAD/cache/398d955e9424deaf0f0c14da92ffc80b.jpg -------------------------------------------------------------------------------- /Music/converter/__init__.py: -------------------------------------------------------------------------------- 1 | from os import listdir 2 | from os import mkdir 3 | 4 | if 'raw_files' not in listdir(): 5 | mkdir('raw_files') 6 | 7 | from Music.converter.converter import convert 8 | 9 | __all__ = ['convert'] 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nikolaik/python-nodejs:python3.10-nodejs17 2 | RUN apt-get update && apt-get upgrade -y 3 | RUN apt-get install ffmpeg -y 4 | COPY . /app/ 5 | WORKDIR /app/ 6 | RUN pip3 install -U pip 7 | RUN pip3 install -U -r requirements.txt 8 | CMD python3 -m Music 9 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/ytdl.py: -------------------------------------------------------------------------------- 1 | from yt_dlp import YoutubeDL 2 | 3 | ytdl = YoutubeDL( 4 | { 5 | "format": "bestaudio/best", 6 | "geo-bypass": True, 7 | "nocheckcertificate": True, 8 | "outtmpl": "downloads/%(id)s.%(ext)s", 9 | } 10 | ) 11 | 12 | ytdl_opts = {"format" : "bestaudio", "quiet":True} 13 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/heroku.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | from Music.config import HEROKU_API_KEY 4 | 5 | 6 | async def is_heroku(): 7 | return "heroku" in socket.getfqdn() 8 | 9 | 10 | async def user_input(input): 11 | if " " in input or "\n" in input: 12 | return str(input.split(maxsplit=1)[1].strip()) 13 | return "" 14 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/__init__.py: -------------------------------------------------------------------------------- 1 | from os import listdir, mkdir 2 | from pyrogram import Client 3 | from Music import config 4 | from Music.MusicUtilities.tgcallsrun.queues import (clear, get, is_empty, put, task_done) 5 | from Music.MusicUtilities.tgcallsrun.downloader import download 6 | from Music.MusicUtilities.tgcallsrun.convert import convert 7 | from Music.MusicUtilities.tgcallsrun.music import run 8 | from Music.MusicUtilities.tgcallsrun.music import smexy as ASS_ACC 9 | smexy = 1 10 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/filters.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from typing import Union 3 | from pyrogram import filters 4 | from Music.config import COMMAND_PREFIXES 5 | 6 | other_filters = filters.group & ~ filters.edited & \ 7 | ~ filters.via_bot & ~ filters.forwarded 8 | other_filters2 = filters.private & ~ filters.edited \ 9 | & ~ filters.via_bot & ~ filters.forwarded 10 | 11 | 12 | def command(commands: Union[str, List[str]]): 13 | return filters.command(commands, COMMAND_PREFIXES) 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp 2 | aiofiles 3 | asyncio 4 | ffmpeg-python 5 | pillow 6 | pyrogram 7 | py-tgcalls 8 | pytube 9 | wget 10 | python-dotenv 11 | search-engine-parser 12 | tgcrypto 13 | youtube-search-python 14 | youtube-search 15 | speedtest-cli 16 | cryptography 17 | dnspython 18 | future 19 | googletrans 20 | hurry.filesize 21 | motor 22 | psutil 23 | pykeyboard 24 | pyromod 25 | requests 26 | speedtest-cli 27 | uvloop 28 | git+https://github.com/Sorrybabe/downloader 29 | telegraph 30 | hachoir 31 | lyricsgenius 32 | httpx>=0.14.2 33 | gitpython 34 | rich 35 | heroku3 36 | -------------------------------------------------------------------------------- /Music/Plugins/cleaners.py: -------------------------------------------------------------------------------- 1 | from Music import app, SUDOERS 2 | from pyrogram import filters, Client 3 | from pyrogram.types import Message 4 | from Music.MusicUtilities.helpers.filters import command 5 | import subprocess 6 | import shutil 7 | import os 8 | 9 | 10 | @Client.on_message(command("clean") & filters.user(SUDOERS)) 11 | async def hsjdjs(_, message: Message): 12 | dir = 'downloads' 13 | dir1 = 'search' 14 | shutil.rmtree(dir) 15 | shutil.rmtree(dir1) 16 | os.mkdir(dir) 17 | os.mkdir(dir1) 18 | await message.reply_text("Successfully cleaned all **temp** dir(s)!") 19 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/onoff.py: -------------------------------------------------------------------------------- 1 | from Music import db 2 | from typing import Dict, List, Union 3 | 4 | onoffdb = db.onoffper 5 | 6 | async def is_on_off(on_off: int) -> bool: 7 | onoff = await onoffdb.find_one({"on_off": on_off}) 8 | if not onoff: 9 | return False 10 | return True 11 | 12 | async def add_on(on_off: int): 13 | is_on = await is_on_off(on_off) 14 | if is_on: 15 | return 16 | return await onoffdb.insert_one({"on_off": on_off}) 17 | 18 | async def add_off(on_off: int): 19 | is_off = await is_on_off(on_off) 20 | if not is_off: 21 | return 22 | return await onoffdb.delete_one({"on_off": on_off}) 23 | -------------------------------------------------------------------------------- /env: -------------------------------------------------------------------------------- 1 | SESSION_NAME=BQAbtm-WzwKEogKQaWmrDVB_67ER22G-Uqr7JAcdfxOGUDUxKpMxjuz_HtOPW-D71YaaQs8U91XF4q6JbTuip5QFgQvdAUR2G5irlOPqY6c3YCgBkfxDB-KxKRAPQyw3QavYaHAArORofm5pS6S1iDdbtBw_e0VHpnZ8Wcr6wIMdUpCPeC6kjvX2Qarrk8_AKF2LE1sPYUxKcfukYhPOny59oeEgyMg_I_jITdoxk0iJCbz5v92CmGFN2oZE3i7VS0oZZEZzRy9ZwWQhY5gYbBuKPmi6Hbx5j5jntE8hKiR1enF3K35J1FnLZmNGx8fO5Clm6oBz1jD6uc62ob-T5rYwTtF0xAA 2 | BOT_TOKEN=1902730189:AAESIPWI2T5au2DemAFy2jjRyiNeTDrdd44 3 | API_ID=7186601 4 | API_HASH=5127bf64f4d0d41a8aaffb8daba414b0 5 | SUDO_USERS=1782996378 6 | OWNER_ID=1782996378 7 | DURATION_LIMIT=540000 8 | MONGO_DB_URI=mongodb+srv://userbot:userbot@music1.p1vej.mongodb.net/test?retryWrites=true&w=majority 9 | LOG_GROUP_ID=-1001429892362 10 | ASS_ID=1446583656 11 | GROUP=FlicksRobotSupport 12 | CHANNEL=SadRoomsInfo 13 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/time.py: -------------------------------------------------------------------------------- 1 | def get_readable_time(seconds: int) -> str: 2 | count = 0 3 | ping_time = "" 4 | time_list = [] 5 | time_suffix_list = ["s", "m", "h", "days"] 6 | while count < 4: 7 | count += 1 8 | if count < 3: 9 | remainder, result = divmod(seconds, 60) 10 | else: 11 | remainder, result = divmod(seconds, 24) 12 | if seconds == 0 and remainder == 0: 13 | break 14 | time_list.append(int(result)) 15 | seconds = int(remainder) 16 | for i in range(len(time_list)): 17 | time_list[i] = str(time_list[i]) + time_suffix_list[i] 18 | if len(time_list) == 4: 19 | ping_time += time_list.pop() + ", " 20 | time_list.reverse() 21 | ping_time += ":".join(time_list) 22 | return ping_time 23 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/blacklistchat.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | from Music import db 3 | 4 | blacklist_chatdb = db.blacklistChat 5 | 6 | async def blacklisted_chats() -> list: 7 | chats = blacklist_chatdb.find({"chat_id": {"$lt": 0}}) 8 | return [chat["chat_id"] for chat in await chats.to_list(length=1000000000)] 9 | 10 | 11 | async def blacklist_chat(chat_id: int) -> bool: 12 | if not await blacklist_chatdb.find_one({"chat_id": chat_id}): 13 | await blacklist_chatdb.insert_one({"chat_id": chat_id}) 14 | return True 15 | return False 16 | 17 | 18 | async def whitelist_chat(chat_id: int) -> bool: 19 | if await blacklist_chatdb.find_one({"chat_id": chat_id}): 20 | await blacklist_chatdb.delete_one({"chat_id": chat_id}) 21 | return True 22 | return False 23 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/functions.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | from Music import db 3 | 4 | 5 | restart_stagedb = db.restart_stage 6 | 7 | 8 | 9 | async def start_restart_stage(chat_id: int, message_id: int): 10 | await restart_stagedb.update_one( 11 | {"something": "something"}, 12 | { 13 | "$set": { 14 | "chat_id": chat_id, 15 | "message_id": message_id, 16 | } 17 | }, 18 | upsert=True, 19 | ) 20 | 21 | 22 | async def clean_restart_stage() -> dict: 23 | data = await restart_stagedb.find_one({"something": "something"}) 24 | if not data: 25 | return {} 26 | await restart_stagedb.delete_one({"something": "something"}) 27 | return {"chat_id": data["chat_id"], "message_id": data["message_id"]} 28 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/sudo.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | from Music import db 3 | 4 | sudoersdb = db.sudoers 5 | 6 | async def get_sudoers() -> list: 7 | sudoers = await sudoersdb.find_one({"sudo": "sudo"}) 8 | if not sudoers: 9 | return [] 10 | return sudoers["sudoers"] 11 | 12 | 13 | async def add_sudo(user_id: int) -> bool: 14 | sudoers = await get_sudoers() 15 | sudoers.append(user_id) 16 | await sudoersdb.update_one( 17 | {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True 18 | ) 19 | return True 20 | 21 | 22 | async def remove_sudo(user_id: int) -> bool: 23 | sudoers = await get_sudoers() 24 | sudoers.remove(user_id) 25 | await sudoersdb.update_one( 26 | {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True 27 | ) 28 | return True 29 | -------------------------------------------------------------------------------- /Music/converter/converter.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from os import path 3 | 4 | from Music.helpers.errors import FFmpegReturnCodeError 5 | 6 | 7 | async def convert(file_path: str) -> str: 8 | out = path.join('raw_files', path.basename(file_path + '.raw')) 9 | if path.isfile(out): 10 | return out 11 | proc = await asyncio.create_subprocess_shell( 12 | cmd=( 13 | 'ffmpeg ' 14 | '-y -i ' 15 | f'{file_path} ' 16 | '-f s16le ' 17 | '-ac 2 ' 18 | '-ar 48000 ' 19 | '-acodec pcm_s16le ' 20 | f'{out}' 21 | ), 22 | stdin=asyncio.subprocess.PIPE, 23 | stderr=asyncio.subprocess.PIPE, 24 | ) 25 | await proc.communicate() 26 | if proc.returncode != 0: 27 | raise FFmpegReturnCodeError('FFmpeg did not return 0') 28 | return out 29 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/theme.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Union, List 2 | from Music import db 3 | 4 | notesdb = db.notes 5 | 6 | async def _get_theme(chat_id: int) -> Dict[str, int]: 7 | _notes = await notesdb.find_one({"chat_id": chat_id}) 8 | if not _notes: 9 | return {} 10 | return _notes["notes"] 11 | 12 | async def get_theme(chat_id: int, name: str) -> Union[bool, dict]: 13 | name = name.lower().strip() 14 | _notes = await _get_theme(chat_id) 15 | if name in _notes: 16 | return _notes[name] 17 | else: 18 | return False 19 | 20 | 21 | async def save_theme(chat_id: int, name: str, note: dict): 22 | name = name.lower().strip() 23 | _notes = await _get_theme(chat_id) 24 | _notes[name] = note 25 | await notesdb.update_one( 26 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True 27 | ) 28 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/gbanned.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | from Music import db 3 | 4 | gbansdb = db.gban 5 | 6 | 7 | async def get_gbans_count() -> int: 8 | users = gbansdb.find({"user_id": {"$gt": 0}}) 9 | users = await users.to_list(length=100000) 10 | return len(users) 11 | 12 | 13 | async def is_gbanned_user(user_id: int) -> bool: 14 | user = await gbansdb.find_one({"user_id": user_id}) 15 | if not user: 16 | return False 17 | return True 18 | 19 | 20 | async def add_gban_user(user_id: int): 21 | is_gbanned = await is_gbanned_user(user_id) 22 | if is_gbanned: 23 | return 24 | return await gbansdb.insert_one({"user_id": user_id}) 25 | 26 | 27 | async def remove_gban_user(user_id: int): 28 | is_gbanned = await is_gbanned_user(user_id) 29 | if not is_gbanned: 30 | return 31 | return await gbansdb.delete_one({"user_id": user_id}) 32 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/downloader.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | import yt_dlp 3 | from yt_dlp.utils import DownloadError 4 | 5 | ytdl = yt_dlp.YoutubeDL( 6 | { 7 | "outtmpl": "downloads/%(id)s.%(ext)s", 8 | "format": "bestaudio/best", 9 | "geo_bypass": True, 10 | "nocheckcertificate": True, 11 | } 12 | ) 13 | 14 | 15 | def download(url: str, my_hook) -> str: 16 | ydl_optssx = { 17 | 'format' : 'bestaudio/best', 18 | "outtmpl": "downloads/%(id)s.%(ext)s", 19 | "geo_bypass": True, 20 | "nocheckcertificate": True, 21 | 'quiet': True, 22 | 'no_warnings': True, 23 | } 24 | info = ytdl.extract_info(url, False) 25 | try: 26 | x = yt_dlp.YoutubeDL(ydl_optssx) 27 | x.add_progress_hook(my_hook) 28 | dloader = x.download([url]) 29 | except Exception as y_e: 30 | return print(y_e) 31 | else: 32 | dloader 33 | xyz = path.join("downloads", f"{info['id']}.{info['ext']}") 34 | return xyz 35 | -------------------------------------------------------------------------------- /Music/config.py: -------------------------------------------------------------------------------- 1 | ##Config 2 | 3 | from os import getenv 4 | from dotenv import load_dotenv 5 | 6 | load_dotenv() 7 | SESSION_NAME = getenv('SESSION_NAME', 'session') 8 | BOT_TOKEN = getenv('BOT_TOKEN') 9 | API_ID = int(getenv('API_ID', "10892147")) 10 | API_HASH = getenv('API_HASH') 11 | DURATION_LIMIT = int(getenv('DURATION_LIMIT', '30')) 12 | COMMAND_PREFIXES = list(getenv('COMMAND_PREFIXES', '/ . , : ; !').split()) 13 | MONGO_DB_URI = getenv("MONGO_DB_URI") 14 | SUDO_USERS = list(map(int, getenv('SUDO_USERS', '').split())) 15 | LOG_GROUP_ID = int(getenv("LOG_GROUP_ID", '-1001288822269')) 16 | ASS_ID = int(getenv("ASS_ID", '2130437611')) 17 | OWNER_ID = list(map(int, getenv('OWNER_ID', '').split())) 18 | BOT_IMG = getenv("BOT_IMG") 19 | GROUP = getenv("GROUP", None) 20 | CHANNEL = getenv("CHANNEL", None) 21 | UPSTREAM_BRANCH = getenv("UPSTREAM_BRANCH", "main") 22 | UPSTREAM_REPO = getenv("UPSTREAM_REPO", "https://github.com/ridho17-ind/SkyzoMusicBot") 23 | HEROKU_API_KEY = getenv("HEROKU_API_KEY") 24 | HEROKU_APP_NAME = getenv("HEROKU_APP_NAME") 25 | -------------------------------------------------------------------------------- /.github/workflows/python-app.yml: -------------------------------------------------------------------------------- 1 | name: FailCheck 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | max-parallel: 5 11 | matrix: 12 | python-version: [3.9.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up Python ${{ matrix.python-version }} 17 | uses: actions/setup-python@v2.2.2 18 | with: 19 | python-version: ${{ matrix.python-version }} 20 | - name: Install dependencies 21 | run: | 22 | sudo apt-get install libpq-dev 23 | python -m pip install --upgrade pip 24 | pip install -r requirements.txt 25 | pip install flake8 flake8-print flake8-quotes 26 | - name: Check for showstoppers 27 | run: | 28 | flake8 . --count --select=E999 --show-source --statistics 29 | shellcheck: 30 | 31 | runs-on: ubuntu-latest 32 | 33 | steps: 34 | - uses: actions/checkout@v1 35 | - name: Check for install script errors 36 | uses: ludeeus/action-shellcheck@0.1.0 37 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/formatter.py: -------------------------------------------------------------------------------- 1 | def get_readable_time(seconds: int) -> str: 2 | count = 0 3 | ping_time = "" 4 | time_list = [] 5 | time_suffix_list = ["s", "m", "h", "days"] 6 | while count < 4: 7 | count += 1 8 | if count < 3: 9 | remainder, result = divmod(seconds, 60) 10 | else: 11 | remainder, result = divmod(seconds, 24) 12 | if seconds == 0 and remainder == 0: 13 | break 14 | time_list.append(int(result)) 15 | seconds = int(remainder) 16 | for i in range(len(time_list)): 17 | time_list[i] = str(time_list[i]) + time_suffix_list[i] 18 | if len(time_list) == 4: 19 | ping_time += time_list.pop() + ", " 20 | time_list.reverse() 21 | ping_time += ":".join(time_list) 22 | return ping_time 23 | 24 | 25 | # Convert seconds to mm:ss 26 | async def convert_seconds_to_minutes(seconds: int): 27 | seconds = int(seconds) 28 | seconds = seconds % (24 * 3600) 29 | seconds %= 3600 30 | minutes = seconds // 60 31 | seconds %= 60 32 | return "%02d:%02d" % (minutes, seconds) 33 | -------------------------------------------------------------------------------- /Music/Plugins/ping.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters, Client 2 | from pyrogram.types import Message 3 | from Music import app, SUDOERS, Music_START_TIME 4 | import os 5 | import psutil 6 | import time 7 | from datetime import datetime 8 | from Music.MusicUtilities.helpers.time import get_readable_time 9 | 10 | async def bot_sys_stats(): 11 | bot_uptime = int(time.time() - Music_START_TIME) 12 | cpu = psutil.cpu_percent(interval=0.5) 13 | mem = psutil.virtual_memory().percent 14 | disk = psutil.disk_usage("/").percent 15 | stats = f''' 16 | Uptime: {get_readable_time((bot_uptime))} 17 | CPU: {cpu}% 18 | RAM: {mem}% 19 | Disk: {disk}%''' 20 | return stats 21 | 22 | 23 | @app.on_message(filters.command(["pingmusic", "ping@Tg_Vc_00_Bot"])) 24 | async def ping(_, message): 25 | uptime = await bot_sys_stats() 26 | start = datetime.now() 27 | response = await message.reply_photo( 28 | photo="cache/Query.png", 29 | caption=">> Pong!" 30 | ) 31 | end = datetime.now() 32 | resp = (end - start).microseconds / 1000 33 | await response.edit_text(f"**Pong!**\n`⚡{resp} ms`\n\nMusic System Stats:{uptime}") 34 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/convert.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from os import path 3 | 4 | class FFmpegReturnCodeError(Exception): 5 | pass 6 | 7 | async def convert(file_path: str) -> str: 8 | out = path.basename(file_path) 9 | out = out.split(".") 10 | out[-1] = "raw" 11 | out = ".".join(out) 12 | out = path.basename(out) 13 | out = path.join("raw_files", out) 14 | 15 | if path.isfile(out): 16 | return out 17 | 18 | try: 19 | proc = await asyncio.create_subprocess_shell( 20 | cmd=( 21 | "ffmpeg " 22 | "-y -i " 23 | f"{file_path} " 24 | "-f s16le " 25 | "-ac 1 " 26 | "-ar 48000 " 27 | "-acodec pcm_s16le " 28 | f"{out}" 29 | ), 30 | stdin=asyncio.subprocess.PIPE, 31 | stderr=asyncio.subprocess.PIPE, 32 | ) 33 | 34 | await proc.communicate() 35 | 36 | if proc.returncode != 0: 37 | raise FFmpegReturnCodeError("FFmpeg did not return 0") 38 | 39 | return out 40 | except: 41 | raise FFmpegReturnCodeError("FFmpeg did not return 0") 42 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/logger.py: -------------------------------------------------------------------------------- 1 | # Skyzo Music Bot 2 | # By Kenkan And Skyzo 3 | 4 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 5 | from Music.config import LOG_GROUP_ID 6 | from Music import app 7 | 8 | 9 | async def LOG_CHAT(message, what): 10 | if message.chat.username: 11 | chatusername = (f"@{message.chat.username}") 12 | else: 13 | chatusername = ("Private Group") 14 | user_id = message.from_user.id 15 | user_name = message.from_user.first_name 16 | mention = "["+user_name+"](tg://user?id="+str(user_id)+")" 17 | logger_text = f""" 18 | **🚀 New {what}** 19 | 20 | **• Chat:** {message.chat.title} 21 | **• Chat ID:** [`{message.chat.id}`] 22 | **• User:** {mention} 23 | **• Username:** @{message.from_user.username} 24 | **• User ID:** `{message.from_user.id}` 25 | **• Chat Link:** {chatusername} 26 | **• Query:** {message.text}""" 27 | await app.send_message(LOG_GROUP_ID, 28 | text = f"{logger_text}", 29 | reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="ᴠɪᴇᴡs​​", url=f"https://t.me/{message.from_user.username}")]]), 30 | disable_web_page_preview=True, 31 | ) 32 | 33 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/paste.py: -------------------------------------------------------------------------------- 1 | import socket 2 | from asyncio import get_running_loop 3 | from functools import partial 4 | from Music import aiohttpsession as session 5 | 6 | 7 | def _netcat(host, port, content): 8 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 9 | s.connect((host, port)) 10 | s.sendall(content.encode()) 11 | s.shutdown(socket.SHUT_WR) 12 | while True: 13 | data = s.recv(4096).decode("utf-8").strip("\n\x00") 14 | if not data: 15 | break 16 | return data 17 | s.close() 18 | 19 | 20 | async def paste(content): 21 | loop = get_running_loop() 22 | link = await loop.run_in_executor( 23 | None, partial(_netcat, "ezup.dev", 9999, content) 24 | ) 25 | return link 26 | 27 | async def isPreviewUp(preview: str) -> bool: 28 | for _ in range(7): 29 | try: 30 | async with session.head(preview, timeout=2) as resp: 31 | status, size = resp.status, resp.content_length 32 | except asyncio.exceptions.TimeoutError: 33 | return False 34 | if status == 404 or (status == 200 and size == 0): 35 | await asyncio.sleep(0.4) 36 | else: 37 | return True if status == 200 else False 38 | return False 39 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/administrator.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden 4 | from pyrogram.types import Message 5 | from Music import app, SUDOERS 6 | from Music.Plugins.admins import member_permissions 7 | 8 | 9 | async def authorised(message): 10 | chatID = message.chat.id 11 | return 0 12 | 13 | 14 | async def unauthorised(message: Message): 15 | chatID = message.chat.id 16 | text = ( 17 | "You don't have the required permission to perform this action." 18 | + f"\n__REQUIRES ADMIN WITH MANAGE VC RIGHTS__" 19 | ) 20 | try: 21 | await message.reply_text(text) 22 | except ChatWriteForbidden: 23 | await app.leave_chat(chatID) 24 | return 1 25 | 26 | async def adminsOnly(permission, message): 27 | chatID = message.chat.id 28 | if not message.from_user: 29 | if message.sender_chat: 30 | return await authorised(message) 31 | return await unauthorised(message) 32 | userID = message.from_user.id 33 | permissions = await member_permissions(chatID, userID) 34 | if userID not in SUDOERS and permission not in permissions: 35 | return await unauthorised(message) 36 | return await authorised( message) 37 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the Flicks-Userbot branch 8 | push: 9 | branches: [ main] 10 | pull_request: 11 | branches: [ main] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | 28 | # Runs a single command using the runners shell 29 | - name: Run a one-line script 30 | run: echo Hello, world! 31 | 32 | # Runs a set of commands using the runners shell 33 | - name: Run a multi-line script 34 | run: | 35 | echo Add other actions to build, 36 | echo test, and deploy your project. 37 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/chats.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Union, List 2 | from Music import db 3 | 4 | chatsdb = db.chats 5 | 6 | async def get_served_chats() -> list: 7 | chats = chatsdb.find({"chat_id": {'$lt': 0}}) 8 | if not chats: 9 | return [] 10 | chats_list = [] 11 | for chat in await chats.to_list(length=1000000000): 12 | chats_list.append(chat) 13 | return chats_list 14 | 15 | async def is_served_chat(chat_id: int) -> bool: 16 | chat = await chatsdb.find_one({"chat_id": chat_id}) 17 | if not chat: 18 | return False 19 | return True 20 | 21 | async def add_served_chat(chat_id: int): 22 | is_served = await is_served_chat(chat_id) 23 | if is_served: 24 | return 25 | return await chatsdb.insert_one({"chat_id": chat_id}) 26 | 27 | async def get_served_chats() -> list: 28 | chats = chatsdb.find({"chat_id": {"$lt": 0}}) 29 | if not chats: 30 | return [] 31 | chats_list = [] 32 | for chat in await chats.to_list(length=1000000000): 33 | chats_list.append(chat) 34 | return chats_list 35 | 36 | async def remove_served_chat(chat_id: int): 37 | is_served = await is_served_chat(chat_id) 38 | if not is_served: 39 | return 40 | return await chatsdb.delete_one({"chat_id": chat_id}) 41 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/changers.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | 3 | 4 | async def int_to_alpha(user_id: int) -> str: 5 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] 6 | text = "" 7 | user_id = str(user_id) 8 | for i in user_id: 9 | text += alphabet[int(i)] 10 | return text 11 | 12 | 13 | async def alpha_to_int(user_id_alphabet: str) -> int: 14 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] 15 | user_id = "" 16 | for i in user_id_alphabet: 17 | index = alphabet.index(i) 18 | user_id += str(index) 19 | user_id = int(user_id) 20 | return user_id 21 | 22 | 23 | def time_to_seconds(time): 24 | stringt = str(time) 25 | return sum( 26 | int(x) * 60 ** i for i, x in enumerate(reversed(stringt.split(":"))) 27 | ) 28 | 29 | 30 | def seconds_to_min(seconds): 31 | if seconds is not None: 32 | seconds = int(seconds) 33 | d, h, m, s = ( 34 | seconds // (3600 * 24), 35 | seconds // 3600 % 24, 36 | seconds % 3600 // 60, 37 | seconds % 3600 % 60, 38 | ) 39 | if d > 0: 40 | return "{:02d}:{:02d}:{:02d}:{:02d}".format(d, h, m, s) 41 | elif h > 0: 42 | return "{:02d}:{:02d}:{:02d}".format(h, m, s) 43 | elif m > 0: 44 | return "{:02d}:{:02d}".format(m, s) 45 | elif s > 0: 46 | return "00:{:02d}".format(s) 47 | return "-" 48 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/assistant.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Union, List 2 | from Music import db 3 | 4 | assisdb = db.assis 5 | 6 | async def get_assistant_count() -> dict: 7 | chats = assisdb.find({"chat_id": {"$lt": 0}}) 8 | if not chats: 9 | return {} 10 | chats_count = 0 11 | notes_count = 0 12 | for chat in await chats.to_list(length=1000000000): 13 | notes_name = await get_as_names(chat["chat_id"]) 14 | notes_count += len(notes_name) 15 | chats_count += 1 16 | return {"chats_count": chats_count, "notes_count": notes_count} 17 | 18 | async def get_as_names(chat_id: int) -> List[str]: 19 | _notes = [] 20 | for note in await _get_assistant(chat_id): 21 | _notes.append(note) 22 | return _notes 23 | 24 | async def _get_assistant(chat_id: int) -> Dict[str, int]: 25 | _notes = await assisdb.find_one({"chat_id": chat_id}) 26 | if not _notes: 27 | return {} 28 | return _notes["notes"] 29 | 30 | async def get_assistant(chat_id: int, name: str) -> Union[bool, dict]: 31 | name = name.lower().strip() 32 | _notes = await _get_assistant(chat_id) 33 | if name in _notes: 34 | return _notes[name] 35 | else: 36 | return False 37 | 38 | async def save_assistant(chat_id: int, name: str, note: dict): 39 | name = name.lower().strip() 40 | _notes = await _get_assistant(chat_id) 41 | _notes[name] = note 42 | await assisdb.update_one( 43 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True 44 | ) 45 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/queue.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | from Music import db 3 | 4 | pytgdb = db.pytg 5 | admindb = db.admin 6 | 7 | ## Queue Chats 8 | 9 | async def get_active_chats() -> list: 10 | chats = pytgdb.find({"chat_id": {"$lt": 0}}) 11 | if not chats: 12 | return [] 13 | chats_list = [] 14 | for chat in await chats.to_list(length=1000000000): 15 | chats_list.append(chat) 16 | return chats_list 17 | 18 | async def is_active_chat(chat_id: int) -> bool: 19 | chat = await pytgdb.find_one({"chat_id": chat_id}) 20 | if not chat: 21 | return False 22 | return True 23 | 24 | async def add_active_chat(chat_id: int): 25 | is_served = await is_active_chat(chat_id) 26 | if is_served: 27 | return 28 | return await pytgdb.insert_one({"chat_id": chat_id}) 29 | 30 | async def remove_active_chat(chat_id: int): 31 | is_served = await is_active_chat(chat_id) 32 | if not is_served: 33 | return 34 | return await pytgdb.delete_one({"chat_id": chat_id}) 35 | 36 | 37 | ## Music Playing or Paused 38 | 39 | async def is_music_playing(chat_id: int) -> bool: 40 | chat = await admindb.find_one({"chat_id_toggle": chat_id}) 41 | if not chat: 42 | return True 43 | return False 44 | 45 | async def music_on(chat_id: int): 46 | is_karma = await is_music_playing(chat_id) 47 | if is_karma: 48 | return 49 | return await admindb.delete_one({"chat_id_toggle": chat_id}) 50 | 51 | async def music_off(chat_id: int): 52 | is_karma = await is_music_playing(chat_id) 53 | if not is_karma: 54 | return 55 | return await admindb.insert_one({"chat_id_toggle": chat_id}) 56 | -------------------------------------------------------------------------------- /Music/Plugins/maintenance.py: -------------------------------------------------------------------------------- 1 | from Music import app, SUDOERS 2 | from pyrogram import filters, Client 3 | from pyrogram.types import Message 4 | from Music.MusicUtilities.database.onoff import (is_on_off, add_on, add_off) 5 | from Music.MusicUtilities.helpers.filters import command 6 | 7 | 8 | @Client.on_message(command("Musicp") & filters.user(SUDOERS)) 9 | async def smex(_, message): 10 | usage = "**Usage:**\n/Musicp [enable|disable]" 11 | if len(message.command) != 2: 12 | return await message.reply_text(usage) 13 | chat_id = message.chat.id 14 | state = message.text.split(None, 1)[1].strip() 15 | state = state.lower() 16 | if state == "enable": 17 | user_id = 1 18 | await add_on(user_id) 19 | await message.reply_text("Music Enabled for Maintenance") 20 | elif state == "disable": 21 | user_id = 1 22 | await add_off(user_id) 23 | await message.reply_text("Maintenance Mode Disabled") 24 | else: 25 | await message.reply_text(usage) 26 | 27 | 28 | @Client.on_message(command("stp") & filters.user(SUDOERS)) 29 | async def sls_skfs(_, message): 30 | usage = "**Usage:**\n/st [enable|disable]" 31 | if len(message.command) != 2: 32 | return await message.reply_text(usage) 33 | chat_id = message.chat.id 34 | state = message.text.split(None, 1)[1].strip() 35 | state = state.lower() 36 | if state == "enable": 37 | user_id = 2 38 | await add_on(user_id) 39 | await message.reply_text("Speedtest Enabled") 40 | elif state == "disable": 41 | user_id = 2 42 | await add_off(user_id) 43 | await message.reply_text("Speedtest Disabled") 44 | else: 45 | await message.reply_text(usage) 46 | -------------------------------------------------------------------------------- /Music/Plugins/speedtest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import speedtest 3 | import wget 4 | from Music.MusicUtilities.helpers.gets import bytes 5 | from Music import app, SUDOERS, BOT_ID 6 | from pyrogram import filters, Client 7 | from Music.MusicUtilities.database.onoff import (is_on_off, add_on, add_off) 8 | from pyrogram.types import Message 9 | 10 | @app.on_message(filters.command("speedtest") & ~filters.edited) 11 | async def gstats(_, message): 12 | userid = message.from_user.id 13 | if await is_on_off(2): 14 | if userid in SUDOERS: 15 | pass 16 | else: 17 | return 18 | m = await message.reply_text("Running Music's speed test") 19 | try: 20 | test = speedtest.Speedtest() 21 | test.get_best_server() 22 | m = await m.edit("Running Download SpeedTest") 23 | test.download() 24 | m = await m.edit("Running Upload SpeedTest") 25 | test.upload() 26 | test.results.share() 27 | result = test.results.dict() 28 | except Exception as e: 29 | await message.err(text=e) 30 | return 31 | m = await m.edit("Sharing SpeedTest Results") 32 | path = wget.download(result["share"]) 33 | output = f"""**Speedtest Results** 34 | 35 | **Client:** 36 | 37 | **__ISP:__** {result['client']['isp']} 38 | **__Country:__** {result['client']['country']} 39 | 40 | **Server:** 41 | 42 | **__Name:__** {result['server']['name']} 43 | **__Country:__** {result['server']['country']}, {result['server']['cc']} 44 | **__Sponsor:__** {result['server']['sponsor']} 45 | **__Latency:__** {result['server']['latency']} 46 | 47 | **__Ping:__** {result['ping']}""" 48 | msg = await app.send_photo( 49 | chat_id=message.chat.id, photo=path, caption=output 50 | ) 51 | os.remove(path) 52 | await m.delete() 53 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/tasks.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from asyncio import Lock, create_task 3 | from time import time 4 | 5 | from pyrogram import filters 6 | from pyrogram.types import Message 7 | 8 | tasks = {} 9 | TASKS_LOCK = Lock() 10 | arrow = lambda x: (x.text if x else "") + "\n`→`" 11 | 12 | import shlex 13 | from typing import Tuple 14 | 15 | 16 | async def install_requirements(cmd: str) -> Tuple[str, str, int, int]: 17 | args = shlex.split(cmd) 18 | process = await asyncio.create_subprocess_exec( 19 | *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE 20 | ) 21 | stdout, stderr = await process.communicate() 22 | return ( 23 | stdout.decode("utf-8", "replace").strip(), 24 | stderr.decode("utf-8", "replace").strip(), 25 | process.returncode, 26 | process.pid, 27 | ) 28 | 29 | 30 | def all_tasks(): 31 | return tasks 32 | 33 | 34 | async def add_task( 35 | taskFunc, 36 | task_name, 37 | *args, 38 | **kwargs, 39 | ): 40 | 41 | async with TASKS_LOCK: 42 | global tasks 43 | 44 | task_id = (list(tasks.keys())[-1] + 1) if tasks else 0 45 | 46 | task = create_task( 47 | taskFunc(*args, **kwargs), 48 | name=task_name, 49 | ) 50 | tasks[task_id] = task, int(time()) 51 | return task, task_id 52 | 53 | 54 | async def rm_task(task_id=None): 55 | global tasks 56 | 57 | async with TASKS_LOCK: 58 | for key, value in list(tasks.items()): 59 | if value[0].done() or value[0].cancelled(): 60 | del tasks[key] 61 | 62 | if (task_id is not None) and (task_id in tasks): 63 | task = tasks[task_id][0] 64 | 65 | if not task.done(): 66 | task.cancel() 67 | 68 | del tasks[task_id] 69 | -------------------------------------------------------------------------------- /Music/Plugins/inlinesearch.py: -------------------------------------------------------------------------------- 1 | # Ported by Fariz 2 | 3 | from pyrogram import errors 4 | from pyrogram.types import ( 5 | InlineQuery, 6 | InlineQueryResultArticle, 7 | InputTextMessageContent, 8 | ) 9 | from youtubesearchpython import VideosSearch 10 | from Music import app 11 | from pyrogram import Client 12 | 13 | @app.on_inline_query() 14 | async def inline(client: Client, query: InlineQuery): 15 | answers = [] 16 | search_query = query.query.lower().strip().rstrip() 17 | 18 | if search_query == "": 19 | await client.answer_inline_query( 20 | query.id, 21 | results=answers, 22 | switch_pm_text="type a youtube video name...", 23 | switch_pm_parameter="help", 24 | cache_time=0, 25 | ) 26 | else: 27 | search = VideosSearch(search_query, limit=50) 28 | 29 | for result in search.result()["result"]: 30 | answers.append( 31 | InlineQueryResultArticle( 32 | title=result["title"], 33 | description="{}, {} views.".format( 34 | result["duration"], result["viewCount"]["short"] 35 | ), 36 | input_message_content=InputTextMessageContent( 37 | "🔗 https://www.youtube.com/watch?v={}".format(result["id"]) 38 | ), 39 | thumb_url=result["thumbnails"][0]["url"], 40 | ) 41 | ) 42 | 43 | try: 44 | await query.answer(results=answers, cache_time=0) 45 | except errors.QueryIdInvalid: 46 | await query.answer( 47 | results=answers, 48 | cache_time=0, 49 | switch_pm_text="error: search timed out", 50 | switch_pm_parameter="", 51 | ) 52 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/playlist.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Union, List 2 | from Music import db 3 | 4 | playlistdb = db.playlist 5 | 6 | 7 | async def get_playlist_count() -> dict: 8 | chats = playlistdb.find({"chat_id": {"$lt": 0}}) 9 | if not chats: 10 | return {} 11 | chats_count = 0 12 | notes_count = 0 13 | for chat in await chats.to_list(length=1000000000): 14 | notes_name = await get_note_names(chat["chat_id"]) 15 | notes_count += len(notes_name) 16 | chats_count += 1 17 | return {"chats_count": chats_count, "notes_count": notes_count} 18 | 19 | 20 | async def _get_playlists(chat_id: int) -> Dict[str, int]: 21 | _notes = await playlistdb.find_one({"chat_id": chat_id}) 22 | if not _notes: 23 | return {} 24 | return _notes["notes"] 25 | 26 | 27 | async def get_note_names(chat_id: int) -> List[str]: 28 | _notes = [] 29 | for note in await _get_playlists(chat_id): 30 | _notes.append(note) 31 | return _notes 32 | 33 | 34 | async def get_playlist(chat_id: int, name: str) -> Union[bool, dict]: 35 | name = name 36 | _notes = await _get_playlists(chat_id) 37 | if name in _notes: 38 | return _notes[name] 39 | else: 40 | return False 41 | 42 | 43 | async def save_playlist(chat_id: int, name: str, note: dict): 44 | name = name 45 | _notes = await _get_playlists(chat_id) 46 | _notes[name] = note 47 | 48 | await playlistdb.update_one( 49 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True 50 | ) 51 | 52 | 53 | async def delete_playlist(chat_id: int, name: str) -> bool: 54 | notesd = await _get_playlists(chat_id) 55 | name = name 56 | if name in notesd: 57 | del notesd[name] 58 | await playlistdb.update_one( 59 | {"chat_id": chat_id}, {"$set": {"notes": notesd}}, upsert=True 60 | ) 61 | return True 62 | return False 63 | -------------------------------------------------------------------------------- /Music/Plugins/restart.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters, Client 2 | from pyrogram.types import Message 3 | from Music import app, SUDOERS 4 | from sys import version as pyver 5 | import subprocess 6 | import shutil 7 | import os 8 | from Music.MusicUtilities.database.functions import start_restart_stage 9 | from Music.MusicUtilities.tgcallsrun import (music, convert, download, clear, get, is_empty, put, task_done) 10 | from Music.MusicUtilities.database.queue import get_active_chats 11 | from Music.MusicUtilities.database.queue import (get_active_chats, is_active_chat, add_active_chat, remove_active_chat, music_on, is_music_playing, music_off) 12 | 13 | @app.on_message(filters.command("restart") & filters.user(SUDOERS)) 14 | async def theme_func(_, message): 15 | A = "downloads" 16 | B = "raw_files" 17 | shutil.rmtree(A) 18 | shutil.rmtree(B) 19 | os.mkdir(A) 20 | os.mkdir(B) 21 | served_chats = [] 22 | try: 23 | chats = await get_active_chats() 24 | for chat in chats: 25 | served_chats.append(int(chat["chat_id"])) 26 | except Exception as e: 27 | pass 28 | for x in served_chats: 29 | try: 30 | await app.send_message(x, "Music has just restarted herself. Sorry for the issues.\n\nStart playing after 10-15 seconds again.") 31 | except Exception: 32 | pass 33 | served_chatss = [] 34 | try: 35 | chats = await get_active_chats() 36 | for chat in chats: 37 | served_chatss.append(int(chat["chat_id"])) 38 | except Exception as e: 39 | pass 40 | for served_chat in served_chatss: 41 | try: 42 | await remove_active_chat(served_chat) 43 | except Exception as e: 44 | await message.reply_text(f"{e}") 45 | pass 46 | x = await message.reply_text(f"**Restarting Music!**") 47 | await start_restart_stage(x.chat.id, x.message_id) 48 | os.execvp(f"python{str(pyver.split(' ')[0])[:3]}", [ 49 | f"python{str(pyver.split(' ')[0])[:3]}", "-m", "Music"]) 50 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/decorators.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Dict, List 2 | 3 | from pyrogram import Client 4 | from pyrogram.types import Chat, Message 5 | 6 | from Music import SUDOERS 7 | 8 | admins = {} 9 | 10 | 11 | admins: Dict[int, List[int]] = {} 12 | 13 | 14 | def set(chat_id: int, admins_: List[int]): 15 | admins[chat_id] = admins_ 16 | 17 | 18 | def gett(chat_id: int) -> List[int]: 19 | if chat_id in admins: 20 | return admins[chat_id] 21 | return [] 22 | 23 | 24 | def errors(func: Callable) -> Callable: 25 | async def decorator(client: Client, message: Message): 26 | try: 27 | return await func(client, message) 28 | except Exception as e: 29 | await message.reply(f"{type(e).__name__}: {e}", False) 30 | 31 | return decorator 32 | 33 | 34 | async def get_administrators(chat: Chat) -> List[int]: 35 | get = gett(chat.id) 36 | 37 | if get: 38 | return get 39 | else: 40 | administrators = await chat.get_members(filter="administrators") 41 | to_set = [] 42 | 43 | for administrator in administrators: 44 | if administrator.can_manage_voice_chats: 45 | to_set.append(administrator.user.id) 46 | 47 | set(chat.id, to_set) 48 | return await get_administrators(chat) 49 | 50 | 51 | def authorized_users_only(func: Callable) -> Callable: 52 | async def decorator(client: Client, message: Message): 53 | if message.from_user.id in SUDOERS: 54 | return await func(client, message) 55 | 56 | administrators = await get_administrators(message.chat) 57 | 58 | for administrator in administrators: 59 | if administrator == message.from_user.id: 60 | return await func(client, message) 61 | 62 | return decorator 63 | 64 | 65 | def errors(func: Callable) -> Callable: 66 | async def decorator(client: Client, message: Message): 67 | try: 68 | return await func(client, message) 69 | except Exception as e: 70 | await message.reply(f'{type(e).__name__}: {e}', False) 71 | 72 | return decorator 73 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/queues.py: -------------------------------------------------------------------------------- 1 | from asyncio import Queue as _Queue 2 | from asyncio import QueueEmpty as Empty 3 | from typing import Dict 4 | 5 | QUEUE = {} 6 | 7 | 8 | class Queue(_Queue): 9 | _queue: list = [] 10 | 11 | def clear(self): 12 | self._queue.clear() 13 | 14 | 15 | queues: Dict[int, Queue] = {} 16 | 17 | 18 | async def put(chat_id: int, **kwargs) -> int: 19 | if chat_id not in queues: 20 | queues[chat_id] = Queue() 21 | await queues[chat_id].put({**kwargs}) 22 | return queues[chat_id].qsize() 23 | 24 | 25 | def get(chat_id: int) -> Dict[str, str]: 26 | if chat_id in queues: 27 | try: 28 | return queues[chat_id].get_nowait() 29 | except Empty: 30 | return {} 31 | return {} 32 | 33 | 34 | def is_empty(chat_id: int) -> bool: 35 | if chat_id in queues: 36 | return queues[chat_id].empty() 37 | return True 38 | 39 | 40 | def task_done(chat_id: int): 41 | if chat_id in queues: 42 | try: 43 | queues[chat_id].task_done() 44 | except ValueError: 45 | pass 46 | 47 | 48 | def clear(chat_id: int): 49 | if chat_id in queues: 50 | if queues[chat_id].empty(): 51 | raise Empty 52 | else: 53 | queues[chat_id].clear() 54 | raise Empty 55 | 56 | 57 | def add_to_queue(chat_id, songname, link, ref, type, quality): 58 | if chat_id in QUEUE: 59 | chat_queue = QUEUE[chat_id] 60 | chat_queue.append([songname, link, ref, type, quality]) 61 | return int(len(chat_queue) - 1) 62 | else: 63 | QUEUE[chat_id] = [[songname, link, ref, type, quality]] 64 | 65 | 66 | def get_queue(chat_id): 67 | if chat_id in QUEUE: 68 | chat_queue = QUEUE[chat_id] 69 | return chat_queue 70 | else: 71 | return 0 72 | 73 | 74 | def pop_an_item(chat_id): 75 | if chat_id in QUEUE: 76 | chat_queue = QUEUE[chat_id] 77 | chat_queue.pop(0) 78 | return 1 79 | else: 80 | return 0 81 | 82 | 83 | def clear_queue(chat_id): 84 | if chat_id in QUEUE: 85 | QUEUE.pop(chat_id) 86 | return 1 87 | else: 88 | return 0 89 | -------------------------------------------------------------------------------- /Music/__main__.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import time 3 | import uvloop 4 | import importlib 5 | from pyrogram import Client 6 | from Music.config import API_ID, API_HASH, BOT_TOKEN, MONGO_DB_URI, SUDO_USERS, LOG_GROUP_ID 7 | from Music import BOT_NAME, ASSNAME, app, client 8 | from Music.MusicUtilities.database.functions import clean_restart_stage 9 | from Music.MusicUtilities.database.queue import (get_active_chats, remove_active_chat) 10 | from Music.MusicUtilities.tgcallsrun import run 11 | from pytgcalls import idle 12 | from motor.motor_asyncio import AsyncIOMotorClient as MongoClient 13 | import time 14 | 15 | Client( 16 | ':Music:', 17 | API_ID, 18 | API_HASH, 19 | bot_token=BOT_TOKEN, 20 | plugins={'root': 'Music.Plugins'}, 21 | ).start() 22 | 23 | 24 | print(f"[INFO]: BOT STARTED AS {BOT_NAME}!") 25 | print(f"[INFO]: ASSISTANT STARTED AS {ASSNAME}!") 26 | 27 | 28 | 29 | async def load_start(): 30 | restart_data = await clean_restart_stage() 31 | if restart_data: 32 | print("[INFO]: SENDING RESTART STATUS") 33 | try: 34 | await app.edit_message_text( 35 | restart_data["chat_id"], 36 | restart_data["message_id"], 37 | "**Restarted The Bot Successfully.**", 38 | ) 39 | except Exception: 40 | pass 41 | served_chats = [] 42 | try: 43 | chats = await get_active_chats() 44 | for chat in chats: 45 | served_chats.append(int(chat["chat_id"])) 46 | except Exception as e: 47 | print("Error came while clearing db") 48 | for served_chat in served_chats: 49 | try: 50 | await remove_active_chat(served_chat) 51 | except Exception as e: 52 | print("Error came while clearing db") 53 | pass 54 | await app.send_message(LOG_GROUP_ID, "**[🤖](https://t.me/flicksrobotsupport/14994) The Music Bot Started Master...**") 55 | await client.send_message(LOG_GROUP_ID, "**[🦸🏻‍♂️](https://t.me/flicksrobotsupport/14995) The Music Assistant Started Master...**") 56 | print("[INFO]: STARTED") 57 | 58 | 59 | loop = asyncio.get_event_loop() 60 | loop.run_until_complete(load_start()) 61 | 62 | run() 63 | idle() 64 | loop.close() 65 | 66 | print("[LOG] CLOSING BOT") 67 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/gets.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | from pyrogram.types import Message, Audio, Voice 3 | 4 | async def convert_count(count): 5 | if int(count) == 1: 6 | x = "First" 7 | elif int(count) == 2: 8 | x = "Second" 9 | elif int(count) == 3: 10 | x = "Third" 11 | elif int(count) == 4: 12 | x = "Fourth" 13 | elif int(count) == 5: 14 | x = "Fifth" 15 | elif int(count) == 6: 16 | x = "Sixth" 17 | elif int(count) == 7: 18 | x = "Seventh" 19 | elif int(count) == 8: 20 | x = "Eighth" 21 | elif int(count) == 9: 22 | x = "Ninth" 23 | elif int(count) == 10: 24 | x = "Tenth" 25 | elif int(count) == 11: 26 | x = "Eleventh" 27 | elif int(count) == 12: 28 | x = "Twelfth" 29 | elif int(count) == 13: 30 | x = "Thirteenth" 31 | elif int(count) == 14: 32 | x = "Fourteenth" 33 | elif int(count) == 15: 34 | x = "Fifteenth" 35 | elif str(count) == "all": 36 | x = "all" 37 | return x 38 | def get_url(message_1: Message) -> Union[str, None]: 39 | messages = [message_1] 40 | if message_1.reply_to_message: 41 | messages.append(message_1.reply_to_message) 42 | text = "" 43 | offset = None 44 | length = None 45 | for message in messages: 46 | if offset: 47 | break 48 | if message.entities: 49 | for entity in message.entities: 50 | if entity.type == "url": 51 | text = message.text or message.caption 52 | offset, length = entity.offset, entity.length 53 | break 54 | if offset in (None,): 55 | return None 56 | return text[offset:offset + length] 57 | random_assistant = ["5", "1", "2", "3", "4"] 58 | 59 | themes = ["Black", "Grey", "Green", "Purple", "Red", "Lightred", "Blue", "Lightblue"] 60 | 61 | def bytes(size: float) -> str: 62 | """humanize size""" 63 | if not size: 64 | return "" 65 | power = 1024 66 | t_n = 0 67 | power_dict = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} 68 | while size > power: 69 | size /= power 70 | t_n += 1 71 | return "{:.2f} {}B".format(size, power_dict[t_n]) 72 | 73 | 74 | async def ass_det(assistant: int): 75 | print("HAHAHHAHA") 76 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/thumbnails.py: -------------------------------------------------------------------------------- 1 | import os 2 | from os import path 3 | import aiohttp 4 | import aiofiles 5 | from PIL import Image 6 | from PIL import ImageFont 7 | from PIL import ImageDraw 8 | 9 | def changeImageSize(maxWidth, maxHeight, image): 10 | widthRatio = maxWidth / image.size[0] 11 | heightRatio = maxHeight / image.size[1] 12 | newWidth = int(widthRatio * image.size[0]) 13 | newHeight = int(heightRatio * image.size[1]) 14 | newImage = image.resize((newWidth, newHeight)) 15 | return newImage 16 | 17 | 18 | async def gen_thumb(thumbnail, title, userid, theme, ctitle): 19 | async with aiohttp.ClientSession() as session: 20 | async with session.get(thumbnail) as resp: 21 | if resp.status == 200: 22 | f = await aiofiles.open(f"search/thumb{userid}.png", mode="wb") 23 | await f.write(await resp.read()) 24 | await f.close() 25 | image1 = Image.open(f"search/thumb{userid}.png") 26 | image2 = Image.open(f"cache/{theme}.png") 27 | image3 = changeImageSize(1280, 720, image1) 28 | image4 = changeImageSize(1280, 720, image2) 29 | image5 = image3.convert("RGBA") 30 | image6 = image4.convert("RGBA") 31 | Image.alpha_composite(image5, image6).save(f"search/temp{userid}.png") 32 | img = Image.open(f"search/temp{userid}.png") 33 | draw = ImageDraw.Draw(img) 34 | font = ImageFont.truetype("cache/finalfont.ttf", 55) 35 | font2 = ImageFont.truetype("cache/finalfont.ttf", 75) 36 | draw.text((25, 528), f"Playing on: {ctitle[:17]}...", fill="black", stroke_width = 1, stroke_fill="black" ,font=font) 37 | draw.text((25, 610), f"{title[:20]}...", fill= "black", stroke_width = 1, stroke_fill="black", font=font2) 38 | img.save(f"search/final{userid}.png") 39 | os.remove(f"search/temp{userid}.png") 40 | os.remove(f"search/thumb{userid}.png") 41 | final = f"search/final{userid}.png" 42 | return final 43 | 44 | 45 | 46 | async def down_thumb(thumbnail, userid): 47 | async with aiohttp.ClientSession() as session: 48 | async with session.get(thumbnail) as resp: 49 | if resp.status == 200: 50 | f = await aiofiles.open(f"search/thumb{userid}.png", mode="wb") 51 | await f.write(await resp.read()) 52 | await f.close() 53 | final = f"search/thumb{userid}.png" 54 | return final 55 | -------------------------------------------------------------------------------- /Music/Plugins/alive.py: -------------------------------------------------------------------------------- 1 | # © KenendyXMusic 2 | # Adjustment for yukki by Fariz 3 | # Thanks Ken 💙 4 | # Ported by Fariz 5 | 6 | from os import path 7 | from pyrogram import Client, filters 8 | from pyrogram import __version__ as pyrover 9 | from pyrogram.types import Message 10 | from time import time 11 | from datetime import datetime 12 | from Music import app 13 | from pytgcalls import __version__ as pytover 14 | 15 | from Music.config import ( 16 | BOT_IMG, 17 | GROUP, 18 | CHANNEL, 19 | ) 20 | from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton 21 | 22 | 23 | 24 | START_TIME = datetime.utcnow() 25 | START_TIME_ISO = START_TIME.replace(microsecond=0).isoformat() 26 | TIME_DURATION_UNITS = ( 27 | ('week', 60 * 60 * 24 * 7), 28 | ('day', 60 * 60 * 24), 29 | ('hour', 60 * 60), 30 | ('min', 60), 31 | ('sec', 1) 32 | ) 33 | 34 | async def _human_time_duration(seconds): 35 | if seconds == 0: 36 | return 'inf' 37 | parts = [] 38 | for unit, div in TIME_DURATION_UNITS: 39 | amount, seconds = divmod(int(seconds), div) 40 | if amount > 0: 41 | parts.append('{} {}{}' 42 | .format(amount, unit, "" if amount == 1 else "s")) 43 | return ', '.join(parts) 44 | 45 | 46 | @app.on_message(filters.command(["alive", "alive@Tg_Vc_00_Bot"])) 47 | async def alive(client, message): 48 | current_time = datetime.utcnow() 49 | uptime_sec = (current_time - START_TIME).total_seconds() 50 | uptime = await _human_time_duration(int(uptime_sec)) 51 | await client.send_photo(message.chat.id, 52 | photo=f"{BOT_IMG}", 53 | caption=f"""**Holla {message.from_user.mention()}.** 54 | ㊙️ **I'm Working Properly** 55 | ㊙️ **Bot : Latest** 56 | ㊙️ **Bot Info : Online** 57 | ㊙️ **Uptime : `{uptime}`** 58 | ㊙️ **Pyrogram Version : `{pyrover}`** 59 | ㊙️ **PyTgCalls Version: `{pytover.__version__}`** 60 | ㊙️ **Using New Version** 61 | **Thanks For Using Me 🚀**""", 62 | reply_markup=InlineKeyboardMarkup( 63 | [ 64 | [ 65 | InlineKeyboardButton( 66 | "Support", url=f"t.me/{GROUP}" 67 | ), 68 | InlineKeyboardButton( 69 | "Updates", url=f"t.me/{CHANNEL}" 70 | ) 71 | ] 72 | ] 73 | ) 74 | ) 75 | -------------------------------------------------------------------------------- /Music/MusicUtilities/database/auth.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | 3 | from Music import db 4 | 5 | authdb = db.adminauth 6 | 7 | 8 | async def is_nonadmin_chat(user_id: int) -> bool: 9 | user = await authdb.find_one({"user_id": user_id}) 10 | if not user: 11 | return False 12 | return True 13 | 14 | 15 | async def add_nonadmin_chat(user_id: int): 16 | is_gbanned = await is_nonadmin_chat(user_id) 17 | if is_gbanned: 18 | return 19 | return await authdb.insert_one({"user_id": user_id}) 20 | 21 | 22 | async def remove_nonadmin_chat(user_id: int): 23 | is_gbanned = await is_nonadmin_chat(user_id) 24 | if not is_gbanned: 25 | return 26 | return await authdb.delete_one({"user_id": user_id}) 27 | 28 | 29 | ## Save Auth User 30 | 31 | authuserdb = db.authuser 32 | 33 | 34 | async def get_authuser_count() -> dict: 35 | chats = authuserdb.find({"chat_id": {"$lt": 0}}) 36 | if not chats: 37 | return {} 38 | chats_count = 0 39 | notes_count = 0 40 | for chat in await chats.to_list(length=1000000000): 41 | notes_name = await get_authuser_names(chat["chat_id"]) 42 | notes_count += len(notes_name) 43 | chats_count += 1 44 | return {"chats_count": chats_count, "notes_count": notes_count} 45 | 46 | 47 | async def _get_authusers(chat_id: int) -> Dict[str, int]: 48 | _notes = await authuserdb.find_one({"chat_id": chat_id}) 49 | if not _notes: 50 | return {} 51 | return _notes["notes"] 52 | 53 | 54 | async def get_authuser_names(chat_id: int) -> List[str]: 55 | _notes = [] 56 | for note in await _get_authusers(chat_id): 57 | _notes.append(note) 58 | return _notes 59 | 60 | 61 | async def get_authuser(chat_id: int, name: str) -> Union[bool, dict]: 62 | name = name 63 | _notes = await _get_authusers(chat_id) 64 | if name in _notes: 65 | return _notes[name] 66 | else: 67 | return False 68 | 69 | 70 | async def save_authuser(chat_id: int, name: str, note: dict): 71 | name = name 72 | _notes = await _get_authusers(chat_id) 73 | _notes[name] = note 74 | 75 | await authuserdb.update_one( 76 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True 77 | ) 78 | 79 | 80 | async def delete_authuser(chat_id: int, name: str) -> bool: 81 | notesd = await _get_authusers(chat_id) 82 | name = name 83 | if name in notesd: 84 | del notesd[name] 85 | await authuserdb.update_one( 86 | {"chat_id": chat_id}, {"$set": {"notes": notesd}}, upsert=True 87 | ) 88 | return True 89 | return False 90 | -------------------------------------------------------------------------------- /Music/Plugins/allow.py: -------------------------------------------------------------------------------- 1 | from Music import app, SUDOERS 2 | from pyrogram import filters, Client 3 | from pyrogram.types import Message 4 | from Music.MusicUtilities.helpers.filters import command 5 | from Music.MusicUtilities.database.chats import (get_served_chats, is_served_chat, add_served_chat, get_served_chats, remove_served_chat) 6 | 7 | chat_watcher_group = 10 8 | 9 | 10 | @app.on_message(group=chat_watcher_group) 11 | async def chat_watcher_func(_, message): 12 | chat_id = message.chat.id 13 | 14 | if not chat_id: 15 | return 16 | 17 | await add_served_chat(chat_id) 18 | 19 | @app.on_message(filters.command("allow") & filters.user(SUDOERS)) 20 | async def blacklist_chat_func(_, message: Message): 21 | if len(message.command) != 2: 22 | return await message.reply_text( 23 | "**Usage:**\n/allow [CHAT_ID]" 24 | ) 25 | chat_id = int(message.text.strip().split()[1]) 26 | if not await is_served_chat(chat_id): 27 | await add_served_chat(chat_id) 28 | await message.reply_text("ADDED CHAT TO ALLOWED LIST") 29 | else: 30 | await message.reply_text("ALREADY IN ALLOWED LIST") 31 | 32 | @app.on_message(filters.command("disallow") & filters.user(SUDOERS)) 33 | async def whitelist_chat_func(_, message: Message): 34 | if len(message.command) != 2: 35 | return await message.reply_text( 36 | "**Usage:**\n/disallow [CHAT_ID]" 37 | ) 38 | chat_id = int(message.text.strip().split()[1]) 39 | if not await is_served_chat(chat_id): 40 | await message.reply_text("Chat not allowed.") 41 | return 42 | try: 43 | await remove_served_chat(chat_id) 44 | await message.reply_text("Chat diallowed.") 45 | return 46 | except Exception as e: 47 | await message.reply_text("Error.") 48 | 49 | 50 | @app.on_message(filters.command("allowedchat") & filters.user(SUDOERS)) 51 | async def blacklisted_chats_func(_, message: Message): 52 | served_chats = [] 53 | text = "**__Allowed Chats__**\n" 54 | try: 55 | chats = await get_served_chats() 56 | for chat in chats: 57 | served_chats.append(int(chat["chat_id"])) 58 | except Exception as e: 59 | await message.reply_text("Error.") 60 | return 61 | count = 0 62 | for served_chat in served_chats: 63 | 64 | try: 65 | title = (await app.get_chat(served_chat)).title 66 | except Exception: 67 | title = "Private" 68 | count += 1 69 | text += f"**{count}. {title}** [`{served_chat}`]\n" 70 | if not text: 71 | await message.reply_text("🉐 No Allowed Chats") 72 | else: 73 | await message.reply_text(text) 74 | -------------------------------------------------------------------------------- /Music/Plugins/stats.py: -------------------------------------------------------------------------------- 1 | from Music import app, SUDOERS, BOT_ID 2 | from pyrogram import filters, Client 3 | from sys import version as pyver 4 | from pyrogram import __version__ as pyrover 5 | from pytgcalls import (__version__ as pytover) 6 | from pyrogram.types import Message 7 | import platform, socket, re, uuid, json, psutil, logging 8 | from Music.MusicUtilities.database.gbanned import get_gbans_count 9 | from Music.MusicUtilities.database.chats import get_served_chats 10 | from Music.MusicUtilities.database.sudo import (get_sudoers, get_sudoers, remove_sudo) 11 | from Music.MusicUtilities.database.playlist import get_playlist_count 12 | from Music.MusicUtilities.helpers.time import get_readable_time 13 | from Music import app, SUDOERS, Music_START_TIME 14 | import os 15 | import time 16 | from pymongo import MongoClient 17 | from Music.config import MONGO_DB_URI as smex 18 | 19 | @app.on_message(filters.command("statsmusic") & ~filters.edited) 20 | async def gstats(_, message): 21 | m = await message.reply_text("**Getting Stats**\n\nPlease wait for some time..") 22 | served_chats = [] 23 | chats = await get_served_chats() 24 | for chat in chats: 25 | served_chats.append(int(chat["chat_id"])) 26 | blocked = await get_gbans_count() 27 | sudoers = await get_sudoers() 28 | j = 0 29 | for count, user_id in enumerate(sudoers, 0): 30 | try: 31 | user = await app.get_users(user_id) 32 | j += 1 33 | except Exception: 34 | continue 35 | modules_count ="17" 36 | sc = platform.system() 37 | arch = platform.machine() 38 | ram = str(round(psutil.virtual_memory().total / (1024.0 **3)))+" GB" 39 | bot_uptime = int(time.time() - Music_START_TIME) 40 | uptime = f"{get_readable_time((bot_uptime))}" 41 | hdd = psutil.disk_usage('/') 42 | total = (hdd.total / (1024.0 ** 3)) 43 | total = str(total) 44 | used = (hdd.used / (1024.0 ** 3)) 45 | used = str(used) 46 | free = (hdd.free / (1024.0 ** 3)) 47 | free = str(free) 48 | msg = f""" 49 | **Global Stats Of Music Bot**:\n\n 50 | [•]__**System Stats**__ 51 | **Music Uptime:** {uptime} 52 | **System Process:** Online 53 | **Platform:** {sc} 54 | **Storage:** Used {used[:4]} GiB out of {total[:4]} GiB, free {free[:4]} GiB 55 | **Architecture:** {arch} 56 | **Ram:** {ram} 57 | **Python Version:** {pyver.split()[0]} 58 | **Pyrogram Version:** {pyrover} 59 | **PyTgCalls Version:** {pytover.__version__} 60 | 61 | [•]__**Bot Music Stats**__ 62 | **Modules Loaded:** {modules_count} 63 | **GBanned Users:** {blocked} 64 | **Sudo Users:** {j} 65 | **Allowed Chats:** {len(served_chats)} 66 | 67 | """ 68 | served_chats.pop(0) 69 | await m.edit(msg, disable_web_page_preview=True) 70 | -------------------------------------------------------------------------------- /Music/Plugins/lyrics.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import ( 2 | CallbackQuery, 3 | InlineKeyboardButton, 4 | InlineKeyboardMarkup, 5 | InputMediaDocument, 6 | InputMediaVideo, 7 | InputMediaAudio, 8 | Message, 9 | ) 10 | from Music import app 11 | from pyrogram import Client, filters 12 | from youtubesearchpython import VideosSearch 13 | import lyricsgenius 14 | import re 15 | 16 | @Client.on_callback_query(filters.regex(pattern=r"lyrics")) 17 | async def lyricssex(_,CallbackQuery): 18 | callback_data = CallbackQuery.data.strip() 19 | callback_request = callback_data.split(None, 1)[1] 20 | try: 21 | id, user_id = callback_request.split("|") 22 | except Exception as e: 23 | return await CallbackQuery.message.edit(f"Error Occured\n**Possible reason could be**:{e}") 24 | url = (f"https://www.youtube.com/watch?v={id}") 25 | print(url) 26 | try: 27 | results = VideosSearch(url, limit=1) 28 | for result in results.result()["result"]: 29 | title = (result["title"]) 30 | except Exception as e: 31 | return await CallbackQuery.answer("Sound not found. Youtube issues.", show_alert=True) 32 | x = "OXaVabSRKQLqwpiYOn-E4Y7k3wj-TNdL5RfDPXlnXhCErbcqVvdCF-WnMR5TBctI" 33 | y = lyricsgenius.Genius(x) 34 | print(title) 35 | t = re.sub(r'[^\w]', ' ', title) 36 | print(t) 37 | y.verbose = False 38 | S = y.search_song(t, get_full_info=False) 39 | if S is None: 40 | return await CallbackQuery.answer("Lyrics not found :p", show_alert=True) 41 | await CallbackQuery.message.delete() 42 | userid = CallbackQuery.from_user.id 43 | usr = f"[{CallbackQuery.from_user.first_name}](tg://user?id={userid})" 44 | xxx = f""" 45 | **🥜 Lyrics Search Powered By Music Bot** 46 | 47 | **🦹🏻 Searched By:-** {usr} 48 | **📚 Searched Song:-** __{title}__ 49 | 50 | **📨 Found Lyrics For:-** __{S.title}__ 51 | **🤼 Artist:-** {S.artist} 52 | 53 | **__Lyrics:__** 54 | 55 | {S.lyrics}""" 56 | await CallbackQuery.message.reply_text(xxx) 57 | 58 | 59 | @Client.on_message(filters.command("lyrics")) 60 | async def lrsearch(_, message: Message): 61 | m = await message.reply_text("Searching Lyrics") 62 | query = message.text.split(None, 1)[1] 63 | x = "OXaVabSRKQLqwpiYOn-E4Y7k3wj-TNdL5RfDPXlnXhCErbcqVvdCF-WnMR5TBctI" 64 | y = lyricsgenius.Genius(x) 65 | y.verbose = False 66 | S = y.search_song(query, get_full_info=False) 67 | if S is None: 68 | return await m.edit("Lyrics not found :p") 69 | xxx = f""" 70 | **Lyrics Search Powered By Music Bot** 71 | 72 | **Searched Song:-** __{query}__ 73 | 74 | **Found Lyrics For:-** __{S.title}__ 75 | **Artist:-** {S.artist} 76 | 77 | **__Lyrics:__** 78 | 79 | {S.lyrics}""" 80 | await m.edit(xxx) 81 | 82 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/chattitle.py: -------------------------------------------------------------------------------- 1 | # Convert special font chat titles to normal title 2 | async def CHAT_TITLE(ctitle): 3 | string = ctitle 4 | font1 = list("𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ") 5 | font2 = list("𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅") 6 | font3 = list("𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩") 7 | font4 = list("𝒜𝐵𝒞𝒟𝐸𝐹𝒢𝐻𝐼𝒥𝒦𝐿𝑀𝒩𝒪𝒫𝒬𝑅𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵") 8 | font5 = list("𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ") 9 | font6 = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 10 | font26 = list("𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙") 11 | font27 = list("𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭") 12 | font28 = list("𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡") 13 | font29 = list("𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕") 14 | font30 = list("𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉") 15 | font1L = list("𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷") 16 | font2L = list("𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟") 17 | font3L = list("𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃") 18 | font4L = list("𝒶𝒷𝒸𝒹𝑒𝒻𝑔𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝑜𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏") 19 | font5L = list("𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫") 20 | font6L = list("abcdefghijklmnopqrstuvwxyz") 21 | font27L = list("𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳") 22 | font28L = list("𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇") 23 | font29L = list("𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻") 24 | font30L = list("𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯") 25 | font31L = list("𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣") 26 | normal = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") 27 | normalL = list("abcdefghijklmnopqrstuvwxyz") 28 | cout = 0 29 | for XCB in font1: 30 | string = string.replace(font1[cout],normal[cout]) 31 | string = string.replace(font2[cout],normal[cout]) 32 | string = string.replace(font3[cout],normal[cout]) 33 | string = string.replace(font4[cout],normal[cout]) 34 | string = string.replace(font5[cout],normal[cout]) 35 | string = string.replace(font6[cout],normal[cout]) 36 | string = string.replace(font26[cout],normal[cout]) 37 | string = string.replace(font27[cout],normal[cout]) 38 | string = string.replace(font28[cout],normal[cout]) 39 | string = string.replace(font29[cout],normal[cout]) 40 | string = string.replace(font30[cout],normal[cout]) 41 | string = string.replace(font1L[cout],normalL[cout]) 42 | string = string.replace(font2L[cout],normalL[cout]) 43 | string = string.replace(font3L[cout],normalL[cout]) 44 | string = string.replace(font4L[cout],normalL[cout]) 45 | string = string.replace(font5L[cout],normalL[cout]) 46 | string = string.replace(font6L[cout],normalL[cout]) 47 | string = string.replace(font27L[cout],normalL[cout]) 48 | string = string.replace(font28L[cout],normalL[cout]) 49 | string = string.replace(font29L[cout],normalL[cout]) 50 | string = string.replace(font30L[cout],normalL[cout]) 51 | string = string.replace(font31L[cout],normalL[cout]) 52 | cout += 1 53 | return string 54 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/admins.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Union 2 | 3 | from Music import SUDOERS, app 4 | from Music.MusicUtilities.database.auth import (_get_authusers, add_nonadmin_chat, 5 | delete_authuser, get_authuser, get_authuser_count, 6 | get_authuser_names, is_nonadmin_chat, 7 | remove_nonadmin_chat, save_authuser) 8 | from Music.MusicUtilities.database.changers import int_to_alpha 9 | 10 | 11 | def AdminRightsCheck(mystic): 12 | async def wrapper(_, message): 13 | if message.sender_chat: 14 | return await message.reply_text( 15 | "You're an __Anonymous Admin__!\nRevert back to User Account." 16 | ) 17 | is_non_admin = await is_nonadmin_chat(message.chat.id) 18 | if not is_non_admin: 19 | member = await app.get_chat_member( 20 | message.chat.id, message.from_user.id 21 | ) 22 | if not member.can_manage_voice_chats: 23 | if message.from_user.id not in SUDOERS: 24 | token = await int_to_alpha(message.from_user.id) 25 | _check = await get_authuser_names(message.chat.id) 26 | if token not in _check: 27 | return await message.reply( 28 | "You don't have the required permission to perform this action.\n\n__REQUIRES ADMIN WITH MANAGE VC RIGHTS__" 29 | ) 30 | return await mystic(_, message) 31 | 32 | return wrapper 33 | 34 | 35 | def AdminActual(mystic): 36 | async def wrapper(_, message): 37 | if message.sender_chat: 38 | return await message.reply_text( 39 | "You're an __Anonymous Admin__!\nRevert back to User Account." 40 | ) 41 | member = await app.get_chat_member( 42 | message.chat.id, message.from_user.id 43 | ) 44 | if not member.can_manage_voice_chats: 45 | return await message.reply( 46 | "You don't have the required permission to perform this action.\n\n__REQUIRES ADMIN WITH MANAGE VC RIGHTS__" 47 | ) 48 | return await mystic(_, message) 49 | 50 | return wrapper 51 | 52 | 53 | def AdminRightsCheckCB(mystic): 54 | async def wrapper(_, CallbackQuery): 55 | is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id) 56 | if not is_non_admin: 57 | a = await app.get_chat_member( 58 | CallbackQuery.message.chat.id, CallbackQuery.from_user.id 59 | ) 60 | if not a.can_manage_voice_chats: 61 | if CallbackQuery.from_user.id not in SUDOERS: 62 | token = await int_to_alpha(CallbackQuery.from_user.id) 63 | _check = await get_authuser_names( 64 | CallbackQuery.from_user.id 65 | ) 66 | if token not in _check: 67 | return await CallbackQuery.answer( 68 | "You don't have the required permission to perform this action.\nPermission: MANAGE VOICE CHATS", 69 | show_alert=True, 70 | ) 71 | return await mystic(_, CallbackQuery) 72 | 73 | return wrapper 74 | 75 | 76 | def ActualAdminCB(mystic): 77 | async def wrapper(_, CallbackQuery): 78 | a = await app.get_chat_member( 79 | CallbackQuery.message.chat.id, CallbackQuery.from_user.id 80 | ) 81 | if not a.can_manage_voice_chats: 82 | return await CallbackQuery.answer( 83 | "You don't have the required permission to perform this action.\nPermission: MANAGE VOICE CHATS", 84 | show_alert=True, 85 | ) 86 | return await mystic(_, CallbackQuery) 87 | 88 | return wrapper 89 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Skyzo Music", 3 | "description": "Music allow you to stream music trought the telegram voice chat feature.", 4 | "keywords": ["music", "voice chat", "telegram"], 5 | "repository": "https://github.com/ridho17-ind/SkyzoMusicBot", 6 | "stack": "container", 7 | "env": { 8 | "SESSION_NAME": { 9 | "description": "fill with the pyrogram session string from account", 10 | "required": true 11 | }, 12 | "OWNER_ID": { 13 | "description": "fill with your telegram id as the owner of the bot", 14 | "required": true, 15 | "value": "Isi Id Lu" 16 | }, 17 | "BOT_IMG": { 18 | "description": "Photo for your bot", 19 | "value": "https://telegra.ph/file/d3f62131358c475dda9ae.jpg", 20 | "required": true 21 | }, 22 | "ASS_ID": { 23 | "description": "fill with telegram id of account", 24 | "required": true, 25 | "value": "Isi Id Asisten Lu" 26 | }, 27 | "LOG_GROUP_ID": { 28 | "description": "create a private group and get the group id, add your bot as admin to the group too", 29 | "required": true, 30 | "value": "Isi Id Log Group Lu Dan Pastikan Bot Dan Asisten Jadi Admin Di Grup Log Lu" 31 | }, 32 | "API_ID": { 33 | "description": "your Api ID from my.telegram.org/apps", 34 | "required": true, 35 | "value": "Isi Pakai Api Id Lu" 36 | }, 37 | "API_HASH": { 38 | "description": "your Api Hash from my.telegram.org/apps", 39 | "required": true, 40 | "value": "Isi Pakai Api Hash Lu" 41 | }, 42 | "HEROKU_API_KEY": { 43 | "description": "Your Heroku account's API key", 44 | "value": "", 45 | "required": false 46 | }, 47 | "HEROKU_APP_NAME": { 48 | "description": "Your heroku app/bot's name", 49 | "value": "", 50 | "required": false 51 | }, 52 | "SUDO_USERS": { 53 | "description": "fill with the user id who can access all function in your bot (separate with space).", 54 | "required": true, 55 | "value": "Isi Id Lu Juga Sebagai Sudo User" 56 | }, 57 | "DURATION_LIMIT": { 58 | "description": "filled, don't change this !", 59 | "required": true, 60 | "value": "54000" 61 | }, 62 | "BOT_TOKEN": { 63 | "description": "fill with your bot token get from @BotFather on telegram", 64 | "required": true, 65 | "value": "Isi Pakai Bot Token" 66 | }, 67 | "MONGO_DB_URI": { 68 | "description": "fill with the mongodb url get from mongodb.cloud.com (don't use mine below !)", 69 | "required": false, 70 | "value": "Isi Pakai Mongo Lu" 71 | }, 72 | "UPSTREAM_REPO": { 73 | "description": "If you dont know this, Leave as it is", 74 | "value": "https://github.com/ridho17-ind/SkyzoMusicBot", 75 | "required": true 76 | }, 77 | "UPSTREAM_BRANCH": { 78 | "description": "Repo's Branch Name", 79 | "value": "main", 80 | "required": true 81 | }, 82 | "CHANNEL": { 83 | "description": "Fill in using your channel username without @", 84 | "required": true, 85 | "value": "SadRoomsInfo" 86 | }, 87 | "GROUP": { 88 | "description": "Fill in using your channel username without the @", 89 | "required": true, 90 | "value": "FlicksRobotSupport" 91 | } 92 | }, 93 | "buildpacks": [ 94 | { 95 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git" 96 | }, 97 | { 98 | "url": "heroku/python" 99 | } 100 | ] 101 | } 102 | -------------------------------------------------------------------------------- /Music/Plugins/sudo.py: -------------------------------------------------------------------------------- 1 | from Music import app, OWNER 2 | import os 3 | import subprocess 4 | import shutil 5 | import re 6 | import sys 7 | import traceback 8 | from Music.MusicUtilities.database.sudo import (get_sudoers, get_sudoers, remove_sudo, add_sudo) 9 | from pyrogram import filters, Client 10 | from pyrogram.types import Message 11 | 12 | @app.on_message(filters.command("addsudo") & filters.user(OWNER)) 13 | async def useradd(_, message: Message): 14 | if not message.reply_to_message: 15 | if len(message.command) != 2: 16 | await message.reply_text("Reply to a user's message or give username/user_id.") 17 | return 18 | user = message.text.split(None, 1)[1] 19 | if "@" in user: 20 | user = user.replace("@", "") 21 | user = (await app.get_users(user)) 22 | from_user = message.from_user 23 | sudoers = await get_sudoers() 24 | if user.id in sudoers: 25 | return await message.reply_text("Aleady a Sudo User.") 26 | added = await add_sudo(user.id) 27 | if added: 28 | await message.reply_text(f"Added **{user.mention}** as a Super User for Music OwO") 29 | return os.execvp("python3", ["python3", "-m", "Music"]) 30 | await edit_or_reply(message, text="Something wrong happened, check logs.") 31 | return 32 | from_user_id = message.from_user.id 33 | user_id = message.reply_to_message.from_user.id 34 | mention = message.reply_to_message.from_user.mention 35 | sudoers = await get_sudoers() 36 | if user_id in sudoers: 37 | return await message.reply_text("Already a Sudo User.") 38 | added = await add_sudo(user_id) 39 | if added: 40 | await message.reply_text(f"Added **{mention}** as a Super User for Music OwO") 41 | return os.execvp("python3", ["python3", "-m", "Music"]) 42 | await edit_or_reply(message, text="Something wrong happened, check logs.") 43 | return 44 | 45 | 46 | @app.on_message(filters.command("delsudo") & filters.user(OWNER)) 47 | async def userdel(_, message: Message): 48 | if not message.reply_to_message: 49 | if len(message.command) != 2: 50 | await message.reply_text("Reply to a user's message or give username/user_id.") 51 | return 52 | user = message.text.split(None, 1)[1] 53 | if "@" in user: 54 | user = user.replace("@", "") 55 | user = (await app.get_users(user)) 56 | from_user = message.from_user 57 | if user.id not in await get_sudoers(): 58 | return await message.reply_text(f"Not a part of Music's Sudo.") 59 | removed = await remove_sudo(user.id) 60 | if removed: 61 | await message.reply_text(f"Removed **{user.mention}** from Music's Sudo.") 62 | return os.execvp("python3", ["python3", "-m", "Music"]) 63 | await message.reply_text(f"Something wrong happened.") 64 | return 65 | from_user_id = message.from_user.id 66 | user_id = message.reply_to_message.from_user.id 67 | mention = message.reply_to_message.from_user.mention 68 | if user_id not in await get_sudoers(): 69 | return await message.reply_text(f"Not a part of Music's Sudo.") 70 | removed = await remove_sudo(user_id) 71 | if removed: 72 | await message.reply_text(f"Removed **{mention}** from Music's Sudo.") 73 | return os.execvp("python3", ["python3", "-m", "Music"]) 74 | await message.reply_text(f"Something wrong happened.") 75 | 76 | 77 | @app.on_message(filters.command("sudolist")) 78 | async def sudoers_list(_, message: Message): 79 | sudoers = await get_sudoers() 80 | text = "**__Sudo Users List of Music:-__**\n\n" 81 | for count, user_id in enumerate(sudoers, 1): 82 | try: 83 | user = await app.get_users(user_id) 84 | user = user.first_name if not user.mention else user.mention 85 | except Exception: 86 | continue 87 | text += f"➤ {user}\n" 88 | if not text: 89 | await message.reply_text("No Sudo Users") 90 | else: 91 | await message.reply_text(text) 92 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/video.py: -------------------------------------------------------------------------------- 1 | from pyrogram.raw.base import Update 2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | from pytgcalls.types import Update 4 | from pytgcalls.types.input_stream import AudioPiped, AudioVideoPiped 5 | from pytgcalls.types.input_stream.quality import ( 6 | HighQualityAudio, 7 | HighQualityVideo, 8 | LowQualityVideo, 9 | MediumQualityVideo, 10 | ) 11 | from pytgcalls.types.stream import StreamVideoEnded 12 | 13 | from Music import app 14 | from Music.config import GROUP, CHANNEL 15 | from Music.MusicUtilities.tgcallsrun.music import pytgcalls as call_py 16 | 17 | from Music.MusicUtilities.tgcallsrun.queues import ( 18 | QUEUE, 19 | clear_queue, 20 | get_queue, 21 | pop_an_item, 22 | ) 23 | 24 | keyboard = InlineKeyboardMarkup( 25 | [ 26 | [ 27 | InlineKeyboardButton("ᴅᴏɴᴀsɪ", url=f"https://t.me/{GROUP}"), 28 | InlineKeyboardButton("sᴜᴘᴘᴏʀᴛ", url=f"https://t.me/{CHANNEL}"), 29 | ] 30 | ] 31 | ) 32 | 33 | 34 | async def skip_current_song(chat_id): 35 | if chat_id in QUEUE: 36 | chat_queue = get_queue(chat_id) 37 | if len(chat_queue) == 1: 38 | await call_py.leave_group_call(chat_id) 39 | clear_queue(chat_id) 40 | return 1 41 | else: 42 | try: 43 | songname = chat_queue[1][0] 44 | url = chat_queue[1][1] 45 | link = chat_queue[1][2] 46 | type = chat_queue[1][3] 47 | Q = chat_queue[1][4] 48 | if type == "Audio": 49 | await call_py.change_stream( 50 | chat_id, 51 | AudioPiped( 52 | url, 53 | ), 54 | ) 55 | elif type == "Video": 56 | if Q == 720: 57 | hm = HighQualityVideo() 58 | elif Q == 480: 59 | hm = MediumQualityVideo() 60 | elif Q == 360: 61 | hm = LowQualityVideo() 62 | await call_py.change_stream( 63 | chat_id, AudioVideoPiped(url, HighQualityAudio(), hm) 64 | ) 65 | pop_an_item(chat_id) 66 | return [songname, link, type] 67 | except: 68 | await call_py.leave_group_call(chat_id) 69 | clear_queue(chat_id) 70 | return 2 71 | else: 72 | return 0 73 | 74 | 75 | async def skip_item(chat_id, h): 76 | if chat_id in QUEUE: 77 | chat_queue = get_queue(chat_id) 78 | try: 79 | x = int(h) 80 | songname = chat_queue[x][0] 81 | chat_queue.pop(x) 82 | return songname 83 | except Exception as e: 84 | print(e) 85 | return 0 86 | else: 87 | return 0 88 | 89 | 90 | @call_py.on_stream_end() 91 | async def stream_end_handler(_, u: Update): 92 | if isinstance(u, StreamVideoEnded): 93 | chat_id = u.chat_id 94 | print(chat_id) 95 | op = await skip_current_song(chat_id) 96 | if op == 1: 97 | await app.send_message( 98 | chat_id, 99 | "**✅ Antrian kosong.\n\n• Assistant meninggalkan obrolan suara**", 100 | ) 101 | elif op == 2: 102 | await app.send_message( 103 | chat_id, 104 | f"**❌ terjadi kesalahan\n\n» Membersihkan antrian dan keluar dari obrolan video.**", 105 | ) 106 | else: 107 | await app.send_message( 108 | chat_id, 109 | f"**▶️ Sekarang memutar video\n\n🏷 Nama: [{op[0]}]({op[1]})**", 110 | disable_web_page_preview=True, 111 | reply_markup=keyboard, 112 | ) 113 | 114 | 115 | @call_py.on_kicked() 116 | async def kicked_handler(_, chat_id: int): 117 | if chat_id in QUEUE: 118 | clear_queue(chat_id) 119 | 120 | 121 | @call_py.on_closed_voice_chat() 122 | async def closed_voice_chat_handler(_, chat_id: int): 123 | if chat_id in QUEUE: 124 | clear_queue(chat_id) 125 | 126 | 127 | @call_py.on_left() 128 | async def left_handler(_, chat_id: int): 129 | if chat_id in QUEUE: 130 | clear_queue(chat_id) 131 | -------------------------------------------------------------------------------- /Music/__init__.py: -------------------------------------------------------------------------------- 1 | print("[INFO]: INITIALIZING") 2 | from pyrogram import Client 3 | import asyncio 4 | from Music.config import API_ID, API_HASH, BOT_TOKEN, MONGO_DB_URI, SUDO_USERS, UPSTREAM_BRANCH, UPSTREAM_REPO 5 | from motor.motor_asyncio import AsyncIOMotorClient as MongoClient 6 | import time 7 | import uvloop 8 | from os import listdir, mkdir 9 | from rich.console import Console 10 | import heroku3 11 | from Music import config 12 | import importlib 13 | from pyrogram import Client as Bot 14 | from Music.config import API_ID, API_HASH, BOT_TOKEN, MONGO_DB_URI, SUDO_USERS, LOG_GROUP_ID, OWNER_ID, CHANNEL, GROUP 15 | from pyrogram import Client 16 | from aiohttp import ClientSession 17 | from motor.motor_asyncio import AsyncIOMotorClient as MongoClient 18 | import time 19 | from git import Repo 20 | from git.exc import GitCommandError, InvalidGitRepositoryError 21 | from Music.MusicUtilities.helpers.tasks import install_requirements 22 | 23 | console = Console() 24 | 25 | def initialize(): 26 | global dbb 27 | dbb = {} 28 | 29 | initialize() 30 | 31 | UPSTREAM_BRANCH = UPSTREAM_BRANCH 32 | UPSTREAM_REPO = UPSTREAM_REPO 33 | 34 | 35 | print("[INFO]: INITIALIZING DATABASE") 36 | MONGODB_CLI = MongoClient(MONGO_DB_URI) 37 | db = MONGODB_CLI.wbb 38 | SUDOERS = SUDO_USERS 39 | OWNER = OWNER_ID 40 | CHANNEL = CHANNEL 41 | GROUP = GROUP 42 | async def load_sudoers(): 43 | global SUDOERS 44 | print("[INFO]: LOADING SUDO USERS") 45 | sudoersdb = db.sudoers 46 | sudoers = await sudoersdb.find_one({"sudo": "sudo"}) 47 | sudoers = [] if not sudoers else sudoers["sudoers"] 48 | for user_id in SUDOERS: 49 | if user_id not in sudoers: 50 | sudoers.append(user_id) 51 | await sudoersdb.update_one( 52 | {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True 53 | ) 54 | SUDOERS = (SUDOERS + sudoers) if sudoers else SUDOERS 55 | print("[INFO]: LOADED SUDO USERS") 56 | try: 57 | repo = Repo() 58 | except GitCommandError: 59 | console.print("┌ [red] Checking Git Updates!") 60 | console.print("└ [red]Git Command Error\n") 61 | return 62 | except InvalidGitRepositoryError: 63 | console.print("┌ [red] Checking Git Updates!") 64 | repo = Repo.init() 65 | if "origin" in repo.remotes: 66 | origin = repo.remote("origin") 67 | else: 68 | origin = repo.create_remote("origin", UPSTREAM_REPO) 69 | origin.fetch() 70 | repo.create_head(UPSTREAM_BRANCH, origin.refs[UPSTREAM_BRANCH]) 71 | repo.heads[UPSTREAM_BRANCH].set_tracking_branch( 72 | origin.refs[UPSTREAM_BRANCH] 73 | ) 74 | repo.heads[UPSTREAM_BRANCH].checkout(True) 75 | try: 76 | repo.create_remote("origin", UPSTREAM_REPO) 77 | except BaseException: 78 | pass 79 | nrs = repo.remote("origin") 80 | nrs.fetch(UPSTREAM_BRANCH) 81 | try: 82 | nrs.pull(UPSTREAM_BRANCH) 83 | except GitCommandError: 84 | repo.git.reset("--hard", "FETCH_HEAD") 85 | await install_requirements( 86 | "pip3 install --no-cache-dir -r requirements.txt" 87 | ) 88 | console.print("└ [red]Git Client Update Completed\n") 89 | 90 | loop = asyncio.get_event_loop() 91 | loop.run_until_complete(load_sudoers()) 92 | Music_START_TIME = time.time() 93 | loop = asyncio.get_event_loop() 94 | 95 | 96 | 97 | BOT_ID = 0 98 | BOT_NAME = "" 99 | BOT_USERNAME = "" 100 | ASSID = 0 101 | ASSNAME = "" 102 | ASSUSERNAME = "" 103 | ASSMENTION = "" 104 | print("[INFO]: INITIALIZING BOT CLIENT") 105 | app = Client( 106 | 'MusicBot', 107 | API_ID, 108 | API_HASH, 109 | bot_token=BOT_TOKEN, 110 | ) 111 | aiohttpsession = ClientSession() 112 | 113 | client = Client(config.SESSION_NAME, config.API_ID, config.API_HASH) 114 | 115 | def all_info(app, client): 116 | global BOT_ID, BOT_NAME, BOT_USERNAME 117 | global ASSID, ASSNAME, ASSMENTION, ASSUSERNAME 118 | getme = app.get_me() 119 | getme1 = client.get_me() 120 | BOT_ID = getme.id 121 | ASSID = getme1.id 122 | if getme.last_name: 123 | BOT_NAME = getme.first_name + " " + getme.last_name 124 | else: 125 | BOT_NAME = getme.first_name 126 | BOT_USERNAME = getme.username 127 | ASSNAME = ( 128 | f"{getme1.first_name} {getme1.last_name}" 129 | if getme1.last_name 130 | else getme1.first_name 131 | ) 132 | ASSUSERNAME = getme1.username 133 | ASSMENTION = getme1.mention 134 | 135 | 136 | 137 | print("[INFO]: STARTING BOT CLIENT") 138 | app.start() 139 | print("[INFO]: STARTING ASSISTANT CLIENT") 140 | client.start() 141 | print("[INFO]: LOADING BOT/ASSISTANT PROFILE INFO") 142 | all_info(app, client) 143 | print("[INFO]: LOADED BOT/ASSISTANT PROFILE INFO") 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

SKYZO MUSIC BOT

2 |

Telegram Music Bot And Stream Feature New Version

3 | 4 |

Coder GIF

5 | 6 |

7 | 8 | Skijo 12 | 13 |

14 | 15 |

16 | Gunakan Metode Ini Jika Anda Deploy Dengan Heroku 17 |

18 | 19 |

20 | Jika Button Deploy To Heroku Eror Silahkan Kalian Fork Repository Ini Lalu Kalian Ubah Link Deploy Tersebut, Seperti Contoh Dibawah 21 | 22 | Dari Link Di Bawah Ini 23 | https://dashboard.heroku.com/new?template=https://github.com/ridho17-ind/SkyzoMusicBot 24 | Ubah Seperti Link Di Bawah Ini 25 | https://dashboard.heroku.com/new?template=https://github.com/username-github-kamu/SkyzoMusicBot 26 |

27 | 28 |

29 | Cara Ubah app.json 30 |

31 | 32 | Setelah kalian ubah link Deploy seperti diatas 33 | Sekarang kalian harus mengubah app.json 34 | Yang harus diubah di app.json adalah Link Repository dari namanya ridho17-ind ke nama github kamu 35 | Contoh 36 | https://github.com/ridho17-ind/SkyzoMusicBot 37 | Lalu Kalian Ubah Ke 38 | https://github.com/username-github-kalian/SkyzoMusicBot 39 | 40 | 41 |

42 | 43 |

44 | Requirements 45 |

46 | 47 |

48 | Python3.9 | 49 | Telegram API Key | 50 | Telegram Bot Token | 51 | MongoDB URI | 52 | Tutorial Deploy 53 |

54 | 55 |

56 | Stay Up-To-Date 57 |

58 | 59 |

Coder GIF

60 | 61 | 62 | 63 |

64 | Metode Deploy 65 |

66 | 67 |

68 | 69 | 70 | 71 | 72 | 73 |

74 | 75 |

76 | Generating Pyrogram Session 77 |

78 | 79 |

80 | 81 |

82 | 83 | 84 |

85 | Config Vars 86 |

87 | 88 | 1. `API_ID` : Assistant Account Telegram API_ID, get it from my.telegram.org 89 | 2. `API_HASH` : Assistant Account Telegram API_HASH, get it from my.telegram.org 90 | 3. `ASS_ID` : Assistant Id Account 91 | 4. `BOT_TOKEN` : Your Telegram Bot Token, get it from @Botfather (Make sure Inline is turned On) 92 | 5. `SESSION_STRING` : Pyrogram Session String of Assistant Account. 93 | 6. `MONGO_DB_URI` : MongoDB Database URL. 94 | 7. `LOG_GROUP_ID` : Chat ID where bot will log everything. Use Group Chats Only. 95 | 8. `DURATION_LIMIT` : Duration Limit for Music (Mins) 96 | 9. `SUDO_USERS` : Sudo Users for Bot. (For multiple users seperate IDs with space) 97 | 10. `OWNER_ID`: Owner ID Of Bot 98 | 11. `GROUP` : Support Group Link (Leave blank if you don't have one) 99 | 12. `CHANNEL` : Support Channel Link ( Leave blank if you don't have one) 100 | 13. `HEROKU_APP_NAME`: Heroku App Name 101 | 14. `HEROKU_API_KEY`: Heroku Api Key 102 | 15. `UPSTREAM_BRANCH`: Branch Repository Original main 103 | 16. `UPSTREAM_REPO`: Repository Link 104 | 17. `BOT_IMG`: Usage Telegraph Link Img 105 | 106 | 107 | 108 |

109 | CONTRIBUTORS 110 |

111 | 112 | 113 | 114 | **[Kenkan Gay](https://github.com/kenkansaja) | [Skyzo Ganteng](https://github.com/ridho17-ind) | [Fariz Gay](https://github.com/fjgaming212) | [Abing Not Gay](https://github.com/SayaAbing)** 115 | 116 | 117 | 118 |

119 | CREDIT 120 |

121 | 122 | 123 | 124 | **[The Yukki Music](https://github.com/NotReallyShikhar/YukkiMusicBot) | [Not Realy Shikhar](https://github.com/NotReallyShikhar)** 125 | -------------------------------------------------------------------------------- /Music/Plugins/db.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram import filters 4 | 5 | from Music import app, SUDOERS 6 | 7 | from Music.MusicUtilities.database.chats import get_served_chats 8 | 9 | @app.on_message(filters.command("broadcast_pin") & filters.user(SUDOERS)) 10 | async def broadcast_message_pin_silent(_, message): 11 | if not message.reply_to_message: 12 | pass 13 | else: 14 | x = message.reply_to_message.message_id 15 | y = message.chat.id 16 | sent = 0 17 | pin = 0 18 | chats = [] 19 | schats = await get_served_chats() 20 | for chat in schats: 21 | chats.append(int(chat["chat_id"])) 22 | for i in chats: 23 | try: 24 | m = await app.forward_messages(i, y, x) 25 | try: 26 | await m.pin(disable_notification=True) 27 | pin += 1 28 | except Exception: 29 | pass 30 | await asyncio.sleep(0.3) 31 | sent += 1 32 | except Exception: 33 | pass 34 | await message.reply_text( 35 | f"**Broadcasted Message In {sent} Chats with {pin} Pins.**" 36 | ) 37 | return 38 | if len(message.command) < 2: 39 | await message.reply_text( 40 | "**Usage**:\n/broadcast [MESSAGE] or [Reply to a Message]" 41 | ) 42 | return 43 | text = message.text.split(None, 1)[1] 44 | sent = 0 45 | pin = 0 46 | chats = [] 47 | schats = await get_served_chats() 48 | for chat in schats: 49 | chats.append(int(chat["chat_id"])) 50 | for i in chats: 51 | try: 52 | m = await app.send_message(i, text=text) 53 | try: 54 | await m.pin(disable_notification=True) 55 | pin += 1 56 | except Exception: 57 | pass 58 | await asyncio.sleep(0.3) 59 | sent += 1 60 | except Exception: 61 | pass 62 | await message.reply_text( 63 | f"**Broadcasted Message In {sent} Chats and {pin} Pins.**" 64 | ) 65 | 66 | 67 | @app.on_message(filters.command("broadcast_pin_loud") & filters.user(SUDOERS)) 68 | async def broadcast_message_pin_loud(_, message): 69 | if not message.reply_to_message: 70 | pass 71 | else: 72 | x = message.reply_to_message.message_id 73 | y = message.chat.id 74 | sent = 0 75 | pin = 0 76 | chats = [] 77 | schats = await get_served_chats() 78 | for chat in schats: 79 | chats.append(int(chat["chat_id"])) 80 | for i in chats: 81 | try: 82 | m = await app.forward_messages(i, y, x) 83 | try: 84 | await m.pin(disable_notification=False) 85 | pin += 1 86 | except Exception: 87 | pass 88 | await asyncio.sleep(0.3) 89 | sent += 1 90 | except Exception: 91 | pass 92 | await message.reply_text( 93 | f"**Broadcasted Message In {sent} Chats with {pin} Pins.**" 94 | ) 95 | return 96 | if len(message.command) < 2: 97 | await message.reply_text( 98 | "**Usage**:\n/broadcast [MESSAGE] or [Reply to a Message]" 99 | ) 100 | return 101 | text = message.text.split(None, 1)[1] 102 | sent = 0 103 | pin = 0 104 | chats = [] 105 | schats = await get_served_chats() 106 | for chat in schats: 107 | chats.append(int(chat["chat_id"])) 108 | for i in chats: 109 | try: 110 | m = await app.send_message(i, text=text) 111 | try: 112 | await m.pin(disable_notification=False) 113 | pin += 1 114 | except Exception: 115 | pass 116 | await asyncio.sleep(0.3) 117 | sent += 1 118 | except Exception: 119 | pass 120 | await message.reply_text( 121 | f"**Broadcasted Message In {sent} Chats and {pin} Pins.**" 122 | ) 123 | 124 | 125 | @app.on_message(filters.command("broadcast") & filters.user(SUDOERS)) 126 | async def broadcast(_, message): 127 | if not message.reply_to_message: 128 | pass 129 | else: 130 | x = message.reply_to_message.message_id 131 | y = message.chat.id 132 | sent = 0 133 | chats = [] 134 | schats = await get_served_chats() 135 | for chat in schats: 136 | chats.append(int(chat["chat_id"])) 137 | for i in chats: 138 | try: 139 | m = await app.forward_messages(i, y, x) 140 | await asyncio.sleep(0.3) 141 | sent += 1 142 | except Exception: 143 | pass 144 | await message.reply_text(f"**Broadcasted Message In {sent} Chats.**") 145 | return 146 | if len(message.command) < 2: 147 | await message.reply_text( 148 | "**Usage**:\n/broadcast [MESSAGE] or [Reply to a Message]" 149 | ) 150 | return 151 | text = message.text.split(None, 1)[1] 152 | sent = 0 153 | chats = [] 154 | schats = await get_served_chats() 155 | for chat in schats: 156 | chats.append(int(chat["chat_id"])) 157 | for i in chats: 158 | try: 159 | m = await app.send_message(i, text=text) 160 | await asyncio.sleep(0.3) 161 | sent += 1 162 | except Exception: 163 | pass 164 | await message.reply_text(f"**Broadcasted Message In {sent} Chats.**") 165 | 166 | -------------------------------------------------------------------------------- /Music/Plugins/auth.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters 2 | from pyrogram.types import Message 3 | 4 | from Music import SUDOERS, app 5 | from Music.MusicUtilities.database.auth import (_get_authusers, delete_authuser, get_authuser, 6 | get_authuser_count, get_authuser_names, 7 | save_authuser) 8 | from Music.MusicUtilities.helpers.admins import AdminActual 9 | from Music.MusicUtilities.database.changers import (alpha_to_int, int_to_alpha, 10 | time_to_seconds) 11 | 12 | 13 | @app.on_message(filters.command("auth") & filters.group) 14 | @AdminActual 15 | async def auth(_, message: Message): 16 | if not message.reply_to_message: 17 | if len(message.command) != 2: 18 | await message.reply_text( 19 | "Reply to a user's message or give username/user_id." 20 | ) 21 | return 22 | user = message.text.split(None, 1)[1] 23 | if "@" in user: 24 | user = user.replace("@", "") 25 | user = await app.get_users(user) 26 | user_id = message.from_user.id 27 | token = await int_to_alpha(user.id) 28 | from_user_name = message.from_user.first_name 29 | from_user_id = message.from_user.id 30 | _check = await get_authuser_names(message.chat.id) 31 | count = 0 32 | for smex in _check: 33 | count += 1 34 | if int(count) == 20: 35 | return await message.reply_text( 36 | "You can only have 20 Users In Your Groups Authorised Users List (AUL)" 37 | ) 38 | if token not in _check: 39 | assis = { 40 | "auth_user_id": user.id, 41 | "auth_name": user.first_name, 42 | "admin_id": from_user_id, 43 | "admin_name": from_user_name, 44 | } 45 | await save_authuser(message.chat.id, token, assis) 46 | await message.reply_text( 47 | f"Added to Authorised Users List of this group." 48 | ) 49 | return 50 | else: 51 | await message.reply_text(f"Already in the Authorised Users List.") 52 | return 53 | from_user_id = message.from_user.id 54 | user_id = message.reply_to_message.from_user.id 55 | user_name = message.reply_to_message.from_user.first_name 56 | token = await int_to_alpha(user_id) 57 | from_user_name = message.from_user.first_name 58 | _check = await get_authuser_names(message.chat.id) 59 | count = 0 60 | for smex in _check: 61 | count += 1 62 | if int(count) == 20: 63 | return await message.reply_text( 64 | "You can only have 20 Users In Your Groups Authorised Users List (AUL)" 65 | ) 66 | if token not in _check: 67 | assis = { 68 | "auth_user_id": user_id, 69 | "auth_name": user_name, 70 | "admin_id": from_user_id, 71 | "admin_name": from_user_name, 72 | } 73 | await save_authuser(message.chat.id, token, assis) 74 | await message.reply_text( 75 | f"Added to Authorised Users List of this group." 76 | ) 77 | return 78 | else: 79 | await message.reply_text(f"Already in the Authorised Users List.") 80 | 81 | 82 | @app.on_message(filters.command("unauth") & filters.group) 83 | @AdminActual 84 | async def whitelist_chat_func(_, message: Message): 85 | if not message.reply_to_message: 86 | if len(message.command) != 2: 87 | await message.reply_text( 88 | "Reply to a user's message or give username/user_id." 89 | ) 90 | return 91 | user = message.text.split(None, 1)[1] 92 | if "@" in user: 93 | user = user.replace("@", "") 94 | user = await app.get_users(user) 95 | token = await int_to_alpha(user.id) 96 | deleted = await delete_authuser(message.chat.id, token) 97 | if deleted: 98 | return await message.reply_text( 99 | f"Removed from Authorised Users List of this Group." 100 | ) 101 | else: 102 | return await message.reply_text(f"Not an Authorised User.") 103 | user_id = message.reply_to_message.from_user.id 104 | token = await int_to_alpha(user_id) 105 | deleted = await delete_authuser(message.chat.id, token) 106 | if deleted: 107 | return await message.reply_text( 108 | f"Removed from Authorised Users List of this Group." 109 | ) 110 | else: 111 | return await message.reply_text(f"Not an Authorised User.") 112 | 113 | 114 | @app.on_message(filters.command("authusers") & filters.group) 115 | async def authusers(_, message: Message): 116 | _playlist = await get_authuser_names(message.chat.id) 117 | if not _playlist: 118 | return await message.reply_text( 119 | f"No Authorised Users in this Group.\n\nAdd Auth users by /auth and remove by /unauth." 120 | ) 121 | else: 122 | j = 0 123 | m = await message.reply_text( 124 | "Fetching Authorised Users... Please Wait" 125 | ) 126 | msg = f"**Authorised Users List[AUL]:**\n\n" 127 | for note in _playlist: 128 | _note = await get_authuser(message.chat.id, note) 129 | user_id = _note["auth_user_id"] 130 | user_name = _note["auth_name"] 131 | admin_id = _note["admin_id"] 132 | admin_name = _note["admin_name"] 133 | try: 134 | user = await app.get_users(user_id) 135 | user = user.first_name 136 | j += 1 137 | except Exception: 138 | continue 139 | msg += f"{j}➤ {user}[`{user_id}`]\n" 140 | msg += f" ┗ Added By:- {admin_name}[`{admin_id}`]\n\n" 141 | await m.edit_text(msg) 142 | -------------------------------------------------------------------------------- /Music/Plugins/playlist.py: -------------------------------------------------------------------------------- 1 | from youtubesearchpython import VideosSearch 2 | import os 3 | from os import path 4 | import random 5 | import asyncio 6 | import shutil 7 | from time import time 8 | import yt_dlp 9 | from Music import converter 10 | from pyrogram import Client 11 | from pyrogram.types import Message 12 | from pyrogram.types import Voice 13 | from Music import (app, BOT_USERNAME, BOT_ID) 14 | from Music.MusicUtilities.tgcallsrun import (music, convert, download, clear, get, is_empty, put, task_done, smexy) 15 | from Music.MusicUtilities.database.queue import (is_active_chat, add_active_chat, remove_active_chat, music_on, is_music_playing, music_off) 16 | from Music.MusicUtilities.database.onoff import (is_on_off, add_on, add_off) 17 | from Music.MusicUtilities.database.blacklistchat import (blacklisted_chats, blacklist_chat, whitelist_chat) 18 | from Music.MusicUtilities.database.gbanned import (get_gbans_count, is_gbanned_user, add_gban_user, add_gban_user) 19 | from Music.MusicUtilities.database.playlist import (get_playlist_count, _get_playlists, get_note_names, get_playlist, save_playlist, delete_playlist) 20 | from Music.MusicUtilities.helpers.inline import play_keyboard, confirm_keyboard, play_list_keyboard, close_keyboard, confirm_group_keyboard 21 | from Music.MusicUtilities.database.theme import (_get_theme, get_theme, save_theme) 22 | from Music.MusicUtilities.database.assistant import (_get_assistant, get_assistant, save_assistant) 23 | from Music.config import DURATION_LIMIT, ASS_ID 24 | from Music.MusicUtilities.helpers.decorators import errors 25 | from Music.MusicUtilities.helpers.filters import command 26 | from Music.MusicUtilities.helpers.gets import (get_url, themes, random_assistant) 27 | from Music.MusicUtilities.helpers.thumbnails import gen_thumb 28 | from Music.MusicUtilities.helpers.chattitle import CHAT_TITLE 29 | from Music.MusicUtilities.helpers.ytdl import ytdl_opts 30 | from Music.MusicUtilities.helpers.inline import (play_keyboard, search_markup, play_markup, playlist_markup) 31 | from pyrogram import filters 32 | from typing import Union 33 | from youtubesearchpython import VideosSearch 34 | from pyrogram.types import Message, Audio, Voice 35 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message, ) 36 | 37 | 38 | options = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "all","16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",] 39 | 40 | 41 | @app.on_message(filters.command("playlist")) 42 | async def pause_cmd(_, message): 43 | thumb ="cache/Playlist.png" 44 | await message.reply_photo( 45 | photo=thumb, 46 | caption=("**__Music's Playlist Feature__**\n\nSelect The Playlist, You want to check!"), 47 | reply_markup=play_list_keyboard) 48 | return 49 | 50 | 51 | @app.on_message(filters.command("delmyplaylist")) 52 | async def pause_cmd(_, message): 53 | usage = ("Usage:\n\n/delmyplaylist [Numbers between 1-30] ( to delete a particular music in playlist )\n\nor\n\n /delmyplaylist all ( to delete whole playlist )") 54 | if len(message.command) < 2: 55 | return await message.reply_text(usage) 56 | name = message.text.split(None, 1)[1].strip() 57 | if not name: 58 | return await message.reply_text(usage) 59 | if name not in options: 60 | return await message.reply_text(usage) 61 | if len(message.text) == 18: 62 | return await message.reply_text(f"Confirmation!!\nYou sure you want to delete your whole playlist?", reply_markup=confirm_keyboard) 63 | else: 64 | _playlist = await get_note_names(message.from_user.id) 65 | if not _playlist: 66 | await message.reply_text("You have no Playlist on Music's Server") 67 | else: 68 | titlex = [] 69 | j = 0 70 | count = int(name) 71 | for note in _playlist: 72 | j += 1 73 | _note = await get_playlist(message.from_user.id, note) 74 | if j == count: 75 | deleted = await delete_playlist(message.from_user.id, note) 76 | if deleted: 77 | return await message.reply_text(f"**Deleted the {count} music in playlist**") 78 | else: 79 | return await message.reply_text(f"**No such saved music in playlist.**") 80 | await message.reply_text("You have no such music in Playlist.") 81 | 82 | 83 | @app.on_message(filters.command("delgroupplaylist")) 84 | async def delgroupplaylist(_, message): 85 | a = await app.get_chat_member(message.chat.id , message.from_user.id) 86 | if not a.can_manage_voice_chats: 87 | return await message.reply_text("I don't have the required permission to perform this action.\n**Permission:** __MANAGE VOICE CHATS__") 88 | usage = ("Usage:\n\n/delgroupplaylist [Numbers between 1-30] ( to delete a particular music in playlist )\n\nor\n\n /delgroupplaylist all ( to delete whole playlist )") 89 | if len(message.command) < 2: 90 | return await message.reply_text(usage) 91 | name = message.text.split(None, 1)[1].strip() 92 | if not name: 93 | return await message.reply_text(usage) 94 | if name not in options: 95 | return await message.reply_text(usage) 96 | if len(message.text) == 21: 97 | return await message.reply_text(f"Confirmation!!\nYou sure you want to delete whole whole playlist?", reply_markup=confirm_group_keyboard) 98 | else: 99 | _playlist = await get_note_names(message.chat.id) 100 | if not _playlist: 101 | await message.reply_text("Group has no Playlist on Music's Server") 102 | else: 103 | titlex = [] 104 | j = 0 105 | count = int(name) 106 | for note in _playlist: 107 | j += 1 108 | _note = await get_playlist(message.chat.id, note) 109 | if j == count: 110 | deleted = await delete_playlist(message.chat.id, note) 111 | if deleted: 112 | return await message.reply_text(f"**Deleted the {count} music in group's playlist**") 113 | else: 114 | return await message.reply_text(f"**No such saved music in Group playlist.**") 115 | await message.reply_text("You have no such music in Group Playlist.") 116 | -------------------------------------------------------------------------------- /Music/Plugins/start.py: -------------------------------------------------------------------------------- 1 | import yt_dlp 2 | from Music import ( 3 | ASSID, 4 | BOT_ID, 5 | BOT_NAME, 6 | BOT_USERNAME, 7 | OWNER, 8 | SUDOERS, 9 | app, 10 | ) 11 | from Music.MusicUtilities.database.chats import is_served_chat 12 | from Music.MusicUtilities.database.queue import remove_active_chat 13 | from Music.MusicUtilities.database.sudo import get_sudoers 14 | from Music.MusicUtilities.helpers.inline import personal_markup 15 | from Music.MusicUtilities.helpers.thumbnails import down_thumb 16 | from Music.MusicUtilities.helpers.ytdl import ytdl_opts 17 | from Music.config import GROUP, CHANNEL, BOT_IMG 18 | from pyrogram import Client, filters 19 | from pyrogram.types import ( 20 | InlineKeyboardButton, 21 | InlineKeyboardMarkup, 22 | Message, 23 | ) 24 | 25 | 26 | def start_pannel(): 27 | buttons = [ 28 | [ 29 | InlineKeyboardButton(text="Support​", url=f"https://t.me/{GROUP}"), 30 | InlineKeyboardButton(text="Updates", url=f"https://t.me/{CHANNEL}"), 31 | ], 32 | [ 33 | InlineKeyboardButton("Command", url="https://telegra.ph/Skyzo-11-10"), 34 | ], 35 | ] 36 | return ( 37 | "🎛 **{BOT_NAME} Is a bot that can play a song or video from the voice chats**", 38 | buttons, 39 | ) 40 | 41 | 42 | pstart_markup = InlineKeyboardMarkup( 43 | [ 44 | [ 45 | InlineKeyboardButton( 46 | "Add Me To Your Group", url=f"https://t.me/{BOT_USERNAME}?startgroup=true"), 47 | ], 48 | [ 49 | InlineKeyboardButton("Support", url=f"https://t.me/{GROUP}"), 50 | InlineKeyboardButton("Updates", url=f"https://t.me/{CHANNEL}"), 51 | ], 52 | [ 53 | InlineKeyboardButton("Cd Music", url="https://telegra.ph/Skyzo-11-10"), 54 | InlineKeyboardButton("Cd Dev", url="https://telegra.ph/壊Skyzo-01-21"), 55 | InlineKeyboardButton("Cd Stream", url="https://telegra.ph/sᴋʏᴢᴏ-ᴇx-12-21"), 56 | ], 57 | ] 58 | ) 59 | welcome_captcha_group = 2 60 | 61 | 62 | @app.on_message(filters.new_chat_members, group=welcome_captcha_group) 63 | async def welcome(_, message: Message): 64 | chat_id = message.chat.id 65 | for member in message.new_chat_members: 66 | try: 67 | if member.id in OWNER: 68 | return await message.reply_text( 69 | f"🦸🏻‍♂️ **Owners Bot [{member.mention}] Has Joined Your Chats.**" 70 | ) 71 | if member.id in SUDOERS: 72 | return await message.reply_text( 73 | f"**🉐 Admin Bot [{member.mention}] Just Joined Your Chats.**" 74 | ) 75 | if member.id == ASSID: 76 | await remove_active_chat(chat_id) 77 | if member.id == BOT_ID: 78 | out = start_pannel() 79 | await message.reply_text( 80 | f""" 81 | 👋 **Hi, Thanks For Adding Me To The Group** 82 | 83 | 🛵 **Don't Forget To Make Me Admin So Music Can Run Normally** 84 | """, 85 | reply_markup=InlineKeyboardMarkup(out[1]), 86 | disable_web_page_preview=True 87 | ) 88 | return 89 | except BaseException: 90 | return 91 | 92 | 93 | @Client.on_message( 94 | filters.group 95 | & filters.command( 96 | ["start", "help", f"start@{BOT_USERNAME}", f"help@{BOT_USERNAME}"] 97 | ) 98 | ) 99 | async def start(_, message: Message): 100 | chat_id = message.chat.id 101 | out = start_pannel() 102 | await message.reply_text( 103 | f""" 104 | **[🚀]({BOT_IMG}) Thanks For Adding Me To {message.chat.title}.** 105 | **㊙️ {BOT_NAME} Is Music Player And Video Player Bot** 106 | """, 107 | reply_markup=InlineKeyboardMarkup(out[1]), 108 | disable_web_page_preview=True 109 | ) 110 | return 111 | 112 | 113 | @Client.on_message(filters.private & filters.incoming & filters.command("start")) 114 | async def play(_, message: Message): 115 | if len(message.command) == 1: 116 | user_id = message.from_user.id 117 | user_name = message.from_user.first_name 118 | rpk = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" 119 | await app.send_message( 120 | message.chat.id, 121 | text=f""" 122 | **[🗣]({BOT_IMG}) Hello {rpk}! Ready Use Me? 123 | 124 | 🉐 [{BOT_NAME}](tg://user?id=2129034376) Is A Bot That Can Be Used To Listen To Songs In Voice Chat And Can Play Videos In Voice Chat! 125 | 126 | 🧰 To Find Out All The Available Command Bots, You Can Press The Two Buttons Below, Namely Cd Music, Cd Dev And Cd Stream** 127 | 128 | """, 129 | parse_mode="markdown", 130 | reply_markup=pstart_markup, 131 | reply_to_message_id=message.message_id, 132 | ) 133 | elif len(message.command) == 2: 134 | query = message.text.split(None, 1)[1] 135 | f1 = query[0] 136 | f2 = query[1] 137 | f3 = query[2] 138 | finxx = f"{f1}{f2}{f3}" 139 | if str(finxx) == "inf": 140 | query = (str(query)).replace("info_", "", 1) 141 | query = f"https://www.youtube.com/watch?v={query}" 142 | with yt_dlp.YoutubeDL(ytdl_opts) as ytdl: 143 | x = ytdl.extract_info(query, download=False) 144 | thumbnail = x["thumbnail"] 145 | searched_text = f""" 146 | 🔍 **Video Track Information** 147 | 148 | ❇️ **Title:** {x["title"]} 149 | 150 | ⏳ **Duration:** {round(x["duration"] / 60)} Mins 151 | 👀 **Views:** `{x["view_count"]}` 152 | 👍 **Like:** `{x["like_count"]}` 153 | 👎 **Dislike:** `{x["dislike_count"]}` 154 | ⭐️ **Rating:** {x["average_rating"]} 155 | 📹 **Channel:** {x["uploader"]} 156 | 📎 **Channel Link:** [Kunjungi Dari Sini]({x["channel_url"]}) 157 | 🔗 **Link:** [Link]({x["webpage_url"]}) 158 | """ 159 | link = x["webpage_url"] 160 | buttons = personal_markup(link) 161 | userid = message.from_user.id 162 | thumb = await down_thumb(thumbnail, userid) 163 | await app.send_photo( 164 | message.chat.id, 165 | photo=thumb, 166 | caption=searched_text, 167 | parse_mode="markdown", 168 | reply_markup=InlineKeyboardMarkup(buttons), 169 | ) 170 | if str(finxx) == "sud": 171 | sudoers = await get_sudoers() 172 | text = "**💻 SUDO USERS FLICKS BOT**\n\n" 173 | for count, user_id in enumerate(sudoers, 1): 174 | try: 175 | user = await app.get_users(user_id) 176 | user = user.first_name if not user.mention else user.mention 177 | except Exception: 178 | continue 179 | text += f"- {user}\n" 180 | if not text: 181 | await message.reply_text("Tidak Ada Pengguna Sudo") 182 | else: 183 | await message.reply_text(text) 184 | -------------------------------------------------------------------------------- /Music/Plugins/gbanmusic.py: -------------------------------------------------------------------------------- 1 | from Music import app, SUDOERS, BOT_ID, OWNER 2 | from Music.MusicUtilities.database.gbanned import (get_gbans_count, is_gbanned_user, add_gban_user, add_gban_user, remove_gban_user) 3 | from Music.MusicUtilities.database.sudo import (get_sudoers, add_sudo, remove_sudo) 4 | from Music.MusicUtilities.database.chats import get_served_chats 5 | from pyrogram import filters, Client 6 | from pyrogram.types import Message 7 | from pyrogram.errors import FloodWait 8 | import asyncio 9 | 10 | @app.on_message(filters.command("gban") & filters.user(OWNER)) 11 | async def ban_globally(_, message): 12 | if not message.reply_to_message: 13 | if len(message.command) < 2: 14 | await message.reply_text("**Usage:**\n/block [USERNAME | USER_ID]") 15 | return 16 | user = message.text.split(None, 2)[1] 17 | if "@" in user: 18 | user = user.replace("@", "") 19 | user = (await app.get_users(user)) 20 | from_user = message.from_user 21 | sudoers = await get_sudoers() 22 | if user.id == from_user.id: 23 | return await message.reply_text("You want to block yourself?") 24 | elif user.id == BOT_ID: 25 | await message.reply_text("Should i block myself?") 26 | elif user.id in sudoers: 27 | await message.reply_text("You want to block a sudo user?") 28 | else: 29 | 30 | await add_gban_user(user.id) 31 | served_chats = [] 32 | chats = await get_served_chats() 33 | for chat in chats: 34 | served_chats.append(int(chat["chat_id"])) 35 | m = await message.reply_text(f"**Initializing Gobal Ban on {user.mention}**\n\nExpected Time : {len(served_chats)}") 36 | number_of_chats = 0 37 | for sex in served_chats: 38 | try: 39 | await app.kick_chat_member(sex, user.id) 40 | number_of_chats += 1 41 | await asyncio.sleep(1) 42 | except FloodWait as e: 43 | await asyncio.sleep(int(e.x)) 44 | except Exception: 45 | pass 46 | ban_text = f""" 47 | **⛔️ New Global Ban on Music** 48 | **🗃️ Origin:** {message.chat.title} [`{message.chat.id}`] 49 | **👮🏻‍♂ Sudo User:** {from_user.mention} 50 | **👩🏻‍🎤 Banned User:** {user.mention} 51 | **🦹🏻 Banned User ID:** `{user.id}` 52 | **📑 Chats:** {number_of_chats}""" 53 | try: 54 | await m.delete() 55 | except Exception: 56 | pass 57 | await message.reply_text(f"{ban_text}",disable_web_page_preview=True,) 58 | return 59 | from_user_id = message.from_user.id 60 | from_user_mention = message.from_user.mention 61 | user_id = message.reply_to_message.from_user.id 62 | mention = message.reply_to_message.from_user.mention 63 | sudoers = await get_sudoers() 64 | if user_id == from_user_id: 65 | await message.reply_text("You want to block yourself?") 66 | elif user_id == BOT_ID: 67 | await message.reply_text("Should i block myself?") 68 | elif user_id in sudoers: 69 | await message.reply_text("You want to block a sudo user?") 70 | else: 71 | is_gbanned = await is_gbanned_user(user_id) 72 | if is_gbanned: 73 | await message.reply_text("Already Gbanned.") 74 | else: 75 | await add_gban_user(user_id) 76 | served_chats = [] 77 | chats = await get_served_chats() 78 | for chat in chats: 79 | served_chats.append(int(chat["chat_id"])) 80 | m = await message.reply_text(f"**Initializing Gobal Ban on {mention}**\n\nExpected Time : {len(served_chats)}") 81 | number_of_chats = 0 82 | for sex in served_chats: 83 | try: 84 | await app.kick_chat_member(sex, user_id) 85 | number_of_chats += 1 86 | await asyncio.sleep(1) 87 | except FloodWait as e: 88 | await asyncio.sleep(int(e.x)) 89 | except Exception: 90 | pass 91 | ban_text = f""" 92 | __**New Global Ban on Music**__ 93 | **Origin:** {message.chat.title} [`{message.chat.id}`] 94 | **Sudo User:** {from_user_mention} 95 | **Banned User:** {mention} 96 | **Banned User ID:** `{user_id}` 97 | **Chats:** {number_of_chats}""" 98 | try: 99 | await m.delete() 100 | except Exception: 101 | pass 102 | await message.reply_text(f"{ban_text}",disable_web_page_preview=True,) 103 | return 104 | 105 | 106 | @app.on_message(filters.command("ungban") & filters.user(OWNER)) 107 | async def unban_globally(_, message): 108 | if not message.reply_to_message: 109 | if len(message.command) != 2: 110 | await message.reply_text("**Usage:**\n/unblock [USERNAME | USER_ID]") 111 | return 112 | user = message.text.split(None, 1)[1] 113 | if "@" in user: 114 | user = user.replace("@", "") 115 | user = (await app.get_users(user)) 116 | from_user = message.from_user 117 | sudoers = await get_sudoers() 118 | if user.id == from_user.id: 119 | await message.reply_text("You want to unblock yourself?") 120 | elif user.id == BOT_ID: 121 | await message.reply_text("Should i unblock myself?") 122 | elif user.id in sudoers: 123 | await message.reply_text("Sudo users can't be blocked/unblocked.") 124 | else: 125 | is_gbanned = await is_gbanned_user(user.id) 126 | if not is_gbanned: 127 | await message.reply_text("He's already free, why bully him?") 128 | else: 129 | await remove_gban_user(user.id) 130 | await message.reply_text(f"Ungbanned!") 131 | return 132 | from_user_id = message.from_user.id 133 | user_id = message.reply_to_message.from_user.id 134 | mention = message.reply_to_message.from_user.mention 135 | sudoers = await get_sudoers() 136 | if user_id == from_user_id: 137 | await message.reply_text("You want to unblock yourself?") 138 | elif user_id == BOT_ID: 139 | await message.reply_text("Should i unblock myself? But i'm not blocked.") 140 | elif user_id in sudoers: 141 | await message.reply_text("Sudo users can't be blocked/unblocked.") 142 | else: 143 | is_gbanned = await is_gbanned_user(user_id) 144 | if not is_gbanned: 145 | await message.reply_text("He's already free, why bully him?") 146 | else: 147 | await remove_gban_user(user_id) 148 | await message.reply_text(f"Ungbanned!") 149 | 150 | 151 | chat_watcher_group = 5 152 | 153 | @app.on_message(group=chat_watcher_group) 154 | async def chat_watcher_func(_, message): 155 | try: 156 | userid = message.from_user.id 157 | except Exception: 158 | return 159 | checking = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 160 | if await is_gbanned_user(userid): 161 | try: 162 | await message.chat.kick_member(userid) 163 | except Exception: 164 | return 165 | await message.reply_text(f"{checking} is globally banned by Music and has been kicked out of the chat.\n\n**Possible Reason:** Potential Spammer and Abuser.") 166 | -------------------------------------------------------------------------------- /Music/Plugins/essentials.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import shutil 4 | import re 5 | import sys 6 | import traceback 7 | from inspect import getfullargspec 8 | from io import StringIO 9 | from time import time 10 | from Music.MusicUtilities.database.queue import (is_active_chat, add_active_chat, remove_active_chat, music_on, is_music_playing, music_off) 11 | from Music.MusicUtilities.database.onoff import (is_on_off, add_on, add_off) 12 | from Music.MusicUtilities.database.blacklistchat import (blacklisted_chats, blacklist_chat, whitelist_chat) 13 | from Music.MusicUtilities.database.gbanned import (get_gbans_count, is_gbanned_user, add_gban_user, add_gban_user) 14 | from Music.MusicUtilities.database.theme import (_get_theme, get_theme, save_theme) 15 | from Music.MusicUtilities.database.assistant import (_get_assistant, get_assistant, save_assistant) 16 | from Music.config import DURATION_LIMIT 17 | from Music.MusicUtilities.tgcallsrun import (music, clear, get, is_empty, put, task_done) 18 | from Music.MusicUtilities.helpers.decorators import errors 19 | from Music.MusicUtilities.helpers.filters import command 20 | from Music.MusicUtilities.helpers.gets import (get_url, themes, random_assistant) 21 | from Music.MusicUtilities.helpers.logger import LOG_CHAT 22 | from Music.MusicUtilities.helpers.thumbnails import gen_thumb 23 | from Music.MusicUtilities.helpers.chattitle import CHAT_TITLE 24 | from Music.MusicUtilities.helpers.ytdl import ytdl 25 | from Music.MusicUtilities.helpers.inline import (play_keyboard, search_markup) 26 | from pyrogram import filters 27 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message 28 | from sys import version as pyver 29 | from pyrogram import Client, filters 30 | from pyrogram.types import Message 31 | from Music import app, SUDOERS, OWNER 32 | from Music.MusicUtilities.helpers.filters import command 33 | from Music.MusicUtilities.helpers.decorators import errors 34 | from Music.MusicUtilities.database.functions import start_restart_stage 35 | 36 | @Client.on_message(command("update") & filters.user(OWNER)) 37 | @errors 38 | async def update(_, message: Message): 39 | m = subprocess.check_output(["git", "pull"]).decode("UTF-8") 40 | if str(m[0]) != "A": 41 | x = await message.reply_text("Found Updates! Pushing Now.") 42 | await start_restart_stage(x.chat.id, x.message_id) 43 | os.execvp("python3", ["python3", "-m", "Music"]) 44 | else: 45 | await message.reply_text("Already Upto Date") 46 | 47 | async def aexec(code, client, message): 48 | exec( 49 | "async def __aexec(client, message): " 50 | + "".join(f"\n {a}" for a in code.split("\n")) 51 | ) 52 | return await locals()["__aexec"](client, message) 53 | 54 | 55 | async def edit_or_reply(msg: Message, **kwargs): 56 | func = msg.edit_text if msg.from_user.is_self else msg.reply 57 | spec = getfullargspec(func.__wrapped__).args 58 | await func(**{k: v for k, v in kwargs.items() if k in spec}) 59 | 60 | 61 | @app.on_message( 62 | filters.user(OWNER) 63 | & ~filters.forwarded 64 | & ~filters.via_bot 65 | & filters.command("eval") 66 | ) 67 | async def executor(client, message): 68 | if len(message.command) < 2: 69 | return await edit_or_reply(message, text="__Nigga Give me some command to execute.__") 70 | try: 71 | cmd = message.text.split(" ", maxsplit=1)[1] 72 | except IndexError: 73 | return await message.delete() 74 | t1 = time() 75 | old_stderr = sys.stderr 76 | old_stdout = sys.stdout 77 | redirected_output = sys.stdout = StringIO() 78 | redirected_error = sys.stderr = StringIO() 79 | stdout, stderr, exc = None, None, None 80 | try: 81 | await aexec(cmd, client, message) 82 | except Exception: 83 | exc = traceback.format_exc() 84 | stdout = redirected_output.getvalue() 85 | stderr = redirected_error.getvalue() 86 | sys.stdout = old_stdout 87 | sys.stderr = old_stderr 88 | evaluation = "" 89 | if exc: 90 | evaluation = exc 91 | elif stderr: 92 | evaluation = stderr 93 | elif stdout: 94 | evaluation = stdout 95 | else: 96 | evaluation = "Success" 97 | final_output = f"**OUTPUT**:\n```{evaluation.strip()}```" 98 | if len(final_output) > 4096: 99 | filename = "output.txt" 100 | with open(filename, "w+", encoding="utf8") as out_file: 101 | out_file.write(str(evaluation.strip())) 102 | t2 = time() 103 | keyboard = InlineKeyboardMarkup( 104 | [ 105 | [ 106 | InlineKeyboardButton( 107 | text="⏳", callback_data=f"runtime {t2-t1} Seconds" 108 | ) 109 | ] 110 | ] 111 | ) 112 | await message.reply_document( 113 | document=filename, 114 | caption=f"**INPUT:**\n`{cmd[0:980]}`\n\n**OUTPUT:**\n`Attached Document`", 115 | quote=False, 116 | reply_markup=keyboard, 117 | ) 118 | await message.delete() 119 | os.remove(filename) 120 | else: 121 | t2 = time() 122 | keyboard = InlineKeyboardMarkup( 123 | [ 124 | [ 125 | InlineKeyboardButton( 126 | text="⏳", 127 | callback_data=f"runtime {round(t2-t1, 3)} Seconds", 128 | ) 129 | ] 130 | ] 131 | ) 132 | await edit_or_reply(message, text=final_output, reply_markup=keyboard) 133 | 134 | 135 | @app.on_callback_query(filters.regex(r"runtime")) 136 | async def runtime_func_cq(_, cq): 137 | runtime = cq.data.split(None, 1)[1] 138 | await cq.answer(runtime, show_alert=True) 139 | 140 | 141 | @app.on_message( 142 | filters.user(OWNER) 143 | & ~filters.forwarded 144 | & ~filters.via_bot 145 | & filters.command("sh"), 146 | ) 147 | async def shellrunner(client, message): 148 | if len(message.command) < 2: 149 | return await edit_or_reply(message, text="**Usage:**\n/sh git pull") 150 | text = message.text.split(None, 1)[1] 151 | if "\n" in text: 152 | code = text.split("\n") 153 | output = "" 154 | for x in code: 155 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x) 156 | try: 157 | process = subprocess.Popen( 158 | shell, 159 | stdout=subprocess.PIPE, 160 | stderr=subprocess.PIPE, 161 | ) 162 | except Exception as err: 163 | print(err) 164 | await edit_or_reply(message, text=f"**ERROR:**\n```{err}```") 165 | output += f"**{code}**\n" 166 | output += process.stdout.read()[:-1].decode("utf-8") 167 | output += "\n" 168 | else: 169 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text) 170 | for a in range(len(shell)): 171 | shell[a] = shell[a].replace('"', "") 172 | try: 173 | process = subprocess.Popen( 174 | shell, 175 | stdout=subprocess.PIPE, 176 | stderr=subprocess.PIPE, 177 | ) 178 | except Exception as err: 179 | print(err) 180 | exc_type, exc_obj, exc_tb = sys.exc_info() 181 | errors = traceback.format_exception( 182 | etype=exc_type, 183 | value=exc_obj, 184 | tb=exc_tb, 185 | ) 186 | return await edit_or_reply( 187 | message, text=f"**ERROR:**\n```{''.join(errors)}```" 188 | ) 189 | output = process.stdout.read()[:-1].decode("utf-8") 190 | if str(output) == "\n": 191 | output = None 192 | if output: 193 | if len(output) > 4096: 194 | with open("output.txt", "w+") as file: 195 | file.write(output) 196 | await app.send_document( 197 | message.chat.id, 198 | "output.txt", 199 | reply_to_message_id=message.message_id, 200 | caption="`Output`", 201 | ) 202 | return os.remove("output.txt") 203 | await edit_or_reply(message, text=f"**OUTPUT:**\n```{output}```") 204 | else: 205 | await edit_or_reply(message, text="**OUTPUT: **\n`No output`") 206 | -------------------------------------------------------------------------------- /Music/MusicUtilities/helpers/inline.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import ( 2 | CallbackQuery, 3 | InlineKeyboardButton, 4 | InlineKeyboardMarkup, 5 | InputMediaPhoto, 6 | Message, 7 | ) 8 | from Music.config import GROUP, CHANNEL 9 | 10 | 11 | def play_markup(videoid, user_id): 12 | buttons= [ 13 | [ 14 | InlineKeyboardButton(text="⚙️ Menu", callback_data=f'other {videoid}|{user_id}'), 15 | InlineKeyboardButton(text="🗑️ Close", callback_data=f'close2') 16 | ], 17 | ] 18 | return buttons 19 | 20 | 21 | def others_markup(videoid, user_id): 22 | buttons= [ 23 | [ 24 | InlineKeyboardButton(text="▶️", callback_data=f'resumevc2'), 25 | InlineKeyboardButton(text="⏸️", callback_data=f'pausevc2'), 26 | InlineKeyboardButton(text="⏭️", callback_data=f'skipvc2'), 27 | InlineKeyboardButton(text="⏹️", callback_data=f'stopvc2'), 28 | ], 29 | [ 30 | InlineKeyboardButton(text="🎸 Add Your List", callback_data=f'playlist {videoid}|{user_id}'), 31 | InlineKeyboardButton(text="🎸 Add Group List", callback_data=f'group_playlist {videoid}|{user_id}') 32 | ], 33 | [ 34 | InlineKeyboardButton(text="📮 Get Audio", callback_data=f'gets audio|{videoid}|{user_id}'), 35 | InlineKeyboardButton(text="📮 Get Video", callback_data=f'gets video|{videoid}|{user_id}') 36 | ], 37 | [ 38 | InlineKeyboardButton(text="⏪ Back To Button", callback_data=f'goback {videoid}|{user_id}'), 39 | ], 40 | ] 41 | return buttons 42 | 43 | 44 | 45 | 46 | play_keyboard = InlineKeyboardMarkup( 47 | [ 48 | [ 49 | InlineKeyboardButton( 50 | "▶️", callback_data="resumevc" 51 | ), 52 | InlineKeyboardButton( 53 | "⏸️", callback_data="pausevc" 54 | ), 55 | InlineKeyboardButton( 56 | "⏭️", callback_data="skipvc" 57 | ), 58 | InlineKeyboardButton( 59 | "⏹️", callback_data="stopvc" 60 | ) 61 | ], 62 | [ 63 | InlineKeyboardButton( 64 | "Close Menu", callback_data="close" 65 | ) 66 | ] 67 | ] 68 | ) 69 | 70 | 71 | 72 | def audio_markup(videoid, user_id): 73 | buttons= [ 74 | [ 75 | InlineKeyboardButton(text="▶️", callback_data=f'resumevc2'), 76 | InlineKeyboardButton(text="⏸️", callback_data=f'pausevc2'), 77 | InlineKeyboardButton(text="⏭️", callback_data=f'skipvc2'), 78 | InlineKeyboardButton(text="⏹️", callback_data=f'stopvc2') 79 | ], 80 | [ 81 | InlineKeyboardButton(text="🗑 Close Menu", callback_data="close2") 82 | ], 83 | ] 84 | return buttons 85 | 86 | 87 | def search_markup(ID1, ID2, ID3, ID4, ID5, duration1, duration2, duration3, duration4, duration5, user_id, query): 88 | buttons= [ 89 | [ 90 | InlineKeyboardButton(text="1️⃣", callback_data=f'Music2 {ID1}|{duration1}|{user_id}'), 91 | InlineKeyboardButton(text="2️⃣", callback_data=f'Music2 {ID2}|{duration2}|{user_id}'), 92 | InlineKeyboardButton(text="3️⃣", callback_data=f'Music2 {ID3}|{duration3}|{user_id}') 93 | ], 94 | [ 95 | InlineKeyboardButton(text="4️⃣", callback_data=f'Music2 {ID4}|{duration4}|{user_id}'), 96 | InlineKeyboardButton(text="5️⃣", callback_data=f'Music2 {ID5}|{duration5}|{user_id}') 97 | ], 98 | [ 99 | 100 | InlineKeyboardButton(text="⬅️", callback_data=f'popat 1|{query}|{user_id}'), 101 | InlineKeyboardButton(text="❌​", callback_data=f"ppcl2 smex|{user_id}") , 102 | InlineKeyboardButton(text="➡️", callback_data=f'popat 1|{query}|{user_id}') 103 | ], 104 | ] 105 | return buttons 106 | 107 | def search_markup2(ID6, ID7, ID8, ID9, ID10, duration6, duration7, duration8, duration9, duration10 ,user_id, query): 108 | buttons= [ 109 | [ 110 | InlineKeyboardButton(text="6️⃣", callback_data=f'Music2 {ID6}|{duration6}|{user_id}'), 111 | InlineKeyboardButton(text="7️⃣", callback_data=f'Music2 {ID7}|{duration7}|{user_id}'), 112 | InlineKeyboardButton(text="8️⃣", callback_data=f'Music2 {ID8}|{duration8}|{user_id}') 113 | ], 114 | [ 115 | InlineKeyboardButton(text="9️⃣", callback_data=f'Music2 {ID9}|{duration9}|{user_id}'), 116 | InlineKeyboardButton(text="🔟", callback_data=f'Music2 {ID10}|{duration10}|{user_id}') 117 | ], 118 | [ 119 | 120 | InlineKeyboardButton(text="⬅️", callback_data=f'popat 2|{query}|{user_id}'), 121 | InlineKeyboardButton(text="❌", callback_data=f"ppcl2 smex|{user_id}") , 122 | InlineKeyboardButton(text="➡️", callback_data=f'popat 2|{query}|{user_id}') 123 | ], 124 | ] 125 | return buttons 126 | 127 | 128 | def personal_markup(link): 129 | buttons= [ 130 | [ 131 | InlineKeyboardButton(text="Watch On Youtube", url=f'{link}') 132 | ], 133 | [ 134 | InlineKeyboardButton(text="🗑 Close", callback_data=f'close2') 135 | ], 136 | ] 137 | return buttons 138 | 139 | start_keyboard = InlineKeyboardMarkup( 140 | [ 141 | [ 142 | InlineKeyboardButton( 143 | "📜 Commands", url="https://telegra.ph/Skyzo-11-10" 144 | ) 145 | ], 146 | [ 147 | InlineKeyboardButton( 148 | "🗑 Close Menu", callback_data="close2" 149 | ) 150 | ] 151 | ] 152 | ) 153 | 154 | confirm_keyboard = InlineKeyboardMarkup( 155 | [ 156 | [ 157 | InlineKeyboardButton( 158 | "Yes", callback_data="cbdel" 159 | ), 160 | InlineKeyboardButton( 161 | "No", callback_data="close2" 162 | ) 163 | ] 164 | ] 165 | ) 166 | 167 | confirm_group_keyboard = InlineKeyboardMarkup( 168 | [ 169 | [ 170 | InlineKeyboardButton( 171 | "Yes", callback_data="cbgroupdel" 172 | ), 173 | InlineKeyboardButton( 174 | "No", callback_data="close2" 175 | ) 176 | ] 177 | ] 178 | ) 179 | 180 | close_keyboard = InlineKeyboardMarkup( 181 | [ 182 | [ 183 | InlineKeyboardButton( 184 | "🗑 Close", callback_data="close2" 185 | ) 186 | ] 187 | ] 188 | ) 189 | 190 | play_list_keyboard = InlineKeyboardMarkup( 191 | [ 192 | [ 193 | InlineKeyboardButton( 194 | "Users Playlist", callback_data="P_list" 195 | ), 196 | InlineKeyboardButton( 197 | "Groups Playlist", callback_data="G_list" 198 | ) 199 | ], 200 | [ 201 | InlineKeyboardButton( 202 | "🗑 Close", callback_data="close2" 203 | ) 204 | ] 205 | ] 206 | ) 207 | 208 | def playlist_markup(user_name, user_id): 209 | buttons= [ 210 | [ 211 | InlineKeyboardButton(text=f"Groups", callback_data=f'play_playlist {user_id}|group'), 212 | InlineKeyboardButton(text=f"{user_name[:8]}", callback_data=f'play_playlist {user_id}|personal'), 213 | ], 214 | [ 215 | InlineKeyboardButton(text="🗑 Close Playlist", callback_data="close2") 216 | ], 217 | ] 218 | return buttons 219 | -------------------------------------------------------------------------------- /Music/MusicUtilities/tgcallsrun/music.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Dict 3 | import random 4 | from pytgcalls import PyTgCalls 5 | from pytgcalls.types import Update 6 | from pytgcalls.types.input_stream import InputAudioStream 7 | from pytgcalls.types.input_stream import InputStream 8 | from Music import app, BOT_USERNAME 9 | from Music import config 10 | from pyrogram import Client 11 | from asyncio import QueueEmpty 12 | from Music.MusicUtilities.database.queue import (is_active_chat, add_active_chat, remove_active_chat, music_on, is_music_playing, music_off) 13 | from Music.MusicUtilities.tgcallsrun import queues 14 | from Music.config import LOG_GROUP_ID 15 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 16 | from Music.MusicUtilities.helpers.inline import play_keyboard 17 | from Music.MusicUtilities.database.assistant import (_get_assistant, get_assistant, save_assistant) 18 | import os 19 | from os import path 20 | from Music import BOT_USERNAME 21 | import asyncio 22 | import yt_dlp 23 | from Music.converter import converter 24 | from pyrogram.types import Message 25 | from Music.MusicUtilities.database.theme import (_get_theme, get_theme, save_theme) 26 | from Music.MusicUtilities.helpers.gets import (get_url, themes, random_assistant) 27 | from Music.MusicUtilities.helpers.thumbnails import gen_thumb 28 | from Music.MusicUtilities.helpers.chattitle import CHAT_TITLE 29 | from Music.MusicUtilities.helpers.ytdl import ytdl_opts 30 | from Music.MusicUtilities.helpers.inline import (play_keyboard, search_markup, play_markup, playlist_markup, audio_markup) 31 | from Music.MusicUtilities.tgcallsrun import (convert, download) 32 | from pyrogram import filters 33 | from typing import Union 34 | from youtubesearchpython import VideosSearch 35 | from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant 36 | from pyrogram.types import Message, Audio, Voice 37 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message, ) 38 | flex = {} 39 | smexy = Client(config.SESSION_NAME, config.API_ID, config.API_HASH) 40 | pytgcalls = PyTgCalls(smexy) 41 | 42 | @pytgcalls.on_kicked() 43 | async def on_kicked(client: PyTgCalls, chat_id: int) -> None: 44 | try: 45 | queues.clear(chat_id) 46 | except QueueEmpty: 47 | pass 48 | await remove_active_chat(chat_id) 49 | 50 | @pytgcalls.on_closed_voice_chat() 51 | async def on_closed(client: PyTgCalls, chat_id: int) -> None: 52 | try: 53 | queues.clear(chat_id) 54 | except QueueEmpty: 55 | pass 56 | await remove_active_chat(chat_id) 57 | 58 | 59 | @pytgcalls.on_stream_end() 60 | async def on_stream_end(client: PyTgCalls, update: Update) -> None: 61 | chat_id = update.chat_id 62 | try: 63 | queues.task_done(chat_id) 64 | if queues.is_empty(chat_id): 65 | await remove_active_chat(chat_id) 66 | await pytgcalls.leave_group_call(chat_id) 67 | else: 68 | afk = queues.get(chat_id)['file'] 69 | f1 = (afk[0]) 70 | f2 = (afk[1]) 71 | f3 = (afk[2]) 72 | finxx = (f"{f1}{f2}{f3}") 73 | if str(finxx) != "raw": 74 | mystic = await app.send_message(chat_id, "Downloading Next Music From Playlist....") 75 | url = (f"https://www.youtube.com/watch?v={afk}") 76 | ctitle = (await app.get_chat(chat_id)).title 77 | logger_text=f"""Playing Next From Playlist 78 | 79 | Group :- {chat_id} 80 | Title :- {ctitle} 81 | 82 | Downloading.... 83 | 84 | {url}""" 85 | okay = await smexy.send_message(LOG_GROUP_ID, f"{logger_text}", disable_web_page_preview=True) 86 | try: 87 | with yt_dlp.YoutubeDL(ytdl_opts) as ytdl: 88 | x = ytdl.extract_info(url, download=False) 89 | except Exception as e: 90 | return await mystic.edit(f"Failed to download this video.\n\n**Reason**:{e}") 91 | 92 | chat_title = ctitle 93 | videoid = afk 94 | title = (x["title"]) 95 | def my_hook(d): 96 | if d['status'] == 'downloading': 97 | percentage = d['_percent_str'] 98 | per = (str(percentage)).replace(".","", 1).replace("%","", 1) 99 | per = int(per) 100 | eta = d['eta'] 101 | speed = d['_speed_str'] 102 | size = d['_total_bytes_str'] 103 | bytesx = d['total_bytes'] 104 | if str(bytesx) in flex: 105 | pass 106 | else: 107 | flex[str(bytesx)] = 1 108 | if flex[str(bytesx)] == 1: 109 | flex[str(bytesx)] += 1 110 | mystic.edit(f"Downloading {title[:50]}\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 111 | if per > 500: 112 | if flex[str(bytesx)] == 2: 113 | flex[str(bytesx)] += 1 114 | mystic.edit(f"Downloading {title[:50]}...\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 115 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 116 | if per > 800: 117 | if flex[str(bytesx)] == 3: 118 | flex[str(bytesx)] += 1 119 | mystic.edit(f"Downloading {title[:50]}....\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 120 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 121 | if per == 1000: 122 | if flex[str(bytesx)] == 4: 123 | flex[str(bytesx)] = 1 124 | mystic.edit(f"Downloading {title[:50]}.....\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 125 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 126 | loop = asyncio.get_event_loop() 127 | xx = await loop.run_in_executor(None, download, url, my_hook) 128 | file = await convert(xx) 129 | await pytgcalls.change_stream( 130 | chat_id, 131 | InputStream( 132 | InputAudioStream( 133 | file, 134 | ), 135 | ), 136 | ) 137 | thumbnail = (x["thumbnail"]) 138 | duration = (x["duration"]) 139 | duration = round(x["duration"] / 60) 140 | theme = random.choice(themes) 141 | ctitle = await CHAT_TITLE(ctitle) 142 | f2 = open(f'search/{afk}id.txt', 'r') 143 | userid =(f2.read()) 144 | thumb = await gen_thumb(thumbnail, title, userid, theme, ctitle) 145 | user_id = userid 146 | videoid = afk 147 | buttons = play_markup(videoid, user_id) 148 | await mystic.delete() 149 | semx = await app.get_users(userid) 150 | await app.send_photo(chat_id, 151 | photo= thumb, 152 | reply_markup=InlineKeyboardMarkup(buttons), 153 | caption=(f"💻 Started Playing: [{title[:25]}]({url}) \n⏰ Duration: {duration} Mins\n🧰 Info: [Get Information Song](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n🦸🏻‍♂️ **Requested By:** {semx.mention}") 154 | ) 155 | os.remove(thumb) 156 | else: 157 | await pytgcalls.change_stream( 158 | chat_id, 159 | InputStream( 160 | InputAudioStream( 161 | afk, 162 | ), 163 | ), 164 | ) 165 | _chat_ = ((str(afk)).replace("_","", 1).replace("/","", 1).replace(".","", 1)) 166 | f2 = open(f'search/{_chat_}title.txt', 'r') 167 | title =(f2.read()) 168 | f3 = open(f'search/{_chat_}duration.txt', 'r') 169 | duration =(f3.read()) 170 | f4 = open(f'search/{_chat_}username.txt', 'r') 171 | username =(f4.read()) 172 | f4 = open(f'search/{_chat_}videoid.txt', 'r') 173 | videoid =(f4.read()) 174 | user_id = 1 175 | videoid = str(videoid) 176 | if videoid == "smex1": 177 | buttons = audio_markup(videoid, user_id) 178 | else: 179 | buttons = play_markup(videoid, user_id) 180 | await app.send_photo(chat_id, 181 | photo=f"downloads/{_chat_}final.png", 182 | reply_markup=InlineKeyboardMarkup(buttons), 183 | caption=f"💻 Started Playing: {title} \n⏰ Duration: {duration} \n🦸🏻‍♂️ Requested By: {username}", 184 | ) 185 | return 186 | 187 | except Exception as e: 188 | print(e) 189 | 190 | 191 | run = pytgcalls.start 192 | -------------------------------------------------------------------------------- /Music/Plugins/admins.py: -------------------------------------------------------------------------------- 1 | from asyncio import QueueEmpty 2 | from pyrogram import Client, filters 3 | from pyrogram.types import Message, Audio, Voice 4 | from Music import app 5 | from Music.MusicUtilities.helpers.decorators import errors 6 | from Music.MusicUtilities.helpers.filters import command, other_filters 7 | from Music.MusicUtilities.database.queue import (is_active_chat, add_active_chat, remove_active_chat, music_on, is_music_playing, music_off) 8 | from pyrogram.types import ( 9 | CallbackQuery, 10 | InlineKeyboardButton, 11 | InlineKeyboardMarkup, 12 | InputMediaPhoto, 13 | Message, 14 | ) 15 | import os 16 | import yt_dlp 17 | from youtubesearchpython import VideosSearch 18 | from os import path 19 | import random 20 | import asyncio 21 | import shutil 22 | from time import time 23 | import time as sedtime 24 | from Music import dbb, app, BOT_USERNAME, BOT_ID, ASSID, ASSNAME, ASSUSERNAME, ASSMENTION 25 | from Music.MusicUtilities.tgcallsrun import (music, convert, download, clear, get, is_empty, put, task_done, smexy) 26 | from Music.MusicUtilities.helpers.gets import (get_url, themes, random_assistant) 27 | from pyrogram.types import Message 28 | from pytgcalls.types.input_stream import InputAudioStream 29 | from pytgcalls.types.input_stream import InputStream 30 | from Music.MusicUtilities.helpers.thumbnails import gen_thumb 31 | from Music.MusicUtilities.helpers.chattitle import CHAT_TITLE 32 | from Music.MusicUtilities.helpers.ytdl import ytdl_opts 33 | from Music.MusicUtilities.helpers.inline import (play_keyboard, search_markup, play_markup, playlist_markup, audio_markup) 34 | from Music.MusicUtilities.tgcallsrun import (convert, download) 35 | from pyrogram import filters 36 | from typing import Union 37 | from youtubesearchpython import VideosSearch 38 | from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant 39 | 40 | flex = {} 41 | 42 | async def member_permissions(chat_id: int, user_id: int): 43 | perms = [] 44 | member = await app.get_chat_member(chat_id, user_id) 45 | if member.can_manage_voice_chats: 46 | perms.append("can_manage_voice_chats") 47 | return perms 48 | from Music.MusicUtilities.helpers.administrator import adminsOnly 49 | 50 | @app.on_message(filters.command("cleandb")) 51 | async def stop_cmd(_, message): 52 | chat_id = message.chat.id 53 | try: 54 | clear(chat_id) 55 | except QueueEmpty: 56 | pass 57 | await remove_active_chat(chat_id) 58 | try: 59 | await music.pytgcalls.leave_group_call(chat_id) 60 | except: 61 | pass 62 | await message.reply_text("Erased Databae, Queues, Logs, Raw Files, Downloads.") 63 | 64 | @app.on_message(filters.command("pause")) 65 | async def pause_cmd(_, message): 66 | if message.sender_chat: 67 | return await message.reply_text("You're an __Anonymous Admin__!\nRevert back to User Account.") 68 | permission = "can_manage_voice_chats" 69 | m = await adminsOnly(permission, message) 70 | if m == 1: 71 | return 72 | checking = message.from_user.mention 73 | chat_id = message.chat.id 74 | if not await is_active_chat(chat_id): 75 | return await message.reply_text("I dont think if something's playing on voice chat") 76 | elif not await is_music_playing(message.chat.id): 77 | return await message.reply_text("I dont think if something's playing on voice chat") 78 | await music_off(chat_id) 79 | await music.pytgcalls.pause_stream(chat_id) 80 | await message.reply_text(f"**🚀 Voicechat Paused By {checking}!**") 81 | 82 | @app.on_message(filters.command("resume")) 83 | async def stop_cmd(_, message): 84 | if message.sender_chat: 85 | return await message.reply_text("You're an __Anonymous Admin__!\nRevert back to User Account.") 86 | permission = "can_manage_voice_chats" 87 | m = await adminsOnly(permission, message) 88 | if m == 1: 89 | return 90 | checking = message.from_user.mention 91 | chat_id = message.chat.id 92 | if not await is_active_chat(chat_id): 93 | return await message.reply_text("I dont think if something's playing on voice chat") 94 | elif await is_music_playing(chat_id): 95 | return await message.reply_text("I dont think if something's playing on voice chat") 96 | else: 97 | await music_on(chat_id) 98 | await music.pytgcalls.resume_stream(chat_id) 99 | await message.reply_text(f"**🚀 Voicechat Resumed By {checking}!**") 100 | 101 | @app.on_message(filters.command(["stop", "end"])) 102 | async def stop_cmd(_, message): 103 | if message.sender_chat: 104 | return await message.reply_text("You're an __Anonymous Admin__!\nRevert back to User Account.") 105 | permission = "can_manage_voice_chats" 106 | m = await adminsOnly(permission, message) 107 | if m == 1: 108 | return 109 | checking = message.from_user.mention 110 | chat_id = message.chat.id 111 | if await is_active_chat(chat_id): 112 | try: 113 | clear(chat_id) 114 | except QueueEmpty: 115 | pass 116 | await remove_active_chat(chat_id) 117 | await music.pytgcalls.leave_group_call(chat_id) 118 | await message.reply_text(f"**🚀 Voicechat End/Stopped By {checking}!**") 119 | else: 120 | return await message.reply_text("**🤷🏻‍♂ I Dont Think If Something Playing On Voice Chat Bro**") 121 | 122 | @app.on_message(filters.command("skip")) 123 | async def stop_cmd(_, message): 124 | if message.sender_chat: 125 | return await message.reply_text("⛔ You're An __Anonymous Admin__!\n⛔ Revert Back To User Account.") 126 | permission = "can_manage_voice_chats" 127 | m = await adminsOnly(permission, message) 128 | if m == 1: 129 | return 130 | checking = message.from_user.mention 131 | chat_id = message.chat.id 132 | chat_title = message.chat.title 133 | if not await is_active_chat(chat_id): 134 | await message.reply_text("Nothing's playing on Music") 135 | else: 136 | task_done(chat_id) 137 | if is_empty(chat_id): 138 | await remove_active_chat(chat_id) 139 | await message.reply_text("⛔ **No More Music In** __Queue__ \n\n**Leaving Voice Chat**") 140 | await music.pytgcalls.leave_group_call(chat_id) 141 | return 142 | else: 143 | afk = get(chat_id)['file'] 144 | f1 = (afk[0]) 145 | f2 = (afk[1]) 146 | f3 = (afk[2]) 147 | finxx = (f"{f1}{f2}{f3}") 148 | if str(finxx) != "raw": 149 | mystic = await message.reply_text("Music is currently playing Playlist...\n\nDownloading Next Music From Playlist....") 150 | url = (f"https://www.youtube.com/watch?v={afk}") 151 | try: 152 | with yt_dlp.YoutubeDL(ytdl_opts) as ytdl: 153 | x = ytdl.extract_info(url, download=False) 154 | except Exception as e: 155 | return await mystic.edit(f"Failed to download this video.\n\n**Reason**:{e}") 156 | title = (x["title"]) 157 | videoid = afk 158 | def my_hook(d): 159 | if d['status'] == 'downloading': 160 | percentage = d['_percent_str'] 161 | per = (str(percentage)).replace(".","", 1).replace("%","", 1) 162 | per = int(per) 163 | eta = d['eta'] 164 | speed = d['_speed_str'] 165 | size = d['_total_bytes_str'] 166 | bytesx = d['total_bytes'] 167 | if str(bytesx) in flex: 168 | pass 169 | else: 170 | flex[str(bytesx)] = 1 171 | if flex[str(bytesx)] == 1: 172 | flex[str(bytesx)] += 1 173 | sedtime.sleep(1) 174 | mystic.edit(f"Downloading {title[:50]}\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 175 | if per > 500: 176 | if flex[str(bytesx)] == 2: 177 | flex[str(bytesx)] += 1 178 | sedtime.sleep(0.5) 179 | mystic.edit(f"Downloading {title[:50]}...\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 180 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 181 | if per > 800: 182 | if flex[str(bytesx)] == 3: 183 | flex[str(bytesx)] += 1 184 | sedtime.sleep(0.5) 185 | mystic.edit(f"Downloading {title[:50]}....\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 186 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 187 | if per == 1000: 188 | if flex[str(bytesx)] == 4: 189 | flex[str(bytesx)] = 1 190 | sedtime.sleep(0.5) 191 | mystic.edit(f"Downloading {title[:50]}.....\n\n**FileSize:** {size}\n**Downloaded:** {percentage}\n**Speed:** {speed}\n**ETA:** {eta} sec") 192 | print(f"[{videoid}] Downloaded {percentage} at a speed of {speed} in {chat_title} | ETA: {eta} seconds") 193 | loop = asyncio.get_event_loop() 194 | xxx = await loop.run_in_executor(None, download, url, my_hook) 195 | file = await convert(xxx) 196 | await music.pytgcalls.change_stream( 197 | chat_id, 198 | InputStream( 199 | InputAudioStream( 200 | file, 201 | ), 202 | ), 203 | ) 204 | thumbnail = (x["thumbnail"]) 205 | duration = (x["duration"]) 206 | duration = round(x["duration"] / 60) 207 | theme = random.choice(themes) 208 | ctitle = (await app.get_chat(chat_id)).title 209 | ctitle = await CHAT_TITLE(ctitle) 210 | f2 = open(f'search/{afk}id.txt', 'r') 211 | userid =(f2.read()) 212 | thumb = await gen_thumb(thumbnail, title, userid, theme, ctitle) 213 | user_id = userid 214 | buttons = play_markup(videoid, user_id) 215 | await mystic.delete() 216 | semx = await app.get_users(userid) 217 | await message.reply_photo( 218 | photo= thumb, 219 | reply_markup=InlineKeyboardMarkup(buttons), 220 | caption=(f"__Skipped Voice Chat__\n\n🔈 __Started Playing:__ [{title[:25]}]({url}) \n⏰ __Duration:__ {duration} Mins\n👩‍💻 **__Requested By:__** {semx.mention}") 221 | ) 222 | os.remove(thumb) 223 | else: 224 | await music.pytgcalls.change_stream( 225 | chat_id, 226 | InputStream( 227 | InputAudioStream( 228 | afk, 229 | ), 230 | ), 231 | ) 232 | _chat_ = ((str(afk)).replace("_","", 1).replace("/","", 1).replace(".","", 1)) 233 | f2 = open(f'search/{_chat_}title.txt', 'r') 234 | title =(f2.read()) 235 | f3 = open(f'search/{_chat_}duration.txt', 'r') 236 | duration =(f3.read()) 237 | f4 = open(f'search/{_chat_}username.txt', 'r') 238 | username =(f4.read()) 239 | f4 = open(f'search/{_chat_}videoid.txt', 'r') 240 | videoid =(f4.read()) 241 | user_id = 1 242 | videoid = str(videoid) 243 | if videoid == "smex1": 244 | buttons = audio_markup(videoid, user_id) 245 | else: 246 | buttons = play_markup(videoid, user_id) 247 | await message.reply_photo( 248 | photo=f"downloads/{_chat_}final.png", 249 | reply_markup=InlineKeyboardMarkup(buttons), 250 | caption=f"__Skipped Voice Chat__\n\n🔈 __Started Playing:__ {title} \n⏰ __Duration:__ {duration} \n🤡 __Requested By:__ {username}", 251 | ) 252 | return 253 | -------------------------------------------------------------------------------- /Music/Plugins/stream.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from Music.MusicUtilities.tgcallsrun import ASS_ACC 4 | 5 | from pyrogram import Client, filters 6 | from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant 7 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message 8 | from pytgcalls import StreamType 9 | from pytgcalls.types.input_stream import AudioVideoPiped 10 | from pytgcalls.types.input_stream.quality import ( 11 | HighQualityAudio, 12 | HighQualityVideo, 13 | LowQualityVideo, 14 | MediumQualityVideo, 15 | ) 16 | from youtubesearchpython import VideosSearch 17 | from Music.config import GROUP, CHANNEL 18 | from Music import BOT_NAME, BOT_USERNAME, app 19 | from Music.MusicUtilities.tgcallsrun.music import pytgcalls as call_py 20 | from Music.MusicUtilities.helpers.filters import command 21 | from Music.MusicUtilities.helpers.logger import LOG_CHAT 22 | from Music.MusicUtilities.tgcallsrun.queues import ( 23 | QUEUE, 24 | add_to_queue, 25 | clear_queue, 26 | get_queue, 27 | ) 28 | 29 | 30 | def ytsearch(query): 31 | try: 32 | search = VideosSearch(query, limit=1).result() 33 | data = search["result"][0] 34 | songname = data["title"] 35 | url = data["link"] 36 | duration = data["duration"] 37 | thumbnail = f"https://i.ytimg.com/vi/{data['id']}/hqdefault.jpg" 38 | return [songname, url, duration, thumbnail] 39 | except Exception as e: 40 | print(e) 41 | return 0 42 | 43 | 44 | async def ytdl(link): 45 | proc = await asyncio.create_subprocess_exec( 46 | "yt-dlp", 47 | "-g", 48 | "-f", 49 | "best[height<=?720][width<=?1280]", 50 | f"{link}", 51 | stdout=asyncio.subprocess.PIPE, 52 | stderr=asyncio.subprocess.PIPE, 53 | ) 54 | stdout, stderr = await proc.communicate() 55 | if stdout: 56 | return 1, stdout.decode().split("\n")[0] 57 | else: 58 | return 0, stderr.decode() 59 | 60 | 61 | 62 | @app.on_message(command("vplay") & filters.group) 63 | async def vplay(c: Client, message: Message): 64 | replied = message.reply_to_message 65 | chat_id = message.chat.id 66 | user_id = message.from_user.id 67 | user_name = message.from_user.first_name 68 | rpk = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" 69 | keyboard = InlineKeyboardMarkup( 70 | [ 71 | [ 72 | InlineKeyboardButton("sᴜᴘᴘᴏʀᴛ", url=f"https://t.me/{GROUP}"), 73 | InlineKeyboardButton("ᴄʜᴀɴɴᴇʟ", url=f"https://t.me/{CHANNEL}"), 74 | ], 75 | [ 76 | InlineKeyboardButton(text="ᴍᴇɴᴜ", callback_data="cbmenu") 77 | ] 78 | ] 79 | ) 80 | if message.sender_chat: 81 | return await message.reply_text( 82 | "Anda adalah **Admin Anonim!**\n\n» Kembali ke akun pengguna dari hak admin." 83 | ) 84 | try: 85 | aing = await c.get_me() 86 | except Exception as e: 87 | return await message.reply_text(f"error:\n\n{e}") 88 | a = await c.get_chat_member(chat_id, aing.id) 89 | if a.status != "administrator": 90 | await message.reply_text( 91 | f""" 92 | 💡 Untuk menggunakan saya, Saya perlu menjadi admin dengan izin: 93 | » ❌ Hapus pesan 94 | » ❌ Blokir pengguna 95 | » ❌ Tambah pengguna 96 | » ❌ Kelola obrolan suara 97 | ✨ Powered by: [{BOT_NAME}](t.me/{BOT_USERNAME}) 98 | """, 99 | disable_web_page_preview=True, 100 | ) 101 | return 102 | if not a.can_manage_voice_chats: 103 | await message.reply_text( 104 | f""" 105 | 💡 Untuk menggunakan saya, Saya perlu menjadi admin dengan izin: 106 | » ❌ Kelola obrolan suara 107 | ✨ Powered by: [{BOT_NAME}](t.me/{BOT_USERNAME}) 108 | """, 109 | disable_web_page_preview=True, 110 | ) 111 | return 112 | if not a.can_delete_messages: 113 | await message.reply_text( 114 | f""" 115 | 💡 Untuk menggunakan saya, Saya perlu menjadi admin dengan izin: 116 | » ❌ Hapus pesan 117 | ✨ Powered by: [{BOT_NAME}](t.me/{BOT_USERNAME}) 118 | """, 119 | disable_web_page_preview=True, 120 | ) 121 | return 122 | if not a.can_invite_users: 123 | await message.reply_text( 124 | f""" 125 | 💡 Untuk menggunakan saya, Saya perlu menjadi admin dengan izin: 126 | » ❌ Tambah pengguna 127 | ✨ Powered by: [{BOT_NAME}](t.me/{BOT_USERNAME}) 128 | """, 129 | disable_web_page_preview=True, 130 | ) 131 | return 132 | try: 133 | ubot = await ASS_ACC.get_me() 134 | b = await c.get_chat_member(chat_id, ubot.id) 135 | if b.status == "kicked": 136 | await message.reply_text( 137 | f"@{ubot.username} **Terkena ban di grup** {message.chat.title}\n\n» **unban Assistant terlebih dahulu jika ingin menggunakan bot ini.**" 138 | ) 139 | return 140 | except UserNotParticipant: 141 | if message.chat.username: 142 | try: 143 | await ASS_ACC.join_chat(message.chat.username) 144 | except Exception as e: 145 | await message.reply_text( 146 | f"❌ **@{ubot.username} Assistant gagal bergabung**\n\n**Alasan**: `{e}`" 147 | ) 148 | return 149 | else: 150 | try: 151 | invite_link = await message.chat.export_invite_link() 152 | if "+" in invite_link: 153 | link_hash = (invite_link.replace("+", "")).split("t.me/")[1] 154 | await ASS_ACC.join_chat(f"https://t.me/joinchat/{link_hash}") 155 | except UserAlreadyParticipant: 156 | pass 157 | except Exception as e: 158 | return await message.reply_text( 159 | f"❌ **@{ubot.username} Assistant gagal bergabung**\n\n**Alasan**: `{e}`" 160 | ) 161 | 162 | if replied: 163 | if replied.video or replied.document: 164 | what = "Audio Searched" 165 | await LOG_CHAT(message, what) 166 | loser = await replied.reply("📥 **Mengunduh Video... Mohon Bersabar**") 167 | dl = await replied.download() 168 | link = replied.link 169 | if len(message.command) < 2: 170 | Q = 720 171 | else: 172 | pq = message.text.split(None, 1)[1] 173 | if pq == "720" or "480" or "360": 174 | Q = int(pq) 175 | else: 176 | Q = 720 177 | await loser.edit( 178 | "» **Hanya 720, 480, 360 yang diizinkan** \n💡 **Sekarang Streaming Video Dalam 720p**" 179 | ) 180 | try: 181 | if replied.video: 182 | songname = replied.video.file_name[:70] 183 | elif replied.document: 184 | songname = replied.document.file_name[:70] 185 | except BaseException: 186 | songname = "Video" 187 | 188 | if chat_id in QUEUE: 189 | pos = add_to_queue(chat_id, songname, dl, link, "Video", Q) 190 | await loser.delete() 191 | requester = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 192 | await app.send_message( 193 | chat_id, 194 | f""" 195 | 📊 **Ditambahkan Ke Antrian** 196 | 📑 **Judul:** [{songname[:999]}]({link}) 197 | 👨🏻‍🎤 **Permintaan:** {requester} 198 | 📝 **Posisi Antrian** {pos} 199 | """, 200 | disable_web_page_preview=True, 201 | reply_markup=keyboard, 202 | ) 203 | else: 204 | if Q == 720: 205 | amaze = HighQualityVideo() 206 | elif Q == 480: 207 | amaze = MediumQualityVideo() 208 | elif Q == 360: 209 | amaze = LowQualityVideo() 210 | await call_py.join_group_call( 211 | chat_id, 212 | AudioVideoPiped( 213 | dl, 214 | HighQualityAudio(), 215 | amaze, 216 | ), 217 | stream_type=StreamType().pulse_stream, 218 | ) 219 | add_to_queue(chat_id, songname, dl, link, "Video", Q) 220 | await loser.delete() 221 | requester = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 222 | await app.send_message( 223 | chat_id, 224 | f""" 225 | 🤖 **Streaming Video Dimulai** 226 | 📊 **Judul:** [{songname[:999]}]({link}) 227 | 👨🏻‍🎤 **Permintaan:** {requester} 228 | 📚 **Diputar Di:** {message.chat.title} 229 | """, 230 | disable_web_page_preview=True, 231 | reply_markup=keyboard, 232 | ) 233 | 234 | else: 235 | if len(message.command) < 2: 236 | await message.reply( 237 | "» Balas ke **file video** atau **berikan sesuatu untuk ditelusuri.**" 238 | ) 239 | else: 240 | what = "Query Given" 241 | await LOG_CHAT(message, what) 242 | loser = await message.reply("🔎 **Pencarian... Mohon Bersabar**") 243 | query = message.text.split(None, 1)[1] 244 | search = ytsearch(query) 245 | Q = 480 246 | amaze = HighQualityVideo() 247 | if search == 0: 248 | await loser.edit("❌ **Tidak ada hasil yang ditemukan.**") 249 | else: 250 | songname = search[0] 251 | url = search[1] 252 | duration = search[2] 253 | thumbnail = search[3] 254 | veez, ytlink = await ytdl(url) 255 | if veez == 0: 256 | await loser.edit(f"❌ yt-dl masalah terdeteksi\n\n» `{ytlink}`") 257 | else: 258 | if chat_id in QUEUE: 259 | pos = add_to_queue(chat_id, songname, ytlink, url, "Video", Q) 260 | await loser.delete() 261 | requester = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 262 | await app.send_message( 263 | chat_id, 264 | f""" 265 | 📊 **Ditambahkan Ke Antrian** 266 | 📑 **Nama:** [{songname[:999]}]({url}) 267 | ♻️ **Durasi:** {duration} 268 | 👨🏻‍🎤 **Permintaan:** {requester} 269 | ♨️ **Posisi Antrian** {pos} 270 | """, 271 | disable_web_page_preview=True, 272 | reply_markup=keyboard, 273 | ) 274 | else: 275 | try: 276 | await call_py.join_group_call( 277 | chat_id, 278 | AudioVideoPiped( 279 | ytlink, 280 | HighQualityAudio(), 281 | amaze, 282 | ), 283 | stream_type=StreamType().pulse_stream, 284 | ) 285 | add_to_queue(chat_id, songname, ytlink, url, "Video", Q) 286 | await loser.delete() 287 | requester = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 288 | await app.send_message( 289 | chat_id, 290 | f""" 291 | 🤖 **Streaming Video Dimulai** 292 | 📑 **Nama:** [{songname[:999]}]({url}) 293 | ⏱️ **Durasi:** {duration} 294 | 👨🏻‍🎤 **Permintaan:** {requester} 295 | 🦊 **Diputar Di:** {message.chat.title} 296 | """, 297 | disable_web_page_preview=True, 298 | reply_markup=keyboard, 299 | ) 300 | except Exception as ep: 301 | await loser.delete() 302 | await message.reply_text(f"Error: `{ep}`") 303 | 304 | 305 | @app.on_message(command("vplaylist") & filters.group) 306 | async def playlist(client, m: Message): 307 | chat_id = m.chat.id 308 | if chat_id in QUEUE: 309 | chat_queue = get_queue(chat_id) 310 | if len(chat_queue) == 1: 311 | await m.delete() 312 | await m.reply( 313 | f"**🤖 SEKARANG MEMUTAR:** \n[{chat_queue[0][0]}]({chat_queue[0][2]}) | `{chat_queue[0][3]}`", 314 | disable_web_page_preview=True, 315 | ) 316 | else: 317 | QUE = f"**🤖 SEKARANG MEMUTAR:** \n[{chat_queue[0][0]}]({chat_queue[0][2]}) | `{chat_queue[0][3]}` \n\n**⏯ DAFTAR ANTRIAN:**" 318 | l = len(chat_queue) 319 | for x in range(1, l): 320 | hmm = chat_queue[x][0] 321 | hmmm = chat_queue[x][2] 322 | hmmmm = chat_queue[x][3] 323 | QUE = QUE + "\n" + f"**#{x}** - [{hmm}]({hmmm}) | `{hmmmm}`\n" 324 | await m.reply(QUE, disable_web_page_preview=True) 325 | else: 326 | await m.reply("**❌ Tidak memutar apapun**") 327 | -------------------------------------------------------------------------------- /Music/Plugins/vadmins.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client, filters 2 | from pyrogram.types import ( 3 | CallbackQuery, 4 | InlineKeyboardButton, 5 | InlineKeyboardMarkup, 6 | Message, 7 | ) 8 | 9 | from Music import app 10 | from Music.MusicUtilities.tgcallsrun.music import pytgcalls as call_py 11 | 12 | from Music.MusicUtilities.helpers.decorators import authorized_users_only 13 | from Music.MusicUtilities.helpers.filters import command 14 | from Music.MusicUtilities.tgcallsrun.queues import QUEUE, clear_queue 15 | from Music.MusicUtilities.tgcallsrun.video import skip_current_song, skip_item 16 | 17 | 18 | bttn = InlineKeyboardMarkup( 19 | [[InlineKeyboardButton("ᴋᴇᴍʙᴀʟɪ", callback_data="cbmenu")]] 20 | ) 21 | 22 | 23 | bcl = InlineKeyboardMarkup([[InlineKeyboardButton("ᴛᴜᴛᴜᴘ", callback_data="cls")]]) 24 | 25 | 26 | @Client.on_callback_query(filters.regex("cbmenu")) 27 | async def cbmenu(_, query: CallbackQuery): 28 | if query.message.sender_chat: 29 | return await query.answer( 30 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 31 | ) 32 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 33 | if not a.can_manage_voice_chats: 34 | return await query.answer( 35 | "🤖 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 36 | show_alert=True, 37 | ) 38 | await query.edit_message_text( 39 | f"🛠️ **Pengaturan Dari** {query.message.chat.title}\n\n**⏸️ : Jeda Streaming**\n**▶️ : Lanjutkan Streaming**\n**🔇 : Bisukan Assistant**\n**🔊 : Bunyikan Assistant**\n**⏹️ : Hentikan Streaming**", 40 | reply_markup=InlineKeyboardMarkup( 41 | [ 42 | [ 43 | InlineKeyboardButton("▶️", callback_data="cbstop"), 44 | InlineKeyboardButton("⏸️", callback_data="cbpause"), 45 | InlineKeyboardButton("▶️", callback_data="cbresume"), 46 | ], 47 | [ 48 | InlineKeyboardButton("🔇", callback_data="cbmute"), 49 | InlineKeyboardButton("🔊", callback_data="cbunmute"), 50 | ], 51 | [InlineKeyboardButton("ᴛᴜᴛᴜᴘ", callback_data="cls")], 52 | ] 53 | ), 54 | ) 55 | 56 | 57 | @Client.on_callback_query(filters.regex("cls")) 58 | async def close(_, query: CallbackQuery): 59 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 60 | if not a.can_manage_voice_chats: 61 | return await query.answer( 62 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 63 | show_alert=True, 64 | ) 65 | await query.message.delete() 66 | 67 | 68 | @app.on_message(command(["vskip"]) & filters.group) 69 | @authorized_users_only 70 | async def skip(client, m: Message): 71 | 72 | keyboard = InlineKeyboardMarkup( 73 | [ 74 | [ 75 | InlineKeyboardButton(text="ᴍᴇɴᴜ", callback_data="cbmenu"), 76 | ] 77 | ] 78 | ) 79 | 80 | chat_id = m.chat.id 81 | if len(m.command) < 2: 82 | op = await skip_current_song(chat_id) 83 | if op == 0: 84 | await m.reply("❌ Tidak ada yang sedang diputar") 85 | elif op == 1: 86 | await m.reply( 87 | "📊 **Antrian Sedang Kosong.**\n\n**• Assistant Meninggalkan Obrolan Suara**" 88 | ) 89 | elif op == 2: 90 | await m.reply( 91 | "🗑️ **Membersihkan Antrian**\n\n**• Assistant Meninggalkan Obrolan Suara**" 92 | ) 93 | else: 94 | await m.reply( 95 | f""" 96 | ⏭️ **Memutar {op[2]} Selanjutnya** 97 | 🏷 **Nama:** [{op[0]}]({op[1]}) 98 | 🙋🏻‍♂️ **Atas permintaan:** {m.from_user.mention()} 99 | """, 100 | disable_web_page_preview=True, 101 | reply_markup=keyboard, 102 | ) 103 | else: 104 | skip = m.text.split(None, 1)[1] 105 | OP = "🗑 **Lagu dihapus dari antrian:**" 106 | if chat_id in QUEUE: 107 | items = [int(x) for x in skip.split(" ") if x.isdigit()] 108 | items.sort(reverse=True) 109 | for x in items: 110 | if x == 0: 111 | pass 112 | else: 113 | hm = await skip_item(chat_id, x) 114 | if hm == 0: 115 | pass 116 | else: 117 | OP = OP + "\n" + f"**#{x}** - {hm}" 118 | await m.reply(OP) 119 | 120 | 121 | @app.on_message(command(["vstop"]) & filters.group) 122 | @authorized_users_only 123 | async def stop(client, m: Message): 124 | chat_id = m.chat.id 125 | if chat_id in QUEUE: 126 | try: 127 | await call_py.leave_group_call(chat_id) 128 | clear_queue(chat_id) 129 | await m.reply("✅ **Streaming telah berakhir.**") 130 | except Exception as e: 131 | await m.reply(f"**Error:**\n\n`{e}`") 132 | else: 133 | await m.reply("❌ **Tidak ada dalam streaming**") 134 | 135 | 136 | @app.on_message(command(["vpause"]) & filters.group) 137 | @authorized_users_only 138 | async def pause(client, m: Message): 139 | chat_id = m.chat.id 140 | if chat_id in QUEUE: 141 | try: 142 | await call_py.pause_stream(chat_id) 143 | await m.reply( 144 | "⏸️ **Video dijeda.**\n\n• **Untuk melanjutkan video, gunakan Perintah** » /vresume" 145 | ) 146 | except Exception as e: 147 | await m.reply(f"**Error:**\n\n`{e}`") 148 | else: 149 | await m.reply("❌ **Tidak ada dalam streaming**") 150 | 151 | 152 | @app.on_message(command(["vresume"]) & filters.group) 153 | @authorized_users_only 154 | async def resume(client, m: Message): 155 | chat_id = m.chat.id 156 | if chat_id in QUEUE: 157 | try: 158 | await call_py.resume_stream(chat_id) 159 | await m.reply( 160 | "▷ **Video dilanjutkan.**\n\n• **Untuk menjeda video, gunakan Perintah** » /vpause" 161 | ) 162 | except Exception as e: 163 | await m.reply(f"**Error:**\n\n`{e}`") 164 | else: 165 | await m.reply("❌ **Tidak ada dalam streaming**") 166 | 167 | 168 | @app.on_message(command(["vmute"]) & filters.group) 169 | @authorized_users_only 170 | async def mute(client, m: Message): 171 | chat_id = m.chat.id 172 | if chat_id in QUEUE: 173 | try: 174 | await call_py.mute_stream(chat_id) 175 | await m.reply( 176 | "🔇 **Assistant dibisukan.**\n\n• **Untuk mengaktifkan suara Assistant, gunakan Perintah**\n» /vunmute" 177 | ) 178 | except Exception as e: 179 | await m.reply(f"**Error:**\n\n`{e}`") 180 | else: 181 | await m.reply("❌ **Tidak ada dalam streaming**") 182 | 183 | 184 | @app.on_message(command(["vunmute"]) & filters.group) 185 | @authorized_users_only 186 | async def unmute(client, m: Message): 187 | chat_id = m.chat.id 188 | if chat_id in QUEUE: 189 | try: 190 | await call_py.unmute_stream(chat_id) 191 | await m.reply( 192 | "🔊 **Assistant diaktifkan.**\n\n• **Untuk menonaktifkan bot pengguna, gunakan Perintah**\n» /vmute" 193 | ) 194 | except Exception as e: 195 | await m.reply(f"**Error:**\n\n`{e}`") 196 | else: 197 | await m.reply("❌ **Tidak ada dalam streaming**") 198 | 199 | 200 | @Client.on_callback_query(filters.regex("cbpause")) 201 | async def cbpause(_, query: CallbackQuery): 202 | if query.message.sender_chat: 203 | return await query.answer( 204 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 205 | ) 206 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 207 | if not a.can_manage_voice_chats: 208 | return await query.answer( 209 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini!", 210 | show_alert=True, 211 | ) 212 | chat_id = query.message.chat.id 213 | if chat_id in QUEUE: 214 | try: 215 | await call_py.pause_stream(chat_id) 216 | await query.edit_message_text("II Streaming telah dijeda", reply_markup=bttn) 217 | except Exception as e: 218 | await query.edit_message_text(f"**Error:**\n\n`{e}`", reply_markup=bcl) 219 | else: 220 | await query.answer("❌ Tidak ada yang sedang streaming", show_alert=True) 221 | 222 | 223 | @Client.on_callback_query(filters.regex("cbresume")) 224 | async def cbresume(_, query: CallbackQuery): 225 | if query.message.sender_chat: 226 | return await query.answer( 227 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 228 | ) 229 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 230 | if not a.can_manage_voice_chats: 231 | return await query.answer( 232 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 233 | show_alert=True, 234 | ) 235 | chat_id = query.message.chat.id 236 | if chat_id in QUEUE: 237 | try: 238 | await call_py.resume_stream(chat_id) 239 | await query.edit_message_text( 240 | "**▶️ Streaming telah dilanjutkan**", reply_markup=bttn 241 | ) 242 | except Exception as e: 243 | await query.edit_message_text(f"**Error:**\n\n`{e}`", reply_markup=bcl) 244 | else: 245 | await query.answer("❌ Tidak ada yang sedang streaming", show_alert=True) 246 | 247 | 248 | @Client.on_callback_query(filters.regex("cbstop")) 249 | async def cbstop(_, query: CallbackQuery): 250 | if query.message.sender_chat: 251 | return await query.answer( 252 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 253 | ) 254 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 255 | if not a.can_manage_voice_chats: 256 | return await query.answer( 257 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 258 | show_alert=True, 259 | ) 260 | chat_id = query.message.chat.id 261 | if chat_id in QUEUE: 262 | try: 263 | await call_py.leave_group_call(chat_id) 264 | clear_queue(chat_id) 265 | await query.edit_message_text( 266 | "✅ **Streaming telah berakhir**", reply_markup=bcl 267 | ) 268 | except Exception as e: 269 | await query.edit_message_text(f"**Error:**\n\n`{e}`", reply_markup=bcl) 270 | else: 271 | await query.answer("❌ Tidak ada yang sedang streaming", show_alert=True) 272 | 273 | 274 | @Client.on_callback_query(filters.regex("cbmute")) 275 | async def cbmute(_, query: CallbackQuery): 276 | if query.message.sender_chat: 277 | return await query.answer( 278 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 279 | ) 280 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 281 | if not a.can_manage_voice_chats: 282 | return await query.answer( 283 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 284 | show_alert=True, 285 | ) 286 | chat_id = query.message.chat.id 287 | if chat_id in QUEUE: 288 | try: 289 | await call_py.mute_stream(chat_id) 290 | await query.edit_message_text( 291 | "🔇 Assistant berhasil dimatikan", reply_markup=bttn 292 | ) 293 | except Exception as e: 294 | await query.edit_message_text(f"***Error:**\n\n`{e}`", reply_markup=bcl) 295 | else: 296 | await query.answer("❌ Tidak ada yang sedang streaming", show_alert=True) 297 | 298 | 299 | @Client.on_callback_query(filters.regex("cbunmute")) 300 | async def cbunmute(_, query: CallbackQuery): 301 | if query.message.sender_chat: 302 | return await query.answer( 303 | "Anda adalah **Admin Anonim** !\n\n» kembali ke akun pengguna dari hak admin." 304 | ) 305 | a = await _.get_chat_member(query.message.chat.id, query.from_user.id) 306 | if not a.can_manage_voice_chats: 307 | return await query.answer( 308 | "💡 Hanya admin dengan izin mengelola obrolan suara yang dapat mengetuk tombol ini !", 309 | show_alert=True, 310 | ) 311 | chat_id = query.message.chat.id 312 | if chat_id in QUEUE: 313 | try: 314 | await call_py.unmute_stream(chat_id) 315 | await query.edit_message_text( 316 | "🔊 Assistant berhasil dibunyikan", reply_markup=bttn 317 | ) 318 | except Exception as e: 319 | await query.edit_message_text(f"**Error:**\n\n`{e}`", reply_markup=bcl) 320 | else: 321 | await query.answer("❌ Tidak ada yang sedang streaming", show_alert=True) 322 | 323 | 324 | @app.on_message(command(["volume", "vol"])) 325 | @authorized_users_only 326 | async def change_volume(client, m: Message): 327 | range = m.command[1] 328 | chat_id = m.chat.id 329 | if chat_id in QUEUE: 330 | try: 331 | await call_py.change_volume_call(chat_id, volume=int(range)) 332 | await m.reply(f"✅ **Volume Disetel Ke** `{range}`%") 333 | except Exception as e: 334 | await m.reply(f"**Error:**\n\n`{e}`") 335 | else: 336 | await m.reply("❌ **Tidak ada dalam streaming**") 337 | -------------------------------------------------------------------------------- /Music/Plugins/song.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from os import path 4 | import random 5 | import asyncio 6 | import shutil 7 | from pytube import YouTube 8 | from yt_dlp import YoutubeDL 9 | from Music import converter 10 | import yt_dlp 11 | import shutil 12 | import psutil 13 | from pyrogram import Client 14 | from pyrogram.types import Message 15 | from pyrogram.types import Voice 16 | from sys import version as pyver 17 | from Music import dbb, app, BOT_USERNAME, BOT_ID, ASSID, ASSNAME, ASSUSERNAME, ASSMENTION 18 | from Music.MusicUtilities.database.onoff import (is_on_off, add_on, add_off) 19 | from Music.MusicUtilities.database.chats import (get_served_chats, is_served_chat, add_served_chat, get_served_chats) 20 | from Music.MusicUtilities.helpers.inline import (play_keyboard, search_markup, play_markup, playlist_markup, audio_markup, play_list_keyboard) 21 | from Music.MusicUtilities.database.blacklistchat import (blacklisted_chats, blacklist_chat, whitelist_chat) 22 | from Music.MusicUtilities.database.gbanned import (get_gbans_count, is_gbanned_user, add_gban_user, add_gban_user) 23 | from Music.MusicUtilities.database.theme import (_get_theme, get_theme, save_theme) 24 | from Music.MusicUtilities.database.assistant import (_get_assistant, get_assistant, save_assistant) 25 | from Music.config import DURATION_LIMIT 26 | from Music.MusicUtilities.helpers.decorators import errors 27 | from Music.MusicUtilities.helpers.filters import command 28 | from Music.MusicUtilities.helpers.gets import (get_url, themes, random_assistant, ass_det) 29 | from Music.MusicUtilities.helpers.logger import LOG_CHAT 30 | from Music.MusicUtilities.helpers.thumbnails import down_thumb 31 | from Music.MusicUtilities.helpers.chattitle import CHAT_TITLE 32 | from Music.MusicUtilities.helpers.ytdl import ytdl_opts 33 | from pyrogram import filters 34 | from typing import Union 35 | import subprocess 36 | from asyncio import QueueEmpty 37 | import shutil 38 | import os 39 | from youtubesearchpython import VideosSearch 40 | from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant 41 | from pyrogram.types import Message, Audio, Voice 42 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message, ) 43 | flex = {} 44 | chat_watcher_group = 3 45 | def time_to_seconds(time): 46 | stringt = str(time) 47 | return sum( 48 | int(x) * 60 ** i for i, x in enumerate(reversed(stringt.split(":"))) 49 | ) 50 | 51 | @Client.on_message(command(["music", "song", "download"])) 52 | async def mpthree(_, message: Message): 53 | chat_id = message.chat.id 54 | if message.sender_chat: 55 | return await message.reply_text("You're an __Anonymous Admin__!\nRevert back to User Account From Admin Rights.") 56 | user_id = message.from_user.id 57 | chat_title = message.chat.title 58 | username = message.from_user.first_name 59 | checking = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" 60 | 61 | url = get_url(message) 62 | await message.delete() 63 | fucksemx = 0 64 | if url: 65 | query = message.text.split(None, 1)[1] 66 | mystic = await message.reply_text("Processing Url") 67 | ydl_opts = {"format": "bestaudio/best"} 68 | try: 69 | results = VideosSearch(query, limit=1) 70 | for result in results.result()["result"]: 71 | title = (result["title"]) 72 | duration = (result["duration"]) 73 | views = (result["viewCount"]["short"]) 74 | thumbnail = (result["thumbnails"][0]["url"]) 75 | link = (result["link"]) 76 | idxz = (result["id"]) 77 | videoid = (result["id"]) 78 | except Exception as e: 79 | return await mystic.edit_text(f"Soung Not Found.\n**Possible Reason:**{e}") 80 | smex = int(time_to_seconds(duration)) 81 | if smex > DURATION_LIMIT: 82 | return await mystic.edit_text(f"**__Duration Error__**\n\n**Allowed Duration: **90 minute(s)\n**Received Duration:** {duration} minute(s)") 83 | if duration == "None": 84 | return await mystic.edit_text("Sorry! Live videos are not Supported") 85 | if views == "None": 86 | return await mystic.edit_text("Sorry! Live videos are not Supported") 87 | thumb = await down_thumb(thumbnail, user_id) 88 | buttons = gets(videoid, user_id) 89 | m = await message.reply_photo( 90 | photo=thumb, 91 | reply_markup=InlineKeyboardMarkup(buttons), 92 | caption=(f"🎥__Title:__ [{title[:25]}]({url})\n💡[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{id})") 93 | ) 94 | os.remove(thumb) 95 | else: 96 | if len(message.command) < 2: 97 | await message.reply_text("**Usage:**\n\n/song or /music [Youtube Url or Music Name]") 98 | query = message.text.split(None, 1)[1] 99 | mystic = await message.reply_text("**🔄 Searching**") 100 | try: 101 | a = VideosSearch(query, limit=5) 102 | result = (a.result()).get("result") 103 | title1 = (result[0]["title"]) 104 | duration1 = (result[0]["duration"]) 105 | title2 = (result[1]["title"]) 106 | duration2 = (result[1]["duration"]) 107 | title3 = (result[2]["title"]) 108 | duration3 = (result[2]["duration"]) 109 | title4 = (result[3]["title"]) 110 | duration4 = (result[3]["duration"]) 111 | title5 = (result[4]["title"]) 112 | duration5 = (result[4]["duration"]) 113 | ID1 = (result[0]["id"]) 114 | ID2 = (result[1]["id"]) 115 | ID3 = (result[2]["id"]) 116 | ID4 = (result[3]["id"]) 117 | ID5 = (result[4]["id"]) 118 | except Exception as e: 119 | return await mystic.edit_text(f"Soung Not Found.\n**Possible Reason:**{e}") 120 | thumb ="cache/IMG_2.png" 121 | await mystic.delete() 122 | buttons = search_markup(ID1, ID2, ID3, ID4, ID5, duration1, duration2, duration3, duration4, duration5, user_id, query) 123 | hmo = await message.reply_photo( 124 | photo=thumb, 125 | caption=(f"**Flicks X Inline Music Downloader**\n\n1️⃣{title1}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID1})__\n\n2️⃣{title2}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID2})__\n\n3️⃣{title3}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID3})__\n\n4️⃣{title4}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID4})__\n\n5️⃣{title5}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID5})__"), 126 | reply_markup=InlineKeyboardMarkup(buttons), 127 | ) 128 | disable_web_page_preview=True 129 | return 130 | 131 | 132 | @Client.on_callback_query(filters.regex(pattern=r"beta")) 133 | async def startyuplay(_,CallbackQuery): 134 | callback_data = CallbackQuery.data.strip() 135 | chat_id = CallbackQuery.message.chat.id 136 | chat_title = CallbackQuery.message.chat.title 137 | callback_request = callback_data.split(None, 1)[1] 138 | userid = CallbackQuery.from_user.id 139 | try: 140 | id,duration,user_id = callback_request.split("|") 141 | except Exception as e: 142 | return await CallbackQuery.message.edit(f"Error Occured\n**Possible reason could be**:{e}") 143 | if duration == "None": 144 | return await CallbackQuery.message.reply_text(f"Sorry!, Live Videos are not supported") 145 | if CallbackQuery.from_user.id != int(user_id): 146 | return await CallbackQuery.answer("This is not for you! Search You Own Song nigga", show_alert=True) 147 | await CallbackQuery.message.delete() 148 | checking = f"[{CallbackQuery.from_user.first_name}](tg://user?id={userid})" 149 | url = (f"https://www.youtube.com/watch?v={id}") 150 | videoid = id 151 | idx = id 152 | smex = int(time_to_seconds(duration)) 153 | if smex > DURATION_LIMIT: 154 | await CallbackQuery.message.reply_text(f"**__Duration Error__**\n\n**Allowed Duration: **90 minute(s)\n**Received Duration:** {duration} minute(s)") 155 | return 156 | try: 157 | with yt_dlp.YoutubeDL(ytdl_opts) as ytdl: 158 | x = ytdl.extract_info(url, download=False) 159 | except Exception as e: 160 | return await CallbackQuery.message.reply_text(f"Failed to download this video.\n\n**Reason**:{e}") 161 | title = (x["title"]) 162 | await CallbackQuery.answer(f"Selected {title[:20]}.... \nProcessing..", show_alert=True) 163 | thumbnail = (x["thumbnail"]) 164 | idx = (x["id"]) 165 | videoid = (x["id"]) 166 | thumb = await down_thumb(thumbnail, user_id) 167 | buttons = gets(videoid, user_id) 168 | m = await CallbackQuery.message.reply_photo( 169 | photo=thumb, 170 | reply_markup=InlineKeyboardMarkup(buttons), 171 | caption=(f"🎥__Title:__ [{title[:25]}]({url})\n💡[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{id})") 172 | ) 173 | os.remove(thumb) 174 | await CallbackQuery.message.delete() 175 | 176 | 177 | 178 | 179 | @Client.on_callback_query(filters.regex(pattern=r"chonga")) 180 | async def chonga(_,CallbackQuery): 181 | callback_data = CallbackQuery.data.strip() 182 | callback_request = callback_data.split(None, 1)[1] 183 | print(callback_request) 184 | userid = CallbackQuery.from_user.id 185 | try: 186 | id , query, user_id = callback_request.split("|") 187 | except Exception as e: 188 | return await CallbackQuery.message.edit(f"Error Occured\n**Possible reason could be**:{e}") 189 | if CallbackQuery.from_user.id != int(user_id): 190 | return await CallbackQuery.answer("This is not for you! Search You Own Song", show_alert=True) 191 | i=int(id) 192 | query = str(query) 193 | try: 194 | a = VideosSearch(query, limit=10) 195 | result = (a.result()).get("result") 196 | title1 = (result[0]["title"]) 197 | duration1 = (result[0]["duration"]) 198 | title2 = (result[1]["title"]) 199 | duration2 = (result[1]["duration"]) 200 | title3 = (result[2]["title"]) 201 | duration3 = (result[2]["duration"]) 202 | title4 = (result[3]["title"]) 203 | duration4 = (result[3]["duration"]) 204 | title5 = (result[4]["title"]) 205 | duration5 = (result[4]["duration"]) 206 | title6 = (result[5]["title"]) 207 | duration6 = (result[5]["duration"]) 208 | title7= (result[6]["title"]) 209 | duration7 = (result[6]["duration"]) 210 | title8 = (result[7]["title"]) 211 | duration8 = (result[7]["duration"]) 212 | title9 = (result[8]["title"]) 213 | duration9 = (result[8]["duration"]) 214 | title10 = (result[9]["title"]) 215 | duration10 = (result[9]["duration"]) 216 | ID1 = (result[0]["id"]) 217 | ID2 = (result[1]["id"]) 218 | ID3 = (result[2]["id"]) 219 | ID4 = (result[3]["id"]) 220 | ID5 = (result[4]["id"]) 221 | ID6 = (result[5]["id"]) 222 | ID7 = (result[6]["id"]) 223 | ID8 = (result[7]["id"]) 224 | ID9 = (result[8]["id"]) 225 | ID10 = (result[9]["id"]) 226 | except Exception as e: 227 | return await mystic.edit_text(f"Soung Not Found.\n**Possible Reason:**{e}") 228 | if i == 1: 229 | buttons = search_markup2(ID6, ID7, ID8, ID9, ID10, duration6, duration7, duration8, duration9, duration10 ,user_id, query) 230 | await CallbackQuery.edit_message_text( 231 | f"6️⃣{title6}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID6})__\n\n7️⃣{title7}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID7})__\n\n8️⃣{title8}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID8})__\n\n9️⃣{title9}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID9})__\n\n🔟{title10}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID10})__", 232 | reply_markup=InlineKeyboardMarkup(buttons), 233 | ) 234 | disable_web_page_preview=True 235 | return 236 | if i == 2: 237 | buttons = search_markup(ID1, ID2, ID3, ID4, ID5, duration1, duration2, duration3, duration4, duration5, user_id, query) 238 | await CallbackQuery.edit_message_text( 239 | f"1️⃣{title1}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID1})__\n\n2️⃣{title2}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID2})__\n\n3️⃣{title3}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID3})__\n\n4️⃣{title4}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID4})__\n\n5️⃣{title5}\n ┗ 🔗 __[Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{ID5})__", 240 | reply_markup=InlineKeyboardMarkup(buttons), 241 | ) 242 | disable_web_page_preview=True 243 | return 244 | 245 | 246 | 247 | 248 | 249 | 250 | def search_markup(ID1, ID2, ID3, ID4, ID5, duration1, duration2, duration3, duration4, duration5, user_id, query): 251 | buttons= [ 252 | [ 253 | InlineKeyboardButton(text="1️⃣", callback_data=f'beta {ID1}|{duration1}|{user_id}'), 254 | InlineKeyboardButton(text="2️⃣", callback_data=f'beta {ID2}|{duration2}|{user_id}'), 255 | InlineKeyboardButton(text="3️⃣", callback_data=f'beta {ID3}|{duration3}|{user_id}') 256 | ], 257 | [ 258 | InlineKeyboardButton(text="4️⃣", callback_data=f'beta {ID4}|{duration4}|{user_id}'), 259 | InlineKeyboardButton(text="5️⃣", callback_data=f'beta {ID5}|{duration5}|{user_id}') 260 | ], 261 | [ 262 | 263 | InlineKeyboardButton(text="⬅️", callback_data=f'chonga 1|{query}|{user_id}'), 264 | InlineKeyboardButton(text="🗑", callback_data=f"ppcl2 smex|{user_id}") , 265 | InlineKeyboardButton(text="➡️", callback_data=f'chonga 1|{query}|{user_id}') 266 | ], 267 | ] 268 | return buttons 269 | 270 | def search_markup2(ID6, ID7, ID8, ID9, ID10, duration6, duration7, duration8, duration9, duration10 ,user_id, query): 271 | buttons= [ 272 | [ 273 | InlineKeyboardButton(text="6️⃣", callback_data=f'beta {ID6}|{duration6}|{user_id}'), 274 | InlineKeyboardButton(text="7️⃣", callback_data=f'beta {ID7}|{duration7}|{user_id}'), 275 | InlineKeyboardButton(text="8️⃣", callback_data=f'beta {ID8}|{duration8}|{user_id}') 276 | ], 277 | [ 278 | InlineKeyboardButton(text="9️⃣", callback_data=f'beta {ID9}|{duration9}|{user_id}'), 279 | InlineKeyboardButton(text="🔟", callback_data=f'beta {ID10}|{duration10}|{user_id}') 280 | ], 281 | [ 282 | 283 | InlineKeyboardButton(text="⬅️", callback_data=f'chonga 2|{query}|{user_id}'), 284 | InlineKeyboardButton(text="🗑️", callback_data=f"ppcl2 smex|{user_id}") , 285 | InlineKeyboardButton(text="➡️", callback_data=f'chonga 2|{query}|{user_id}') 286 | ], 287 | ] 288 | return buttons 289 | 290 | def gets(videoid, user_id): 291 | buttons= [ 292 | [ 293 | InlineKeyboardButton(text="🧰 Get Audio", callback_data=f'gets audio|{videoid}|{user_id}'), 294 | InlineKeyboardButton(text="🧰 Get Video", callback_data=f'gets video|{videoid}|{user_id}') 295 | ], 296 | [ 297 | InlineKeyboardButton(text="🗑 Close Menu", callback_data=f'close2') 298 | ], 299 | ] 300 | return buttons 301 | --------------------------------------------------------------------------------