├── 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 | 
5 |
6 |
7 |
8 |
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 | 
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 |
--------------------------------------------------------------------------------