Spaces:
Paused
Paused
BinaryONe
commited on
Commit
·
2f67506
1
Parent(s):
c65bc69
Refresh Update
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .dockerignore +10 -0
- .gitattributes +35 -0
- .gitignore +10 -0
- Dockerfile +12 -0
- LICENSE +21 -0
- README.md +11 -0
- YukkiMusic/__init__.py +48 -0
- YukkiMusic/__main__.py +86 -0
- YukkiMusic/core/bot.py +73 -0
- YukkiMusic/core/call.py +750 -0
- YukkiMusic/core/dir.py +33 -0
- YukkiMusic/core/git.py +84 -0
- YukkiMusic/core/mongo.py +43 -0
- YukkiMusic/core/userbot.py +193 -0
- YukkiMusic/logging.py +23 -0
- YukkiMusic/misc.py +90 -0
- YukkiMusic/platforms/Apple.py +86 -0
- YukkiMusic/platforms/Carbon.py +115 -0
- YukkiMusic/platforms/Resso.py +63 -0
- YukkiMusic/platforms/Soundcloud.py +49 -0
- YukkiMusic/platforms/Spotify.py +109 -0
- YukkiMusic/platforms/Telegram.py +205 -0
- YukkiMusic/platforms/Youtube.py +467 -0
- YukkiMusic/platforms/YoutubeAPI/BS4scrapAPI.py +179 -0
- YukkiMusic/platforms/YoutubeAPI/InnertubeAPI.py +250 -0
- YukkiMusic/platforms/YoutubeAPI/JSON_DATA.py +58 -0
- YukkiMusic/platforms/YoutubeAPI/__init__.py +0 -0
- YukkiMusic/platforms/__init__.py +16 -0
- YukkiMusic/platforms/custom_dl.py +185 -0
- YukkiMusic/platforms/file_properties.py +98 -0
- YukkiMusic/plugins/__init__.py +31 -0
- YukkiMusic/plugins/admins/auth.py +159 -0
- YukkiMusic/plugins/admins/callback.py +444 -0
- YukkiMusic/plugins/admins/loop.py +60 -0
- YukkiMusic/plugins/admins/mute.py +39 -0
- YukkiMusic/plugins/admins/pause.py +39 -0
- YukkiMusic/plugins/admins/resume.py +39 -0
- YukkiMusic/plugins/admins/seek.py +87 -0
- YukkiMusic/plugins/admins/shuffle.py +49 -0
- YukkiMusic/plugins/admins/skip.py +223 -0
- YukkiMusic/plugins/admins/stop.py +37 -0
- YukkiMusic/plugins/admins/unmute.py +39 -0
- YukkiMusic/plugins/bot/help.py +122 -0
- YukkiMusic/plugins/bot/inline.py +83 -0
- YukkiMusic/plugins/bot/settings.py +568 -0
- YukkiMusic/plugins/bot/start.py +294 -0
- YukkiMusic/plugins/devs/dev.py +225 -0
- YukkiMusic/plugins/misc/autoleave.py +88 -0
- YukkiMusic/plugins/misc/cleanmode.py +279 -0
- YukkiMusic/plugins/misc/seeker.py +103 -0
.dockerignore
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
.cache
|
| 3 |
+
Yukkilogs.txt
|
| 4 |
+
.DS_Store
|
| 5 |
+
*.session
|
| 6 |
+
raw_files/
|
| 7 |
+
cache/
|
| 8 |
+
downloads/
|
| 9 |
+
__pycache__/
|
| 10 |
+
*.session-journal
|
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
.cache
|
| 3 |
+
Yukkilogs.txt
|
| 4 |
+
.DS_Store
|
| 5 |
+
*.session
|
| 6 |
+
raw_files/
|
| 7 |
+
cache/
|
| 8 |
+
downloads/
|
| 9 |
+
__pycache__/
|
| 10 |
+
*.session-journal
|
Dockerfile
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM nikolaik/python-nodejs:python3.9-nodejs18
|
| 2 |
+
RUN apt-get update -y && apt-get upgrade -y \
|
| 3 |
+
&& apt-get install -y --no-install-recommends ffmpeg \
|
| 4 |
+
&& apt-get clean \
|
| 5 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 6 |
+
COPY . /app
|
| 7 |
+
|
| 8 |
+
RUN chmod 777 /app
|
| 9 |
+
WORKDIR /app
|
| 10 |
+
RUN pip3 install --no-cache-dir --upgrade --requirement requirements.txt
|
| 11 |
+
|
| 12 |
+
CMD ["python", "-u","-m", "YukkiMusic"]
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2022 Team Yukki
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: One Stream
|
| 3 |
+
emoji: 📈
|
| 4 |
+
colorFrom: indigo
|
| 5 |
+
colorTo: gray
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
license: gpl-2.0
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
YukkiMusic/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from YukkiMusic.core.bot import YukkiBot
|
| 11 |
+
from YukkiMusic.core.dir import dirr
|
| 12 |
+
from YukkiMusic.core.git import git
|
| 13 |
+
from YukkiMusic.core.userbot import Userbot
|
| 14 |
+
from YukkiMusic.misc import dbb, heroku, sudo
|
| 15 |
+
|
| 16 |
+
from .logging import LOGGER
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# Directories
|
| 20 |
+
dirr()
|
| 21 |
+
|
| 22 |
+
# Check Git Updates
|
| 23 |
+
git()
|
| 24 |
+
|
| 25 |
+
# Initialize Memory DB
|
| 26 |
+
dbb()
|
| 27 |
+
|
| 28 |
+
# Heroku APP
|
| 29 |
+
heroku()
|
| 30 |
+
|
| 31 |
+
# Load Sudo Users from DB
|
| 32 |
+
sudo()
|
| 33 |
+
|
| 34 |
+
# Bot Client
|
| 35 |
+
app = YukkiBot()
|
| 36 |
+
|
| 37 |
+
# Assistant Client
|
| 38 |
+
userbot = Userbot()
|
| 39 |
+
|
| 40 |
+
from .platforms import *
|
| 41 |
+
|
| 42 |
+
YouTube = YouTubeAPI()
|
| 43 |
+
Carbon = CarbonAPI()
|
| 44 |
+
Spotify = SpotifyAPI()
|
| 45 |
+
Apple = AppleAPI()
|
| 46 |
+
Resso = RessoAPI()
|
| 47 |
+
SoundCloud = SoundAPI()
|
| 48 |
+
Telegram = TeleAPI()
|
YukkiMusic/__main__.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
import importlib
|
| 12 |
+
import sys
|
| 13 |
+
from aiohttp import web
|
| 14 |
+
from pyrogram import idle
|
| 15 |
+
from pytgcalls.exceptions import NoActiveGroupCall
|
| 16 |
+
|
| 17 |
+
import config
|
| 18 |
+
from config import BANNED_USERS
|
| 19 |
+
from YukkiMusic import LOGGER, app, userbot
|
| 20 |
+
from .alive import web_server
|
| 21 |
+
from YukkiMusic.core.call import Yukki
|
| 22 |
+
from YukkiMusic.plugins import ALL_MODULES
|
| 23 |
+
from YukkiMusic.utils.database import get_banned_users, get_gbanned
|
| 24 |
+
|
| 25 |
+
loop = asyncio.get_event_loop()
|
| 26 |
+
server = web.AppRunner(web_server())
|
| 27 |
+
|
| 28 |
+
async def init():
|
| 29 |
+
await server.setup()
|
| 30 |
+
await web.TCPSite(server,'0.0.0.0', 7860).start()
|
| 31 |
+
print("------------------------------Web Server Started ------------------------------")
|
| 32 |
+
|
| 33 |
+
if (
|
| 34 |
+
not config.STRING1
|
| 35 |
+
and not config.STRING2
|
| 36 |
+
and not config.STRING3
|
| 37 |
+
and not config.STRING4
|
| 38 |
+
and not config.STRING5
|
| 39 |
+
):
|
| 40 |
+
LOGGER("YukkiMusic").error(
|
| 41 |
+
"No Assistant Clients Vars Defined!.. Exiting Process."
|
| 42 |
+
)
|
| 43 |
+
return
|
| 44 |
+
if (
|
| 45 |
+
not config.SPOTIFY_CLIENT_ID
|
| 46 |
+
and not config.SPOTIFY_CLIENT_SECRET
|
| 47 |
+
):
|
| 48 |
+
LOGGER("YukkiMusic").warning(
|
| 49 |
+
"No Spotify Vars defined. Your bot won't be able to play spotify queries."
|
| 50 |
+
)
|
| 51 |
+
try:
|
| 52 |
+
users = await get_gbanned()
|
| 53 |
+
for user_id in users:
|
| 54 |
+
BANNED_USERS.add(user_id)
|
| 55 |
+
users = await get_banned_users()
|
| 56 |
+
for user_id in users:
|
| 57 |
+
BANNED_USERS.add(user_id)
|
| 58 |
+
except:
|
| 59 |
+
pass
|
| 60 |
+
await app.start()
|
| 61 |
+
for all_module in ALL_MODULES:
|
| 62 |
+
importlib.import_module("YukkiMusic.plugins" + all_module)
|
| 63 |
+
LOGGER("Yukkimusic.plugins").info("Successfully Imported Modules ")
|
| 64 |
+
|
| 65 |
+
await userbot.start()
|
| 66 |
+
await Yukki.start()
|
| 67 |
+
try:
|
| 68 |
+
await Yukki.stream_call(
|
| 69 |
+
"http://docs.evostream.com/sample_content/assets/sintel1m720p.mp4"
|
| 70 |
+
)
|
| 71 |
+
except NoActiveGroupCall:
|
| 72 |
+
LOGGER("YukkiMusic").error(
|
| 73 |
+
"[ERROR] - \n\nPlease turn on your Logger Group's Voice Call. Make sure you never close/end voice call in your log group"
|
| 74 |
+
)
|
| 75 |
+
sys.exit()
|
| 76 |
+
except:
|
| 77 |
+
pass
|
| 78 |
+
await Yukki.decorators()
|
| 79 |
+
LOGGER("YukkiMusic").info("Yukki Music Bot Started Successfully")
|
| 80 |
+
await idle()
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
if __name__ == "__main__":
|
| 84 |
+
#keep_alive()
|
| 85 |
+
loop.run_until_complete(init())
|
| 86 |
+
LOGGER("YukkiMusic").info("Stopping Yukki Music Bot! GoodBye")
|
YukkiMusic/core/bot.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import sys
|
| 11 |
+
|
| 12 |
+
from pyrogram import Client
|
| 13 |
+
from pyrogram.types import BotCommand
|
| 14 |
+
|
| 15 |
+
import config
|
| 16 |
+
|
| 17 |
+
from ..logging import LOGGER
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class YukkiBot(Client):
|
| 21 |
+
|
| 22 |
+
def __init__(self):
|
| 23 |
+
LOGGER(__name__).info(f"Starting Bot")
|
| 24 |
+
super().__init__(
|
| 25 |
+
"YukkiMusicBot",
|
| 26 |
+
api_id=config.API_ID,
|
| 27 |
+
api_hash=config.API_HASH,
|
| 28 |
+
bot_token=config.BOT_TOKEN,
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
async def start(self):
|
| 32 |
+
await super().start()
|
| 33 |
+
get_me = await self.get_me()
|
| 34 |
+
self.username = get_me.username
|
| 35 |
+
self.id = get_me.id
|
| 36 |
+
try:
|
| 37 |
+
await self.send_message(config.LOG_GROUP_ID, "Bot Started")
|
| 38 |
+
except:
|
| 39 |
+
LOGGER(__name__).error(
|
| 40 |
+
"Bot has failed to access the log Group. Make sure that you have added your bot to your log channel and promoted as admin!"
|
| 41 |
+
)
|
| 42 |
+
sys.exit()
|
| 43 |
+
if config.SET_CMDS :
|
| 44 |
+
try:
|
| 45 |
+
await self.set_bot_commands([
|
| 46 |
+
BotCommand("ping", "Check that bot is alive or dead"),
|
| 47 |
+
BotCommand("play", "Starts playing the requested song"),
|
| 48 |
+
BotCommand("webapp","Open webapp of the music bot for your chat."),
|
| 49 |
+
BotCommand("skip", "Moves to the next track in queue"),
|
| 50 |
+
BotCommand("pause", "Pause the current playing song"),
|
| 51 |
+
BotCommand("resume", "Resume the paused song"),
|
| 52 |
+
BotCommand("end", "Clear the queue and leave voice chat"),
|
| 53 |
+
BotCommand("shuffle", "Randomly shuffles the queued playlist."),
|
| 54 |
+
BotCommand("playmode","Allows you to change the default playmode for your chat"),
|
| 55 |
+
BotCommand("settings","Open the settings of the music bot for your chat.")
|
| 56 |
+
])
|
| 57 |
+
except:
|
| 58 |
+
pass
|
| 59 |
+
else:
|
| 60 |
+
pass
|
| 61 |
+
a = await self.get_chat_member(config.LOG_GROUP_ID, self.id)
|
| 62 |
+
#print(a)
|
| 63 |
+
'''if a.status != "ChatMemberStatus.ADMINISTRATOR":
|
| 64 |
+
LOGGER(__name__).error(
|
| 65 |
+
"Please promote Bot as Admin in Logger Group"
|
| 66 |
+
)
|
| 67 |
+
sys.exit()'''
|
| 68 |
+
if get_me.last_name:
|
| 69 |
+
self.name = get_me.first_name + " " + get_me.last_name
|
| 70 |
+
else:
|
| 71 |
+
self.name = get_me.first_name
|
| 72 |
+
LOGGER(__name__).info(f"MusicBot Started as {self.name}")
|
| 73 |
+
|
YukkiMusic/core/call.py
ADDED
|
@@ -0,0 +1,750 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
from datetime import datetime, timedelta
|
| 12 |
+
from typing import Union
|
| 13 |
+
|
| 14 |
+
from pyrogram import Client
|
| 15 |
+
from pyrogram.errors import (ChatAdminRequired, UserAlreadyParticipant,
|
| 16 |
+
UserNotParticipant)
|
| 17 |
+
from pyrogram.types import InlineKeyboardMarkup
|
| 18 |
+
from pytgcalls import PyTgCalls, StreamType
|
| 19 |
+
from pytgcalls.exceptions import (AlreadyJoinedError, NoActiveGroupCall)
|
| 20 |
+
from pytgcalls.types import (JoinedGroupCallParticipant,
|
| 21 |
+
LeftGroupCallParticipant, Update)
|
| 22 |
+
from pytgcalls.types.stream.legacy import AudioPiped, AudioVideoPiped
|
| 23 |
+
from pytgcalls.types.stream import MediaStream
|
| 24 |
+
from pytgcalls.types.stream import StreamAudioEnded
|
| 25 |
+
|
| 26 |
+
import config
|
| 27 |
+
from strings import get_string
|
| 28 |
+
from YukkiMusic import LOGGER, YouTube, app
|
| 29 |
+
from YukkiMusic.misc import db
|
| 30 |
+
from YukkiMusic.utils.database import (add_active_chat, add_active_video_chat,
|
| 31 |
+
get_assistant, get_audio_bitrate,
|
| 32 |
+
get_lang, get_loop, get_video_bitrate,
|
| 33 |
+
group_assistant, is_autoend, music_on,
|
| 34 |
+
mute_off, remove_active_chat,
|
| 35 |
+
remove_active_video_chat, set_loop)
|
| 36 |
+
from YukkiMusic.utils.exceptions import AssistantErr
|
| 37 |
+
from YukkiMusic.utils.inline.play import (stream_markup, telegram_markup)
|
| 38 |
+
from YukkiMusic.utils.stream.autoclear import auto_clean
|
| 39 |
+
from YukkiMusic.utils.thumbnails import gen_thumb
|
| 40 |
+
|
| 41 |
+
autoend = {}
|
| 42 |
+
counter = {}
|
| 43 |
+
AUTO_END_TIME = 3
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
async def _clear_(chat_id):
|
| 47 |
+
db[chat_id] = []
|
| 48 |
+
await remove_active_video_chat(chat_id)
|
| 49 |
+
await remove_active_chat(chat_id)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class Call(PyTgCalls):
|
| 53 |
+
|
| 54 |
+
def __init__(self):
|
| 55 |
+
self.userbot1 = Client(
|
| 56 |
+
name="1",
|
| 57 |
+
api_id=config.API_ID,
|
| 58 |
+
api_hash=config.API_HASH,
|
| 59 |
+
session_string=str(config.STRING1),
|
| 60 |
+
)
|
| 61 |
+
self.one = PyTgCalls(
|
| 62 |
+
self.userbot1,
|
| 63 |
+
cache_duration=100,
|
| 64 |
+
)
|
| 65 |
+
self.userbot2 = Client(
|
| 66 |
+
name="2",
|
| 67 |
+
api_id=config.API_ID,
|
| 68 |
+
api_hash=config.API_HASH,
|
| 69 |
+
session_string=str(config.STRING2),
|
| 70 |
+
)
|
| 71 |
+
self.two = PyTgCalls(
|
| 72 |
+
self.userbot2,
|
| 73 |
+
cache_duration=100,
|
| 74 |
+
)
|
| 75 |
+
self.userbot3 = Client(
|
| 76 |
+
name="3",
|
| 77 |
+
api_id=config.API_ID,
|
| 78 |
+
api_hash=config.API_HASH,
|
| 79 |
+
session_string=str(config.STRING3),
|
| 80 |
+
)
|
| 81 |
+
self.three = PyTgCalls(
|
| 82 |
+
self.userbot3,
|
| 83 |
+
cache_duration=100,
|
| 84 |
+
)
|
| 85 |
+
self.userbot4 = Client(
|
| 86 |
+
name="4",
|
| 87 |
+
api_id=config.API_ID,
|
| 88 |
+
api_hash=config.API_HASH,
|
| 89 |
+
session_string=str(config.STRING4),
|
| 90 |
+
)
|
| 91 |
+
self.four = PyTgCalls(
|
| 92 |
+
self.userbot4,
|
| 93 |
+
cache_duration=100,
|
| 94 |
+
)
|
| 95 |
+
self.userbot5 = Client(
|
| 96 |
+
name="5",
|
| 97 |
+
api_id=config.API_ID,
|
| 98 |
+
api_hash=config.API_HASH,
|
| 99 |
+
session_string=str(config.STRING5),
|
| 100 |
+
|
| 101 |
+
)
|
| 102 |
+
self.five = PyTgCalls(
|
| 103 |
+
self.userbot5,
|
| 104 |
+
cache_duration=100,
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
async def pause_stream(self, chat_id: int):
|
| 108 |
+
assistant = await group_assistant(self, chat_id)
|
| 109 |
+
await assistant.pause_stream(chat_id)
|
| 110 |
+
|
| 111 |
+
async def resume_stream(self, chat_id: int):
|
| 112 |
+
assistant = await group_assistant(self, chat_id)
|
| 113 |
+
await assistant.resume_stream(chat_id)
|
| 114 |
+
|
| 115 |
+
async def mute_stream(self, chat_id: int):
|
| 116 |
+
assistant = await group_assistant(self, chat_id)
|
| 117 |
+
await assistant.mute_stream(chat_id)
|
| 118 |
+
|
| 119 |
+
async def unmute_stream(self, chat_id: int):
|
| 120 |
+
assistant = await group_assistant(self, chat_id)
|
| 121 |
+
await assistant.unmute_stream(chat_id)
|
| 122 |
+
|
| 123 |
+
async def stop_stream(self, chat_id: int):
|
| 124 |
+
assistant = await group_assistant(self, chat_id)
|
| 125 |
+
try:
|
| 126 |
+
await _clear_(chat_id)
|
| 127 |
+
await assistant.leave_group_call(chat_id)
|
| 128 |
+
except:
|
| 129 |
+
pass
|
| 130 |
+
|
| 131 |
+
async def force_stop_stream(self, chat_id: int):
|
| 132 |
+
assistant = await group_assistant(self, chat_id)
|
| 133 |
+
try:
|
| 134 |
+
check = db.get(chat_id)
|
| 135 |
+
check.pop(0)
|
| 136 |
+
except:
|
| 137 |
+
pass
|
| 138 |
+
await remove_active_video_chat(chat_id)
|
| 139 |
+
await remove_active_chat(chat_id)
|
| 140 |
+
try:
|
| 141 |
+
await assistant.leave_group_call(chat_id)
|
| 142 |
+
except:
|
| 143 |
+
pass
|
| 144 |
+
|
| 145 |
+
async def skip_stream(self,
|
| 146 |
+
chat_id: int,
|
| 147 |
+
link: str,
|
| 148 |
+
video: Union[bool, str] = None):
|
| 149 |
+
assistant = await group_assistant(self, chat_id)
|
| 150 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 151 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 152 |
+
stream = (AudioVideoPiped(
|
| 153 |
+
link,
|
| 154 |
+
audio_parameters=audio_stream_quality,
|
| 155 |
+
video_parameters=video_stream_quality,
|
| 156 |
+
) if video else AudioPiped(link, audio_parameters=audio_stream_quality))
|
| 157 |
+
await assistant.change_stream(
|
| 158 |
+
chat_id,
|
| 159 |
+
stream,
|
| 160 |
+
)
|
| 161 |
+
|
| 162 |
+
async def seek_stream(self, chat_id, file_path, to_seek, duration, mode):
|
| 163 |
+
assistant = await group_assistant(self, chat_id)
|
| 164 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 165 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 166 |
+
stream = (AudioVideoPiped(
|
| 167 |
+
file_path,
|
| 168 |
+
audio_parameters=audio_stream_quality,
|
| 169 |
+
video_parameters=video_stream_quality,
|
| 170 |
+
additional_ffmpeg_parameters=f"-ss {to_seek} -to {duration}",
|
| 171 |
+
) if mode == "video" else AudioPiped(
|
| 172 |
+
file_path,
|
| 173 |
+
audio_parameters=audio_stream_quality,
|
| 174 |
+
additional_ffmpeg_parameters=f"-ss {to_seek} -to {duration}",
|
| 175 |
+
))
|
| 176 |
+
await assistant.change_stream(chat_id, stream)
|
| 177 |
+
|
| 178 |
+
async def stream_call(self, link):
|
| 179 |
+
assistant = await group_assistant(self, config.LOG_GROUP_ID)
|
| 180 |
+
await assistant.join_group_call(
|
| 181 |
+
config.LOG_GROUP_ID,
|
| 182 |
+
AudioVideoPiped(link),
|
| 183 |
+
#stream_type=StreamType().pulse_stream,
|
| 184 |
+
)
|
| 185 |
+
await asyncio.sleep(0.5)
|
| 186 |
+
await assistant.leave_group_call(config.LOG_GROUP_ID)
|
| 187 |
+
#####################################################################################################
|
| 188 |
+
'''async def live_call(self):
|
| 189 |
+
assistant = await group_assistant(self, config.LOG_GROUP_ID)
|
| 190 |
+
video_url="https://rr3---sn-gwpa-jj0k.googlevideo.com/videoplayback?expire=1720992868&ei=BPCTZo2hIcms9fwPxuiMoAQ&ip=34.93.83.202&id=o-AMlVXbysivqlwX1nPegSYVckA8UO6qOI1HNjA_C3ILVm&itag=137&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&bui=AXc671JgbdicNDMCvD64suPqy3V2hQF-GNxvsTkZ4Qpvo2dmu4bM_1b8SqzJ_I9_xQETqJurEz1vxgA2&vprv=1&mime=video%2Fmp4&rqh=1&gir=yes&clen=73860085&dur=221.916&lmt=1720511440920986&keepalive=yes&lmw=1&c=ANDROID_TV&txp=5532434&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cvprv%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRgIhAOjSd5GnA0fj9-jgOyQmW1sXSKx8WClSlO75pIYEZmjlAiEAkhn6qXR6My5_e1z4RBR6C6uGmYKrgaGnhWPYJ9S9ljc%3D&redirect_counter=1&rm=sn-cvh6l7e&fexp=24350516,24350518&req_id=f179ac02cc1ba3ee&cms_redirect=yes&cmsv=e&ipbypass=yes&mh=_i&mip=2409:40e1:1f:e1b6:6820:58cf:6a51:f4ca&mm=31&mn=sn-gwpa-jj0k&ms=au&mt=1720970964&mv=m&mvi=3&pl=48&lsparams=ipbypass,mh,mip,mm,mn,ms,mv,mvi,pl&lsig=AHlkHjAwRQIhAOJXJOUSYjnXhP8mIhp7BXilkWg27LhQwSgFo7h7Sqr9AiBFk9gtmm9mYJoANtxtJDYO92RdMgOq_AXd9D-mcxHuyw%3D%3D"
|
| 191 |
+
audio_url="https://rr3---sn-gwpa-jj0k.googlevideo.com/videoplayback?expire=1720992868&ei=BPCTZo2hIcms9fwPxuiMoAQ&ip=34.93.83.202&id=o-AMlVXbysivqlwX1nPegSYVckA8UO6qOI1HNjA_C3ILVm&itag=251&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&bui=AXc671JgbdicNDMCvD64suPqy3V2hQF-GNxvsTkZ4Qpvo2dmu4bM_1b8SqzJ_I9_xQETqJurEz1vxgA2&vprv=1&mime=audio%2Fwebm&rqh=1&gir=yes&clen=3994328&dur=221.941&lmt=1720508953333763&keepalive=yes&lmw=1&c=ANDROID_TV&txp=5532434&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cvprv%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIgDKbPBz-4y2_EOaOVAA99AggLmKgrfnV21tW1KGXdPPICIQD3ZGqgy9ewLeEK2-WHYpE7P1-Lqm48qYyWOOwZzuvHCA%3D%3D&redirect_counter=1&rm=sn-cvh6l7e&fexp=24350516,24350518&req_id=877fdd961f2a3ee&cms_redirect=yes&cmsv=e&ipbypass=yes&mh=_i&mip=2409:40e1:1f:e1b6:6820:58cf:6a51:f4ca&mm=31&mn=sn-gwpa-jj0k&ms=au&mt=1720970964&mv=m&mvi=3&pl=48&lsparams=ipbypass,mh,mip,mm,mn,ms,mv,mvi,pl&lsig=AHlkHjAwRAIgJmYgFL-esOsvjZ0cLdtkGojJf2RAvyY3BghjEGHqxI4CIDMb2rdPML37UNGuGCZbrkwsKjgfI5FAZ3fOGO-3VO7X"
|
| 192 |
+
|
| 193 |
+
await assistant.join_group_call(
|
| 194 |
+
config.LOG_GROUP_ID,
|
| 195 |
+
MediaStream(
|
| 196 |
+
media_path=video_url,
|
| 197 |
+
audio_path=audio_url,
|
| 198 |
+
),
|
| 199 |
+
#stream_type=StreamType().pulse_stream,
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
'''
|
| 203 |
+
async def join_assistant(self, original_chat_id, chat_id):
|
| 204 |
+
language = await get_lang(original_chat_id)
|
| 205 |
+
_ = get_string(language)
|
| 206 |
+
userbot = await get_assistant(chat_id)
|
| 207 |
+
try:
|
| 208 |
+
try:
|
| 209 |
+
get = await app.get_chat_member(chat_id, userbot.id)
|
| 210 |
+
except ChatAdminRequired:
|
| 211 |
+
raise AssistantErr(_["call_1"])
|
| 212 |
+
if get.status == "banned" or get.status == "kicked":
|
| 213 |
+
raise AssistantErr(_["call_2"].format(userbot.username, userbot.id))
|
| 214 |
+
except UserNotParticipant:
|
| 215 |
+
chat = await app.get_chat(chat_id)
|
| 216 |
+
if chat.username:
|
| 217 |
+
try:
|
| 218 |
+
await userbot.join_chat(chat.username)
|
| 219 |
+
except UserAlreadyParticipant:
|
| 220 |
+
pass
|
| 221 |
+
except Exception as e:
|
| 222 |
+
raise AssistantErr(_["call_3"].format(e))
|
| 223 |
+
else:
|
| 224 |
+
try:
|
| 225 |
+
try:
|
| 226 |
+
try:
|
| 227 |
+
invitelink = chat.invite_link
|
| 228 |
+
if invitelink is None:
|
| 229 |
+
invitelink = (await app.export_chat_invite_link(chat_id))
|
| 230 |
+
except:
|
| 231 |
+
invitelink = (await app.export_chat_invite_link(chat_id))
|
| 232 |
+
except ChatAdminRequired:
|
| 233 |
+
raise AssistantErr(_["call_4"])
|
| 234 |
+
except Exception as e:
|
| 235 |
+
raise AssistantErr(e)
|
| 236 |
+
m = await app.send_message(original_chat_id, _["call_5"])
|
| 237 |
+
if invitelink.startswith("https://t.me/+"):
|
| 238 |
+
invitelink = invitelink.replace("https://t.me/+",
|
| 239 |
+
"https://t.me/joinchat/")
|
| 240 |
+
await asyncio.sleep(3)
|
| 241 |
+
await userbot.join_chat(invitelink)
|
| 242 |
+
await asyncio.sleep(4)
|
| 243 |
+
await m.edit(_["call_6"].format(userbot.name))
|
| 244 |
+
except UserAlreadyParticipant:
|
| 245 |
+
pass
|
| 246 |
+
except Exception as e:
|
| 247 |
+
raise AssistantErr(_["call_3"].format(e))
|
| 248 |
+
|
| 249 |
+
async def join_call(
|
| 250 |
+
self,
|
| 251 |
+
chat_id: int,
|
| 252 |
+
original_chat_id: int,
|
| 253 |
+
link,
|
| 254 |
+
video: Union[bool, str] = None,
|
| 255 |
+
):
|
| 256 |
+
assistant = await group_assistant(self, chat_id)
|
| 257 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 258 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 259 |
+
stream = (AudioVideoPiped(
|
| 260 |
+
link,
|
| 261 |
+
audio_parameters=audio_stream_quality,
|
| 262 |
+
video_parameters=video_stream_quality,
|
| 263 |
+
) if video else AudioPiped(link, audio_parameters=audio_stream_quality))
|
| 264 |
+
try:
|
| 265 |
+
print("join call")
|
| 266 |
+
await assistant.join_group_call(
|
| 267 |
+
chat_id,
|
| 268 |
+
stream,
|
| 269 |
+
#stream_type=StreamType().pulse_stream,
|
| 270 |
+
)
|
| 271 |
+
except NoActiveGroupCall:
|
| 272 |
+
try:
|
| 273 |
+
await self.join_assistant(original_chat_id, chat_id)
|
| 274 |
+
except Exception as e:
|
| 275 |
+
raise e
|
| 276 |
+
try:
|
| 277 |
+
await assistant.join_group_call(
|
| 278 |
+
chat_id,
|
| 279 |
+
stream,
|
| 280 |
+
#stream_type=StreamType().pulse_stream,
|
| 281 |
+
)
|
| 282 |
+
except Exception as e:
|
| 283 |
+
raise AssistantErr(
|
| 284 |
+
"**No Active Voice Chat Found**\n\nPlease make sure group's voice chat is enabled. If already enabled, please end it and start fresh voice chat again and if the problem continues, try /restart"
|
| 285 |
+
)
|
| 286 |
+
except AlreadyJoinedError:
|
| 287 |
+
raise AssistantErr(
|
| 288 |
+
"**Assistant Already in Voice Chat**\n\nSystems have detected that assistant is already there in the voice chat, this issue generally comes when you play 2 queries together.\n\nIf assistant is not present in voice chat, please end voice chat and start fresh voice chat again and if the problem continues, try /restart"
|
| 289 |
+
)
|
| 290 |
+
'''except TelegramServerError:
|
| 291 |
+
raise AssistantErr(
|
| 292 |
+
"**Telegram Server Error**\n\nTelegram is having some internal server problems, Please try playing again.\n\n If this problem keeps coming everytime, please end your voice chat and start fresh voice chat again."
|
| 293 |
+
)'''
|
| 294 |
+
await add_active_chat(chat_id)
|
| 295 |
+
await mute_off(chat_id)
|
| 296 |
+
await music_on(chat_id)
|
| 297 |
+
if video:
|
| 298 |
+
await add_active_video_chat(chat_id)
|
| 299 |
+
if await is_autoend():
|
| 300 |
+
counter[chat_id] = {}
|
| 301 |
+
users = len(await assistant.get_participants(chat_id))
|
| 302 |
+
if users == 1:
|
| 303 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=AUTO_END_TIME)
|
| 304 |
+
|
| 305 |
+
async def join_live_call(
|
| 306 |
+
self,
|
| 307 |
+
chat_id: int,
|
| 308 |
+
original_chat_id: int,
|
| 309 |
+
link,
|
| 310 |
+
video: Union[bool, str] = None,
|
| 311 |
+
):
|
| 312 |
+
assistant = await group_assistant(self, chat_id)
|
| 313 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 314 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 315 |
+
'''stream = (AudioVideoPiped(
|
| 316 |
+
link,
|
| 317 |
+
audio_parameters=audio_stream_quality,
|
| 318 |
+
video_parameters=video_stream_quality,
|
| 319 |
+
) if video else AudioPiped(link, audio_parameters=audio_stream_quality))'''
|
| 320 |
+
try:
|
| 321 |
+
print("join live call")
|
| 322 |
+
if video:
|
| 323 |
+
await assistant.join_group_call(
|
| 324 |
+
chat_id,
|
| 325 |
+
MediaStream(
|
| 326 |
+
media_path=link,
|
| 327 |
+
video_parameters=video_stream_quality,
|
| 328 |
+
),
|
| 329 |
+
#stream_type=StreamType().pulse_stream,
|
| 330 |
+
)
|
| 331 |
+
else:
|
| 332 |
+
await assistant.join_group_call(
|
| 333 |
+
chat_id,
|
| 334 |
+
MediaStream(
|
| 335 |
+
media_path=link,
|
| 336 |
+
audio_parameters=audio_stream_quality,
|
| 337 |
+
),
|
| 338 |
+
#stream_type=StreamType().pulse_stream,
|
| 339 |
+
)
|
| 340 |
+
except NoActiveGroupCall:
|
| 341 |
+
try:
|
| 342 |
+
await self.join_assistant(original_chat_id, chat_id)
|
| 343 |
+
except Exception as e:
|
| 344 |
+
raise e
|
| 345 |
+
try:
|
| 346 |
+
if video:
|
| 347 |
+
await assistant.join_group_call(
|
| 348 |
+
chat_id,
|
| 349 |
+
MediaStream(
|
| 350 |
+
media_path=link,
|
| 351 |
+
video_parameters=video_stream_quality,
|
| 352 |
+
),
|
| 353 |
+
#stream_type=StreamType().pulse_stream,
|
| 354 |
+
)
|
| 355 |
+
else:
|
| 356 |
+
await assistant.join_group_call(
|
| 357 |
+
chat_id,
|
| 358 |
+
MediaStream(
|
| 359 |
+
media_path=link,
|
| 360 |
+
audio_parameters=audio_stream_quality,
|
| 361 |
+
),
|
| 362 |
+
#stream_type=StreamType().pulse_stream,
|
| 363 |
+
)
|
| 364 |
+
except Exception as e:
|
| 365 |
+
raise AssistantErr(
|
| 366 |
+
"**No Active Voice Chat Found**\n\nPlease make sure group's voice chat is enabled. If already enabled, please end it and start fresh voice chat again and if the problem continues, try /restart"
|
| 367 |
+
)
|
| 368 |
+
except AlreadyJoinedError:
|
| 369 |
+
raise AssistantErr(
|
| 370 |
+
"**Assistant Already in Voice Chat**\n\nSystems have detected that assistant is already there in the voice chat, this issue generally comes when you play 2 queries together.\n\nIf assistant is not present in voice chat, please end voice chat and start fresh voice chat again and if the problem continues, try /restart"
|
| 371 |
+
)
|
| 372 |
+
'''except TelegramServerError:
|
| 373 |
+
raise AssistantErr(
|
| 374 |
+
"**Telegram Server Error**\n\nTelegram is having some internal server problems, Please try playing again.\n\n If this problem keeps coming everytime, please end your voice chat and start fresh voice chat again."
|
| 375 |
+
)'''
|
| 376 |
+
await add_active_chat(chat_id)
|
| 377 |
+
await mute_off(chat_id)
|
| 378 |
+
await music_on(chat_id)
|
| 379 |
+
if video:
|
| 380 |
+
await add_active_video_chat(chat_id)
|
| 381 |
+
if await is_autoend():
|
| 382 |
+
counter[chat_id] = {}
|
| 383 |
+
users = len(await assistant.get_participants(chat_id))
|
| 384 |
+
if users == 1:
|
| 385 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=AUTO_END_TIME)
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
|
| 390 |
+
async def live_call(
|
| 391 |
+
self,
|
| 392 |
+
chat_id: int,
|
| 393 |
+
original_chat_id: int,
|
| 394 |
+
video_url,
|
| 395 |
+
audio_url,
|
| 396 |
+
video: Union[bool, str] = None,
|
| 397 |
+
):
|
| 398 |
+
|
| 399 |
+
assistant = await group_assistant(self, chat_id)
|
| 400 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 401 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 402 |
+
'''stream = (AudioVideoPiped(
|
| 403 |
+
link,
|
| 404 |
+
audio_parameters=audio_stream_quality,
|
| 405 |
+
video_parameters=video_stream_quality,
|
| 406 |
+
) if video else AudioPiped(link, audio_parameters=audio_stream_quality))'''
|
| 407 |
+
try:
|
| 408 |
+
print("live call")
|
| 409 |
+
if video:
|
| 410 |
+
await assistant.join_group_call(
|
| 411 |
+
chat_id,
|
| 412 |
+
MediaStream(
|
| 413 |
+
media_path=video_url,
|
| 414 |
+
audio_path=audio_url,
|
| 415 |
+
audio_parameters=audio_stream_quality,
|
| 416 |
+
video_parameters=video_stream_quality,
|
| 417 |
+
),
|
| 418 |
+
#stream_type=StreamType().pulse_stream,
|
| 419 |
+
)
|
| 420 |
+
else:
|
| 421 |
+
await assistant.join_group_call(
|
| 422 |
+
chat_id,
|
| 423 |
+
MediaStream(
|
| 424 |
+
media_path=audio_url,
|
| 425 |
+
audio_parameters=audio_stream_quality,
|
| 426 |
+
),
|
| 427 |
+
#stream_type=StreamType().pulse_stream,
|
| 428 |
+
)
|
| 429 |
+
except NoActiveGroupCall:
|
| 430 |
+
try:
|
| 431 |
+
await self.join_assistant(original_chat_id, chat_id)
|
| 432 |
+
except Exception as e:
|
| 433 |
+
raise e
|
| 434 |
+
try:
|
| 435 |
+
print("live call")
|
| 436 |
+
if video:
|
| 437 |
+
await assistant.join_group_call(
|
| 438 |
+
chat_id,
|
| 439 |
+
MediaStream(
|
| 440 |
+
media_path=video_url,
|
| 441 |
+
audio_path=audio_url,
|
| 442 |
+
audio_parameters=audio_stream_quality,
|
| 443 |
+
video_parameters=video_stream_quality,
|
| 444 |
+
),
|
| 445 |
+
#stream_type=StreamType().pulse_stream,
|
| 446 |
+
)
|
| 447 |
+
else:
|
| 448 |
+
await assistant.join_group_call(
|
| 449 |
+
chat_id,
|
| 450 |
+
MediaStream(
|
| 451 |
+
media_path=audio_url,
|
| 452 |
+
audio_parameters=audio_stream_quality,
|
| 453 |
+
),
|
| 454 |
+
#stream_type=StreamType().pulse_stream,
|
| 455 |
+
)
|
| 456 |
+
except Exception as e:
|
| 457 |
+
raise AssistantErr(
|
| 458 |
+
"**No Active Voice Chat Found**\n\nPlease make sure group's voice chat is enabled. If already enabled, please end it and start fresh voice chat again and if the problem continues, try /restart"
|
| 459 |
+
)
|
| 460 |
+
except AlreadyJoinedError:
|
| 461 |
+
raise AssistantErr(
|
| 462 |
+
"**Assistant Already in Voice Chat**\n\nSystems have detected that assistant is already there in the voice chat, this issue generally comes when you play 2 queries together.\n\nIf assistant is not present in voice chat, please end voice chat and start fresh voice chat again and if the problem continues, try /restart"
|
| 463 |
+
)
|
| 464 |
+
'''except TelegramServerError:
|
| 465 |
+
raise AssistantErr(
|
| 466 |
+
"**Telegram Server Error**\n\nTelegram is having some internal server problems, Please try playing again.\n\n If this problem keeps coming everytime, please end your voice chat and start fresh voice chat again."
|
| 467 |
+
)'''
|
| 468 |
+
await add_active_chat(chat_id)
|
| 469 |
+
await mute_off(chat_id)
|
| 470 |
+
await music_on(chat_id)
|
| 471 |
+
if video:
|
| 472 |
+
await add_active_video_chat(chat_id)
|
| 473 |
+
if await is_autoend():
|
| 474 |
+
counter[chat_id] = {}
|
| 475 |
+
users = len(await assistant.get_participants(chat_id))
|
| 476 |
+
if users == 1:
|
| 477 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=AUTO_END_TIME)
|
| 478 |
+
|
| 479 |
+
async def change_stream(self, client, chat_id):
|
| 480 |
+
check = db.get(chat_id)
|
| 481 |
+
popped = None
|
| 482 |
+
loop = await get_loop(chat_id)
|
| 483 |
+
try:
|
| 484 |
+
if loop == 0:
|
| 485 |
+
popped = check.pop(0)
|
| 486 |
+
else:
|
| 487 |
+
loop = loop - 1
|
| 488 |
+
await set_loop(chat_id, loop)
|
| 489 |
+
if popped:
|
| 490 |
+
if config.AUTO_DOWNLOADS_CLEAR == str(True):
|
| 491 |
+
await auto_clean(popped)
|
| 492 |
+
if not check:
|
| 493 |
+
await _clear_(chat_id)
|
| 494 |
+
return await client.leave_group_call(chat_id)
|
| 495 |
+
except:
|
| 496 |
+
try:
|
| 497 |
+
await _clear_(chat_id)
|
| 498 |
+
return await client.leave_group_call(chat_id)
|
| 499 |
+
except:
|
| 500 |
+
return
|
| 501 |
+
else:
|
| 502 |
+
queued = check[0]["file"]
|
| 503 |
+
language = await get_lang(chat_id)
|
| 504 |
+
_ = get_string(language)
|
| 505 |
+
title = (check[0]["title"]).title()
|
| 506 |
+
user = check[0]["by"]
|
| 507 |
+
original_chat_id = check[0]["chat_id"]
|
| 508 |
+
streamtype = check[0]["streamtype"]
|
| 509 |
+
audio_stream_quality = await get_audio_bitrate(chat_id)
|
| 510 |
+
video_stream_quality = await get_video_bitrate(chat_id)
|
| 511 |
+
videoid = check[0]["vidid"]
|
| 512 |
+
check[0]["played"] = 0
|
| 513 |
+
if "live_" in queued:
|
| 514 |
+
n, link = await YouTube.video(videoid, True)
|
| 515 |
+
if n == 0:
|
| 516 |
+
return await app.send_message(
|
| 517 |
+
original_chat_id,
|
| 518 |
+
text=_["call_9"],
|
| 519 |
+
)
|
| 520 |
+
stream = (AudioVideoPiped(
|
| 521 |
+
link,
|
| 522 |
+
audio_parameters=audio_stream_quality,
|
| 523 |
+
video_parameters=video_stream_quality,
|
| 524 |
+
) if str(streamtype) == "video" else AudioPiped(
|
| 525 |
+
link, audio_parameters=audio_stream_quality))
|
| 526 |
+
try:
|
| 527 |
+
await client.change_stream(chat_id, stream)
|
| 528 |
+
except Exception:
|
| 529 |
+
return await app.send_message(
|
| 530 |
+
original_chat_id,
|
| 531 |
+
text=_["call_9"],
|
| 532 |
+
)
|
| 533 |
+
img = await gen_thumb(videoid)
|
| 534 |
+
button = telegram_markup(_, chat_id)
|
| 535 |
+
run = await app.send_photo(
|
| 536 |
+
original_chat_id,
|
| 537 |
+
photo=img,
|
| 538 |
+
caption=_["stream_1"].format(
|
| 539 |
+
user,
|
| 540 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 541 |
+
),
|
| 542 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 543 |
+
)
|
| 544 |
+
db[chat_id][0]["mystic"] = run
|
| 545 |
+
db[chat_id][0]["markup"] = "tg"
|
| 546 |
+
elif "vid_" in queued:
|
| 547 |
+
mystic = await app.send_message(original_chat_id, _["call_10"])
|
| 548 |
+
try:
|
| 549 |
+
file_path, direct = await YouTube.download(
|
| 550 |
+
videoid,
|
| 551 |
+
mystic,
|
| 552 |
+
videoid=True,
|
| 553 |
+
video=True if str(streamtype) == "video" else False,
|
| 554 |
+
)
|
| 555 |
+
except:
|
| 556 |
+
return await mystic.edit_text(_["call_9"],
|
| 557 |
+
disable_web_page_preview=True)
|
| 558 |
+
stream = (AudioVideoPiped(
|
| 559 |
+
file_path,
|
| 560 |
+
audio_parameters=audio_stream_quality,
|
| 561 |
+
video_parameters=video_stream_quality,
|
| 562 |
+
) if str(streamtype) == "video" else AudioPiped(
|
| 563 |
+
file_path,
|
| 564 |
+
audio_parameters=audio_stream_quality,
|
| 565 |
+
))
|
| 566 |
+
try:
|
| 567 |
+
await client.change_stream(chat_id, stream)
|
| 568 |
+
except Exception:
|
| 569 |
+
return await app.send_message(
|
| 570 |
+
original_chat_id,
|
| 571 |
+
text=_["call_9"],
|
| 572 |
+
)
|
| 573 |
+
img = await gen_thumb(videoid)
|
| 574 |
+
button = stream_markup(_, videoid, chat_id)
|
| 575 |
+
await mystic.delete()
|
| 576 |
+
run = await app.send_photo(
|
| 577 |
+
original_chat_id,
|
| 578 |
+
photo=img,
|
| 579 |
+
caption=_["stream_1"].format(
|
| 580 |
+
user,
|
| 581 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 582 |
+
),
|
| 583 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 584 |
+
)
|
| 585 |
+
db[chat_id][0]["mystic"] = run
|
| 586 |
+
db[chat_id][0]["markup"] = "stream"
|
| 587 |
+
elif "index_" in queued:
|
| 588 |
+
stream = (AudioVideoPiped(
|
| 589 |
+
videoid,
|
| 590 |
+
audio_parameters=audio_stream_quality,
|
| 591 |
+
video_parameters=video_stream_quality,
|
| 592 |
+
) if str(streamtype) == "video" else AudioPiped(
|
| 593 |
+
videoid, audio_parameters=audio_stream_quality))
|
| 594 |
+
try:
|
| 595 |
+
await client.change_stream(chat_id, stream)
|
| 596 |
+
except Exception:
|
| 597 |
+
return await app.send_message(
|
| 598 |
+
original_chat_id,
|
| 599 |
+
text=_["call_9"],
|
| 600 |
+
)
|
| 601 |
+
button = telegram_markup(_, chat_id)
|
| 602 |
+
run = await app.send_photo(
|
| 603 |
+
original_chat_id,
|
| 604 |
+
photo=config.STREAM_IMG_URL,
|
| 605 |
+
caption=_["stream_2"].format(user),
|
| 606 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 607 |
+
)
|
| 608 |
+
db[chat_id][0]["mystic"] = run
|
| 609 |
+
db[chat_id][0]["markup"] = "tg"
|
| 610 |
+
else:
|
| 611 |
+
stream = (AudioVideoPiped(
|
| 612 |
+
queued,
|
| 613 |
+
audio_parameters=audio_stream_quality,
|
| 614 |
+
video_parameters=video_stream_quality,
|
| 615 |
+
) if str(streamtype) == "video" else AudioPiped(
|
| 616 |
+
queued, audio_parameters=audio_stream_quality))
|
| 617 |
+
try:
|
| 618 |
+
await client.change_stream(chat_id, stream)
|
| 619 |
+
except Exception:
|
| 620 |
+
return await app.send_message(
|
| 621 |
+
original_chat_id,
|
| 622 |
+
text=_["call_9"],
|
| 623 |
+
)
|
| 624 |
+
if videoid == "telegram":
|
| 625 |
+
button = telegram_markup(_, chat_id)
|
| 626 |
+
run = await app.send_photo(
|
| 627 |
+
original_chat_id,
|
| 628 |
+
photo=config.TELEGRAM_AUDIO_URL
|
| 629 |
+
if str(streamtype) == "audio" else config.TELEGRAM_VIDEO_URL,
|
| 630 |
+
caption=_["stream_3"].format(title, check[0]["dur"], user),
|
| 631 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 632 |
+
)
|
| 633 |
+
db[chat_id][0]["mystic"] = run
|
| 634 |
+
db[chat_id][0]["markup"] = "tg"
|
| 635 |
+
elif videoid == "soundcloud":
|
| 636 |
+
button = telegram_markup(_, chat_id)
|
| 637 |
+
run = await app.send_photo(
|
| 638 |
+
original_chat_id,
|
| 639 |
+
photo=config.SOUNCLOUD_IMG_URL,
|
| 640 |
+
caption=_["stream_3"].format(title, check[0]["dur"], user),
|
| 641 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 642 |
+
)
|
| 643 |
+
db[chat_id][0]["mystic"] = run
|
| 644 |
+
db[chat_id][0]["markup"] = "tg"
|
| 645 |
+
else:
|
| 646 |
+
img = await gen_thumb(videoid)
|
| 647 |
+
button = stream_markup(_, videoid, chat_id)
|
| 648 |
+
run = await app.send_photo(
|
| 649 |
+
original_chat_id,
|
| 650 |
+
photo=img,
|
| 651 |
+
caption=_["stream_1"].format(
|
| 652 |
+
user,
|
| 653 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 654 |
+
),
|
| 655 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 656 |
+
)
|
| 657 |
+
db[chat_id][0]["mystic"] = run
|
| 658 |
+
db[chat_id][0]["markup"] = "stream"
|
| 659 |
+
|
| 660 |
+
async def ping(self):
|
| 661 |
+
pings = []
|
| 662 |
+
if config.STRING1:
|
| 663 |
+
pings.append(await self.one.ping)
|
| 664 |
+
if config.STRING2:
|
| 665 |
+
pings.append(await self.two.ping)
|
| 666 |
+
if config.STRING3:
|
| 667 |
+
pings.append(await self.three.ping)
|
| 668 |
+
if config.STRING4:
|
| 669 |
+
pings.append(await self.four.ping)
|
| 670 |
+
if config.STRING5:
|
| 671 |
+
pings.append(await self.five.ping)
|
| 672 |
+
return str(round(sum(pings) / len(pings), 3))
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
async def start(self):
|
| 676 |
+
LOGGER(__name__).info("Starting PyTgCalls Client\n")
|
| 677 |
+
if config.STRING1:
|
| 678 |
+
await self.one.start()
|
| 679 |
+
if config.STRING2:
|
| 680 |
+
await self.two.start()
|
| 681 |
+
if config.STRING3:
|
| 682 |
+
await self.three.start()
|
| 683 |
+
if config.STRING4:
|
| 684 |
+
await self.four.start()
|
| 685 |
+
if config.STRING5:
|
| 686 |
+
await self.five.start()
|
| 687 |
+
|
| 688 |
+
async def decorators(self):
|
| 689 |
+
|
| 690 |
+
@self.one.on_kicked()
|
| 691 |
+
@self.two.on_kicked()
|
| 692 |
+
@self.three.on_kicked()
|
| 693 |
+
@self.four.on_kicked()
|
| 694 |
+
@self.five.on_kicked()
|
| 695 |
+
@self.one.on_closed_voice_chat()
|
| 696 |
+
@self.two.on_closed_voice_chat()
|
| 697 |
+
@self.three.on_closed_voice_chat()
|
| 698 |
+
@self.four.on_closed_voice_chat()
|
| 699 |
+
@self.five.on_closed_voice_chat()
|
| 700 |
+
@self.one.on_left()
|
| 701 |
+
@self.two.on_left()
|
| 702 |
+
@self.three.on_left()
|
| 703 |
+
@self.four.on_left()
|
| 704 |
+
@self.five.on_left()
|
| 705 |
+
async def stream_services_handler(_, chat_id: int):
|
| 706 |
+
await self.stop_stream(chat_id)
|
| 707 |
+
|
| 708 |
+
@self.one.on_stream_end()
|
| 709 |
+
@self.two.on_stream_end()
|
| 710 |
+
@self.three.on_stream_end()
|
| 711 |
+
@self.four.on_stream_end()
|
| 712 |
+
@self.five.on_stream_end()
|
| 713 |
+
async def stream_end_handler1(client, update: Update):
|
| 714 |
+
if not isinstance(update, StreamAudioEnded):
|
| 715 |
+
return
|
| 716 |
+
await self.change_stream(client, update.chat_id)
|
| 717 |
+
|
| 718 |
+
@self.one.on_participants_change()
|
| 719 |
+
@self.two.on_participants_change()
|
| 720 |
+
@self.three.on_participants_change()
|
| 721 |
+
@self.four.on_participants_change()
|
| 722 |
+
@self.five.on_participants_change()
|
| 723 |
+
async def participants_change_handler(client, update: Update):
|
| 724 |
+
if not isinstance(update, JoinedGroupCallParticipant) and not isinstance(
|
| 725 |
+
update, LeftGroupCallParticipant):
|
| 726 |
+
return
|
| 727 |
+
chat_id = update.chat_id
|
| 728 |
+
users = counter.get(chat_id)
|
| 729 |
+
if not users:
|
| 730 |
+
try:
|
| 731 |
+
got = len(await client.get_participants(chat_id))
|
| 732 |
+
except:
|
| 733 |
+
return
|
| 734 |
+
counter[chat_id] = got
|
| 735 |
+
if got == 1:
|
| 736 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=AUTO_END_TIME)
|
| 737 |
+
return
|
| 738 |
+
autoend[chat_id] = {}
|
| 739 |
+
else:
|
| 740 |
+
final = (users + 1 if isinstance(update, JoinedGroupCallParticipant)
|
| 741 |
+
else users - 1)
|
| 742 |
+
counter[chat_id] = final
|
| 743 |
+
if final == 1:
|
| 744 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=AUTO_END_TIME)
|
| 745 |
+
return
|
| 746 |
+
autoend[chat_id] = {}
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
|
| 750 |
+
Yukki = Call()
|
YukkiMusic/core/dir.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import os
|
| 11 |
+
import sys
|
| 12 |
+
from os import listdir, mkdir
|
| 13 |
+
|
| 14 |
+
from ..logging import LOGGER
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def dirr():
|
| 18 |
+
if "assets" not in listdir():
|
| 19 |
+
LOGGER(__name__).warning(
|
| 20 |
+
f"Assets Folder not Found. Please clone repository again."
|
| 21 |
+
)
|
| 22 |
+
sys.exit()
|
| 23 |
+
for file in os.listdir():
|
| 24 |
+
if file.endswith(".jpg"):
|
| 25 |
+
os.remove(file)
|
| 26 |
+
for file in os.listdir():
|
| 27 |
+
if file.endswith(".jpeg"):
|
| 28 |
+
os.remove(file)
|
| 29 |
+
if "downloads" not in listdir():
|
| 30 |
+
mkdir("downloads")
|
| 31 |
+
if "cache" not in listdir():
|
| 32 |
+
mkdir("cache")
|
| 33 |
+
LOGGER(__name__).info("Directories Updated.")
|
YukkiMusic/core/git.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
import shlex
|
| 12 |
+
from typing import Tuple
|
| 13 |
+
|
| 14 |
+
from git import Repo
|
| 15 |
+
from git.exc import GitCommandError, InvalidGitRepositoryError
|
| 16 |
+
|
| 17 |
+
import config
|
| 18 |
+
|
| 19 |
+
from ..logging import LOGGER
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def install_req(cmd: str) -> Tuple[str, str, int, int]:
|
| 23 |
+
async def install_requirements():
|
| 24 |
+
args = shlex.split(cmd)
|
| 25 |
+
process = await asyncio.create_subprocess_exec(
|
| 26 |
+
*args,
|
| 27 |
+
stdout=asyncio.subprocess.PIPE,
|
| 28 |
+
stderr=asyncio.subprocess.PIPE,
|
| 29 |
+
)
|
| 30 |
+
stdout, stderr = await process.communicate()
|
| 31 |
+
return (
|
| 32 |
+
stdout.decode("utf-8", "replace").strip(),
|
| 33 |
+
stderr.decode("utf-8", "replace").strip(),
|
| 34 |
+
process.returncode,
|
| 35 |
+
process.pid,
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
return asyncio.get_event_loop().run_until_complete(
|
| 39 |
+
install_requirements()
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def git():
|
| 44 |
+
REPO_LINK = config.UPSTREAM_REPO
|
| 45 |
+
if config.GIT_TOKEN:
|
| 46 |
+
GIT_USERNAME = REPO_LINK.split("com/")[1].split("/")[0]
|
| 47 |
+
TEMP_REPO = REPO_LINK.split("https://")[1]
|
| 48 |
+
UPSTREAM_REPO = (
|
| 49 |
+
f"https://{GIT_USERNAME}:{config.GIT_TOKEN}@{TEMP_REPO}"
|
| 50 |
+
)
|
| 51 |
+
else:
|
| 52 |
+
UPSTREAM_REPO = config.UPSTREAM_REPO
|
| 53 |
+
try:
|
| 54 |
+
repo = Repo()
|
| 55 |
+
LOGGER(__name__).info(f"Git Client Found [VPS DEPLOYER]")
|
| 56 |
+
except GitCommandError:
|
| 57 |
+
LOGGER(__name__).info(f"Invalid Git Command")
|
| 58 |
+
except InvalidGitRepositoryError:
|
| 59 |
+
repo = Repo.init()
|
| 60 |
+
if "origin" in repo.remotes:
|
| 61 |
+
origin = repo.remote("origin")
|
| 62 |
+
else:
|
| 63 |
+
origin = repo.create_remote("origin", UPSTREAM_REPO)
|
| 64 |
+
origin.fetch()
|
| 65 |
+
repo.create_head(
|
| 66 |
+
config.UPSTREAM_BRANCH,
|
| 67 |
+
origin.refs[config.UPSTREAM_BRANCH],
|
| 68 |
+
)
|
| 69 |
+
repo.heads[config.UPSTREAM_BRANCH].set_tracking_branch(
|
| 70 |
+
origin.refs[config.UPSTREAM_BRANCH]
|
| 71 |
+
)
|
| 72 |
+
repo.heads[config.UPSTREAM_BRANCH].checkout(True)
|
| 73 |
+
try:
|
| 74 |
+
repo.create_remote("origin", config.UPSTREAM_REPO)
|
| 75 |
+
except BaseException:
|
| 76 |
+
pass
|
| 77 |
+
nrs = repo.remote("origin")
|
| 78 |
+
nrs.fetch(config.UPSTREAM_BRANCH)
|
| 79 |
+
try:
|
| 80 |
+
nrs.pull(config.UPSTREAM_BRANCH)
|
| 81 |
+
except GitCommandError:
|
| 82 |
+
repo.git.reset("--hard", "FETCH_HEAD")
|
| 83 |
+
install_req("pip3 install --no-cache-dir -r requirements.txt")
|
| 84 |
+
LOGGER(__name__).info(f"Fetched Updates from: {REPO_LINK}")
|
YukkiMusic/core/mongo.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from motor.motor_asyncio import AsyncIOMotorClient as _mongo_client_
|
| 11 |
+
from pymongo import MongoClient
|
| 12 |
+
from pyrogram import Client
|
| 13 |
+
|
| 14 |
+
import config
|
| 15 |
+
|
| 16 |
+
from ..logging import LOGGER
|
| 17 |
+
|
| 18 |
+
TEMP_MONGODB = "mongodb+srv://shikhar:shikhar@cluster0.6xzlh.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
if config.MONGO_DB_URI is None:
|
| 22 |
+
LOGGER(__name__).warning(
|
| 23 |
+
"No MONGO DB URL found.. Your Bot will work on Yukki's Database"
|
| 24 |
+
)
|
| 25 |
+
temp_client = Client(
|
| 26 |
+
"Yukki",
|
| 27 |
+
bot_token=config.BOT_TOKEN,
|
| 28 |
+
api_id=config.API_ID,
|
| 29 |
+
api_hash=config.API_HASH,
|
| 30 |
+
)
|
| 31 |
+
temp_client.start()
|
| 32 |
+
info = temp_client.get_me()
|
| 33 |
+
username = info.username
|
| 34 |
+
temp_client.stop()
|
| 35 |
+
_mongo_async_ = _mongo_client_(TEMP_MONGODB)
|
| 36 |
+
_mongo_sync_ = MongoClient(TEMP_MONGODB)
|
| 37 |
+
mongodb = _mongo_async_[username]
|
| 38 |
+
pymongodb = _mongo_sync_[username]
|
| 39 |
+
else:
|
| 40 |
+
_mongo_async_ = _mongo_client_(config.MONGO_DB_URI)
|
| 41 |
+
_mongo_sync_ = MongoClient(config.MONGO_DB_URI)
|
| 42 |
+
mongodb = _mongo_async_.Yukki
|
| 43 |
+
pymongodb = _mongo_sync_.Yukki
|
YukkiMusic/core/userbot.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import sys
|
| 11 |
+
|
| 12 |
+
from pyrogram import Client
|
| 13 |
+
|
| 14 |
+
import config
|
| 15 |
+
|
| 16 |
+
from ..logging import LOGGER
|
| 17 |
+
|
| 18 |
+
assistants = []
|
| 19 |
+
assistantids = []
|
| 20 |
+
multi_clients = {}
|
| 21 |
+
work_loads = {}
|
| 22 |
+
|
| 23 |
+
async def req_client():
|
| 24 |
+
index = min(work_loads, key=work_loads.get)
|
| 25 |
+
faster_client = multi_clients[index]
|
| 26 |
+
response = dict(index=index, client=faster_client)
|
| 27 |
+
return response
|
| 28 |
+
|
| 29 |
+
class Userbot(Client):
|
| 30 |
+
|
| 31 |
+
def __init__(self):
|
| 32 |
+
self.one = Client(
|
| 33 |
+
name="1",
|
| 34 |
+
api_id=config.API_ID,
|
| 35 |
+
api_hash=config.API_HASH,
|
| 36 |
+
session_string=str(config.STRING1),
|
| 37 |
+
no_updates=True,
|
| 38 |
+
)
|
| 39 |
+
self.two = Client(
|
| 40 |
+
name="2",
|
| 41 |
+
api_id=config.API_ID,
|
| 42 |
+
api_hash=config.API_HASH,
|
| 43 |
+
session_string=str(config.STRING2),
|
| 44 |
+
no_updates=True,
|
| 45 |
+
)
|
| 46 |
+
self.three = Client(
|
| 47 |
+
name="3",
|
| 48 |
+
api_id=config.API_ID,
|
| 49 |
+
api_hash=config.API_HASH,
|
| 50 |
+
session_string=str(config.STRING3),
|
| 51 |
+
no_updates=True,
|
| 52 |
+
)
|
| 53 |
+
self.four = Client(
|
| 54 |
+
name="4",
|
| 55 |
+
api_id=config.API_ID,
|
| 56 |
+
api_hash=config.API_HASH,
|
| 57 |
+
session_string=str(config.STRING4),
|
| 58 |
+
no_updates=True,
|
| 59 |
+
)
|
| 60 |
+
self.five = Client(
|
| 61 |
+
name="5",
|
| 62 |
+
api_id=config.API_ID,
|
| 63 |
+
api_hash=config.API_HASH,
|
| 64 |
+
session_string=str(config.STRING5),
|
| 65 |
+
no_updates=True,
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
async def start(self):
|
| 69 |
+
LOGGER(__name__).info(f"Starting Assistant Clients")
|
| 70 |
+
if config.STRING1:
|
| 71 |
+
await self.one.start()
|
| 72 |
+
|
| 73 |
+
assistants.append(1)
|
| 74 |
+
try:
|
| 75 |
+
await self.one.send_message(config.LOG_GROUP_ID, f"Assistant Started")
|
| 76 |
+
except:
|
| 77 |
+
LOGGER(__name__).error(
|
| 78 |
+
f"Assistant Account 1 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
| 79 |
+
)
|
| 80 |
+
sys.exit()
|
| 81 |
+
get_me = await self.one.get_me()
|
| 82 |
+
self.one.username = get_me.username
|
| 83 |
+
self.one.id = get_me.id
|
| 84 |
+
assistantids.append(get_me.id)
|
| 85 |
+
if get_me.last_name:
|
| 86 |
+
self.one.name = (get_me.first_name + " " + get_me.last_name)
|
| 87 |
+
else:
|
| 88 |
+
self.one.name = get_me.first_name
|
| 89 |
+
LOGGER(__name__).info(f"Assistant Started as {self.one.name}")
|
| 90 |
+
if config.STRING2:
|
| 91 |
+
await self.two.start()
|
| 92 |
+
|
| 93 |
+
assistants.append(2)
|
| 94 |
+
try:
|
| 95 |
+
await self.two.send_message(
|
| 96 |
+
config.LOG_GROUP_ID, "Assistant Started"
|
| 97 |
+
)
|
| 98 |
+
except:
|
| 99 |
+
LOGGER(__name__).error(
|
| 100 |
+
f"Assistant Account 2 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
| 101 |
+
)
|
| 102 |
+
sys.exit()
|
| 103 |
+
get_me = await self.two.get_me()
|
| 104 |
+
self.two.username = get_me.username
|
| 105 |
+
self.two.id = get_me.id
|
| 106 |
+
assistantids.append(get_me.id)
|
| 107 |
+
if get_me.last_name:
|
| 108 |
+
self.two.name = (
|
| 109 |
+
get_me.first_name + " " + get_me.last_name
|
| 110 |
+
)
|
| 111 |
+
else:
|
| 112 |
+
self.two.name = get_me.first_name
|
| 113 |
+
LOGGER(__name__).info(
|
| 114 |
+
f"Assistant Two Started as {self.two.name}"
|
| 115 |
+
)
|
| 116 |
+
if config.STRING3:
|
| 117 |
+
await self.three.start()
|
| 118 |
+
|
| 119 |
+
assistants.append(3)
|
| 120 |
+
try:
|
| 121 |
+
await self.three.send_message(
|
| 122 |
+
config.LOG_GROUP_ID, "Assistant Started"
|
| 123 |
+
)
|
| 124 |
+
except:
|
| 125 |
+
LOGGER(__name__).error(
|
| 126 |
+
f"Assistant Account 3 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
| 127 |
+
)
|
| 128 |
+
sys.exit()
|
| 129 |
+
get_me = await self.three.get_me()
|
| 130 |
+
self.three.username = get_me.username
|
| 131 |
+
self.three.id = get_me.id
|
| 132 |
+
assistantids.append(get_me.id)
|
| 133 |
+
if get_me.last_name:
|
| 134 |
+
self.three.name = (
|
| 135 |
+
get_me.first_name + " " + get_me.last_name
|
| 136 |
+
)
|
| 137 |
+
else:
|
| 138 |
+
self.three.name = get_me.first_name
|
| 139 |
+
LOGGER(__name__).info(
|
| 140 |
+
f"Assistant Three Started as {self.three.name}"
|
| 141 |
+
)
|
| 142 |
+
if config.STRING4:
|
| 143 |
+
await self.four.start()
|
| 144 |
+
|
| 145 |
+
assistants.append(4)
|
| 146 |
+
try:
|
| 147 |
+
await self.four.send_message(
|
| 148 |
+
config.LOG_GROUP_ID, "Assistant Started"
|
| 149 |
+
)
|
| 150 |
+
except:
|
| 151 |
+
LOGGER(__name__).error(
|
| 152 |
+
f"Assistant Account 4 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
| 153 |
+
)
|
| 154 |
+
sys.exit()
|
| 155 |
+
get_me = await self.four.get_me()
|
| 156 |
+
self.four.username = get_me.username
|
| 157 |
+
self.four.id = get_me.id
|
| 158 |
+
assistantids.append(get_me.id)
|
| 159 |
+
if get_me.last_name:
|
| 160 |
+
self.four.name = (
|
| 161 |
+
get_me.first_name + " " + get_me.last_name
|
| 162 |
+
)
|
| 163 |
+
else:
|
| 164 |
+
self.four.name = get_me.first_name
|
| 165 |
+
LOGGER(__name__).info(
|
| 166 |
+
f"Assistant Four Started as {self.four.name}"
|
| 167 |
+
)
|
| 168 |
+
if config.STRING5:
|
| 169 |
+
await self.five.start()
|
| 170 |
+
|
| 171 |
+
assistants.append(5)
|
| 172 |
+
try:
|
| 173 |
+
await self.five.send_message(
|
| 174 |
+
config.LOG_GROUP_ID, "Assistant Started"
|
| 175 |
+
)
|
| 176 |
+
except:
|
| 177 |
+
LOGGER(__name__).error(
|
| 178 |
+
f"Assistant Account 5 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
| 179 |
+
)
|
| 180 |
+
sys.exit()
|
| 181 |
+
get_me = await self.five.get_me()
|
| 182 |
+
self.five.username = get_me.username
|
| 183 |
+
self.five.id = get_me.id
|
| 184 |
+
assistantids.append(get_me.id)
|
| 185 |
+
if get_me.last_name:
|
| 186 |
+
self.five.name = (
|
| 187 |
+
get_me.first_name + " " + get_me.last_name
|
| 188 |
+
)
|
| 189 |
+
else:
|
| 190 |
+
self.five.name = get_me.first_name
|
| 191 |
+
LOGGER(__name__).info(
|
| 192 |
+
f"Assistant Five Started as {self.five.name}"
|
| 193 |
+
)
|
YukkiMusic/logging.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
#from logging.handlers import RotatingFileHandler
|
| 3 |
+
|
| 4 |
+
from config import LOG_FILE_NAME
|
| 5 |
+
|
| 6 |
+
'''logging.basicConfig(
|
| 7 |
+
level=logging.INFO,
|
| 8 |
+
format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s",
|
| 9 |
+
datefmt="%d-%b-%y %H:%M:%S",
|
| 10 |
+
handlers=[
|
| 11 |
+
RotatingFileHandler(
|
| 12 |
+
LOG_FILE_NAME, maxBytes=5000000, backupCount=10
|
| 13 |
+
),
|
| 14 |
+
logging.StreamHandler(),
|
| 15 |
+
],
|
| 16 |
+
)'''
|
| 17 |
+
|
| 18 |
+
logging.getLogger("pyrogram").setLevel(logging.ERROR)
|
| 19 |
+
logging.getLogger("pytgcalls").setLevel(logging.ERROR)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def LOGGER(name: str) -> logging.Logger:
|
| 23 |
+
return logging.getLogger(name)
|
YukkiMusic/misc.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import socket
|
| 11 |
+
import time
|
| 12 |
+
|
| 13 |
+
import heroku3
|
| 14 |
+
from pyrogram import filters
|
| 15 |
+
|
| 16 |
+
import config
|
| 17 |
+
from YukkiMusic.core.mongo import pymongodb
|
| 18 |
+
|
| 19 |
+
from .logging import LOGGER
|
| 20 |
+
|
| 21 |
+
SUDOERS = filters.user()
|
| 22 |
+
|
| 23 |
+
HAPP = None
|
| 24 |
+
_boot_ = time.time()
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def is_heroku():
|
| 28 |
+
return "heroku" in socket.getfqdn()
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
XCB = [
|
| 32 |
+
"/",
|
| 33 |
+
"@",
|
| 34 |
+
".",
|
| 35 |
+
"com",
|
| 36 |
+
":",
|
| 37 |
+
"git",
|
| 38 |
+
"heroku",
|
| 39 |
+
"push",
|
| 40 |
+
str(config.HEROKU_API_KEY),
|
| 41 |
+
"https",
|
| 42 |
+
str(config.HEROKU_APP_NAME),
|
| 43 |
+
"HEAD",
|
| 44 |
+
"main",
|
| 45 |
+
]
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
def dbb():
|
| 49 |
+
global db
|
| 50 |
+
db = {}
|
| 51 |
+
LOGGER(__name__).info(f"Database Initialized.")
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def sudo():
|
| 55 |
+
global SUDOERS
|
| 56 |
+
OWNER = config.OWNER_ID
|
| 57 |
+
if config.MONGO_DB_URI is None:
|
| 58 |
+
for user_id in OWNER:
|
| 59 |
+
SUDOERS.add(user_id)
|
| 60 |
+
else:
|
| 61 |
+
sudoersdb = pymongodb.sudoers
|
| 62 |
+
sudoers = sudoersdb.find_one({"sudo": "sudo"})
|
| 63 |
+
sudoers = [] if not sudoers else sudoers["sudoers"]
|
| 64 |
+
for user_id in OWNER:
|
| 65 |
+
SUDOERS.add(user_id)
|
| 66 |
+
if user_id not in sudoers:
|
| 67 |
+
sudoers.append(user_id)
|
| 68 |
+
sudoersdb.update_one(
|
| 69 |
+
{"sudo": "sudo"},
|
| 70 |
+
{"$set": {"sudoers": sudoers}},
|
| 71 |
+
upsert=True,
|
| 72 |
+
)
|
| 73 |
+
if sudoers:
|
| 74 |
+
for x in sudoers:
|
| 75 |
+
SUDOERS.add(x)
|
| 76 |
+
LOGGER(__name__).info(f"Sudoers Loaded.")
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def heroku():
|
| 80 |
+
global HAPP
|
| 81 |
+
if is_heroku:
|
| 82 |
+
if config.HEROKU_API_KEY and config.HEROKU_APP_NAME:
|
| 83 |
+
try:
|
| 84 |
+
Heroku = heroku3.from_key(config.HEROKU_API_KEY)
|
| 85 |
+
HAPP = Heroku.app(config.HEROKU_APP_NAME)
|
| 86 |
+
LOGGER(__name__).info(f"Heroku App Configured")
|
| 87 |
+
except BaseException:
|
| 88 |
+
LOGGER(__name__).warning(
|
| 89 |
+
f"Please make sure your Heroku API Key and Your App name are configured correctly in the heroku."
|
| 90 |
+
)
|
YukkiMusic/platforms/Apple.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import re
|
| 11 |
+
from typing import Union
|
| 12 |
+
|
| 13 |
+
import aiohttp
|
| 14 |
+
from bs4 import BeautifulSoup
|
| 15 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class AppleAPI:
|
| 19 |
+
def __init__(self):
|
| 20 |
+
self.regex = r"^(https:\/\/music.apple.com\/)(.*)$"
|
| 21 |
+
self.base = "https://music.apple.com/in/playlist/"
|
| 22 |
+
|
| 23 |
+
async def valid(self, link: str):
|
| 24 |
+
if re.search(self.regex, link):
|
| 25 |
+
return True
|
| 26 |
+
else:
|
| 27 |
+
return False
|
| 28 |
+
|
| 29 |
+
async def track(self, url, playid: Union[bool, str] = None):
|
| 30 |
+
if playid:
|
| 31 |
+
url = self.base + url
|
| 32 |
+
async with aiohttp.ClientSession() as session:
|
| 33 |
+
async with session.get(url) as response:
|
| 34 |
+
if response.status != 200:
|
| 35 |
+
return False
|
| 36 |
+
html = await response.text()
|
| 37 |
+
soup = BeautifulSoup(html, "html.parser")
|
| 38 |
+
search = None
|
| 39 |
+
for tag in soup.find_all("meta"):
|
| 40 |
+
if tag.get("property", None) == "og:title":
|
| 41 |
+
search = tag.get("content", None)
|
| 42 |
+
if search is None:
|
| 43 |
+
return False
|
| 44 |
+
results = VideosSearch(search, limit=1)
|
| 45 |
+
for result in (await results.next())["result"]:
|
| 46 |
+
title = result["title"]
|
| 47 |
+
ytlink = result["link"]
|
| 48 |
+
vidid = result["id"]
|
| 49 |
+
duration_min = result["duration"]
|
| 50 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 51 |
+
track_details = {
|
| 52 |
+
"title": title,
|
| 53 |
+
"link": ytlink,
|
| 54 |
+
"vidid": vidid,
|
| 55 |
+
"duration_min": duration_min,
|
| 56 |
+
"thumb": thumbnail,
|
| 57 |
+
}
|
| 58 |
+
return track_details, vidid
|
| 59 |
+
|
| 60 |
+
async def playlist(self, url, playid: Union[bool, str] = None):
|
| 61 |
+
if playid:
|
| 62 |
+
url = self.base + url
|
| 63 |
+
playlist_id = url.split("playlist/")[1]
|
| 64 |
+
async with aiohttp.ClientSession() as session:
|
| 65 |
+
async with session.get(url) as response:
|
| 66 |
+
if response.status != 200:
|
| 67 |
+
return False
|
| 68 |
+
html = await response.text()
|
| 69 |
+
soup = BeautifulSoup(html, "html.parser")
|
| 70 |
+
applelinks = soup.find_all(
|
| 71 |
+
"meta", attrs={"property": "music:song"}
|
| 72 |
+
)
|
| 73 |
+
results = []
|
| 74 |
+
for item in applelinks:
|
| 75 |
+
try:
|
| 76 |
+
xx = (
|
| 77 |
+
((item["content"]).split("album/")[1]).split("/")[
|
| 78 |
+
0
|
| 79 |
+
]
|
| 80 |
+
).replace("-", " ")
|
| 81 |
+
except:
|
| 82 |
+
xx = ((item["content"]).split("album/")[1]).split(
|
| 83 |
+
"/"
|
| 84 |
+
)[0]
|
| 85 |
+
results.append(xx)
|
| 86 |
+
return results, playlist_id
|
YukkiMusic/platforms/Carbon.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import random
|
| 11 |
+
from os.path import realpath
|
| 12 |
+
|
| 13 |
+
import aiohttp
|
| 14 |
+
from aiohttp import client_exceptions
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class UnableToFetchCarbon(Exception):
|
| 18 |
+
pass
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
themes = [
|
| 22 |
+
"3024-night",
|
| 23 |
+
"a11y-dark",
|
| 24 |
+
"blackboard",
|
| 25 |
+
"base16-dark",
|
| 26 |
+
"base16-light",
|
| 27 |
+
"cobalt",
|
| 28 |
+
"duotone-dark",
|
| 29 |
+
"dracula-pro",
|
| 30 |
+
"hopscotch",
|
| 31 |
+
"lucario",
|
| 32 |
+
"material",
|
| 33 |
+
"monokai",
|
| 34 |
+
"nightowl",
|
| 35 |
+
"nord",
|
| 36 |
+
"oceanic-next",
|
| 37 |
+
"one-light",
|
| 38 |
+
"one-dark",
|
| 39 |
+
"panda-syntax",
|
| 40 |
+
"parasio-dark",
|
| 41 |
+
"seti",
|
| 42 |
+
"shades-of-purple",
|
| 43 |
+
"solarized+dark",
|
| 44 |
+
"solarized+light",
|
| 45 |
+
"synthwave-84",
|
| 46 |
+
"twilight",
|
| 47 |
+
"verminal",
|
| 48 |
+
"vscode",
|
| 49 |
+
"yeti",
|
| 50 |
+
"zenburn",
|
| 51 |
+
]
|
| 52 |
+
|
| 53 |
+
colour = [
|
| 54 |
+
"#FF0000",
|
| 55 |
+
"#FF5733",
|
| 56 |
+
"#FFFF00",
|
| 57 |
+
"#008000",
|
| 58 |
+
"#0000FF",
|
| 59 |
+
"#800080",
|
| 60 |
+
"#A52A2A",
|
| 61 |
+
"#FF00FF",
|
| 62 |
+
"#D2B48C",
|
| 63 |
+
"#00FFFF",
|
| 64 |
+
"#808000",
|
| 65 |
+
"#800000",
|
| 66 |
+
"#00FFFF",
|
| 67 |
+
"#30D5C8",
|
| 68 |
+
"#00FF00",
|
| 69 |
+
"#008080",
|
| 70 |
+
"#4B0082",
|
| 71 |
+
"#EE82EE",
|
| 72 |
+
"#FFC0CB",
|
| 73 |
+
"#000000",
|
| 74 |
+
"#FFFFFF",
|
| 75 |
+
"#808080",
|
| 76 |
+
]
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
class CarbonAPI:
|
| 80 |
+
def __init__(self):
|
| 81 |
+
self.language = "auto"
|
| 82 |
+
self.drop_shadow = True
|
| 83 |
+
self.drop_shadow_blur = "68px"
|
| 84 |
+
self.drop_shadow_offset = "20px"
|
| 85 |
+
self.font_family = "JetBrains Mono"
|
| 86 |
+
self.width_adjustment = True
|
| 87 |
+
self.watermark = False
|
| 88 |
+
|
| 89 |
+
async def generate(self, text: str, user_id):
|
| 90 |
+
async with aiohttp.ClientSession(
|
| 91 |
+
headers={"Content-Type": "application/json"},
|
| 92 |
+
) as ses:
|
| 93 |
+
params = {
|
| 94 |
+
"code": text,
|
| 95 |
+
}
|
| 96 |
+
params["backgroundColor"] = random.choice(colour)
|
| 97 |
+
params["theme"] = random.choice(themes)
|
| 98 |
+
params["dropShadow"] = self.drop_shadow
|
| 99 |
+
params["dropShadowOffsetY"] = self.drop_shadow_offset
|
| 100 |
+
params["dropShadowBlurRadius"] = self.drop_shadow_blur
|
| 101 |
+
params["fontFamily"] = self.font_family
|
| 102 |
+
params["language"] = self.language
|
| 103 |
+
params["watermark"] = self.watermark
|
| 104 |
+
params["widthAdjustment"] = self.width_adjustment
|
| 105 |
+
try:
|
| 106 |
+
request = await ses.post(
|
| 107 |
+
"https://carbonara.vercel.app/api/cook",
|
| 108 |
+
json=params,
|
| 109 |
+
)
|
| 110 |
+
except client_exceptions.ClientConnectorError:
|
| 111 |
+
raise UnableToFetchCarbon("Can not reach the Host!")
|
| 112 |
+
resp = await request.read()
|
| 113 |
+
with open(f"cache/carbon{user_id}.jpg", "wb") as f:
|
| 114 |
+
f.write(resp)
|
| 115 |
+
return realpath(f.name)
|
YukkiMusic/platforms/Resso.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import re
|
| 11 |
+
from typing import Union
|
| 12 |
+
|
| 13 |
+
import aiohttp
|
| 14 |
+
from bs4 import BeautifulSoup
|
| 15 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class RessoAPI:
|
| 19 |
+
def __init__(self):
|
| 20 |
+
self.regex = r"^(https:\/\/m.resso.com\/)(.*)$"
|
| 21 |
+
self.base = "https://m.resso.com/"
|
| 22 |
+
|
| 23 |
+
async def valid(self, link: str):
|
| 24 |
+
if re.search(self.regex, link):
|
| 25 |
+
return True
|
| 26 |
+
else:
|
| 27 |
+
return False
|
| 28 |
+
|
| 29 |
+
async def track(self, url, playid: Union[bool, str] = None):
|
| 30 |
+
if playid:
|
| 31 |
+
url = self.base + url
|
| 32 |
+
async with aiohttp.ClientSession() as session:
|
| 33 |
+
async with session.get(url) as response:
|
| 34 |
+
if response.status != 200:
|
| 35 |
+
return False
|
| 36 |
+
html = await response.text()
|
| 37 |
+
soup = BeautifulSoup(html, "html.parser")
|
| 38 |
+
for tag in soup.find_all("meta"):
|
| 39 |
+
if tag.get("property", None) == "og:title":
|
| 40 |
+
title = tag.get("content", None)
|
| 41 |
+
if tag.get("property", None) == "og:description":
|
| 42 |
+
des = tag.get("content", None)
|
| 43 |
+
try:
|
| 44 |
+
des = des.split("·")[0]
|
| 45 |
+
except:
|
| 46 |
+
pass
|
| 47 |
+
if des == "":
|
| 48 |
+
return
|
| 49 |
+
results = VideosSearch(title, limit=1)
|
| 50 |
+
for result in (await results.next())["result"]:
|
| 51 |
+
title = result["title"]
|
| 52 |
+
ytlink = result["link"]
|
| 53 |
+
vidid = result["id"]
|
| 54 |
+
duration_min = result["duration"]
|
| 55 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 56 |
+
track_details = {
|
| 57 |
+
"title": title,
|
| 58 |
+
"link": ytlink,
|
| 59 |
+
"vidid": vidid,
|
| 60 |
+
"duration_min": duration_min,
|
| 61 |
+
"thumb": thumbnail,
|
| 62 |
+
}
|
| 63 |
+
return track_details, vidid
|
YukkiMusic/platforms/Soundcloud.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import re
|
| 11 |
+
from os import path
|
| 12 |
+
|
| 13 |
+
from yt_dlp import YoutubeDL
|
| 14 |
+
|
| 15 |
+
from YukkiMusic.utils.formatters import seconds_to_min
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class SoundAPI:
|
| 19 |
+
def __init__(self):
|
| 20 |
+
self.opts = {
|
| 21 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
| 22 |
+
"format": "best",
|
| 23 |
+
"retries": 3,
|
| 24 |
+
"nooverwrites": False,
|
| 25 |
+
"continuedl": True,
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
async def valid(self, link: str):
|
| 29 |
+
if "soundcloud" in link:
|
| 30 |
+
return True
|
| 31 |
+
else:
|
| 32 |
+
return False
|
| 33 |
+
|
| 34 |
+
async def download(self, url):
|
| 35 |
+
d = YoutubeDL(self.opts)
|
| 36 |
+
try:
|
| 37 |
+
info = d.extract_info(url)
|
| 38 |
+
except:
|
| 39 |
+
return False
|
| 40 |
+
xyz = path.join("downloads", f"{info['id']}.{info['ext']}")
|
| 41 |
+
duration_min = seconds_to_min(info["duration"])
|
| 42 |
+
track_details = {
|
| 43 |
+
"title": info["title"],
|
| 44 |
+
"duration_sec": info["duration"],
|
| 45 |
+
"duration_min": duration_min,
|
| 46 |
+
"uploader": info["uploader"],
|
| 47 |
+
"filepath": xyz,
|
| 48 |
+
}
|
| 49 |
+
return track_details, xyz
|
YukkiMusic/platforms/Spotify.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import re
|
| 11 |
+
|
| 12 |
+
import spotipy
|
| 13 |
+
from spotipy.oauth2 import SpotifyClientCredentials
|
| 14 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 15 |
+
|
| 16 |
+
import config
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class SpotifyAPI:
|
| 20 |
+
def __init__(self):
|
| 21 |
+
self.regex = r"^(https:\/\/open.spotify.com\/)(.*)$"
|
| 22 |
+
self.client_id = config.SPOTIFY_CLIENT_ID
|
| 23 |
+
self.client_secret = config.SPOTIFY_CLIENT_SECRET
|
| 24 |
+
if config.SPOTIFY_CLIENT_ID and config.SPOTIFY_CLIENT_SECRET:
|
| 25 |
+
self.client_credentials_manager = (
|
| 26 |
+
SpotifyClientCredentials(
|
| 27 |
+
self.client_id, self.client_secret
|
| 28 |
+
)
|
| 29 |
+
)
|
| 30 |
+
self.spotify = spotipy.Spotify(
|
| 31 |
+
client_credentials_manager=self.client_credentials_manager
|
| 32 |
+
)
|
| 33 |
+
else:
|
| 34 |
+
self.spotify = None
|
| 35 |
+
|
| 36 |
+
async def valid(self, link: str):
|
| 37 |
+
if re.search(self.regex, link):
|
| 38 |
+
return True
|
| 39 |
+
else:
|
| 40 |
+
return False
|
| 41 |
+
|
| 42 |
+
async def track(self, link: str):
|
| 43 |
+
track = self.spotify.track(link)
|
| 44 |
+
info = track["name"]
|
| 45 |
+
for artist in track["artists"]:
|
| 46 |
+
fetched = f' {artist["name"]}'
|
| 47 |
+
if "Various Artists" not in fetched:
|
| 48 |
+
info += fetched
|
| 49 |
+
results = VideosSearch(info, limit=1)
|
| 50 |
+
for result in (await results.next())["result"]:
|
| 51 |
+
ytlink = result["link"]
|
| 52 |
+
title = result["title"]
|
| 53 |
+
vidid = result["id"]
|
| 54 |
+
duration_min = result["duration"]
|
| 55 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 56 |
+
track_details = {
|
| 57 |
+
"title": title,
|
| 58 |
+
"link": ytlink,
|
| 59 |
+
"vidid": vidid,
|
| 60 |
+
"duration_min": duration_min,
|
| 61 |
+
"thumb": thumbnail,
|
| 62 |
+
}
|
| 63 |
+
return track_details, vidid
|
| 64 |
+
|
| 65 |
+
async def playlist(self, url):
|
| 66 |
+
playlist = self.spotify.playlist(url)
|
| 67 |
+
playlist_id = playlist["id"]
|
| 68 |
+
results = []
|
| 69 |
+
for item in playlist["tracks"]["items"]:
|
| 70 |
+
music_track = item["track"]
|
| 71 |
+
info = music_track["name"]
|
| 72 |
+
for artist in music_track["artists"]:
|
| 73 |
+
fetched = f' {artist["name"]}'
|
| 74 |
+
if "Various Artists" not in fetched:
|
| 75 |
+
info += fetched
|
| 76 |
+
results.append(info)
|
| 77 |
+
return results, playlist_id
|
| 78 |
+
|
| 79 |
+
async def album(self, url):
|
| 80 |
+
album = self.spotify.album(url)
|
| 81 |
+
album_id = album["id"]
|
| 82 |
+
results = []
|
| 83 |
+
for item in album["tracks"]["items"]:
|
| 84 |
+
info = item["name"]
|
| 85 |
+
for artist in item["artists"]:
|
| 86 |
+
fetched = f' {artist["name"]}'
|
| 87 |
+
if "Various Artists" not in fetched:
|
| 88 |
+
info += fetched
|
| 89 |
+
results.append(info)
|
| 90 |
+
|
| 91 |
+
return (
|
| 92 |
+
results,
|
| 93 |
+
album_id,
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
async def artist(self, url):
|
| 97 |
+
artistinfo = self.spotify.artist(url)
|
| 98 |
+
artist_id = artistinfo["id"]
|
| 99 |
+
results = []
|
| 100 |
+
artisttoptracks = self.spotify.artist_top_tracks(url)
|
| 101 |
+
for item in artisttoptracks["tracks"]:
|
| 102 |
+
info = item["name"]
|
| 103 |
+
for artist in item["artists"]:
|
| 104 |
+
fetched = f' {artist["name"]}'
|
| 105 |
+
if "Various Artists" not in fetched:
|
| 106 |
+
info += fetched
|
| 107 |
+
results.append(info)
|
| 108 |
+
|
| 109 |
+
return results, artist_id
|
YukkiMusic/platforms/Telegram.py
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
import os
|
| 12 |
+
import time
|
| 13 |
+
from datetime import datetime, timedelta
|
| 14 |
+
from typing import Union
|
| 15 |
+
|
| 16 |
+
from pyrogram.types import (InlineKeyboardButton,
|
| 17 |
+
InlineKeyboardMarkup, Voice)
|
| 18 |
+
|
| 19 |
+
import config
|
| 20 |
+
from config import MUSIC_BOT_NAME, lyrical
|
| 21 |
+
from YukkiMusic import app
|
| 22 |
+
|
| 23 |
+
from ..utils.formatters import (convert_bytes, get_readable_time,
|
| 24 |
+
seconds_to_min)
|
| 25 |
+
|
| 26 |
+
downloader = {}
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class TeleAPI:
|
| 30 |
+
def __init__(self):
|
| 31 |
+
self.chars_limit = 4096
|
| 32 |
+
self.sleep = config.TELEGRAM_DOWNLOAD_EDIT_SLEEP
|
| 33 |
+
|
| 34 |
+
async def send_split_text(self, message, string):
|
| 35 |
+
n = self.chars_limit
|
| 36 |
+
out = [(string[i : i + n]) for i in range(0, len(string), n)]
|
| 37 |
+
j = 0
|
| 38 |
+
for x in out:
|
| 39 |
+
if j <= 2:
|
| 40 |
+
j += 1
|
| 41 |
+
await message.reply_text(x)
|
| 42 |
+
return True
|
| 43 |
+
|
| 44 |
+
async def get_link(self, message):
|
| 45 |
+
if message.chat.username:
|
| 46 |
+
link = f"https://t.me/{message.chat.username}/{message.reply_to_message.id}"
|
| 47 |
+
else:
|
| 48 |
+
xf = str((message.chat.id))[4:]
|
| 49 |
+
link = f"https://t.me/c/{xf}/{message.reply_to_message.id}"
|
| 50 |
+
return link
|
| 51 |
+
|
| 52 |
+
async def get_filename(
|
| 53 |
+
self, file, audio: Union[bool, str] = None
|
| 54 |
+
):
|
| 55 |
+
try:
|
| 56 |
+
file_name = file.file_name
|
| 57 |
+
if file_name is None:
|
| 58 |
+
file_name = (
|
| 59 |
+
"Telegram Audio File"
|
| 60 |
+
if audio
|
| 61 |
+
else "Telegram Video File"
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
except:
|
| 65 |
+
file_name = (
|
| 66 |
+
"Telegram Audio File"
|
| 67 |
+
if audio
|
| 68 |
+
else "Telegram Video File"
|
| 69 |
+
)
|
| 70 |
+
return file_name
|
| 71 |
+
|
| 72 |
+
async def get_duration(self, file):
|
| 73 |
+
try:
|
| 74 |
+
dur = seconds_to_min(file.duration)
|
| 75 |
+
except:
|
| 76 |
+
dur = "Unknown"
|
| 77 |
+
return dur
|
| 78 |
+
|
| 79 |
+
async def get_filepath(
|
| 80 |
+
self,
|
| 81 |
+
audio: Union[bool, str] = None,
|
| 82 |
+
video: Union[bool, str] = None,
|
| 83 |
+
):
|
| 84 |
+
if audio:
|
| 85 |
+
try:
|
| 86 |
+
file_name = (
|
| 87 |
+
audio.file_unique_id
|
| 88 |
+
+ "."
|
| 89 |
+
+ (
|
| 90 |
+
(audio.file_name.split(".")[-1])
|
| 91 |
+
if (not isinstance(audio, Voice))
|
| 92 |
+
else "ogg"
|
| 93 |
+
)
|
| 94 |
+
)
|
| 95 |
+
except:
|
| 96 |
+
file_name = audio.file_unique_id + "." + ".ogg"
|
| 97 |
+
file_name = os.path.join(
|
| 98 |
+
os.path.realpath("downloads"), file_name
|
| 99 |
+
)
|
| 100 |
+
if video:
|
| 101 |
+
try:
|
| 102 |
+
file_name = (
|
| 103 |
+
video.file_unique_id
|
| 104 |
+
+ "."
|
| 105 |
+
+ (video.file_name.split(".")[-1])
|
| 106 |
+
)
|
| 107 |
+
except:
|
| 108 |
+
file_name = video.file_unique_id + "." + "mp4"
|
| 109 |
+
file_name = os.path.join(
|
| 110 |
+
os.path.realpath("downloads"), file_name
|
| 111 |
+
)
|
| 112 |
+
return file_name
|
| 113 |
+
|
| 114 |
+
async def download(self, _, message, mystic, fname):
|
| 115 |
+
left_time = {}
|
| 116 |
+
speed_counter = {}
|
| 117 |
+
if os.path.exists(fname):
|
| 118 |
+
return True
|
| 119 |
+
|
| 120 |
+
async def down_load():
|
| 121 |
+
async def progress(current, total):
|
| 122 |
+
if current == total:
|
| 123 |
+
return
|
| 124 |
+
current_time = time.time()
|
| 125 |
+
start_time = speed_counter.get(message.id)
|
| 126 |
+
check_time = current_time - start_time
|
| 127 |
+
upl = InlineKeyboardMarkup(
|
| 128 |
+
[
|
| 129 |
+
[
|
| 130 |
+
InlineKeyboardButton(
|
| 131 |
+
text="🚦 Cancel Downloading",
|
| 132 |
+
callback_data="stop_downloading",
|
| 133 |
+
),
|
| 134 |
+
]
|
| 135 |
+
]
|
| 136 |
+
)
|
| 137 |
+
if datetime.now() > left_time.get(message.id):
|
| 138 |
+
percentage = current * 100 / total
|
| 139 |
+
percentage = str(round(percentage, 2))
|
| 140 |
+
speed = current / check_time
|
| 141 |
+
eta = int((total - current) / speed)
|
| 142 |
+
downloader[message.id] = eta
|
| 143 |
+
eta = get_readable_time(eta)
|
| 144 |
+
if not eta:
|
| 145 |
+
eta = "0 sec"
|
| 146 |
+
total_size = convert_bytes(total)
|
| 147 |
+
completed_size = convert_bytes(current)
|
| 148 |
+
speed = convert_bytes(speed)
|
| 149 |
+
text = f"""
|
| 150 |
+
**{MUSIC_BOT_NAME} Telegram Media Downloader**
|
| 151 |
+
|
| 152 |
+
**Total FileSize:** {total_size}
|
| 153 |
+
**Completed:** {completed_size}
|
| 154 |
+
**Percentage:** {percentage[:5]}%
|
| 155 |
+
|
| 156 |
+
**Speed:** {speed}/s
|
| 157 |
+
**ETA:** {eta}"""
|
| 158 |
+
try:
|
| 159 |
+
await mystic.edit_text(text, reply_markup=upl)
|
| 160 |
+
except:
|
| 161 |
+
pass
|
| 162 |
+
left_time[
|
| 163 |
+
message.id
|
| 164 |
+
] = datetime.now() + timedelta(seconds=self.sleep)
|
| 165 |
+
|
| 166 |
+
speed_counter[message.id] = time.time()
|
| 167 |
+
left_time[message.id] = datetime.now()
|
| 168 |
+
|
| 169 |
+
try:
|
| 170 |
+
await app.download_media(
|
| 171 |
+
message.reply_to_message,
|
| 172 |
+
file_name=fname,
|
| 173 |
+
progress=progress,
|
| 174 |
+
)
|
| 175 |
+
await mystic.edit_text(
|
| 176 |
+
"Successfully Downloaded.. Processing file now"
|
| 177 |
+
)
|
| 178 |
+
downloader.pop(message.id)
|
| 179 |
+
except:
|
| 180 |
+
await mystic.edit_text(_["tg_2"])
|
| 181 |
+
|
| 182 |
+
if len(downloader) > 10:
|
| 183 |
+
timers = []
|
| 184 |
+
for x in downloader:
|
| 185 |
+
timers.append(downloader[x])
|
| 186 |
+
try:
|
| 187 |
+
low = min(timers)
|
| 188 |
+
eta = get_readable_time(low)
|
| 189 |
+
except:
|
| 190 |
+
eta = "Unknown"
|
| 191 |
+
await mystic.edit_text(_["tg_1"].format(eta))
|
| 192 |
+
return False
|
| 193 |
+
|
| 194 |
+
task = asyncio.create_task(down_load())
|
| 195 |
+
lyrical[mystic.id] = task
|
| 196 |
+
await task
|
| 197 |
+
downloaded = downloader.get(message.id)
|
| 198 |
+
if downloaded:
|
| 199 |
+
downloader.pop(message.id)
|
| 200 |
+
return False
|
| 201 |
+
verify = lyrical.get(mystic.id)
|
| 202 |
+
if not verify:
|
| 203 |
+
return False
|
| 204 |
+
lyrical.pop(mystic.id)
|
| 205 |
+
return True
|
YukkiMusic/platforms/Youtube.py
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
import os
|
| 12 |
+
import re
|
| 13 |
+
from typing import Union
|
| 14 |
+
|
| 15 |
+
import aiohttp
|
| 16 |
+
import yt_dlp
|
| 17 |
+
from pyrogram.types import Message
|
| 18 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 19 |
+
import scrapetube
|
| 20 |
+
from innertube import InnerTube
|
| 21 |
+
from pprint import pprint
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
import config
|
| 25 |
+
from YukkiMusic.utils.database import is_on_off
|
| 26 |
+
from YukkiMusic.utils.formatters import time_to_seconds
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
async def shell_cmd(cmd):
|
| 30 |
+
proc = await asyncio.create_subprocess_shell(
|
| 31 |
+
cmd,
|
| 32 |
+
stdout=asyncio.subprocess.PIPE,
|
| 33 |
+
stderr=asyncio.subprocess.PIPE,
|
| 34 |
+
)
|
| 35 |
+
out, errorz = await proc.communicate()
|
| 36 |
+
if errorz:
|
| 37 |
+
if (
|
| 38 |
+
"unavailable videos are hidden"
|
| 39 |
+
in (errorz.decode("utf-8")).lower()
|
| 40 |
+
):
|
| 41 |
+
return out.decode("utf-8")
|
| 42 |
+
else:
|
| 43 |
+
return errorz.decode("utf-8")
|
| 44 |
+
return out.decode("utf-8")
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class YouTubeAPI:
|
| 48 |
+
def __init__(self):
|
| 49 |
+
self.base = "https://www.youtube.com/watch?v="
|
| 50 |
+
self.regex = r"(?:youtube\.com|youtu\.be)"
|
| 51 |
+
self.status = "https://www.youtube.com/oembed?url="
|
| 52 |
+
self.listbase = "https://youtube.com/playlist?list="
|
| 53 |
+
self.reg = re.compile(
|
| 54 |
+
r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])"
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
async def exists(
|
| 58 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 59 |
+
):
|
| 60 |
+
if videoid:
|
| 61 |
+
link = self.base + link
|
| 62 |
+
if re.search(self.regex, link):
|
| 63 |
+
return True
|
| 64 |
+
else:
|
| 65 |
+
return False
|
| 66 |
+
|
| 67 |
+
async def url(self, message_1: Message) -> Union[str, None]:
|
| 68 |
+
messages = [message_1]
|
| 69 |
+
if message_1.reply_to_message:
|
| 70 |
+
messages.append(message_1.reply_to_message)
|
| 71 |
+
text = ""
|
| 72 |
+
offset = None
|
| 73 |
+
length = None
|
| 74 |
+
for message in messages:
|
| 75 |
+
if offset:
|
| 76 |
+
break
|
| 77 |
+
if message.entities:
|
| 78 |
+
for entity in message.entities:
|
| 79 |
+
if entity.type == "url":
|
| 80 |
+
text = message.text or message.caption
|
| 81 |
+
offset, length = entity.offset, entity.length
|
| 82 |
+
break
|
| 83 |
+
elif message.caption_entities:
|
| 84 |
+
for entity in message.caption_entities:
|
| 85 |
+
if entity.type == "text_link":
|
| 86 |
+
return entity.url
|
| 87 |
+
if offset in (None,):
|
| 88 |
+
return None
|
| 89 |
+
return text[offset : offset + length]
|
| 90 |
+
|
| 91 |
+
async def details(
|
| 92 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 93 |
+
):
|
| 94 |
+
if videoid:
|
| 95 |
+
link1 = self.base + link
|
| 96 |
+
if "&" in link:
|
| 97 |
+
link1 = link.split("&")[0]
|
| 98 |
+
results = VideosSearch(link, limit=1)
|
| 99 |
+
for result in (await results.next())["result"]:
|
| 100 |
+
title = result["title"]
|
| 101 |
+
duration_min = result["duration"]
|
| 102 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 103 |
+
vidid = result["id"]
|
| 104 |
+
if str(duration_min) == "None":
|
| 105 |
+
duration_sec = 0
|
| 106 |
+
else:
|
| 107 |
+
duration_sec = int(time_to_seconds(duration_min))
|
| 108 |
+
return title, duration_min, duration_sec, thumbnail, vidid
|
| 109 |
+
|
| 110 |
+
async def title(
|
| 111 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 112 |
+
):
|
| 113 |
+
if videoid:
|
| 114 |
+
link = self.base + link
|
| 115 |
+
if "&" in link:
|
| 116 |
+
link = link.split("&")[0]
|
| 117 |
+
results = VideosSearch(link, limit=1)
|
| 118 |
+
for result in (await results.next())["result"]:
|
| 119 |
+
title = result["title"]
|
| 120 |
+
return title
|
| 121 |
+
|
| 122 |
+
async def duration(
|
| 123 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 124 |
+
):
|
| 125 |
+
if videoid:
|
| 126 |
+
link = self.base + link
|
| 127 |
+
if "&" in link:
|
| 128 |
+
link = link.split("&")[0]
|
| 129 |
+
results = VideosSearch(link, limit=1)
|
| 130 |
+
for result in (await results.next())["result"]:
|
| 131 |
+
duration = result["duration"]
|
| 132 |
+
return duration
|
| 133 |
+
|
| 134 |
+
async def thumbnail(
|
| 135 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 136 |
+
):
|
| 137 |
+
if videoid:
|
| 138 |
+
link = self.base + link
|
| 139 |
+
if "&" in link:
|
| 140 |
+
link = link.split("&")[0]
|
| 141 |
+
results = VideosSearch(link, limit=1)
|
| 142 |
+
for result in (await results.next())["result"]:
|
| 143 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 144 |
+
return thumbnail
|
| 145 |
+
|
| 146 |
+
async def video(
|
| 147 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 148 |
+
):
|
| 149 |
+
if videoid:
|
| 150 |
+
link = self.base + link
|
| 151 |
+
if "&" in link:
|
| 152 |
+
link = link.split("&")[0]
|
| 153 |
+
proc = await asyncio.create_subprocess_exec(
|
| 154 |
+
"yt-dlp",
|
| 155 |
+
"-g",
|
| 156 |
+
"-f",
|
| 157 |
+
"best[height<=?720][width<=?1280]",
|
| 158 |
+
f"{link}",
|
| 159 |
+
stdout=asyncio.subprocess.PIPE,
|
| 160 |
+
stderr=asyncio.subprocess.PIPE,
|
| 161 |
+
)
|
| 162 |
+
stdout, stderr = await proc.communicate()
|
| 163 |
+
if stdout:
|
| 164 |
+
return 1, stdout.decode().split("\n")[0]
|
| 165 |
+
else:
|
| 166 |
+
return 0, stderr.decode()
|
| 167 |
+
|
| 168 |
+
async def playlist(
|
| 169 |
+
self, link, limit, user_id, videoid: Union[bool, str] = None
|
| 170 |
+
):
|
| 171 |
+
if videoid:
|
| 172 |
+
link1 = self.listbase + link
|
| 173 |
+
if "&" in link:
|
| 174 |
+
link1 = link.split("&")[0]
|
| 175 |
+
playlist = await shell_cmd(
|
| 176 |
+
f"yt-dlp -i --get-id --flat-playlist --playlist-end {limit} --skip-download {link}"
|
| 177 |
+
)
|
| 178 |
+
try:
|
| 179 |
+
result = playlist.split("\n")
|
| 180 |
+
for key in result:
|
| 181 |
+
if key == "":
|
| 182 |
+
result.remove(key)
|
| 183 |
+
except:
|
| 184 |
+
result = []
|
| 185 |
+
return result
|
| 186 |
+
|
| 187 |
+
async def track(
|
| 188 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 189 |
+
):
|
| 190 |
+
if videoid:
|
| 191 |
+
link = self.base + link
|
| 192 |
+
if "&" in link:
|
| 193 |
+
link = link.split("&")[0]
|
| 194 |
+
results = VideosSearch(link, limit=1)
|
| 195 |
+
#results = scrapetube.get_search(link,limit=1)
|
| 196 |
+
for result in (await results.next())["result"]:
|
| 197 |
+
#print(result)
|
| 198 |
+
title = result["id"] if result["title"]=='' else result["title"]
|
| 199 |
+
duration_min = result["duration"]
|
| 200 |
+
vidid = result["id"]
|
| 201 |
+
yturl = result["link"]
|
| 202 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
| 203 |
+
track_details = {
|
| 204 |
+
"title": title,
|
| 205 |
+
"link": yturl,
|
| 206 |
+
"vidid": vidid,
|
| 207 |
+
"duration_min": duration_min,
|
| 208 |
+
"thumb": thumbnail,
|
| 209 |
+
}
|
| 210 |
+
'''
|
| 211 |
+
for result in results:
|
| 212 |
+
print(result)
|
| 213 |
+
title = result['title']['runs']['text']
|
| 214 |
+
duration_min = result['lengthText']['simpleText']
|
| 215 |
+
vidid = result['videoId']
|
| 216 |
+
yturl = link
|
| 217 |
+
thumbnail = result['thumbnail']['thumbnails'][0]['url']
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
track_details = {
|
| 221 |
+
"title":title ,
|
| 222 |
+
"link": link,
|
| 223 |
+
"vidid": vidid,
|
| 224 |
+
"duration_min": duration_min,
|
| 225 |
+
"thumb": thumbnail,
|
| 226 |
+
}'''
|
| 227 |
+
return track_details, vidid
|
| 228 |
+
|
| 229 |
+
async def formats(
|
| 230 |
+
self, link: str, videoid: Union[bool, str] = None
|
| 231 |
+
):
|
| 232 |
+
if videoid:
|
| 233 |
+
link = self.base + link
|
| 234 |
+
if "&" in link:
|
| 235 |
+
link = link.split("&")[0]
|
| 236 |
+
ytdl_opts = {"quiet": True}
|
| 237 |
+
ydl = yt_dlp.YoutubeDL(ytdl_opts)
|
| 238 |
+
with ydl:
|
| 239 |
+
formats_available = []
|
| 240 |
+
r = ydl.extract_info(link, download=False)
|
| 241 |
+
for format in r["formats"]:
|
| 242 |
+
try:
|
| 243 |
+
str(format["format"])
|
| 244 |
+
except:
|
| 245 |
+
continue
|
| 246 |
+
if not "dash" in str(format["format"]).lower():
|
| 247 |
+
try:
|
| 248 |
+
format["format"]
|
| 249 |
+
format["filesize"]
|
| 250 |
+
format["format_id"]
|
| 251 |
+
format["ext"]
|
| 252 |
+
format["format_note"]
|
| 253 |
+
except:
|
| 254 |
+
continue
|
| 255 |
+
formats_available.append(
|
| 256 |
+
{
|
| 257 |
+
"format": format["format"],
|
| 258 |
+
"filesize": format["filesize"],
|
| 259 |
+
"format_id": format["format_id"],
|
| 260 |
+
"ext": format["ext"],
|
| 261 |
+
"format_note": format["format_note"],
|
| 262 |
+
"yturl": link,
|
| 263 |
+
}
|
| 264 |
+
)
|
| 265 |
+
return formats_available, link
|
| 266 |
+
|
| 267 |
+
async def slider(
|
| 268 |
+
self,
|
| 269 |
+
link: str,
|
| 270 |
+
query_type: int,
|
| 271 |
+
videoid: Union[bool, str] = None,
|
| 272 |
+
):
|
| 273 |
+
if videoid:
|
| 274 |
+
link = self.base + link
|
| 275 |
+
if "&" in link:
|
| 276 |
+
link = link.split("&")[0]
|
| 277 |
+
a = VideosSearch(link, limit=10)
|
| 278 |
+
result = (await a.next()).get("result")
|
| 279 |
+
title = result[query_type]["title"]
|
| 280 |
+
duration_min = result[query_type]["duration"]
|
| 281 |
+
vidid = result[query_type]["id"]
|
| 282 |
+
thumbnail = result[query_type]["thumbnails"][0]["url"].split(
|
| 283 |
+
"?"
|
| 284 |
+
)[0]
|
| 285 |
+
return title, duration_min, thumbnail, vidid
|
| 286 |
+
|
| 287 |
+
async def download(
|
| 288 |
+
self,
|
| 289 |
+
link: str,
|
| 290 |
+
mystic,
|
| 291 |
+
video: Union[bool, str] = None,
|
| 292 |
+
videoid: Union[bool, str] = None,
|
| 293 |
+
songaudio: Union[bool, str] = None,
|
| 294 |
+
songvideo: Union[bool, str] = None,
|
| 295 |
+
format_id: Union[bool, str] = None,
|
| 296 |
+
title: Union[bool, str] = None,
|
| 297 |
+
) -> str:
|
| 298 |
+
if videoid:
|
| 299 |
+
link = self.base + link
|
| 300 |
+
loop = asyncio.get_running_loop()
|
| 301 |
+
|
| 302 |
+
def audio_dl():
|
| 303 |
+
ydl_optssx = {
|
| 304 |
+
"format": "bestaudio/best",
|
| 305 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
| 306 |
+
"geo_bypass": True,
|
| 307 |
+
"nocheckcertificate": True,
|
| 308 |
+
"quiet": True,
|
| 309 |
+
"no_warnings": True,
|
| 310 |
+
}
|
| 311 |
+
x = yt_dlp.YoutubeDL(ydl_optssx)
|
| 312 |
+
info = x.extract_info(link, False)
|
| 313 |
+
xyz = os.path.join(
|
| 314 |
+
"downloads", f"{info['id']}.{info['ext']}"
|
| 315 |
+
)
|
| 316 |
+
if os.path.exists(xyz):
|
| 317 |
+
return xyz
|
| 318 |
+
x.download([link])
|
| 319 |
+
return xyz
|
| 320 |
+
|
| 321 |
+
def video_dl():
|
| 322 |
+
ydl_optssx = {
|
| 323 |
+
"format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
|
| 324 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
| 325 |
+
"geo_bypass": True,
|
| 326 |
+
"nocheckcertificate": True,
|
| 327 |
+
"quiet": True,
|
| 328 |
+
"no_warnings": True,
|
| 329 |
+
}
|
| 330 |
+
x = yt_dlp.YoutubeDL(ydl_optssx)
|
| 331 |
+
info = x.extract_info(link, False)
|
| 332 |
+
xyz = os.path.join(
|
| 333 |
+
"downloads", f"{info['id']}.{info['ext']}"
|
| 334 |
+
)
|
| 335 |
+
if os.path.exists(xyz):
|
| 336 |
+
return xyz
|
| 337 |
+
x.download([link])
|
| 338 |
+
return xyz
|
| 339 |
+
|
| 340 |
+
def song_video_dl():
|
| 341 |
+
formats = f"{format_id}+140"
|
| 342 |
+
fpath = f"downloads/{title}"
|
| 343 |
+
ydl_optssx = {
|
| 344 |
+
"format": formats,
|
| 345 |
+
"outtmpl": fpath,
|
| 346 |
+
"geo_bypass": True,
|
| 347 |
+
"nocheckcertificate": True,
|
| 348 |
+
"quiet": True,
|
| 349 |
+
"no_warnings": True,
|
| 350 |
+
"prefer_ffmpeg": True,
|
| 351 |
+
"merge_output_format": "mp4",
|
| 352 |
+
}
|
| 353 |
+
x = yt_dlp.YoutubeDL(ydl_optssx)
|
| 354 |
+
x.download([link])
|
| 355 |
+
|
| 356 |
+
def song_audio_dl():
|
| 357 |
+
fpath = f"downloads/{title}.%(ext)s"
|
| 358 |
+
ydl_optssx = {
|
| 359 |
+
"format": format_id,
|
| 360 |
+
"outtmpl": fpath,
|
| 361 |
+
"geo_bypass": True,
|
| 362 |
+
"nocheckcertificate": True,
|
| 363 |
+
"quiet": True,
|
| 364 |
+
"no_warnings": True,
|
| 365 |
+
"prefer_ffmpeg": True,
|
| 366 |
+
"postprocessors": [
|
| 367 |
+
{
|
| 368 |
+
"key": "FFmpegExtractAudio",
|
| 369 |
+
"preferredcodec": "mp3",
|
| 370 |
+
"preferredquality": "192",
|
| 371 |
+
}
|
| 372 |
+
],
|
| 373 |
+
}
|
| 374 |
+
x = yt_dlp.YoutubeDL(ydl_optssx)
|
| 375 |
+
x.download([link])
|
| 376 |
+
|
| 377 |
+
if songvideo:
|
| 378 |
+
await loop.run_in_executor(None, song_video_dl)
|
| 379 |
+
fpath = f"downloads/{title}.mp4"
|
| 380 |
+
return fpath
|
| 381 |
+
elif songaudio:
|
| 382 |
+
await loop.run_in_executor(None, song_audio_dl)
|
| 383 |
+
fpath = f"downloads/{title}.mp3"
|
| 384 |
+
return fpath
|
| 385 |
+
elif video:
|
| 386 |
+
if await is_on_off(config.YTDOWNLOADER):
|
| 387 |
+
direct = True
|
| 388 |
+
downloaded_file = await loop.run_in_executor(
|
| 389 |
+
None, video_dl
|
| 390 |
+
)
|
| 391 |
+
else:
|
| 392 |
+
proc = await asyncio.create_subprocess_exec(
|
| 393 |
+
"yt-dlp",
|
| 394 |
+
"-g",
|
| 395 |
+
"-f",
|
| 396 |
+
"best[height<=?720][width<=?1280]",
|
| 397 |
+
f"{link}",
|
| 398 |
+
stdout=asyncio.subprocess.PIPE,
|
| 399 |
+
stderr=asyncio.subprocess.PIPE,
|
| 400 |
+
)
|
| 401 |
+
stdout, stderr = await proc.communicate()
|
| 402 |
+
if stdout:
|
| 403 |
+
downloaded_file = stdout.decode().split("\n")[0]
|
| 404 |
+
direct = None
|
| 405 |
+
else:
|
| 406 |
+
return
|
| 407 |
+
else:
|
| 408 |
+
direct = True
|
| 409 |
+
downloaded_file = await loop.run_in_executor(
|
| 410 |
+
None, audio_dl
|
| 411 |
+
)
|
| 412 |
+
return downloaded_file, direct
|
| 413 |
+
async def audio_video_url(self,
|
| 414 |
+
link: str,
|
| 415 |
+
mystic,
|
| 416 |
+
video: Union[bool, str] = None,
|
| 417 |
+
videoid: Union[bool, str] = None,
|
| 418 |
+
songaudio: Union[bool, str] = None,
|
| 419 |
+
songvideo: Union[bool, str] = None,
|
| 420 |
+
format_id: Union[bool, str] = None,
|
| 421 |
+
title: Union[bool, str] = None,
|
| 422 |
+
) -> str:
|
| 423 |
+
if videoid:
|
| 424 |
+
video_id= link
|
| 425 |
+
loop = asyncio.get_running_loop()
|
| 426 |
+
|
| 427 |
+
def get_audio_url():
|
| 428 |
+
#yclient = InnerTube("ANDROID_TV")
|
| 429 |
+
yclient = InnerTube("ANDROID_LITE")
|
| 430 |
+
# Fetch the player data for the video
|
| 431 |
+
data = yclient.player(video_id)
|
| 432 |
+
|
| 433 |
+
# List of streams of the video
|
| 434 |
+
streams = data["streamingData"]["adaptiveFormats"]
|
| 435 |
+
for stream in streams:
|
| 436 |
+
if stream["mimeType"].find('video'):
|
| 437 |
+
audio_url=stream['url']
|
| 438 |
+
break
|
| 439 |
+
else:
|
| 440 |
+
continue
|
| 441 |
+
return audio_url
|
| 442 |
+
def get_video_url():
|
| 443 |
+
|
| 444 |
+
#yclient = InnerTube("ANDROID_TV")
|
| 445 |
+
yclient = InnerTube("ANDROID_LITE")
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
# Fetch the player data for the video
|
| 449 |
+
data = yclient.player(video_id)
|
| 450 |
+
|
| 451 |
+
# List of streams of the video
|
| 452 |
+
streams = data["streamingData"]["adaptiveFormats"]
|
| 453 |
+
for stream in streams:
|
| 454 |
+
if stream["mimeType"].find('audio'):
|
| 455 |
+
video_url=stream['url']
|
| 456 |
+
break
|
| 457 |
+
else:
|
| 458 |
+
continue
|
| 459 |
+
return video_url
|
| 460 |
+
video_url = await loop.run_in_executor(
|
| 461 |
+
None, get_video_url
|
| 462 |
+
)
|
| 463 |
+
audio_url = await loop.run_in_executor(
|
| 464 |
+
None, get_audio_url
|
| 465 |
+
)
|
| 466 |
+
|
| 467 |
+
return video_url, audio_url
|
YukkiMusic/platforms/YoutubeAPI/BS4scrapAPI.py
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from bs4 import BeautifulSoup
|
| 3 |
+
from urllib.request import urlopen
|
| 4 |
+
from urllib.parse import urlencode
|
| 5 |
+
import requests
|
| 6 |
+
import re
|
| 7 |
+
import json
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
async def extract_json_tranding(data):
|
| 12 |
+
# Join the list into a single string
|
| 13 |
+
combined_str = ''.join(data)
|
| 14 |
+
|
| 15 |
+
# Use regular expression to find the JSON data after 'ytInitialData = '
|
| 16 |
+
match = re.search(r'var ytInitialData\s*=\s*(\{.*\});', combined_str)
|
| 17 |
+
|
| 18 |
+
if match:
|
| 19 |
+
json_str = match.group(1) # Extract the JSON string
|
| 20 |
+
json_str = json_str.encode('utf-8').decode('unicode_escape')
|
| 21 |
+
try:
|
| 22 |
+
# Parse the JSON data
|
| 23 |
+
json_data = json.loads(json_str)
|
| 24 |
+
return json_data
|
| 25 |
+
except json.JSONDecodeError as e:
|
| 26 |
+
print("Error decoding JSON:", e)
|
| 27 |
+
return None
|
| 28 |
+
else:
|
| 29 |
+
print("No JSON data found.")
|
| 30 |
+
return None
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
async def search_videos(query):
|
| 35 |
+
searchresult_list=[]
|
| 36 |
+
|
| 37 |
+
final_query={'search_query':query,'sp':'EgIQAQ%253D%253D','persist_gl':'IN'}
|
| 38 |
+
param=urlencode(final_query)
|
| 39 |
+
url = urlopen(f'https://www.youtube.com/results?{param}').read()
|
| 40 |
+
soup = BeautifulSoup(url, 'lxml')
|
| 41 |
+
allscript = soup.findAll('script')
|
| 42 |
+
text = ''
|
| 43 |
+
for script in allscript:
|
| 44 |
+
if 'var ytInitialData' in str(script.contents):
|
| 45 |
+
text = str(script.contents)
|
| 46 |
+
else:
|
| 47 |
+
continue
|
| 48 |
+
|
| 49 |
+
json_data = await extract_json_tranding(text)
|
| 50 |
+
all_search_video = json_data.get('contents', {}).get(
|
| 51 |
+
'twoColumnSearchResultsRenderer',
|
| 52 |
+
{}).get('primaryContents',
|
| 53 |
+
{}).get('sectionListRenderer',
|
| 54 |
+
{}).get('contents', [])[0].get('itemSectionRenderer',
|
| 55 |
+
{}).get('contents', [])
|
| 56 |
+
|
| 57 |
+
for video in all_search_video:
|
| 58 |
+
if video.get('videoRenderer', {}):
|
| 59 |
+
if video.get('videoRenderer',{}).get('descriptionSnippet',{}):
|
| 60 |
+
description=video['videoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 61 |
+
else:
|
| 62 |
+
description=''
|
| 63 |
+
details={
|
| 64 |
+
"id":video['videoRenderer']['videoId'],
|
| 65 |
+
"title":video['videoRenderer']['title']['runs'][0]['text'],
|
| 66 |
+
"thumbnails":video['videoRenderer']['thumbnail']['thumbnails'],
|
| 67 |
+
"description":description,
|
| 68 |
+
"publishedTime":video['videoRenderer']['publishedTimeText']['simpleText'] if video.get('videoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 69 |
+
"length":video['videoRenderer']['lengthText']['simpleText'] if video.get('videoRenderer',{}).get('lengthText',{}) else '',
|
| 70 |
+
"views":video['videoRenderer']['viewCountText']['simpleText'] if video.get('videoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 71 |
+
"url":f"https://www.youtube.com{video['videoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 72 |
+
"short_views":video['videoRenderer']['shortViewCountText']['simpleText'] if video.get('videoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 73 |
+
"channelThumbnail":video['videoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('videoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 74 |
+
"channel":video['videoRenderer']['ownerText']['runs'][0]['text']
|
| 75 |
+
|
| 76 |
+
}
|
| 77 |
+
searchresult_list.append(details)
|
| 78 |
+
elif video.get('childVideoRenderer', {}):
|
| 79 |
+
if video.get('childVideoRenderer',{}).get('descriptionSnippet',{}):
|
| 80 |
+
description=video['childVideoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 81 |
+
else:
|
| 82 |
+
description=''
|
| 83 |
+
details={
|
| 84 |
+
"id":video['childVideoRenderer']['videoId'],
|
| 85 |
+
"title":video['childVideoRenderer']['title']['runs'][0]['text'],
|
| 86 |
+
"thumbnails":video['childVideoRenderer']['thumbnail']['thumbnails'],
|
| 87 |
+
"description":description,
|
| 88 |
+
"publishedTime":video['childVideoRenderer']['publishedTimeText']['simpleText'] if video.get('childVideoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 89 |
+
"length":video['childVideoRenderer']['lengthText']['simpleText'] if video.get('childVideoRenderer',{}).get('lengthText',{}) else '',
|
| 90 |
+
"views":video['childVideoRenderer']['viewCountText']['simpleText'] if video.get('childVideoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 91 |
+
"url":f"https://www.youtube.com{video['childVideoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 92 |
+
"short_views":video['childVideoRenderer']['shortViewCountText']['simpleText'] if video.get('childVideoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 93 |
+
"channelThumbnail":video['childVideoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('childVideoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 94 |
+
"channel":video['childVideoRenderer']['ownerText']['runs'][0]['text']
|
| 95 |
+
|
| 96 |
+
}
|
| 97 |
+
searchresult_list.append(details)
|
| 98 |
+
elif video.get('gridVideoRenderer', {}):
|
| 99 |
+
if video.get('gridVideoRenderer',{}).get('descriptionSnippet',{}):
|
| 100 |
+
description=video['gridVideoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 101 |
+
else:
|
| 102 |
+
description=''
|
| 103 |
+
details={
|
| 104 |
+
"id":video['gridVideoRenderer']['videoId'],
|
| 105 |
+
"title":video['gridVideoRenderer']['title']['runs'][0]['text'],
|
| 106 |
+
"thumbnails":video['gridVideoRenderer']['thumbnail']['thumbnails'],
|
| 107 |
+
"description":description,
|
| 108 |
+
"publishedTime":video['gridVideoRenderer']['publishedTimeText']['simpleText'] if video.get('gridVideoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 109 |
+
"length":video['gridVideoRenderer']['lengthText']['simpleText'] if video.get('gridVideoRenderer',{}).get('lengthText',{}) else '',
|
| 110 |
+
"views":video['gridVideoRenderer']['viewCountText']['simpleText'] if video.get('gridVideoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 111 |
+
"url":f"https://www.youtube.com{video['gridVideoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 112 |
+
"short_views":video['gridVideoRenderer']['shortViewCountText']['simpleText'] if video.get('gridVideoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 113 |
+
"channelThumbnail":video['gridVideoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('gridVideoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 114 |
+
"channel":video['gridVideoRenderer']['ownerText']['runs'][0]['text']
|
| 115 |
+
|
| 116 |
+
}
|
| 117 |
+
searchresult_list.append(details)
|
| 118 |
+
#print(url,searchresult_list)
|
| 119 |
+
return searchresult_list
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
async def tranding_videos():
|
| 124 |
+
tranding_list=[]
|
| 125 |
+
url = urlopen('https://www.youtube.com/feed/trending/?persist_gl=1&gl=IN').read()
|
| 126 |
+
soup = BeautifulSoup(url, 'lxml')
|
| 127 |
+
allscript = soup.findAll('script')
|
| 128 |
+
text = ''
|
| 129 |
+
for script in allscript:
|
| 130 |
+
if 'var ytInitialData' in str(script.contents):
|
| 131 |
+
text = str(script.contents)
|
| 132 |
+
else:
|
| 133 |
+
continue
|
| 134 |
+
|
| 135 |
+
json_data = await extract_json_tranding(text)
|
| 136 |
+
|
| 137 |
+
all_video = json_data.get('contents', {}).get(
|
| 138 |
+
'twoColumnBrowseResultsRenderer',
|
| 139 |
+
{}).get('tabs', [])[0].get('tabRenderer', {}).get('content', {}).get(
|
| 140 |
+
'sectionListRenderer',
|
| 141 |
+
{}).get('contents', [])[3].get('itemSectionRenderer', {}).get(
|
| 142 |
+
'contents',
|
| 143 |
+
[])[0].get('shelfRenderer',
|
| 144 |
+
{}).get('content',
|
| 145 |
+
{}).get('expandedShelfContentsRenderer',
|
| 146 |
+
{}).get('items', [])
|
| 147 |
+
#"descriptions":video['videoRenderer']['descriptionSnippet']['runs'][0]['text'],
|
| 148 |
+
'''nextPageToken = json_data['contents']['twoColumnSearchResultsRenderer']['primaryContents']['sectionListRenderer']['contents'][1]['continuationItemRenderer']['continuationEndpoint']['continuationCommand']['token'] if json_data.get('contents', {}).get(
|
| 149 |
+
'twoColumnSearchResultsRenderer',
|
| 150 |
+
{}).get('primaryContents',
|
| 151 |
+
{}).get('sectionListRenderer',
|
| 152 |
+
{}).get('contents', [])[1].get('continuationItemRenderer',{}).get('continuationEndpoint',{}).get('continuationCommand',{}).get('token','') else None
|
| 153 |
+
'''
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
for video in all_video:
|
| 158 |
+
if video.get('videoRenderer',{}).get('descriptionSnippet',{}):
|
| 159 |
+
description=video['videoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 160 |
+
else:
|
| 161 |
+
description=''
|
| 162 |
+
details={
|
| 163 |
+
"id":video['videoRenderer']['videoId'],
|
| 164 |
+
"title":video['videoRenderer']['title']['runs'][0]['text'],
|
| 165 |
+
"thumbnails":video['videoRenderer']['thumbnail']['thumbnails'],
|
| 166 |
+
"description":description,
|
| 167 |
+
"publishedTime":video['videoRenderer']['publishedTimeText']['simpleText'] if video.get('videoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 168 |
+
"length":video['videoRenderer']['lengthText']['simpleText'] if video.get('videoRenderer',{}).get('lengthText',{}) else '',
|
| 169 |
+
"views":video['videoRenderer']['viewCountText']['simpleText'] if video.get('videoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 170 |
+
"url":f"https://www.youtube.com{video['videoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 171 |
+
"short_views":video['videoRenderer']['shortViewCountText']['simpleText'] if video.get('videoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 172 |
+
"channelThumbnail":video['videoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('videoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 173 |
+
"channel":video['videoRenderer']['ownerText']['runs'][0]['text']
|
| 174 |
+
|
| 175 |
+
}
|
| 176 |
+
tranding_list.append(details)
|
| 177 |
+
#print(tranding_list)
|
| 178 |
+
return tranding_list
|
| 179 |
+
|
YukkiMusic/platforms/YoutubeAPI/InnertubeAPI.py
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from urllib.request import urlopen
|
| 2 |
+
from urllib.parse import urlencode
|
| 3 |
+
import requests
|
| 4 |
+
import re
|
| 5 |
+
import json
|
| 6 |
+
import asyncio
|
| 7 |
+
import aiohttp
|
| 8 |
+
from .JSON_DATA import *
|
| 9 |
+
|
| 10 |
+
async def trending_with_post_api(query):
|
| 11 |
+
#res = requests.get('https://www.youtube.com/')
|
| 12 |
+
searchresult_list=[]
|
| 13 |
+
|
| 14 |
+
key_value ={
|
| 15 |
+
"now":"",
|
| 16 |
+
"music":"4gINGgt5dG1hX2NoYXJ0cw%3D%3D",
|
| 17 |
+
"gaming":"4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D",
|
| 18 |
+
"movies":"4gIKGgh0cmFpbGVycw%3D%3D",
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
final_query={
|
| 22 |
+
"browseId": "FEtrending",
|
| 23 |
+
"params": key_value.get(query),
|
| 24 |
+
"context": {
|
| 25 |
+
"client": {
|
| 26 |
+
"hl":"en",
|
| 27 |
+
"gl":"IN",
|
| 28 |
+
"clientName": "WEB",
|
| 29 |
+
"clientVersion": "2.20230728.00.00"
|
| 30 |
+
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
async with aiohttp.ClientSession() as session:
|
| 36 |
+
async with session.post(
|
| 37 |
+
'https://youtubei.googleapis.com/youtubei/v1/browse',
|
| 38 |
+
json=final_query) as response:
|
| 39 |
+
|
| 40 |
+
json_data= await response.text()
|
| 41 |
+
json_data=json.loads(json_data)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
key_value_list=list(key_value.keys())
|
| 45 |
+
print(key_value_list,key_value_list.index(query))
|
| 46 |
+
all_search_video = json_data.get('contents', {}).get('twoColumnBrowseResultsRenderer',{}).get('tabs',[])[ key_value_list.index(query) ].get('tabRenderer',{}).get('content', {}).get('sectionListRenderer',{}).get('contents', [])[0].get('itemSectionRenderer',{}).get('contents', [])[0].get('shelfRenderer',{}).get('content',{}).get('expandedShelfContentsRenderer',{}).get('items',[])
|
| 47 |
+
#.get('twoColumnSearchResultsRenderer',{}).get('tabs',[])
|
| 48 |
+
#.get('sectionListRenderer',{}).get('contents', [])[0].get('itemSectionRenderer',{}).get('contents', [])[0].get('shelfRenderer',{}).get('content',{}).get('expandedShelfContentsRenderer',{}).get('items',[])
|
| 49 |
+
#return all_search_video
|
| 50 |
+
for video in all_search_video:
|
| 51 |
+
if video.get('videoRenderer', {}):
|
| 52 |
+
searchresult_list.append(JSON_videoRenderer_Formatter(video))
|
| 53 |
+
|
| 54 |
+
if query == 'now':
|
| 55 |
+
all_video_Now = json_data.get('contents', {}).get('twoColumnBrowseResultsRenderer',{}).get('tabs',[])[ key_value_list.index(query) ].get('tabRenderer',{}).get('content', {}).get('sectionListRenderer',{}).get('contents', [])[2].get('itemSectionRenderer',{}).get('contents', [])[0].get('shelfRenderer',{}).get('content',{}).get('expandedShelfContentsRenderer',{}).get('items',[])
|
| 56 |
+
for video in all_video_Now:
|
| 57 |
+
if video.get('videoRenderer', {}):
|
| 58 |
+
searchresult_list.append(JSON_videoRenderer_Formatter(video))
|
| 59 |
+
|
| 60 |
+
return searchresult_list
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
async def search_videos_with_post_api(query):
|
| 66 |
+
searchresult_list=[]
|
| 67 |
+
final_query={
|
| 68 |
+
"query": query,
|
| 69 |
+
"key":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
| 70 |
+
"context": {
|
| 71 |
+
"client": {
|
| 72 |
+
"clientName": "WEB",
|
| 73 |
+
"clientVersion": "2.20230728.00.00"
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
async with aiohttp.ClientSession() as session:
|
| 78 |
+
async with session.post(
|
| 79 |
+
'https://youtubei.googleapis.com/youtubei/v1/search',
|
| 80 |
+
json=final_query) as response:
|
| 81 |
+
|
| 82 |
+
json_data= await response.text()
|
| 83 |
+
json_data=json.loads(json_data)
|
| 84 |
+
|
| 85 |
+
all_search_video = json_data.get('contents', {}).get(
|
| 86 |
+
'twoColumnSearchResultsRenderer',
|
| 87 |
+
{}).get('primaryContents',
|
| 88 |
+
{}).get('sectionListRenderer',
|
| 89 |
+
{}).get('contents', [])[0].get('itemSectionRenderer',
|
| 90 |
+
{}).get('contents', [])
|
| 91 |
+
|
| 92 |
+
nextPageToken = json_data['contents']['twoColumnSearchResultsRenderer']['primaryContents']['sectionListRenderer']['contents'][1]['continuationItemRenderer']['continuationEndpoint']['continuationCommand']['token'] if json_data.get('contents', {}).get(
|
| 93 |
+
'twoColumnSearchResultsRenderer',
|
| 94 |
+
{}).get('primaryContents',
|
| 95 |
+
{}).get('sectionListRenderer',
|
| 96 |
+
{}).get('contents', [])[1].get('continuationItemRenderer',{}).get('continuationEndpoint',{}).get('continuationCommand',{}).get('token','') else None
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
for video in all_search_video:
|
| 101 |
+
if video.get('videoRenderer', {}):
|
| 102 |
+
searchresult_list.append(JSON_videoRenderer_Formatter(video))
|
| 103 |
+
|
| 104 |
+
elif video.get('childVideoRenderer', {}):
|
| 105 |
+
searchresult_list.append(JSON_childVideoRenderer_Formatter(video))
|
| 106 |
+
|
| 107 |
+
elif video.get('gridVideoRenderer', {}):
|
| 108 |
+
searchresult_list.append(JSON_childVideoRenderer_Formatter(video))
|
| 109 |
+
|
| 110 |
+
#print(url,searchresult_list)
|
| 111 |
+
return searchresult_list, nextPageToken
|
| 112 |
+
|
| 113 |
+
async def search_scroll_videos_with_post_api(query):
|
| 114 |
+
searchresult_list=[]
|
| 115 |
+
|
| 116 |
+
final_query={
|
| 117 |
+
"continuation": query,
|
| 118 |
+
"key":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
| 119 |
+
"context": {
|
| 120 |
+
"client": {
|
| 121 |
+
"clientName": "WEB",
|
| 122 |
+
"clientVersion": "2.20230728.00.00"
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
async with aiohttp.ClientSession() as session:
|
| 128 |
+
async with session.post(
|
| 129 |
+
'https://youtubei.googleapis.com/youtubei/v1/search',
|
| 130 |
+
json=final_query) as response:
|
| 131 |
+
|
| 132 |
+
json_data= await response.text()
|
| 133 |
+
json_data=json.loads(json_data)
|
| 134 |
+
#return json_data
|
| 135 |
+
all_search_video = json_data.get('onResponseReceivedCommands', [])[0].get(
|
| 136 |
+
'appendContinuationItemsAction',
|
| 137 |
+
{}).get('continuationItems',
|
| 138 |
+
[])[0].get('itemSectionRenderer',
|
| 139 |
+
{}).get('contents', [])
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
nextPageToken =json_data['onResponseReceivedCommands'][0]['appendContinuationItemsAction']['continuationItems'][1]['continuationItemRenderer']['continuationEndpoint']['continuationCommand']['token'] if len(json_data.get('onResponseReceivedCommands', [])) > 0 and json_data.get('onResponseReceivedCommands', [])[0].get(
|
| 143 |
+
'appendContinuationItemsAction',
|
| 144 |
+
{}).get('continuationItems',
|
| 145 |
+
[])[1].get('continuationItemRenderer',{}).get('continuationEndpoint',{}).get('continuationCommand',{}).get('token','') else None
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
for video in all_search_video:
|
| 149 |
+
if video.get('videoRenderer', {}):
|
| 150 |
+
searchresult_list.append(JSON_videoRenderer_Formatter(video))
|
| 151 |
+
|
| 152 |
+
elif video.get('childVideoRenderer', {}):
|
| 153 |
+
searchresult_list.append(JSON_childVideoRenderer_Formatter(video))
|
| 154 |
+
|
| 155 |
+
elif video.get('gridVideoRenderer', {}):
|
| 156 |
+
searchresult_list.append(JSON_childVideoRenderer_Formatter(video))
|
| 157 |
+
|
| 158 |
+
#print(url,searchresult_list)
|
| 159 |
+
return searchresult_list, nextPageToken
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
#####-------------RETURN VIDEO LIST WITH STREAMING URL BY VIDEO ID------######
|
| 164 |
+
async def search_player_data_with_post_api(query):
|
| 165 |
+
searchresult_list=[]
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
final_query={
|
| 169 |
+
"videoId": query,
|
| 170 |
+
"key":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
| 171 |
+
"context": {
|
| 172 |
+
"client": {
|
| 173 |
+
"clientName": "ANDROID_TV",
|
| 174 |
+
"clientVersion": "2.16.032"
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
async with aiohttp.ClientSession() as session:
|
| 179 |
+
async with session.post(
|
| 180 |
+
'https://youtubei.googleapis.com/youtubei/v1/player',
|
| 181 |
+
json=final_query) as response:
|
| 182 |
+
|
| 183 |
+
json_data= await response.text()
|
| 184 |
+
json_data=json.loads(json_data)
|
| 185 |
+
#return json_data
|
| 186 |
+
all_formats_video = json_data.get('streamingData', {}).get(
|
| 187 |
+
'formats',
|
| 188 |
+
[])
|
| 189 |
+
all_adaptive_formats_video = json_data.get('streamingData', {}).get(
|
| 190 |
+
'adaptiveFormats',
|
| 191 |
+
[])
|
| 192 |
+
''' video details content JSON DATA {} with key:value
|
| 193 |
+
demo data
|
| 194 |
+
{
|
| 195 |
+
"videoId": "k3g_WjLCsXM",
|
| 196 |
+
"title": "Sajni (Song): Arijit Singh, Ram Sampath | Laapataa Ladies | Aamir Khan Productions",
|
| 197 |
+
"lengthSeconds": "146",
|
| 198 |
+
"keywords": [
|
| 199 |
+
"sajni laapata ladies",
|
| 200 |
+
"sajni laapataa ladies",
|
| 201 |
+
"sajni"
|
| 202 |
+
],
|
| 203 |
+
"channelId": "UCq-Fj5jknLsUf-MWSy4_brA",
|
| 204 |
+
"isOwnerViewing": false,
|
| 205 |
+
"shortDescription": "Presenting the Song \"Sajni\" from the upcoming film Laapataa Ladies. Sung by Arijit Singh, Composed by Ram Sampath and Penned by Prashant Pandey.\n\n#LaapataaLadies #Sajni #ArijitSingh #RamSampath\n\nJio Studios Presents \nAamir Khan Productions \"LAAPATAA LADIES\" \n\n♪Full Song Available on♪ \nJioSaavn: https://bit.ly/3SV0n0w\nSpotify: https://bit.ly/3wgICzV\nHungama: https://bit.ly/499FkNy\nApple Music: https://bit.ly/3SEqRlL\nAmazon Prime Music: https://bit.ly/3Uxi1Zv\nWynk: https://bit.ly/3uwyX7O\nYouTube Music: https://bit.ly/4bzkV5R\n\nSong Credits:\nSong Name: Sajni\nComposed By : Ram Sampath\nLyricist : Prashant Pandey\nSinger : Arijit Singh\nMusic Arranged & Produced by : Ram Sampath\nMusic Supervisor : Vrashal Chavan\nRecorded & Mixed at Omgrown Music, Mumbai by Amey Wadibhasme\nMastered by Gethin John at Hafod Mastering\nVocal Recordist : Sukanto Singha\nVocal Editor : Prithviraj Sarkar\nMusic Label: T-Series\n\nFilm Credits: \nDirected by Kiran Rao \nProduced by Aamir Khan, Kiran Rao & Jyoti Deshpande\nStarring : Nitanshi Goel, Pratibha Ranta, Sparsh Shrivastava, Ravi Kishan and Chhaya Kadam\nCo Stars : Bhaskar Jha, Durgesh Kumar, Geeta Aggarwal, Pankaj Sharma, Rachna Gupta, Abeer Jain, Kirti Jain, Daood Hussain, Pranjal Pateriya, Samarth Mohar, Satendra Soni, Ravi Kapadiya, Kishore Soni. \nOriginal Story : Biplab Goswami \nScreenplay & Dialogues : Sneha Desai \nAdditional Dialogues : Divyanidhi Sharma \nMusic : Ram Sampath \nLyricists : Swanand Kirkire, Prashant Pandey, Divyanidhi Sharma \nSingers: Shreya Ghoshal, Arijit Singh, Sukhwinder Singh, Sona Mohapatra\nDirector of Photography : Vikash Nowlakha\nEditor : Jabeen Merchant \nProduction Designer : Vikram Singh \nCostume Designer : Darshan Jalan \nCasting : Romil Jain \nSound Designer : Ayush Ahuja \nProduction Sound Mixer : Ravi Dev Singh \nMake Up Designer : Kamlesh Shinde \nHair Designer : Joyce Fernandez \n1st Assistant Director : Rakesh E. Nair \nLine Producer : Jaspal Dogra \nScript Supervisor : Mandira Roy \nDialect Coach : Sonu Anand \nDirector's Assistant : Pooja Kumar \nColorist : Michele Ricossa \nVisual Effects Studio : SM Rolling \nVFX DI Studio : Prasad Labs \nVisual Promotions : Just Right Studioz NX \nAKP Finance Team : Sharada Harihar, Aditya Shah, Huzvak Batliwala, Pankti Mehta, Tejasvi Gurav, Manisha Abhyankar\nFinancial Advisor : Bimal Parekh & Co \nExecutive Producers : Antara Banerjee & Naved Farooqui \nCo-Producers : B. Shrinivas Rao & Tanaji Dasgupta \n\nDownload Song Beat: https://bit.ly/3Cjh24R \n\n___________________________________\nEnjoy & stay connected with us!\n👉 Subscribe to T-Series: https://youtube.com/tseries\n👉 Like us on Facebook: https://www.facebook.com/tseriesmusic\n👉 Follow us on X: https://twitter.com/tseries\n👉 Follow us on Instagram: https://instagram.com/tseries.official",
|
| 206 |
+
"isCrawlable": true,
|
| 207 |
+
"thumbnail": {
|
| 208 |
+
"thumbnails": [
|
| 209 |
+
{
|
| 210 |
+
"url": "https://i.ytimg.com/vi/k3g_WjLCsXM/default.jpg",
|
| 211 |
+
"width": 120,
|
| 212 |
+
"height": 90
|
| 213 |
+
},
|
| 214 |
+
{
|
| 215 |
+
"url": "https://i.ytimg.com/vi/k3g_WjLCsXM/mqdefault.jpg",
|
| 216 |
+
"width": 320,
|
| 217 |
+
"height": 180
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"url": "https://i.ytimg.com/vi/k3g_WjLCsXM/hqdefault.jpg",
|
| 221 |
+
"width": 480,
|
| 222 |
+
"height": 360
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"url": "https://i.ytimg.com/vi/k3g_WjLCsXM/sddefault.jpg",
|
| 226 |
+
"width": 640,
|
| 227 |
+
"height": 480
|
| 228 |
+
}
|
| 229 |
+
]
|
| 230 |
+
},
|
| 231 |
+
"allowRatings": true,
|
| 232 |
+
"viewCount": "70761818",
|
| 233 |
+
"author": "T-Series",
|
| 234 |
+
"isPrivate": false,
|
| 235 |
+
"isUnpluggedCorpus": false,
|
| 236 |
+
"isLiveContent": false
|
| 237 |
+
}'''
|
| 238 |
+
|
| 239 |
+
videodetails = json_data.get('videoDetails', {})
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
for video in all_formats_video:
|
| 243 |
+
|
| 244 |
+
searchresult_list.append(video)
|
| 245 |
+
for video in all_adaptive_formats_video:
|
| 246 |
+
|
| 247 |
+
searchresult_list.append(video)
|
| 248 |
+
|
| 249 |
+
#print(url,searchresult_list)
|
| 250 |
+
return searchresult_list, videodetails
|
YukkiMusic/platforms/YoutubeAPI/JSON_DATA.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def JSON_gridVideoRenderer_Formatter(video):
|
| 2 |
+
if video.get('gridVideoRenderer',{}).get('descriptionSnippet',{}):
|
| 3 |
+
description=video['gridVideoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 4 |
+
else:
|
| 5 |
+
description=''
|
| 6 |
+
|
| 7 |
+
return{
|
| 8 |
+
"id":video['gridVideoRenderer']['videoId'],
|
| 9 |
+
"title":video['gridVideoRenderer']['title']['runs'][0]['text'],
|
| 10 |
+
"thumbnails":video['gridVideoRenderer']['thumbnail']['thumbnails'],
|
| 11 |
+
"description":description,
|
| 12 |
+
"publishedTime":video['gridVideoRenderer']['publishedTimeText']['simpleText'] if video.get('gridVideoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 13 |
+
"length":video['gridVideoRenderer']['lengthText']['simpleText'] if video.get('gridVideoRenderer',{}).get('lengthText',{}) else '',
|
| 14 |
+
"views":video['gridVideoRenderer']['viewCountText']['simpleText'] if video.get('gridVideoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 15 |
+
"url":f"https://www.youtube.com{video['gridVideoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 16 |
+
"short_views":video['gridVideoRenderer']['shortViewCountText']['simpleText'] if video.get('gridVideoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 17 |
+
"channelThumbnail":video['gridVideoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('gridVideoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 18 |
+
"channel":video['gridVideoRenderer']['ownerText']['runs'][0]['text']
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
def JSON_childVideoRenderer_Formatter(video):
|
| 22 |
+
if video.get('childVideoRenderer',{}).get('descriptionSnippet',{}):
|
| 23 |
+
description=video['childVideoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 24 |
+
else:
|
| 25 |
+
description=''
|
| 26 |
+
|
| 27 |
+
return {
|
| 28 |
+
"id":video['childVideoRenderer']['videoId'],
|
| 29 |
+
"title":video['childVideoRenderer']['title']['runs'][0]['text'],
|
| 30 |
+
"thumbnails":video['childVideoRenderer']['thumbnail']['thumbnails'],
|
| 31 |
+
"description":description,
|
| 32 |
+
"publishedTime":video['childVideoRenderer']['publishedTimeText']['simpleText'] if video.get('childVideoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 33 |
+
"length":video['childVideoRenderer']['lengthText']['simpleText'] if video.get('childVideoRenderer',{}).get('lengthText',{}) else '',
|
| 34 |
+
"views":video['childVideoRenderer']['viewCountText']['simpleText'] if video.get('childVideoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 35 |
+
"url":f"https://www.youtube.com{video['childVideoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 36 |
+
"short_views":video['childVideoRenderer']['shortViewCountText']['simpleText'] if video.get('childVideoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 37 |
+
"channelThumbnail":video['childVideoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('childVideoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 38 |
+
"channel":video['childVideoRenderer']['ownerText']['runs'][0]['text']
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
def JSON_videoRenderer_Formatter(video):
|
| 42 |
+
if video.get('videoRenderer',{}).get('descriptionSnippet',{}):
|
| 43 |
+
description=video['videoRenderer']['descriptionSnippet']['runs'][0]['text']
|
| 44 |
+
else:
|
| 45 |
+
description=''
|
| 46 |
+
return{
|
| 47 |
+
"id":video['videoRenderer']['videoId'],
|
| 48 |
+
"title":video['videoRenderer']['title']['runs'][0]['text'],
|
| 49 |
+
"thumbnails":video['videoRenderer']['thumbnail']['thumbnails'],
|
| 50 |
+
"description":description,
|
| 51 |
+
"publishedTime":video['videoRenderer']['publishedTimeText']['simpleText'] if video.get('videoRenderer',{}).get('publishedTimeText',{}) else '' ,
|
| 52 |
+
"length":video['videoRenderer']['lengthText']['simpleText'] if video.get('videoRenderer',{}).get('lengthText',{}) else '',
|
| 53 |
+
"views":video['videoRenderer']['viewCountText']['simpleText'] if video.get('videoRenderer',{}).get('viewCountText',{}).get('simpleText','') else '',
|
| 54 |
+
"url":f"https://www.youtube.com{video['videoRenderer']['navigationEndpoint']['commandMetadata']['webCommandMetadata']['url']}",
|
| 55 |
+
"short_views":video['videoRenderer']['shortViewCountText']['simpleText'] if video.get('videoRenderer',{}).get('shortViewCountText',{}).get('simpleText','') else '',
|
| 56 |
+
"channelThumbnail":video['videoRenderer']['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']['thumbnail']['thumbnails'][0]['url'] if video.get('videoRenderer',{}).get('channelThumbnailSupportedRenderers',{}) else '',
|
| 57 |
+
"channel":video['videoRenderer']['ownerText']['runs'][0]['text']
|
| 58 |
+
}
|
YukkiMusic/platforms/YoutubeAPI/__init__.py
ADDED
|
File without changes
|
YukkiMusic/platforms/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from .Apple import AppleAPI
|
| 11 |
+
from .Carbon import CarbonAPI
|
| 12 |
+
from .Resso import RessoAPI
|
| 13 |
+
from .Soundcloud import SoundAPI
|
| 14 |
+
from .Spotify import SpotifyAPI
|
| 15 |
+
from .Telegram import TeleAPI
|
| 16 |
+
from .Youtube import YouTubeAPI
|
YukkiMusic/platforms/custom_dl.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
import logging
|
| 3 |
+
from typing import Dict, Union
|
| 4 |
+
from YukkiMusic.core.userbot import work_loads
|
| 5 |
+
from pyrogram import Client, utils, raw
|
| 6 |
+
#from .file_properties import get_file_ids
|
| 7 |
+
from pyrogram.session import Session, Auth
|
| 8 |
+
from pyrogram.errors import AuthBytesInvalid
|
| 9 |
+
from pyrogram.file_id import FileId, FileType, ThumbnailSource
|
| 10 |
+
from pyrogram.types import Message
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class ByteStreamer:
|
| 14 |
+
|
| 15 |
+
def __init__(self, client: Client):
|
| 16 |
+
self.clean_timer = 30 * 60
|
| 17 |
+
self.client: Client = client
|
| 18 |
+
self.cached_file_ids: Dict[str, FileId] = {}
|
| 19 |
+
asyncio.create_task(self.clean_cache())
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
async def generate_media_session(self, client: Client,
|
| 24 |
+
file_id: FileId) -> Session:
|
| 25 |
+
"""
|
| 26 |
+
Generates the media session for the DC that contains the media file.
|
| 27 |
+
This is required for getting the bytes from Telegram servers.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
media_session = client.media_sessions.get(file_id.dc_id, None)
|
| 31 |
+
|
| 32 |
+
if media_session is None:
|
| 33 |
+
if file_id.dc_id != await client.storage.dc_id():
|
| 34 |
+
media_session = Session(
|
| 35 |
+
client,
|
| 36 |
+
file_id.dc_id,
|
| 37 |
+
await Auth(client, file_id.dc_id, await
|
| 38 |
+
client.storage.test_mode()).create(),
|
| 39 |
+
await client.storage.test_mode(),
|
| 40 |
+
is_media=True,
|
| 41 |
+
)
|
| 42 |
+
await media_session.start()
|
| 43 |
+
|
| 44 |
+
for _ in range(6):
|
| 45 |
+
exported_auth = await client.invoke(
|
| 46 |
+
raw.functions.auth.ExportAuthorization(dc_id=file_id.dc_id))
|
| 47 |
+
|
| 48 |
+
try:
|
| 49 |
+
await media_session.invoke(
|
| 50 |
+
raw.functions.auth.ImportAuthorization(
|
| 51 |
+
id=exported_auth.id, bytes=exported_auth.bytes))
|
| 52 |
+
break
|
| 53 |
+
except AuthBytesInvalid:
|
| 54 |
+
logging.debug(
|
| 55 |
+
f"Invalid authorization bytes for DC {file_id.dc_id}")
|
| 56 |
+
continue
|
| 57 |
+
else:
|
| 58 |
+
await media_session.stop()
|
| 59 |
+
raise AuthBytesInvalid
|
| 60 |
+
else:
|
| 61 |
+
media_session = Session(
|
| 62 |
+
client,
|
| 63 |
+
file_id.dc_id,
|
| 64 |
+
await client.storage.auth_key(),
|
| 65 |
+
await client.storage.test_mode(),
|
| 66 |
+
is_media=True,
|
| 67 |
+
)
|
| 68 |
+
await media_session.start()
|
| 69 |
+
logging.debug(f"Created media session for DC {file_id.dc_id}")
|
| 70 |
+
client.media_sessions[file_id.dc_id] = media_session
|
| 71 |
+
else:
|
| 72 |
+
logging.debug(f"Using cached media session for DC {file_id.dc_id}")
|
| 73 |
+
return media_session
|
| 74 |
+
|
| 75 |
+
@staticmethod
|
| 76 |
+
async def get_location(
|
| 77 |
+
file_id: FileId
|
| 78 |
+
) -> Union[
|
| 79 |
+
raw.types.InputPhotoFileLocation,
|
| 80 |
+
raw.types.InputDocumentFileLocation,
|
| 81 |
+
raw.types.InputPeerPhotoFileLocation,
|
| 82 |
+
]:
|
| 83 |
+
"""
|
| 84 |
+
Returns the file location for the media file.
|
| 85 |
+
"""
|
| 86 |
+
file_type = file_id.file_type
|
| 87 |
+
|
| 88 |
+
if file_type == FileType.CHAT_PHOTO:
|
| 89 |
+
if file_id.chat_id > 0:
|
| 90 |
+
peer = raw.types.InputPeerUser(user_id=file_id.chat_id,
|
| 91 |
+
access_hash=file_id.chat_access_hash)
|
| 92 |
+
else:
|
| 93 |
+
if file_id.chat_access_hash == 0:
|
| 94 |
+
peer = raw.types.InputPeerChat(chat_id=-file_id.chat_id)
|
| 95 |
+
else:
|
| 96 |
+
peer = raw.types.InputPeerChannel(
|
| 97 |
+
channel_id=utils.get_channel_id(file_id.chat_id),
|
| 98 |
+
access_hash=file_id.chat_access_hash,
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
location = raw.types.InputPeerPhotoFileLocation(
|
| 102 |
+
peer=peer,
|
| 103 |
+
volume_id=file_id.volume_id,
|
| 104 |
+
local_id=file_id.local_id,
|
| 105 |
+
big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG,
|
| 106 |
+
)
|
| 107 |
+
elif file_type == FileType.PHOTO:
|
| 108 |
+
location = raw.types.InputPhotoFileLocation(
|
| 109 |
+
id=file_id.media_id,
|
| 110 |
+
access_hash=file_id.access_hash,
|
| 111 |
+
file_reference=file_id.file_reference,
|
| 112 |
+
thumb_size=file_id.thumbnail_size,
|
| 113 |
+
)
|
| 114 |
+
else:
|
| 115 |
+
location = raw.types.InputDocumentFileLocation(
|
| 116 |
+
id=file_id.media_id,
|
| 117 |
+
access_hash=file_id.access_hash,
|
| 118 |
+
file_reference=file_id.file_reference,
|
| 119 |
+
thumb_size=file_id.thumbnail_size,
|
| 120 |
+
)
|
| 121 |
+
return location
|
| 122 |
+
|
| 123 |
+
async def yield_file(
|
| 124 |
+
self,
|
| 125 |
+
file_id: FileId,
|
| 126 |
+
index: int,
|
| 127 |
+
offset: int,
|
| 128 |
+
first_part_cut: int,
|
| 129 |
+
last_part_cut: int,
|
| 130 |
+
part_count: int,
|
| 131 |
+
chunk_size: int,
|
| 132 |
+
) -> Union[str, None]:
|
| 133 |
+
|
| 134 |
+
client = self.client
|
| 135 |
+
#work_loads[index] += 1
|
| 136 |
+
logging.debug(f"Starting to yielding file with client {index}.")
|
| 137 |
+
media_session = await self.generate_media_session(client, file_id)
|
| 138 |
+
|
| 139 |
+
current_part = 1
|
| 140 |
+
|
| 141 |
+
location = await self.get_location(file_id)
|
| 142 |
+
|
| 143 |
+
try:
|
| 144 |
+
r = await media_session.invoke(
|
| 145 |
+
raw.functions.upload.GetFile(location=location,
|
| 146 |
+
offset=offset,
|
| 147 |
+
limit=chunk_size), )
|
| 148 |
+
if isinstance(r, raw.types.upload.File):
|
| 149 |
+
while True:
|
| 150 |
+
chunk = r.bytes
|
| 151 |
+
if not chunk:
|
| 152 |
+
break
|
| 153 |
+
elif part_count == 1:
|
| 154 |
+
yield chunk[first_part_cut:last_part_cut]
|
| 155 |
+
elif current_part == 1:
|
| 156 |
+
yield chunk[first_part_cut:]
|
| 157 |
+
elif current_part == part_count:
|
| 158 |
+
yield chunk[:last_part_cut]
|
| 159 |
+
else:
|
| 160 |
+
yield chunk
|
| 161 |
+
|
| 162 |
+
current_part += 1
|
| 163 |
+
offset += chunk_size
|
| 164 |
+
|
| 165 |
+
if current_part > part_count:
|
| 166 |
+
break
|
| 167 |
+
|
| 168 |
+
r = await media_session.invoke(
|
| 169 |
+
raw.functions.upload.GetFile(location=location,
|
| 170 |
+
offset=offset,
|
| 171 |
+
limit=chunk_size), )
|
| 172 |
+
except (TimeoutError, AttributeError):
|
| 173 |
+
pass
|
| 174 |
+
finally:
|
| 175 |
+
logging.debug(f"Finished yielding file with {current_part} parts.")
|
| 176 |
+
#work_loads[index] -= 1
|
| 177 |
+
|
| 178 |
+
async def clean_cache(self) -> None:
|
| 179 |
+
"""
|
| 180 |
+
function to clean the cache to reduce memory usage
|
| 181 |
+
"""
|
| 182 |
+
while True:
|
| 183 |
+
await asyncio.sleep(self.clean_timer)
|
| 184 |
+
self.cached_file_ids.clear()
|
| 185 |
+
logging.debug("Cleaned the cache")
|
YukkiMusic/platforms/file_properties.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
import logging
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
from pyrogram import Client
|
| 5 |
+
from typing import Any, Optional
|
| 6 |
+
|
| 7 |
+
from pyrogram.enums import ParseMode, ChatType
|
| 8 |
+
from pyrogram.types import Message
|
| 9 |
+
from pyrogram.file_id import FileId
|
| 10 |
+
#-----------------------------------------------------
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
#------------------------------
|
| 16 |
+
def get_media_from_message(message: "Message") -> Any:
|
| 17 |
+
media_types = (
|
| 18 |
+
"audio",
|
| 19 |
+
"document",
|
| 20 |
+
"photo",
|
| 21 |
+
"sticker",
|
| 22 |
+
"animation",
|
| 23 |
+
"video",
|
| 24 |
+
"voice",
|
| 25 |
+
"video_note",
|
| 26 |
+
)
|
| 27 |
+
for attr in media_types:
|
| 28 |
+
media = getattr(message, attr, None)
|
| 29 |
+
if media:
|
| 30 |
+
return media
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def get_media_file_size(m):
|
| 34 |
+
media = get_media_from_message(m)
|
| 35 |
+
return getattr(media, "file_size", "None")
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def get_name(media_msg: Message | FileId) -> str:
|
| 39 |
+
if isinstance(media_msg, Message):
|
| 40 |
+
media = get_media_from_message(media_msg)
|
| 41 |
+
file_name = getattr(media, "file_name", "")
|
| 42 |
+
|
| 43 |
+
elif isinstance(media_msg, FileId):
|
| 44 |
+
file_name = getattr(media_msg, "file_name", "")
|
| 45 |
+
|
| 46 |
+
if not file_name:
|
| 47 |
+
if isinstance(media_msg, Message) and media_msg.media:
|
| 48 |
+
media_type = media_msg.media.value
|
| 49 |
+
elif media_msg.file_type:
|
| 50 |
+
media_type = media_msg.file_type.name.lower()
|
| 51 |
+
else:
|
| 52 |
+
media_type = "file"
|
| 53 |
+
|
| 54 |
+
formats = {
|
| 55 |
+
"photo": "jpg",
|
| 56 |
+
"audio": "mp3",
|
| 57 |
+
"voice": "ogg",
|
| 58 |
+
"video": "mp4",
|
| 59 |
+
"animation": "mp4",
|
| 60 |
+
"video_note": "mp4",
|
| 61 |
+
"sticker": "webp"
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
ext = formats.get(media_type)
|
| 65 |
+
ext = "." + ext if ext else ""
|
| 66 |
+
|
| 67 |
+
date = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
| 68 |
+
file_name = f"{media_type}-{date}{ext}"
|
| 69 |
+
|
| 70 |
+
return file_name
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def get_file_info(message):
|
| 74 |
+
media = get_media_from_message(message)
|
| 75 |
+
"""
|
| 76 |
+
//Used a single Liner Insted of this Block
|
| 77 |
+
if message.chat.type == ChatType.PRIVATE:
|
| 78 |
+
user_idx = message.from_user.id
|
| 79 |
+
else:
|
| 80 |
+
user_idx = message.chat.id
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
return {
|
| 84 |
+
|
| 85 |
+
"message_id": message.id,
|
| 86 |
+
"location": message.from_user.id if (message.chat.type == ChatType.PRIVATE) else message.chat.id,
|
| 87 |
+
"file": {
|
| 88 |
+
"file_id": getattr(media, "file_id", ""),
|
| 89 |
+
"file_unique_id": getattr(media, "file_unique_id", ""),
|
| 90 |
+
"file_name": get_name(message),
|
| 91 |
+
"file_size": getattr(media, "file_size", 0),
|
| 92 |
+
"mime_type": getattr(media, "mime_type", "None/unknown"),
|
| 93 |
+
|
| 94 |
+
},
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
|
YukkiMusic/plugins/__init__.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
#
|
| 10 |
+
|
| 11 |
+
import glob
|
| 12 |
+
from os.path import dirname, isfile
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def __list_all_modules():
|
| 16 |
+
work_dir = dirname(__file__)
|
| 17 |
+
mod_paths = glob.glob(work_dir + "/*/*.py")
|
| 18 |
+
|
| 19 |
+
all_modules = [
|
| 20 |
+
(((f.replace(work_dir, "")).replace("/", "."))[:-3])
|
| 21 |
+
for f in mod_paths
|
| 22 |
+
if isfile(f)
|
| 23 |
+
and f.endswith(".py")
|
| 24 |
+
and not f.endswith("__init__.py")
|
| 25 |
+
]
|
| 26 |
+
|
| 27 |
+
return all_modules
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
ALL_MODULES = sorted(__list_all_modules())
|
| 31 |
+
__all__ = ALL_MODULES + ["ALL_MODULES"]
|
YukkiMusic/plugins/admins/auth.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS, adminlist
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.utils.database import (delete_authuser, get_authuser,
|
| 17 |
+
get_authuser_names,
|
| 18 |
+
save_authuser)
|
| 19 |
+
from YukkiMusic.utils.decorators import AdminActual, language
|
| 20 |
+
from YukkiMusic.utils.formatters import int_to_alpha
|
| 21 |
+
|
| 22 |
+
# Command
|
| 23 |
+
AUTH_COMMAND = get_command("AUTH_COMMAND")
|
| 24 |
+
UNAUTH_COMMAND = get_command("UNAUTH_COMMAND")
|
| 25 |
+
AUTHUSERS_COMMAND = get_command("AUTHUSERS_COMMAND")
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@app.on_message(
|
| 29 |
+
filters.command(AUTH_COMMAND)
|
| 30 |
+
& filters.group
|
| 31 |
+
& ~BANNED_USERS
|
| 32 |
+
)
|
| 33 |
+
@AdminActual
|
| 34 |
+
async def auth(client, message: Message, _):
|
| 35 |
+
if not message.reply_to_message:
|
| 36 |
+
if len(message.command) != 2:
|
| 37 |
+
return await message.reply_text(_["general_1"])
|
| 38 |
+
user = message.text.split(None, 1)[1]
|
| 39 |
+
if "@" in user:
|
| 40 |
+
user = user.replace("@", "")
|
| 41 |
+
user = await app.get_users(user)
|
| 42 |
+
user_id = message.from_user.id
|
| 43 |
+
token = await int_to_alpha(user.id)
|
| 44 |
+
from_user_name = message.from_user.first_name
|
| 45 |
+
from_user_id = message.from_user.id
|
| 46 |
+
_check = await get_authuser_names(message.chat.id)
|
| 47 |
+
count = len(_check)
|
| 48 |
+
if int(count) == 20:
|
| 49 |
+
return await message.reply_text(_["auth_1"])
|
| 50 |
+
if token not in _check:
|
| 51 |
+
assis = {
|
| 52 |
+
"auth_user_id": user.id,
|
| 53 |
+
"auth_name": user.first_name,
|
| 54 |
+
"admin_id": from_user_id,
|
| 55 |
+
"admin_name": from_user_name,
|
| 56 |
+
}
|
| 57 |
+
get = adminlist.get(message.chat.id)
|
| 58 |
+
if get:
|
| 59 |
+
if user.id not in get:
|
| 60 |
+
get.append(user.id)
|
| 61 |
+
await save_authuser(message.chat.id, token, assis)
|
| 62 |
+
return await message.reply_text(_["auth_2"])
|
| 63 |
+
else:
|
| 64 |
+
await message.reply_text(_["auth_3"])
|
| 65 |
+
return
|
| 66 |
+
from_user_id = message.from_user.id
|
| 67 |
+
user_id = message.reply_to_message.from_user.id
|
| 68 |
+
user_name = message.reply_to_message.from_user.first_name
|
| 69 |
+
token = await int_to_alpha(user_id)
|
| 70 |
+
from_user_name = message.from_user.first_name
|
| 71 |
+
_check = await get_authuser_names(message.chat.id)
|
| 72 |
+
count = 0
|
| 73 |
+
for smex in _check:
|
| 74 |
+
count += 1
|
| 75 |
+
if int(count) == 20:
|
| 76 |
+
return await message.reply_text(_["auth_1"])
|
| 77 |
+
if token not in _check:
|
| 78 |
+
assis = {
|
| 79 |
+
"auth_user_id": user_id,
|
| 80 |
+
"auth_name": user_name,
|
| 81 |
+
"admin_id": from_user_id,
|
| 82 |
+
"admin_name": from_user_name,
|
| 83 |
+
}
|
| 84 |
+
get = adminlist.get(message.chat.id)
|
| 85 |
+
if get:
|
| 86 |
+
if user_id not in get:
|
| 87 |
+
get.append(user_id)
|
| 88 |
+
await save_authuser(message.chat.id, token, assis)
|
| 89 |
+
return await message.reply_text(_["auth_2"])
|
| 90 |
+
else:
|
| 91 |
+
await message.reply_text(_["auth_3"])
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
@app.on_message(
|
| 95 |
+
filters.command(UNAUTH_COMMAND)
|
| 96 |
+
& filters.group
|
| 97 |
+
& ~BANNED_USERS
|
| 98 |
+
)
|
| 99 |
+
@AdminActual
|
| 100 |
+
async def unauthusers(client, message: Message, _):
|
| 101 |
+
if not message.reply_to_message:
|
| 102 |
+
if len(message.command) != 2:
|
| 103 |
+
return await message.reply_text(_["general_1"])
|
| 104 |
+
user = message.text.split(None, 1)[1]
|
| 105 |
+
if "@" in user:
|
| 106 |
+
user = user.replace("@", "")
|
| 107 |
+
user = await app.get_users(user)
|
| 108 |
+
token = await int_to_alpha(user.id)
|
| 109 |
+
deleted = await delete_authuser(message.chat.id, token)
|
| 110 |
+
get = adminlist.get(message.chat.id)
|
| 111 |
+
if get:
|
| 112 |
+
if user.id in get:
|
| 113 |
+
get.remove(user.id)
|
| 114 |
+
if deleted:
|
| 115 |
+
return await message.reply_text(_["auth_4"])
|
| 116 |
+
else:
|
| 117 |
+
return await message.reply_text(_["auth_5"])
|
| 118 |
+
user_id = message.reply_to_message.from_user.id
|
| 119 |
+
token = await int_to_alpha(user_id)
|
| 120 |
+
deleted = await delete_authuser(message.chat.id, token)
|
| 121 |
+
get = adminlist.get(message.chat.id)
|
| 122 |
+
if get:
|
| 123 |
+
if user_id in get:
|
| 124 |
+
get.remove(user_id)
|
| 125 |
+
if deleted:
|
| 126 |
+
return await message.reply_text(_["auth_4"])
|
| 127 |
+
else:
|
| 128 |
+
return await message.reply_text(_["auth_5"])
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
@app.on_message(
|
| 132 |
+
filters.command(AUTHUSERS_COMMAND)
|
| 133 |
+
& filters.group
|
| 134 |
+
& ~BANNED_USERS
|
| 135 |
+
)
|
| 136 |
+
@language
|
| 137 |
+
async def authusers(client, message: Message, _):
|
| 138 |
+
_playlist = await get_authuser_names(message.chat.id)
|
| 139 |
+
if not _playlist:
|
| 140 |
+
return await message.reply_text(_["setting_5"])
|
| 141 |
+
else:
|
| 142 |
+
j = 0
|
| 143 |
+
mystic = await message.reply_text(_["auth_6"])
|
| 144 |
+
text = _["auth_7"]
|
| 145 |
+
for note in _playlist:
|
| 146 |
+
_note = await get_authuser(message.chat.id, note)
|
| 147 |
+
user_id = _note["auth_user_id"]
|
| 148 |
+
admin_id = _note["admin_id"]
|
| 149 |
+
admin_name = _note["admin_name"]
|
| 150 |
+
try:
|
| 151 |
+
user = await app.get_users(user_id)
|
| 152 |
+
user = user.first_name
|
| 153 |
+
j += 1
|
| 154 |
+
except Exception:
|
| 155 |
+
continue
|
| 156 |
+
text += f"{j}➤ {user}[`{user_id}`]\n"
|
| 157 |
+
text += f" {_['auth_8']} {admin_name}[`{admin_id}`]\n\n"
|
| 158 |
+
await mystic.delete()
|
| 159 |
+
await message.reply_text(text)
|
YukkiMusic/plugins/admins/callback.py
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
|
| 3 |
+
from pyrogram import filters
|
| 4 |
+
from pyrogram.types import CallbackQuery, InlineKeyboardMarkup
|
| 5 |
+
|
| 6 |
+
from config import (AUTO_DOWNLOADS_CLEAR, BANNED_USERS,
|
| 7 |
+
SOUNCLOUD_IMG_URL, STREAM_IMG_URL,
|
| 8 |
+
TELEGRAM_AUDIO_URL, TELEGRAM_VIDEO_URL, adminlist)
|
| 9 |
+
from YukkiMusic import YouTube, app
|
| 10 |
+
from YukkiMusic.core.call import Yukki
|
| 11 |
+
from YukkiMusic.misc import SUDOERS, db
|
| 12 |
+
from YukkiMusic.utils.database import (is_active_chat,
|
| 13 |
+
is_music_playing, is_muted,
|
| 14 |
+
is_nonadmin_chat, music_off,
|
| 15 |
+
music_on, mute_off, mute_on,
|
| 16 |
+
set_loop)
|
| 17 |
+
from YukkiMusic.utils.decorators.language import languageCB
|
| 18 |
+
from YukkiMusic.utils.formatters import seconds_to_min
|
| 19 |
+
from YukkiMusic.utils.inline.play import (panel_markup_1,
|
| 20 |
+
panel_markup_2,
|
| 21 |
+
panel_markup_3,
|
| 22 |
+
stream_markup,
|
| 23 |
+
telegram_markup)
|
| 24 |
+
from YukkiMusic.utils.stream.autoclear import auto_clean
|
| 25 |
+
from YukkiMusic.utils.thumbnails import gen_thumb
|
| 26 |
+
|
| 27 |
+
wrong = {}
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
@app.on_callback_query(filters.regex("PanelMarkup") & ~BANNED_USERS)
|
| 31 |
+
@languageCB
|
| 32 |
+
async def markup_panel(client, CallbackQuery: CallbackQuery, _):
|
| 33 |
+
await CallbackQuery.answer()
|
| 34 |
+
callback_data = CallbackQuery.data.strip()
|
| 35 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 36 |
+
videoid, chat_id = callback_request.split("|")
|
| 37 |
+
chat_id = CallbackQuery.message.chat.id
|
| 38 |
+
buttons = panel_markup_1(_, videoid, chat_id)
|
| 39 |
+
try:
|
| 40 |
+
await CallbackQuery.edit_message_reply_markup(
|
| 41 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 42 |
+
)
|
| 43 |
+
except:
|
| 44 |
+
return
|
| 45 |
+
if chat_id not in wrong:
|
| 46 |
+
wrong[chat_id] = {}
|
| 47 |
+
wrong[chat_id][CallbackQuery.message.id] = False
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
@app.on_callback_query(filters.regex("MainMarkup") & ~BANNED_USERS)
|
| 51 |
+
@languageCB
|
| 52 |
+
async def del_back_playlist(client, CallbackQuery, _):
|
| 53 |
+
await CallbackQuery.answer()
|
| 54 |
+
callback_data = CallbackQuery.data.strip()
|
| 55 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 56 |
+
videoid, chat_id = callback_request.split("|")
|
| 57 |
+
if videoid == str(None):
|
| 58 |
+
buttons = telegram_markup(_, chat_id)
|
| 59 |
+
else:
|
| 60 |
+
buttons = stream_markup(_, videoid, chat_id)
|
| 61 |
+
chat_id = CallbackQuery.message.chat.id
|
| 62 |
+
try:
|
| 63 |
+
await CallbackQuery.edit_message_reply_markup(
|
| 64 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 65 |
+
)
|
| 66 |
+
except:
|
| 67 |
+
return
|
| 68 |
+
if chat_id not in wrong:
|
| 69 |
+
wrong[chat_id] = {}
|
| 70 |
+
wrong[chat_id][CallbackQuery.message.message.id] = True
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
@app.on_callback_query(filters.regex("Pages") & ~BANNED_USERS)
|
| 74 |
+
@languageCB
|
| 75 |
+
async def del_back_playlist(client, CallbackQuery, _):
|
| 76 |
+
await CallbackQuery.answer()
|
| 77 |
+
callback_data = CallbackQuery.data.strip()
|
| 78 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 79 |
+
state, pages, videoid, chat = callback_request.split("|")
|
| 80 |
+
chat_id = int(chat)
|
| 81 |
+
pages = int(pages)
|
| 82 |
+
if state == "Forw":
|
| 83 |
+
if pages == 0:
|
| 84 |
+
buttons = panel_markup_2(_, videoid, chat_id)
|
| 85 |
+
if pages == 2:
|
| 86 |
+
buttons = panel_markup_1(_, videoid, chat_id)
|
| 87 |
+
if pages == 1:
|
| 88 |
+
buttons = panel_markup_3(_, videoid, chat_id)
|
| 89 |
+
if state == "Back":
|
| 90 |
+
if pages == 2:
|
| 91 |
+
buttons = panel_markup_2(_, videoid, chat_id)
|
| 92 |
+
if pages == 1:
|
| 93 |
+
buttons = panel_markup_1(_, videoid, chat_id)
|
| 94 |
+
if pages == 0:
|
| 95 |
+
buttons = panel_markup_3(_, videoid, chat_id)
|
| 96 |
+
try:
|
| 97 |
+
await CallbackQuery.edit_message_reply_markup(
|
| 98 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 99 |
+
)
|
| 100 |
+
except:
|
| 101 |
+
return
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
downvote = {}
|
| 105 |
+
downvoters = {}
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
@app.on_callback_query(filters.regex("ADMIN") & ~BANNED_USERS)
|
| 109 |
+
@languageCB
|
| 110 |
+
async def del_back_playlist(client, CallbackQuery, _):
|
| 111 |
+
callback_data = CallbackQuery.data.strip()
|
| 112 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 113 |
+
command, chat = callback_request.split("|")
|
| 114 |
+
chat_id = int(chat)
|
| 115 |
+
if not await is_active_chat(chat_id):
|
| 116 |
+
return await CallbackQuery.answer(
|
| 117 |
+
_["general_6"], show_alert=True
|
| 118 |
+
)
|
| 119 |
+
mention = CallbackQuery.from_user.mention
|
| 120 |
+
is_non_admin = await is_nonadmin_chat(
|
| 121 |
+
CallbackQuery.message.chat.id
|
| 122 |
+
)
|
| 123 |
+
if not is_non_admin:
|
| 124 |
+
if CallbackQuery.from_user.id not in SUDOERS:
|
| 125 |
+
admins = adminlist.get(CallbackQuery.message.chat.id)
|
| 126 |
+
if not admins:
|
| 127 |
+
return await CallbackQuery.answer(
|
| 128 |
+
_["admin_18"], show_alert=True
|
| 129 |
+
)
|
| 130 |
+
else:
|
| 131 |
+
if CallbackQuery.from_user.id not in admins:
|
| 132 |
+
return await CallbackQuery.answer(
|
| 133 |
+
_["admin_19"], show_alert=True
|
| 134 |
+
)
|
| 135 |
+
if command == "Pause":
|
| 136 |
+
if not await is_music_playing(chat_id):
|
| 137 |
+
return await CallbackQuery.answer(
|
| 138 |
+
_["admin_1"], show_alert=True
|
| 139 |
+
)
|
| 140 |
+
await CallbackQuery.answer()
|
| 141 |
+
await music_off(chat_id)
|
| 142 |
+
await Yukki.pause_stream(chat_id)
|
| 143 |
+
await CallbackQuery.message.reply_text(
|
| 144 |
+
_["admin_2"].format(mention)
|
| 145 |
+
)
|
| 146 |
+
elif command == "Resume":
|
| 147 |
+
if await is_music_playing(chat_id):
|
| 148 |
+
return await CallbackQuery.answer(
|
| 149 |
+
_["admin_3"], show_alert=True
|
| 150 |
+
)
|
| 151 |
+
await CallbackQuery.answer()
|
| 152 |
+
await music_on(chat_id)
|
| 153 |
+
await Yukki.resume_stream(chat_id)
|
| 154 |
+
await CallbackQuery.message.reply_text(
|
| 155 |
+
_["admin_4"].format(mention)
|
| 156 |
+
)
|
| 157 |
+
elif command == "Stop" or command == "End":
|
| 158 |
+
await CallbackQuery.answer()
|
| 159 |
+
await Yukki.stop_stream(chat_id)
|
| 160 |
+
await set_loop(chat_id, 0)
|
| 161 |
+
await CallbackQuery.message.reply_text(
|
| 162 |
+
_["admin_9"].format(mention)
|
| 163 |
+
)
|
| 164 |
+
elif command == "Mute":
|
| 165 |
+
if await is_muted(chat_id):
|
| 166 |
+
return await CallbackQuery.answer(
|
| 167 |
+
_["admin_5"], show_alert=True
|
| 168 |
+
)
|
| 169 |
+
await CallbackQuery.answer()
|
| 170 |
+
await mute_on(chat_id)
|
| 171 |
+
await Yukki.mute_stream(chat_id)
|
| 172 |
+
await CallbackQuery.message.reply_text(
|
| 173 |
+
_["admin_6"].format(mention)
|
| 174 |
+
)
|
| 175 |
+
elif command == "Unmute":
|
| 176 |
+
if not await is_muted(chat_id):
|
| 177 |
+
return await CallbackQuery.answer(
|
| 178 |
+
_["admin_7"], show_alert=True
|
| 179 |
+
)
|
| 180 |
+
await CallbackQuery.answer()
|
| 181 |
+
await mute_off(chat_id)
|
| 182 |
+
await Yukki.unmute_stream(chat_id)
|
| 183 |
+
await CallbackQuery.message.reply_text(
|
| 184 |
+
_["admin_8"].format(mention)
|
| 185 |
+
)
|
| 186 |
+
elif command == "Loop":
|
| 187 |
+
await CallbackQuery.answer()
|
| 188 |
+
await set_loop(chat_id, 3)
|
| 189 |
+
await CallbackQuery.message.reply_text(
|
| 190 |
+
_["admin_25"].format(mention, 3)
|
| 191 |
+
)
|
| 192 |
+
elif command == "Shuffle":
|
| 193 |
+
check = db.get(chat_id)
|
| 194 |
+
if not check:
|
| 195 |
+
return await CallbackQuery.answer(
|
| 196 |
+
_["admin_21"], show_alert=True
|
| 197 |
+
)
|
| 198 |
+
try:
|
| 199 |
+
popped = check.pop(0)
|
| 200 |
+
except:
|
| 201 |
+
return await CallbackQuery.answer(
|
| 202 |
+
_["admin_22"], show_alert=True
|
| 203 |
+
)
|
| 204 |
+
check = db.get(chat_id)
|
| 205 |
+
if not check:
|
| 206 |
+
check.insert(0, popped)
|
| 207 |
+
return await CallbackQuery.answer(
|
| 208 |
+
_["admin_22"], show_alert=True
|
| 209 |
+
)
|
| 210 |
+
await CallbackQuery.answer()
|
| 211 |
+
random.shuffle(check)
|
| 212 |
+
check.insert(0, popped)
|
| 213 |
+
await CallbackQuery.message.reply_text(
|
| 214 |
+
_["admin_23"].format(mention)
|
| 215 |
+
)
|
| 216 |
+
elif command == "Skip":
|
| 217 |
+
check = db.get(chat_id)
|
| 218 |
+
txt = f"Skipped by {mention}"
|
| 219 |
+
popped = None
|
| 220 |
+
try:
|
| 221 |
+
popped = check.pop(0)
|
| 222 |
+
if popped:
|
| 223 |
+
if AUTO_DOWNLOADS_CLEAR == str(True):
|
| 224 |
+
await auto_clean(popped)
|
| 225 |
+
if not check:
|
| 226 |
+
await CallbackQuery.edit_message_text(
|
| 227 |
+
f"Skipped by {mention}"
|
| 228 |
+
)
|
| 229 |
+
await CallbackQuery.message.reply_text(
|
| 230 |
+
_["admin_10"].format(mention)
|
| 231 |
+
)
|
| 232 |
+
try:
|
| 233 |
+
return await Yukki.stop_stream(chat_id)
|
| 234 |
+
except:
|
| 235 |
+
return
|
| 236 |
+
except:
|
| 237 |
+
try:
|
| 238 |
+
await CallbackQuery.edit_message_text(
|
| 239 |
+
f"Skipped by {mention}"
|
| 240 |
+
)
|
| 241 |
+
await CallbackQuery.message.reply_text(
|
| 242 |
+
_["admin_10"].format(mention)
|
| 243 |
+
)
|
| 244 |
+
return await Yukki.stop_stream(chat_id)
|
| 245 |
+
except:
|
| 246 |
+
return
|
| 247 |
+
await CallbackQuery.answer()
|
| 248 |
+
queued = check[0]["file"]
|
| 249 |
+
title = (check[0]["title"]).title()
|
| 250 |
+
user = check[0]["by"]
|
| 251 |
+
streamtype = check[0]["streamtype"]
|
| 252 |
+
videoid = check[0]["vidid"]
|
| 253 |
+
status = True if str(streamtype) == "video" else None
|
| 254 |
+
db[chat_id][0]["played"] = 0
|
| 255 |
+
if "live_" in queued:
|
| 256 |
+
n, link = await YouTube.video(videoid, True)
|
| 257 |
+
if n == 0:
|
| 258 |
+
return await CallbackQuery.message.reply_text(
|
| 259 |
+
_["admin_11"].format(title)
|
| 260 |
+
)
|
| 261 |
+
try:
|
| 262 |
+
await Yukki.skip_stream(chat_id, link, video=status)
|
| 263 |
+
except Exception:
|
| 264 |
+
return await CallbackQuery.message.reply_text(
|
| 265 |
+
_["call_9"]
|
| 266 |
+
)
|
| 267 |
+
button = telegram_markup(_, chat_id)
|
| 268 |
+
img = await gen_thumb(videoid)
|
| 269 |
+
run = await CallbackQuery.message.reply_photo(
|
| 270 |
+
photo=img,
|
| 271 |
+
caption=_["stream_1"].format(
|
| 272 |
+
user,
|
| 273 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 274 |
+
),
|
| 275 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 276 |
+
)
|
| 277 |
+
db[chat_id][0]["mystic"] = run
|
| 278 |
+
db[chat_id][0]["markup"] = "tg"
|
| 279 |
+
await CallbackQuery.edit_message_text(txt)
|
| 280 |
+
elif "vid_" in queued:
|
| 281 |
+
mystic = await CallbackQuery.message.reply_text(
|
| 282 |
+
_["call_10"], disable_web_page_preview=True
|
| 283 |
+
)
|
| 284 |
+
try:
|
| 285 |
+
file_path, direct = await YouTube.download(
|
| 286 |
+
videoid,
|
| 287 |
+
mystic,
|
| 288 |
+
videoid=True,
|
| 289 |
+
video=status,
|
| 290 |
+
)
|
| 291 |
+
except:
|
| 292 |
+
return await mystic.edit_text(_["call_9"])
|
| 293 |
+
try:
|
| 294 |
+
await Yukki.skip_stream(
|
| 295 |
+
chat_id, file_path, video=status
|
| 296 |
+
)
|
| 297 |
+
except Exception:
|
| 298 |
+
return await mystic.edit_text(_["call_9"])
|
| 299 |
+
button = stream_markup(_, videoid, chat_id)
|
| 300 |
+
img = await gen_thumb(videoid)
|
| 301 |
+
run = await CallbackQuery.message.reply_photo(
|
| 302 |
+
photo=img,
|
| 303 |
+
caption=_["stream_1"].format(
|
| 304 |
+
user,
|
| 305 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 306 |
+
),
|
| 307 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 308 |
+
)
|
| 309 |
+
db[chat_id][0]["mystic"] = run
|
| 310 |
+
db[chat_id][0]["markup"] = "stream"
|
| 311 |
+
await CallbackQuery.edit_message_text(txt)
|
| 312 |
+
await mystic.delete()
|
| 313 |
+
elif "index_" in queued:
|
| 314 |
+
try:
|
| 315 |
+
await Yukki.skip_stream(
|
| 316 |
+
chat_id, videoid, video=status
|
| 317 |
+
)
|
| 318 |
+
except Exception:
|
| 319 |
+
return await CallbackQuery.message.reply_text(
|
| 320 |
+
_["call_9"]
|
| 321 |
+
)
|
| 322 |
+
button = telegram_markup(_, chat_id)
|
| 323 |
+
run = await CallbackQuery.message.reply_photo(
|
| 324 |
+
photo=STREAM_IMG_URL,
|
| 325 |
+
caption=_["stream_2"].format(user),
|
| 326 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 327 |
+
)
|
| 328 |
+
db[chat_id][0]["mystic"] = run
|
| 329 |
+
db[chat_id][0]["markup"] = "tg"
|
| 330 |
+
await CallbackQuery.edit_message_text(txt)
|
| 331 |
+
else:
|
| 332 |
+
try:
|
| 333 |
+
await Yukki.skip_stream(chat_id, queued, video=status)
|
| 334 |
+
except Exception:
|
| 335 |
+
return await CallbackQuery.message.reply_text(
|
| 336 |
+
_["call_9"]
|
| 337 |
+
)
|
| 338 |
+
if videoid == "telegram":
|
| 339 |
+
button = telegram_markup(_, chat_id)
|
| 340 |
+
run = await CallbackQuery.message.reply_photo(
|
| 341 |
+
photo=TELEGRAM_AUDIO_URL
|
| 342 |
+
if str(streamtype) == "audio"
|
| 343 |
+
else TELEGRAM_VIDEO_URL,
|
| 344 |
+
caption=_["stream_3"].format(
|
| 345 |
+
title, check[0]["dur"], user
|
| 346 |
+
),
|
| 347 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 348 |
+
)
|
| 349 |
+
db[chat_id][0]["mystic"] = run
|
| 350 |
+
db[chat_id][0]["markup"] = "tg"
|
| 351 |
+
elif videoid == "soundcloud":
|
| 352 |
+
button = telegram_markup(_, chat_id)
|
| 353 |
+
run = await CallbackQuery.message.reply_photo(
|
| 354 |
+
photo=SOUNCLOUD_IMG_URL
|
| 355 |
+
if str(streamtype) == "audio"
|
| 356 |
+
else TELEGRAM_VIDEO_URL,
|
| 357 |
+
caption=_["stream_3"].format(
|
| 358 |
+
title, check[0]["dur"], user
|
| 359 |
+
),
|
| 360 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 361 |
+
)
|
| 362 |
+
db[chat_id][0]["mystic"] = run
|
| 363 |
+
db[chat_id][0]["markup"] = "tg"
|
| 364 |
+
else:
|
| 365 |
+
button = stream_markup(_, videoid, chat_id)
|
| 366 |
+
img = await gen_thumb(videoid)
|
| 367 |
+
run = await CallbackQuery.message.reply_photo(
|
| 368 |
+
photo=img,
|
| 369 |
+
caption=_["stream_1"].format(
|
| 370 |
+
user,
|
| 371 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 372 |
+
),
|
| 373 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 374 |
+
)
|
| 375 |
+
db[chat_id][0]["mystic"] = run
|
| 376 |
+
db[chat_id][0]["markup"] = "stream"
|
| 377 |
+
await CallbackQuery.edit_message_text(txt)
|
| 378 |
+
else:
|
| 379 |
+
playing = db.get(chat_id)
|
| 380 |
+
if not playing:
|
| 381 |
+
return await CallbackQuery.answer(
|
| 382 |
+
_["queue_2"], show_alert=True
|
| 383 |
+
)
|
| 384 |
+
duration_seconds = int(playing[0]["seconds"])
|
| 385 |
+
if duration_seconds == 0:
|
| 386 |
+
return await CallbackQuery.answer(
|
| 387 |
+
_["admin_30"], show_alert=True
|
| 388 |
+
)
|
| 389 |
+
file_path = playing[0]["file"]
|
| 390 |
+
if "index_" in file_path or "live_" in file_path:
|
| 391 |
+
return await CallbackQuery.answer(
|
| 392 |
+
_["admin_30"], show_alert=True
|
| 393 |
+
)
|
| 394 |
+
duration_played = int(playing[0]["played"])
|
| 395 |
+
if int(command) in [1, 2]:
|
| 396 |
+
duration_to_skip = 10
|
| 397 |
+
else:
|
| 398 |
+
duration_to_skip = 30
|
| 399 |
+
duration = playing[0]["dur"]
|
| 400 |
+
if int(command) in [1, 3]:
|
| 401 |
+
if (duration_played - duration_to_skip) <= 10:
|
| 402 |
+
bet = seconds_to_min(duration_played)
|
| 403 |
+
return await CallbackQuery.answer(
|
| 404 |
+
f"Bot is not able to seek due to total duration has been exceeded.\n\nCurrently played** {bet}** mins out of **{duration}** mins",
|
| 405 |
+
show_alert=True,
|
| 406 |
+
)
|
| 407 |
+
to_seek = duration_played - duration_to_skip + 1
|
| 408 |
+
else:
|
| 409 |
+
if (
|
| 410 |
+
duration_seconds
|
| 411 |
+
- (duration_played + duration_to_skip)
|
| 412 |
+
) <= 10:
|
| 413 |
+
bet = seconds_to_min(duration_played)
|
| 414 |
+
return await CallbackQuery.answer(
|
| 415 |
+
f"Bot is not able to seek due to total duration has been exceeded.\n\nCurrently played** {bet}** mins out of **{duration}** mins",
|
| 416 |
+
show_alert=True,
|
| 417 |
+
)
|
| 418 |
+
to_seek = duration_played + duration_to_skip + 1
|
| 419 |
+
await CallbackQuery.answer()
|
| 420 |
+
mystic = await CallbackQuery.message.reply_text(_["admin_32"])
|
| 421 |
+
if "vid_" in file_path:
|
| 422 |
+
n, file_path = await YouTube.video(
|
| 423 |
+
playing[0]["vidid"], True
|
| 424 |
+
)
|
| 425 |
+
if n == 0:
|
| 426 |
+
return await mystic.edit_text(_["admin_30"])
|
| 427 |
+
try:
|
| 428 |
+
await Yukki.seek_stream(
|
| 429 |
+
chat_id,
|
| 430 |
+
file_path,
|
| 431 |
+
seconds_to_min(to_seek),
|
| 432 |
+
duration,
|
| 433 |
+
playing[0]["streamtype"],
|
| 434 |
+
)
|
| 435 |
+
except:
|
| 436 |
+
return await mystic.edit_text(_["admin_34"])
|
| 437 |
+
if int(command) in [1, 3]:
|
| 438 |
+
db[chat_id][0]["played"] -= duration_to_skip
|
| 439 |
+
else:
|
| 440 |
+
db[chat_id][0]["played"] += duration_to_skip
|
| 441 |
+
string = _["admin_33"].format(seconds_to_min(to_seek))
|
| 442 |
+
await mystic.edit_text(
|
| 443 |
+
f"{string}\n\nChanges done by: {mention}"
|
| 444 |
+
)
|
YukkiMusic/plugins/admins/loop.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.utils.database.memorydatabase import (get_loop,
|
| 17 |
+
set_loop)
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
LOOP_COMMAND = get_command("LOOP_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(LOOP_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def admins(cli, message: Message, _, chat_id):
|
| 31 |
+
usage = _["admin_24"]
|
| 32 |
+
if len(message.command) != 2:
|
| 33 |
+
return await message.reply_text(usage)
|
| 34 |
+
state = message.text.split(None, 1)[1].strip()
|
| 35 |
+
if state.isnumeric():
|
| 36 |
+
state = int(state)
|
| 37 |
+
if 1 <= state <= 10:
|
| 38 |
+
got = await get_loop(chat_id)
|
| 39 |
+
if got != 0:
|
| 40 |
+
state = got + state
|
| 41 |
+
if int(state) > 10:
|
| 42 |
+
state = 10
|
| 43 |
+
await set_loop(chat_id, state)
|
| 44 |
+
return await message.reply_text(
|
| 45 |
+
_["admin_25"].format(
|
| 46 |
+
message.from_user.first_name, state
|
| 47 |
+
)
|
| 48 |
+
)
|
| 49 |
+
else:
|
| 50 |
+
return await message.reply_text(_["admin_26"])
|
| 51 |
+
elif state.lower() == "enable":
|
| 52 |
+
await set_loop(chat_id, 10)
|
| 53 |
+
return await message.reply_text(
|
| 54 |
+
_["admin_25"].format(message.from_user.first_name, 10)
|
| 55 |
+
)
|
| 56 |
+
elif state.lower() == "disable":
|
| 57 |
+
await set_loop(chat_id, 0)
|
| 58 |
+
return await message.reply_text(_["admin_27"])
|
| 59 |
+
else:
|
| 60 |
+
return await message.reply_text(usage)
|
YukkiMusic/plugins/admins/mute.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.utils.database import is_muted, mute_on
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
MUTE_COMMAND = get_command("MUTE_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(MUTE_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def mute_admin(cli, message: Message, _, chat_id):
|
| 31 |
+
if not len(message.command) == 1 or message.reply_to_message:
|
| 32 |
+
return await message.reply_text(_["general_2"])
|
| 33 |
+
if await is_muted(chat_id):
|
| 34 |
+
return await message.reply_text(_["admin_5"])
|
| 35 |
+
await mute_on(chat_id)
|
| 36 |
+
await Yukki.mute_stream(chat_id)
|
| 37 |
+
await message.reply_text(
|
| 38 |
+
_["admin_6"].format(message.from_user.mention)
|
| 39 |
+
)
|
YukkiMusic/plugins/admins/pause.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.utils.database import is_music_playing, music_off
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
PAUSE_COMMAND = get_command("PAUSE_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(PAUSE_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def pause_admin(cli, message: Message, _, chat_id):
|
| 31 |
+
if not len(message.command) == 1:
|
| 32 |
+
return await message.reply_text(_["general_2"])
|
| 33 |
+
if not await is_music_playing(chat_id):
|
| 34 |
+
return await message.reply_text(_["admin_1"])
|
| 35 |
+
await music_off(chat_id)
|
| 36 |
+
await Yukki.pause_stream(chat_id)
|
| 37 |
+
await message.reply_text(
|
| 38 |
+
_["admin_2"].format(message.from_user.mention)
|
| 39 |
+
)
|
YukkiMusic/plugins/admins/resume.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.utils.database import is_music_playing, music_on
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
RESUME_COMMAND = get_command("RESUME_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(RESUME_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def resume_com(cli, message: Message, _, chat_id):
|
| 31 |
+
if not len(message.command) == 1:
|
| 32 |
+
return await message.reply_text(_["general_2"])
|
| 33 |
+
if await is_music_playing(chat_id):
|
| 34 |
+
return await message.reply_text(_["admin_3"])
|
| 35 |
+
await music_on(chat_id)
|
| 36 |
+
await Yukki.resume_stream(chat_id)
|
| 37 |
+
await message.reply_text(
|
| 38 |
+
_["admin_4"].format(message.from_user.mention)
|
| 39 |
+
)
|
YukkiMusic/plugins/admins/seek.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import YouTube, app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.misc import db
|
| 18 |
+
from YukkiMusic.utils import AdminRightsCheck, seconds_to_min
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
SEEK_COMMAND = get_command("SEEK_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(SEEK_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def seek_comm(cli, message: Message, _, chat_id):
|
| 31 |
+
if len(message.command) == 1:
|
| 32 |
+
return await message.reply_text(_["admin_28"])
|
| 33 |
+
query = message.text.split(None, 1)[1].strip()
|
| 34 |
+
if not query.isnumeric():
|
| 35 |
+
return await message.reply_text(_["admin_29"])
|
| 36 |
+
playing = db.get(chat_id)
|
| 37 |
+
if not playing:
|
| 38 |
+
return await message.reply_text(_["queue_2"])
|
| 39 |
+
duration_seconds = int(playing[0]["seconds"])
|
| 40 |
+
if duration_seconds == 0:
|
| 41 |
+
return await message.reply_text(_["admin_30"])
|
| 42 |
+
file_path = playing[0]["file"]
|
| 43 |
+
if "index_" in file_path or "live_" in file_path:
|
| 44 |
+
return await message.reply_text(_["admin_30"])
|
| 45 |
+
duration_played = int(playing[0]["played"])
|
| 46 |
+
duration_to_skip = int(query)
|
| 47 |
+
duration = playing[0]["dur"]
|
| 48 |
+
if message.command[0][-2] == "c":
|
| 49 |
+
if (duration_played - duration_to_skip) <= 10:
|
| 50 |
+
return await message.reply_text(
|
| 51 |
+
_["admin_31"].format(
|
| 52 |
+
seconds_to_min(duration_played), duration
|
| 53 |
+
)
|
| 54 |
+
)
|
| 55 |
+
to_seek = duration_played - duration_to_skip + 1
|
| 56 |
+
else:
|
| 57 |
+
if (
|
| 58 |
+
duration_seconds - (duration_played + duration_to_skip)
|
| 59 |
+
) <= 10:
|
| 60 |
+
return await message.reply_text(
|
| 61 |
+
_["admin_31"].format(
|
| 62 |
+
seconds_to_min(duration_played), duration
|
| 63 |
+
)
|
| 64 |
+
)
|
| 65 |
+
to_seek = duration_played + duration_to_skip + 1
|
| 66 |
+
mystic = await message.reply_text(_["admin_32"])
|
| 67 |
+
if "vid_" in file_path:
|
| 68 |
+
n, file_path = await YouTube.video(playing[0]["vidid"], True)
|
| 69 |
+
if n == 0:
|
| 70 |
+
return await message.reply_text(_["admin_30"])
|
| 71 |
+
try:
|
| 72 |
+
await Yukki.seek_stream(
|
| 73 |
+
chat_id,
|
| 74 |
+
file_path,
|
| 75 |
+
seconds_to_min(to_seek),
|
| 76 |
+
duration,
|
| 77 |
+
playing[0]["streamtype"],
|
| 78 |
+
)
|
| 79 |
+
except:
|
| 80 |
+
return await mystic.edit_text(_["admin_34"])
|
| 81 |
+
if message.command[0][-2] == "c":
|
| 82 |
+
db[chat_id][0]["played"] -= duration_to_skip
|
| 83 |
+
else:
|
| 84 |
+
db[chat_id][0]["played"] += duration_to_skip
|
| 85 |
+
await mystic.edit_text(
|
| 86 |
+
_["admin_33"].format(seconds_to_min(to_seek))
|
| 87 |
+
)
|
YukkiMusic/plugins/admins/shuffle.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import random
|
| 11 |
+
|
| 12 |
+
from pyrogram import filters
|
| 13 |
+
from pyrogram.types import Message
|
| 14 |
+
|
| 15 |
+
from config import BANNED_USERS
|
| 16 |
+
from strings import get_command
|
| 17 |
+
from YukkiMusic import app
|
| 18 |
+
from YukkiMusic.misc import db
|
| 19 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 20 |
+
|
| 21 |
+
# Commands
|
| 22 |
+
SHUFFLE_COMMAND = get_command("SHUFFLE_COMMAND")
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@app.on_message(
|
| 26 |
+
filters.command(SHUFFLE_COMMAND)
|
| 27 |
+
& filters.group
|
| 28 |
+
& ~BANNED_USERS
|
| 29 |
+
)
|
| 30 |
+
@AdminRightsCheck
|
| 31 |
+
async def admins(Client, message: Message, _, chat_id):
|
| 32 |
+
if not len(message.command) == 1:
|
| 33 |
+
return await message.reply_text(_["general_2"])
|
| 34 |
+
check = db.get(chat_id)
|
| 35 |
+
if not check:
|
| 36 |
+
return await message.reply_text(_["admin_21"])
|
| 37 |
+
try:
|
| 38 |
+
popped = check.pop(0)
|
| 39 |
+
except:
|
| 40 |
+
return await message.reply_text(_["admin_22"])
|
| 41 |
+
check = db.get(chat_id)
|
| 42 |
+
if not check:
|
| 43 |
+
check.insert(0, popped)
|
| 44 |
+
return await message.reply_text(_["admin_22"])
|
| 45 |
+
random.shuffle(check)
|
| 46 |
+
check.insert(0, popped)
|
| 47 |
+
await message.reply_text(
|
| 48 |
+
_["admin_23"].format(message.from_user.first_name)
|
| 49 |
+
)
|
YukkiMusic/plugins/admins/skip.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import InlineKeyboardMarkup, Message
|
| 12 |
+
|
| 13 |
+
import config
|
| 14 |
+
from config import BANNED_USERS
|
| 15 |
+
from strings import get_command
|
| 16 |
+
from YukkiMusic import YouTube, app
|
| 17 |
+
from YukkiMusic.core.call import Yukki
|
| 18 |
+
from YukkiMusic.misc import db
|
| 19 |
+
from YukkiMusic.utils.database import get_loop
|
| 20 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 21 |
+
from YukkiMusic.utils.inline.play import (stream_markup,
|
| 22 |
+
telegram_markup)
|
| 23 |
+
from YukkiMusic.utils.stream.autoclear import auto_clean
|
| 24 |
+
from YukkiMusic.utils.thumbnails import gen_thumb
|
| 25 |
+
|
| 26 |
+
# Commands
|
| 27 |
+
SKIP_COMMAND = get_command("SKIP_COMMAND")
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
@app.on_message(
|
| 31 |
+
filters.command(SKIP_COMMAND)
|
| 32 |
+
& filters.group
|
| 33 |
+
& ~BANNED_USERS
|
| 34 |
+
)
|
| 35 |
+
@AdminRightsCheck
|
| 36 |
+
async def skip(cli, message: Message, _, chat_id):
|
| 37 |
+
if not len(message.command) < 2:
|
| 38 |
+
loop = await get_loop(chat_id)
|
| 39 |
+
if loop != 0:
|
| 40 |
+
return await message.reply_text(_["admin_12"])
|
| 41 |
+
state = message.text.split(None, 1)[1].strip()
|
| 42 |
+
if state.isnumeric():
|
| 43 |
+
state = int(state)
|
| 44 |
+
check = db.get(chat_id)
|
| 45 |
+
if check:
|
| 46 |
+
count = len(check)
|
| 47 |
+
if count > 2:
|
| 48 |
+
count = int(count - 1)
|
| 49 |
+
if 1 <= state <= count:
|
| 50 |
+
for x in range(state):
|
| 51 |
+
popped = None
|
| 52 |
+
try:
|
| 53 |
+
popped = check.pop(0)
|
| 54 |
+
except:
|
| 55 |
+
return await message.reply_text(
|
| 56 |
+
_["admin_16"]
|
| 57 |
+
)
|
| 58 |
+
if popped:
|
| 59 |
+
if (
|
| 60 |
+
config.AUTO_DOWNLOADS_CLEAR
|
| 61 |
+
== str(True)
|
| 62 |
+
):
|
| 63 |
+
await auto_clean(popped)
|
| 64 |
+
if not check:
|
| 65 |
+
try:
|
| 66 |
+
await message.reply_text(
|
| 67 |
+
_["admin_10"].format(
|
| 68 |
+
message.from_user.first_name
|
| 69 |
+
)
|
| 70 |
+
)
|
| 71 |
+
await Yukki.stop_stream(chat_id)
|
| 72 |
+
except:
|
| 73 |
+
return
|
| 74 |
+
break
|
| 75 |
+
else:
|
| 76 |
+
return await message.reply_text(
|
| 77 |
+
_["admin_15"].format(count)
|
| 78 |
+
)
|
| 79 |
+
else:
|
| 80 |
+
return await message.reply_text(_["admin_14"])
|
| 81 |
+
else:
|
| 82 |
+
return await message.reply_text(_["queue_2"])
|
| 83 |
+
else:
|
| 84 |
+
return await message.reply_text(_["admin_13"])
|
| 85 |
+
else:
|
| 86 |
+
check = db.get(chat_id)
|
| 87 |
+
popped = None
|
| 88 |
+
try:
|
| 89 |
+
popped = check.pop(0)
|
| 90 |
+
if popped:
|
| 91 |
+
if config.AUTO_DOWNLOADS_CLEAR == str(True):
|
| 92 |
+
await auto_clean(popped)
|
| 93 |
+
if not check:
|
| 94 |
+
await message.reply_text(
|
| 95 |
+
_["admin_10"].format(message.from_user.first_name)
|
| 96 |
+
)
|
| 97 |
+
try:
|
| 98 |
+
return await Yukki.stop_stream(chat_id)
|
| 99 |
+
except:
|
| 100 |
+
return
|
| 101 |
+
except:
|
| 102 |
+
try:
|
| 103 |
+
await message.reply_text(
|
| 104 |
+
_["admin_10"].format(message.from_user.first_name)
|
| 105 |
+
)
|
| 106 |
+
return await Yukki.stop_stream(chat_id)
|
| 107 |
+
except:
|
| 108 |
+
return
|
| 109 |
+
queued = check[0]["file"]
|
| 110 |
+
title = (check[0]["title"]).title()
|
| 111 |
+
user = check[0]["by"]
|
| 112 |
+
streamtype = check[0]["streamtype"]
|
| 113 |
+
videoid = check[0]["vidid"]
|
| 114 |
+
status = True if str(streamtype) == "video" else None
|
| 115 |
+
if "live_" in queued:
|
| 116 |
+
n, link = await YouTube.video(videoid, True)
|
| 117 |
+
if n == 0:
|
| 118 |
+
return await message.reply_text(
|
| 119 |
+
_["admin_11"].format(title)
|
| 120 |
+
)
|
| 121 |
+
try:
|
| 122 |
+
await Yukki.skip_stream(chat_id, link, video=status)
|
| 123 |
+
except Exception:
|
| 124 |
+
return await message.reply_text(_["call_9"])
|
| 125 |
+
button = telegram_markup(_, chat_id)
|
| 126 |
+
img = await gen_thumb(videoid)
|
| 127 |
+
run = await message.reply_photo(
|
| 128 |
+
photo=img,
|
| 129 |
+
caption=_["stream_1"].format(
|
| 130 |
+
user,
|
| 131 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 132 |
+
),
|
| 133 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 134 |
+
)
|
| 135 |
+
db[chat_id][0]["mystic"] = run
|
| 136 |
+
db[chat_id][0]["markup"] = "tg"
|
| 137 |
+
elif "vid_" in queued:
|
| 138 |
+
mystic = await message.reply_text(
|
| 139 |
+
_["call_10"], disable_web_page_preview=True
|
| 140 |
+
)
|
| 141 |
+
try:
|
| 142 |
+
file_path, direct = await YouTube.download(
|
| 143 |
+
videoid,
|
| 144 |
+
mystic,
|
| 145 |
+
videoid=True,
|
| 146 |
+
video=status,
|
| 147 |
+
)
|
| 148 |
+
except:
|
| 149 |
+
return await mystic.edit_text(_["call_9"])
|
| 150 |
+
try:
|
| 151 |
+
await Yukki.skip_stream(chat_id, file_path, video=status)
|
| 152 |
+
except Exception:
|
| 153 |
+
return await mystic.edit_text(_["call_9"])
|
| 154 |
+
button = stream_markup(_, videoid, chat_id)
|
| 155 |
+
img = await gen_thumb(videoid)
|
| 156 |
+
run = await message.reply_photo(
|
| 157 |
+
photo=img,
|
| 158 |
+
caption=_["stream_1"].format(
|
| 159 |
+
user,
|
| 160 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 161 |
+
),
|
| 162 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 163 |
+
)
|
| 164 |
+
db[chat_id][0]["mystic"] = run
|
| 165 |
+
db[chat_id][0]["markup"] = "stream"
|
| 166 |
+
await mystic.delete()
|
| 167 |
+
elif "index_" in queued:
|
| 168 |
+
try:
|
| 169 |
+
await Yukki.skip_stream(chat_id, videoid, video=status)
|
| 170 |
+
except Exception:
|
| 171 |
+
return await message.reply_text(_["call_9"])
|
| 172 |
+
button = telegram_markup(_, chat_id)
|
| 173 |
+
run = await message.reply_photo(
|
| 174 |
+
photo=config.STREAM_IMG_URL,
|
| 175 |
+
caption=_["stream_2"].format(user),
|
| 176 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 177 |
+
)
|
| 178 |
+
db[chat_id][0]["mystic"] = run
|
| 179 |
+
db[chat_id][0]["markup"] = "tg"
|
| 180 |
+
else:
|
| 181 |
+
try:
|
| 182 |
+
await Yukki.skip_stream(chat_id, queued, video=status)
|
| 183 |
+
except Exception:
|
| 184 |
+
return await message.reply_text(_["call_9"])
|
| 185 |
+
if videoid == "telegram":
|
| 186 |
+
button = telegram_markup(_, chat_id)
|
| 187 |
+
run = await message.reply_photo(
|
| 188 |
+
photo=config.TELEGRAM_AUDIO_URL
|
| 189 |
+
if str(streamtype) == "audio"
|
| 190 |
+
else config.TELEGRAM_VIDEO_URL,
|
| 191 |
+
caption=_["stream_3"].format(
|
| 192 |
+
title, check[0]["dur"], user
|
| 193 |
+
),
|
| 194 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 195 |
+
)
|
| 196 |
+
db[chat_id][0]["mystic"] = run
|
| 197 |
+
db[chat_id][0]["markup"] = "tg"
|
| 198 |
+
elif videoid == "soundcloud":
|
| 199 |
+
button = telegram_markup(_, chat_id)
|
| 200 |
+
run = await message.reply_photo(
|
| 201 |
+
photo=config.SOUNCLOUD_IMG_URL
|
| 202 |
+
if str(streamtype) == "audio"
|
| 203 |
+
else config.TELEGRAM_VIDEO_URL,
|
| 204 |
+
caption=_["stream_3"].format(
|
| 205 |
+
title, check[0]["dur"], user
|
| 206 |
+
),
|
| 207 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 208 |
+
)
|
| 209 |
+
db[chat_id][0]["mystic"] = run
|
| 210 |
+
db[chat_id][0]["markup"] = "tg"
|
| 211 |
+
else:
|
| 212 |
+
button = stream_markup(_, videoid, chat_id)
|
| 213 |
+
img = await gen_thumb(videoid)
|
| 214 |
+
run = await message.reply_photo(
|
| 215 |
+
photo=img,
|
| 216 |
+
caption=_["stream_1"].format(
|
| 217 |
+
user,
|
| 218 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
| 219 |
+
),
|
| 220 |
+
reply_markup=InlineKeyboardMarkup(button),
|
| 221 |
+
)
|
| 222 |
+
db[chat_id][0]["mystic"] = run
|
| 223 |
+
db[chat_id][0]["markup"] = "stream"
|
YukkiMusic/plugins/admins/stop.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.utils.database import set_loop
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
STOP_COMMAND = get_command("STOP_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(STOP_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def stop_music(cli, message: Message, _, chat_id):
|
| 31 |
+
if not len(message.command) == 1:
|
| 32 |
+
return await message.reply_text(_["general_2"])
|
| 33 |
+
await Yukki.stop_stream(chat_id)
|
| 34 |
+
await set_loop(chat_id, 0)
|
| 35 |
+
await message.reply_text(
|
| 36 |
+
_["admin_9"].format(message.from_user.mention)
|
| 37 |
+
)
|
YukkiMusic/plugins/admins/unmute.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.types import Message
|
| 12 |
+
|
| 13 |
+
from config import BANNED_USERS
|
| 14 |
+
from strings import get_command
|
| 15 |
+
from YukkiMusic import app
|
| 16 |
+
from YukkiMusic.core.call import Yukki
|
| 17 |
+
from YukkiMusic.utils.database import is_muted, mute_off
|
| 18 |
+
from YukkiMusic.utils.decorators import AdminRightsCheck
|
| 19 |
+
|
| 20 |
+
# Commands
|
| 21 |
+
UNMUTE_COMMAND = get_command("UNMUTE_COMMAND")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
@app.on_message(
|
| 25 |
+
filters.command(UNMUTE_COMMAND)
|
| 26 |
+
& filters.group
|
| 27 |
+
& ~BANNED_USERS
|
| 28 |
+
)
|
| 29 |
+
@AdminRightsCheck
|
| 30 |
+
async def unmute_admin(Client, message: Message, _, chat_id):
|
| 31 |
+
if not len(message.command) == 1 or message.reply_to_message:
|
| 32 |
+
return await message.reply_text(_["general_2"])
|
| 33 |
+
if not await is_muted(chat_id):
|
| 34 |
+
return await message.reply_text(_["admin_7"])
|
| 35 |
+
await mute_off(chat_id)
|
| 36 |
+
await Yukki.unmute_stream(chat_id)
|
| 37 |
+
await message.reply_text(
|
| 38 |
+
_["admin_8"].format(message.from_user.mention)
|
| 39 |
+
)
|
YukkiMusic/plugins/bot/help.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
from typing import Union
|
| 12 |
+
|
| 13 |
+
from pyrogram import filters, types
|
| 14 |
+
from pyrogram.types import InlineKeyboardMarkup, Message
|
| 15 |
+
|
| 16 |
+
from config import BANNED_USERS
|
| 17 |
+
from strings import get_command, get_string, helpers
|
| 18 |
+
from YukkiMusic import app
|
| 19 |
+
from YukkiMusic.misc import SUDOERS
|
| 20 |
+
from YukkiMusic.utils import help_pannel
|
| 21 |
+
from YukkiMusic.utils.database import get_lang, is_commanddelete_on
|
| 22 |
+
from YukkiMusic.utils.decorators.language import (LanguageStart,
|
| 23 |
+
languageCB)
|
| 24 |
+
from YukkiMusic.utils.inline.help import (help_back_markup,
|
| 25 |
+
private_help_panel)
|
| 26 |
+
|
| 27 |
+
### Command
|
| 28 |
+
HELP_COMMAND = get_command("HELP_COMMAND")
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
@app.on_message(
|
| 32 |
+
filters.command(HELP_COMMAND)
|
| 33 |
+
& filters.private
|
| 34 |
+
& ~BANNED_USERS
|
| 35 |
+
)
|
| 36 |
+
@app.on_callback_query(
|
| 37 |
+
filters.regex("settings_back_helper") & ~BANNED_USERS
|
| 38 |
+
)
|
| 39 |
+
async def helper_private(
|
| 40 |
+
client: app, update: Union[types.Message, types.CallbackQuery]
|
| 41 |
+
):
|
| 42 |
+
is_callback = isinstance(update, types.CallbackQuery)
|
| 43 |
+
if is_callback:
|
| 44 |
+
try:
|
| 45 |
+
await update.answer()
|
| 46 |
+
except:
|
| 47 |
+
pass
|
| 48 |
+
chat_id = update.message.chat.id
|
| 49 |
+
language = await get_lang(chat_id)
|
| 50 |
+
_ = get_string(language)
|
| 51 |
+
keyboard = help_pannel(_, True)
|
| 52 |
+
if update.message.photo:
|
| 53 |
+
await update.message.delete()
|
| 54 |
+
await update.message.reply_text(
|
| 55 |
+
_["help_1"], reply_markup=keyboard
|
| 56 |
+
)
|
| 57 |
+
else:
|
| 58 |
+
await update.edit_message_text(
|
| 59 |
+
_["help_1"], reply_markup=keyboard
|
| 60 |
+
)
|
| 61 |
+
else:
|
| 62 |
+
chat_id = update.chat.id
|
| 63 |
+
if await is_commanddelete_on(update.chat.id):
|
| 64 |
+
try:
|
| 65 |
+
await update.delete()
|
| 66 |
+
except:
|
| 67 |
+
pass
|
| 68 |
+
language = await get_lang(chat_id)
|
| 69 |
+
_ = get_string(language)
|
| 70 |
+
keyboard = help_pannel(_)
|
| 71 |
+
await update.reply_text(_["help_1"], reply_markup=keyboard)
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
@app.on_message(
|
| 75 |
+
filters.command(HELP_COMMAND)
|
| 76 |
+
& filters.group
|
| 77 |
+
& ~BANNED_USERS
|
| 78 |
+
)
|
| 79 |
+
@LanguageStart
|
| 80 |
+
async def help_com_group(client, message: Message, _):
|
| 81 |
+
keyboard = private_help_panel(_)
|
| 82 |
+
await message.reply_text(
|
| 83 |
+
_["help_2"], reply_markup=InlineKeyboardMarkup(keyboard)
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
@app.on_callback_query(filters.regex("help_callback") & ~BANNED_USERS)
|
| 88 |
+
@languageCB
|
| 89 |
+
async def helper_cb(client, CallbackQuery, _):
|
| 90 |
+
callback_data = CallbackQuery.data.strip()
|
| 91 |
+
cb = callback_data.split(None, 1)[1]
|
| 92 |
+
keyboard = help_back_markup(_)
|
| 93 |
+
if cb == "hb5":
|
| 94 |
+
if CallbackQuery.from_user.id not in SUDOERS:
|
| 95 |
+
return await CallbackQuery.answer(
|
| 96 |
+
"Only for Sudo Users", show_alert=True
|
| 97 |
+
)
|
| 98 |
+
else:
|
| 99 |
+
await CallbackQuery.edit_message_text(
|
| 100 |
+
helpers.HELP_5, reply_markup=keyboard
|
| 101 |
+
)
|
| 102 |
+
return await CallbackQuery.answer()
|
| 103 |
+
try:
|
| 104 |
+
await CallbackQuery.answer()
|
| 105 |
+
except:
|
| 106 |
+
pass
|
| 107 |
+
if cb == "hb1":
|
| 108 |
+
await CallbackQuery.edit_message_text(
|
| 109 |
+
helpers.HELP_1, reply_markup=keyboard
|
| 110 |
+
)
|
| 111 |
+
elif cb == "hb2":
|
| 112 |
+
await CallbackQuery.edit_message_text(
|
| 113 |
+
helpers.HELP_2, reply_markup=keyboard
|
| 114 |
+
)
|
| 115 |
+
elif cb == "hb3":
|
| 116 |
+
await CallbackQuery.edit_message_text(
|
| 117 |
+
helpers.HELP_3, reply_markup=keyboard
|
| 118 |
+
)
|
| 119 |
+
elif cb == "hb4":
|
| 120 |
+
await CallbackQuery.edit_message_text(
|
| 121 |
+
helpers.HELP_4, reply_markup=keyboard
|
| 122 |
+
)
|
YukkiMusic/plugins/bot/inline.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram.types import (InlineKeyboardButton,
|
| 11 |
+
InlineKeyboardMarkup,
|
| 12 |
+
InlineQueryResultPhoto)
|
| 13 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 14 |
+
|
| 15 |
+
from config import BANNED_USERS, MUSIC_BOT_NAME
|
| 16 |
+
from YukkiMusic import app
|
| 17 |
+
from YukkiMusic.utils.inlinequery import answer
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
@app.on_inline_query(~BANNED_USERS)
|
| 21 |
+
async def inline_query_handler(client, query):
|
| 22 |
+
text = query.query.strip().lower()
|
| 23 |
+
answers = []
|
| 24 |
+
if text.strip() == "":
|
| 25 |
+
try:
|
| 26 |
+
await client.answer_inline_query(
|
| 27 |
+
query.id, results=answer, cache_time=10
|
| 28 |
+
)
|
| 29 |
+
except:
|
| 30 |
+
return
|
| 31 |
+
else:
|
| 32 |
+
a = VideosSearch(text, limit=20)
|
| 33 |
+
result = (await a.next()).get("result")
|
| 34 |
+
for x in range(15):
|
| 35 |
+
title = (result[x]["title"]).title()
|
| 36 |
+
duration = result[x]["duration"]
|
| 37 |
+
views = result[x]["viewCount"]["short"]
|
| 38 |
+
thumbnail = result[x]["thumbnails"][0]["url"].split("?")[
|
| 39 |
+
0
|
| 40 |
+
]
|
| 41 |
+
channellink = result[x]["channel"]["link"]
|
| 42 |
+
channel = result[x]["channel"]["name"]
|
| 43 |
+
link = result[x]["link"]
|
| 44 |
+
published = result[x]["publishedTime"]
|
| 45 |
+
description = f"{views} | {duration} Mins | {channel} | {published}"
|
| 46 |
+
buttons = InlineKeyboardMarkup(
|
| 47 |
+
[
|
| 48 |
+
[
|
| 49 |
+
InlineKeyboardButton(
|
| 50 |
+
text="🎥 Watch on Youtube",
|
| 51 |
+
url=link,
|
| 52 |
+
)
|
| 53 |
+
],
|
| 54 |
+
]
|
| 55 |
+
)
|
| 56 |
+
searched_text = f"""
|
| 57 |
+
❇️**Title:** [{title}]({link})
|
| 58 |
+
|
| 59 |
+
⏳**Duration:** {duration} Mins
|
| 60 |
+
👀**Views:** `{views}`
|
| 61 |
+
⏰**Published Time:** {published}
|
| 62 |
+
🎥**Channel Name:** {channel}
|
| 63 |
+
📎**Channel Link:** [Visit From Here]({channellink})
|
| 64 |
+
|
| 65 |
+
__Reply with /play on this searched message to stream it on voice chat.__
|
| 66 |
+
|
| 67 |
+
⚡️ ** Inline Search By {MUSIC_BOT_NAME} **"""
|
| 68 |
+
answers.append(
|
| 69 |
+
InlineQueryResultPhoto(
|
| 70 |
+
photo_url=thumbnail,
|
| 71 |
+
title=title,
|
| 72 |
+
thumb_url=thumbnail,
|
| 73 |
+
description=description,
|
| 74 |
+
caption=searched_text,
|
| 75 |
+
reply_markup=buttons,
|
| 76 |
+
)
|
| 77 |
+
)
|
| 78 |
+
try:
|
| 79 |
+
return await client.answer_inline_query(
|
| 80 |
+
query.id, results=answers
|
| 81 |
+
)
|
| 82 |
+
except:
|
| 83 |
+
return
|
YukkiMusic/plugins/bot/settings.py
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
from pyrogram.errors import MessageNotModified
|
| 12 |
+
from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
|
| 13 |
+
InlineKeyboardMarkup, Message)
|
| 14 |
+
|
| 15 |
+
from config import (BANNED_USERS, CLEANMODE_DELETE_MINS,
|
| 16 |
+
MUSIC_BOT_NAME, OWNER_ID)
|
| 17 |
+
from strings import get_command
|
| 18 |
+
from YukkiMusic import app
|
| 19 |
+
from YukkiMusic.utils.database import (add_nonadmin_chat,
|
| 20 |
+
cleanmode_off, cleanmode_on,
|
| 21 |
+
commanddelete_off,
|
| 22 |
+
commanddelete_on,
|
| 23 |
+
get_aud_bit_name, get_authuser,
|
| 24 |
+
get_authuser_names,
|
| 25 |
+
get_playmode, get_playtype,
|
| 26 |
+
get_vid_bit_name,
|
| 27 |
+
is_cleanmode_on,
|
| 28 |
+
is_commanddelete_on,
|
| 29 |
+
is_nonadmin_chat,
|
| 30 |
+
is_suggestion,
|
| 31 |
+
remove_nonadmin_chat,
|
| 32 |
+
save_audio_bitrate,
|
| 33 |
+
save_video_bitrate,
|
| 34 |
+
set_playmode, set_playtype,
|
| 35 |
+
suggestion_off, suggestion_on)
|
| 36 |
+
from YukkiMusic.utils.decorators.admins import ActualAdminCB
|
| 37 |
+
from YukkiMusic.utils.decorators.language import language, languageCB
|
| 38 |
+
from YukkiMusic.utils.inline.settings import (
|
| 39 |
+
audio_quality_markup, auth_users_markup,
|
| 40 |
+
cleanmode_settings_markup, playmode_users_markup, setting_markup,
|
| 41 |
+
video_quality_markup)
|
| 42 |
+
from YukkiMusic.utils.inline.start import private_panel
|
| 43 |
+
|
| 44 |
+
### Command
|
| 45 |
+
SETTINGS_COMMAND = get_command("SETTINGS_COMMAND")
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
@app.on_message(
|
| 49 |
+
filters.command(SETTINGS_COMMAND)
|
| 50 |
+
& filters.group
|
| 51 |
+
& ~BANNED_USERS
|
| 52 |
+
)
|
| 53 |
+
@language
|
| 54 |
+
async def settings_mar(client, message: Message, _):
|
| 55 |
+
buttons = setting_markup(_)
|
| 56 |
+
await message.reply_text(
|
| 57 |
+
_["setting_1"].format(message.chat.title, message.chat.id),
|
| 58 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@app.on_callback_query(
|
| 63 |
+
filters.regex("settings_helper") & ~BANNED_USERS
|
| 64 |
+
)
|
| 65 |
+
@languageCB
|
| 66 |
+
async def settings_cb(client, CallbackQuery, _):
|
| 67 |
+
try:
|
| 68 |
+
await CallbackQuery.answer(_["set_cb_8"])
|
| 69 |
+
except:
|
| 70 |
+
pass
|
| 71 |
+
buttons = setting_markup(_)
|
| 72 |
+
return await CallbackQuery.edit_message_text(
|
| 73 |
+
_["setting_1"].format(
|
| 74 |
+
CallbackQuery.message.chat.title,
|
| 75 |
+
CallbackQuery.message.chat.id,
|
| 76 |
+
),
|
| 77 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
@app.on_callback_query(
|
| 82 |
+
filters.regex("settingsback_helper") & ~BANNED_USERS
|
| 83 |
+
)
|
| 84 |
+
@languageCB
|
| 85 |
+
async def settings_back_markup(
|
| 86 |
+
client, CallbackQuery: CallbackQuery, _
|
| 87 |
+
):
|
| 88 |
+
try:
|
| 89 |
+
await CallbackQuery.answer()
|
| 90 |
+
except:
|
| 91 |
+
pass
|
| 92 |
+
if CallbackQuery.message.chat.type == "private":
|
| 93 |
+
try:
|
| 94 |
+
await app.resolve_peer(OWNER_ID[0])
|
| 95 |
+
OWNER = OWNER_ID[0]
|
| 96 |
+
except:
|
| 97 |
+
OWNER = None
|
| 98 |
+
buttons = private_panel(_, app.username, OWNER)
|
| 99 |
+
return await CallbackQuery.edit_message_text(
|
| 100 |
+
_["start_2"].format(MUSIC_BOT_NAME),
|
| 101 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
| 102 |
+
)
|
| 103 |
+
else:
|
| 104 |
+
buttons = setting_markup(_)
|
| 105 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 106 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
## Audio and Video Quality
|
| 111 |
+
async def gen_buttons_aud(_, aud):
|
| 112 |
+
if aud == "High":
|
| 113 |
+
buttons = audio_quality_markup(_, high=True)
|
| 114 |
+
elif aud == "Medium":
|
| 115 |
+
buttons = audio_quality_markup(_, medium=True)
|
| 116 |
+
elif aud == "Low":
|
| 117 |
+
buttons = audio_quality_markup(_, low=True)
|
| 118 |
+
return buttons
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
async def gen_buttons_vid(_, aud):
|
| 122 |
+
if aud == "High":
|
| 123 |
+
buttons = video_quality_markup(_, high=True)
|
| 124 |
+
elif aud == "Medium":
|
| 125 |
+
buttons = video_quality_markup(_, medium=True)
|
| 126 |
+
elif aud == "Low":
|
| 127 |
+
buttons = video_quality_markup(_, low=True)
|
| 128 |
+
return buttons
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
# without admin rights
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
@app.on_callback_query(
|
| 135 |
+
filters.regex(
|
| 136 |
+
pattern=r"^(SEARCHANSWER|PLAYMODEANSWER|PLAYTYPEANSWER|AUTHANSWER|CMANSWER|COMMANDANSWER|SUGGANSWER|CM|AQ|VQ|PM|AU)$"
|
| 137 |
+
)
|
| 138 |
+
& ~BANNED_USERS
|
| 139 |
+
)
|
| 140 |
+
@languageCB
|
| 141 |
+
async def without_Admin_rights(client, CallbackQuery, _):
|
| 142 |
+
command = CallbackQuery.matches[0].group(1)
|
| 143 |
+
if command == "SEARCHANSWER":
|
| 144 |
+
try:
|
| 145 |
+
return await CallbackQuery.answer(
|
| 146 |
+
_["setting_3"], show_alert=True
|
| 147 |
+
)
|
| 148 |
+
except:
|
| 149 |
+
return
|
| 150 |
+
if command == "PLAYMODEANSWER":
|
| 151 |
+
try:
|
| 152 |
+
return await CallbackQuery.answer(
|
| 153 |
+
_["setting_10"], show_alert=True
|
| 154 |
+
)
|
| 155 |
+
except:
|
| 156 |
+
return
|
| 157 |
+
if command == "PLAYTYPEANSWER":
|
| 158 |
+
try:
|
| 159 |
+
return await CallbackQuery.answer(
|
| 160 |
+
_["setting_11"], show_alert=True
|
| 161 |
+
)
|
| 162 |
+
except:
|
| 163 |
+
return
|
| 164 |
+
if command == "AUTHANSWER":
|
| 165 |
+
try:
|
| 166 |
+
return await CallbackQuery.answer(
|
| 167 |
+
_["setting_4"], show_alert=True
|
| 168 |
+
)
|
| 169 |
+
except:
|
| 170 |
+
return
|
| 171 |
+
if command == "CMANSWER":
|
| 172 |
+
try:
|
| 173 |
+
return await CallbackQuery.answer(
|
| 174 |
+
_["setting_9"].format(CLEANMODE_DELETE_MINS),
|
| 175 |
+
show_alert=True,
|
| 176 |
+
)
|
| 177 |
+
except:
|
| 178 |
+
return
|
| 179 |
+
if command == "COMMANDANSWER":
|
| 180 |
+
try:
|
| 181 |
+
return await CallbackQuery.answer(
|
| 182 |
+
_["setting_14"], show_alert=True
|
| 183 |
+
)
|
| 184 |
+
except:
|
| 185 |
+
return
|
| 186 |
+
if command == "SUGGANSWER":
|
| 187 |
+
try:
|
| 188 |
+
return await CallbackQuery.answer(
|
| 189 |
+
_["setting_16"], show_alert=True
|
| 190 |
+
)
|
| 191 |
+
except:
|
| 192 |
+
return
|
| 193 |
+
if command == "CM":
|
| 194 |
+
try:
|
| 195 |
+
await CallbackQuery.answer(_["set_cb_5"], show_alert=True)
|
| 196 |
+
except:
|
| 197 |
+
pass
|
| 198 |
+
sta = None
|
| 199 |
+
cle = None
|
| 200 |
+
if await is_cleanmode_on(CallbackQuery.message.chat.id):
|
| 201 |
+
cle = True
|
| 202 |
+
if await is_commanddelete_on(CallbackQuery.message.chat.id):
|
| 203 |
+
sta = True
|
| 204 |
+
sug = None
|
| 205 |
+
if await is_suggestion(CallbackQuery.message.chat.id):
|
| 206 |
+
sug = True
|
| 207 |
+
buttons = cleanmode_settings_markup(
|
| 208 |
+
_, status=cle, dels=sta, sug=sug
|
| 209 |
+
)
|
| 210 |
+
if command == "AQ":
|
| 211 |
+
try:
|
| 212 |
+
await CallbackQuery.answer(_["set_cb_1"], show_alert=True)
|
| 213 |
+
except:
|
| 214 |
+
pass
|
| 215 |
+
aud = await get_aud_bit_name(CallbackQuery.message.chat.id)
|
| 216 |
+
buttons = await gen_buttons_aud(_, aud)
|
| 217 |
+
if command == "VQ":
|
| 218 |
+
try:
|
| 219 |
+
await CallbackQuery.answer(_["set_cb_2"], show_alert=True)
|
| 220 |
+
except:
|
| 221 |
+
pass
|
| 222 |
+
aud = await get_vid_bit_name(CallbackQuery.message.chat.id)
|
| 223 |
+
buttons = await gen_buttons_vid(_, aud)
|
| 224 |
+
if command == "PM":
|
| 225 |
+
try:
|
| 226 |
+
await CallbackQuery.answer(_["set_cb_4"], show_alert=True)
|
| 227 |
+
except:
|
| 228 |
+
pass
|
| 229 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
| 230 |
+
if playmode == "Direct":
|
| 231 |
+
Direct = True
|
| 232 |
+
else:
|
| 233 |
+
Direct = None
|
| 234 |
+
is_non_admin = await is_nonadmin_chat(
|
| 235 |
+
CallbackQuery.message.chat.id
|
| 236 |
+
)
|
| 237 |
+
if not is_non_admin:
|
| 238 |
+
Group = True
|
| 239 |
+
else:
|
| 240 |
+
Group = None
|
| 241 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
| 242 |
+
if playty == "Everyone":
|
| 243 |
+
Playtype = None
|
| 244 |
+
else:
|
| 245 |
+
Playtype = True
|
| 246 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
| 247 |
+
if command == "AU":
|
| 248 |
+
try:
|
| 249 |
+
await CallbackQuery.answer(_["set_cb_3"], show_alert=True)
|
| 250 |
+
except:
|
| 251 |
+
pass
|
| 252 |
+
is_non_admin = await is_nonadmin_chat(
|
| 253 |
+
CallbackQuery.message.chat.id
|
| 254 |
+
)
|
| 255 |
+
if not is_non_admin:
|
| 256 |
+
buttons = auth_users_markup(_, True)
|
| 257 |
+
else:
|
| 258 |
+
buttons = auth_users_markup(_)
|
| 259 |
+
try:
|
| 260 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 261 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 262 |
+
)
|
| 263 |
+
except MessageNotModified:
|
| 264 |
+
return
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
# Audio Video Quality
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
@app.on_callback_query(
|
| 271 |
+
filters.regex(pattern=r"^(LQA|MQA|HQA|LQV|MQV|HQV)$")
|
| 272 |
+
& ~BANNED_USERS
|
| 273 |
+
)
|
| 274 |
+
@ActualAdminCB
|
| 275 |
+
async def aud_vid_cb(client, CallbackQuery, _):
|
| 276 |
+
command = CallbackQuery.matches[0].group(1)
|
| 277 |
+
try:
|
| 278 |
+
await CallbackQuery.answer(_["set_cb_6"], show_alert=True)
|
| 279 |
+
except:
|
| 280 |
+
pass
|
| 281 |
+
if command == "LQA":
|
| 282 |
+
await save_audio_bitrate(CallbackQuery.message.chat.id, "Low")
|
| 283 |
+
buttons = audio_quality_markup(_, low=True)
|
| 284 |
+
if command == "MQA":
|
| 285 |
+
await save_audio_bitrate(
|
| 286 |
+
CallbackQuery.message.chat.id, "Medium"
|
| 287 |
+
)
|
| 288 |
+
buttons = audio_quality_markup(_, medium=True)
|
| 289 |
+
if command == "HQA":
|
| 290 |
+
await save_audio_bitrate(
|
| 291 |
+
CallbackQuery.message.chat.id, "High"
|
| 292 |
+
)
|
| 293 |
+
buttons = audio_quality_markup(_, high=True)
|
| 294 |
+
if command == "LQV":
|
| 295 |
+
await save_video_bitrate(CallbackQuery.message.chat.id, "Low")
|
| 296 |
+
buttons = video_quality_markup(_, low=True)
|
| 297 |
+
if command == "MQV":
|
| 298 |
+
await save_video_bitrate(
|
| 299 |
+
CallbackQuery.message.chat.id, "Medium"
|
| 300 |
+
)
|
| 301 |
+
buttons = video_quality_markup(_, medium=True)
|
| 302 |
+
if command == "HQV":
|
| 303 |
+
await save_video_bitrate(
|
| 304 |
+
CallbackQuery.message.chat.id, "High"
|
| 305 |
+
)
|
| 306 |
+
buttons = video_quality_markup(_, high=True)
|
| 307 |
+
try:
|
| 308 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 309 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 310 |
+
)
|
| 311 |
+
except MessageNotModified:
|
| 312 |
+
return
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
# Play Mode Settings
|
| 316 |
+
@app.on_callback_query(
|
| 317 |
+
filters.regex(
|
| 318 |
+
pattern=r"^(|MODECHANGE|CHANNELMODECHANGE|PLAYTYPECHANGE)$"
|
| 319 |
+
)
|
| 320 |
+
& ~BANNED_USERS
|
| 321 |
+
)
|
| 322 |
+
@ActualAdminCB
|
| 323 |
+
async def playmode_ans(client, CallbackQuery, _):
|
| 324 |
+
command = CallbackQuery.matches[0].group(1)
|
| 325 |
+
if command == "CHANNELMODECHANGE":
|
| 326 |
+
is_non_admin = await is_nonadmin_chat(
|
| 327 |
+
CallbackQuery.message.chat.id
|
| 328 |
+
)
|
| 329 |
+
if not is_non_admin:
|
| 330 |
+
await add_nonadmin_chat(CallbackQuery.message.chat.id)
|
| 331 |
+
Group = None
|
| 332 |
+
else:
|
| 333 |
+
await remove_nonadmin_chat(CallbackQuery.message.chat.id)
|
| 334 |
+
Group = True
|
| 335 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
| 336 |
+
if playmode == "Direct":
|
| 337 |
+
Direct = True
|
| 338 |
+
else:
|
| 339 |
+
Direct = None
|
| 340 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
| 341 |
+
if playty == "Everyone":
|
| 342 |
+
Playtype = None
|
| 343 |
+
else:
|
| 344 |
+
Playtype = True
|
| 345 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
| 346 |
+
if command == "MODECHANGE":
|
| 347 |
+
try:
|
| 348 |
+
await CallbackQuery.answer(_["set_cb_6"], show_alert=True)
|
| 349 |
+
except:
|
| 350 |
+
pass
|
| 351 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
| 352 |
+
if playmode == "Direct":
|
| 353 |
+
await set_playmode(
|
| 354 |
+
CallbackQuery.message.chat.id, "Inline"
|
| 355 |
+
)
|
| 356 |
+
Direct = None
|
| 357 |
+
else:
|
| 358 |
+
await set_playmode(
|
| 359 |
+
CallbackQuery.message.chat.id, "Direct"
|
| 360 |
+
)
|
| 361 |
+
Direct = True
|
| 362 |
+
is_non_admin = await is_nonadmin_chat(
|
| 363 |
+
CallbackQuery.message.chat.id
|
| 364 |
+
)
|
| 365 |
+
if not is_non_admin:
|
| 366 |
+
Group = True
|
| 367 |
+
else:
|
| 368 |
+
Group = None
|
| 369 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
| 370 |
+
if playty == "Everyone":
|
| 371 |
+
Playtype = False
|
| 372 |
+
else:
|
| 373 |
+
Playtype = True
|
| 374 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
| 375 |
+
if command == "PLAYTYPECHANGE":
|
| 376 |
+
try:
|
| 377 |
+
await CallbackQuery.answer(_["set_cb_6"], show_alert=True)
|
| 378 |
+
except:
|
| 379 |
+
pass
|
| 380 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
| 381 |
+
if playty == "Everyone":
|
| 382 |
+
await set_playtype(CallbackQuery.message.chat.id, "Admin")
|
| 383 |
+
Playtype = False
|
| 384 |
+
else:
|
| 385 |
+
await set_playtype(
|
| 386 |
+
CallbackQuery.message.chat.id, "Everyone"
|
| 387 |
+
)
|
| 388 |
+
Playtype = True
|
| 389 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
| 390 |
+
if playmode == "Direct":
|
| 391 |
+
Direct = True
|
| 392 |
+
else:
|
| 393 |
+
Direct = None
|
| 394 |
+
is_non_admin = await is_nonadmin_chat(
|
| 395 |
+
CallbackQuery.message.chat.id
|
| 396 |
+
)
|
| 397 |
+
if not is_non_admin:
|
| 398 |
+
Group = True
|
| 399 |
+
else:
|
| 400 |
+
Group = None
|
| 401 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
| 402 |
+
try:
|
| 403 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 404 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 405 |
+
)
|
| 406 |
+
except MessageNotModified:
|
| 407 |
+
return
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
# Auth Users Settings
|
| 411 |
+
@app.on_callback_query(
|
| 412 |
+
filters.regex(pattern=r"^(AUTH|AUTHLIST)$") & ~BANNED_USERS
|
| 413 |
+
)
|
| 414 |
+
@ActualAdminCB
|
| 415 |
+
async def authusers_mar(client, CallbackQuery, _):
|
| 416 |
+
command = CallbackQuery.matches[0].group(1)
|
| 417 |
+
if command == "AUTHLIST":
|
| 418 |
+
_authusers = await get_authuser_names(
|
| 419 |
+
CallbackQuery.message.chat.id
|
| 420 |
+
)
|
| 421 |
+
if not _authusers:
|
| 422 |
+
try:
|
| 423 |
+
return await CallbackQuery.answer(
|
| 424 |
+
_["setting_5"], show_alert=True
|
| 425 |
+
)
|
| 426 |
+
except:
|
| 427 |
+
return
|
| 428 |
+
else:
|
| 429 |
+
try:
|
| 430 |
+
await CallbackQuery.answer(
|
| 431 |
+
_["set_cb_7"], show_alert=True
|
| 432 |
+
)
|
| 433 |
+
except:
|
| 434 |
+
pass
|
| 435 |
+
j = 0
|
| 436 |
+
await CallbackQuery.edit_message_text(_["auth_6"])
|
| 437 |
+
msg = _["auth_7"]
|
| 438 |
+
for note in _authusers:
|
| 439 |
+
_note = await get_authuser(
|
| 440 |
+
CallbackQuery.message.chat.id, note
|
| 441 |
+
)
|
| 442 |
+
user_id = _note["auth_user_id"]
|
| 443 |
+
admin_id = _note["admin_id"]
|
| 444 |
+
admin_name = _note["admin_name"]
|
| 445 |
+
try:
|
| 446 |
+
user = await client.get_users(user_id)
|
| 447 |
+
user = user.first_name
|
| 448 |
+
j += 1
|
| 449 |
+
except Exception:
|
| 450 |
+
continue
|
| 451 |
+
msg += f"{j}➤ {user}[`{user_id}`]\n"
|
| 452 |
+
msg += (
|
| 453 |
+
f" {_['auth_8']} {admin_name}[`{admin_id}`]\n\n"
|
| 454 |
+
)
|
| 455 |
+
upl = InlineKeyboardMarkup(
|
| 456 |
+
[
|
| 457 |
+
[
|
| 458 |
+
InlineKeyboardButton(
|
| 459 |
+
text=_["BACK_BUTTON"], callback_data=f"AU"
|
| 460 |
+
),
|
| 461 |
+
InlineKeyboardButton(
|
| 462 |
+
text=_["CLOSE_BUTTON"],
|
| 463 |
+
callback_data=f"close",
|
| 464 |
+
),
|
| 465 |
+
]
|
| 466 |
+
]
|
| 467 |
+
)
|
| 468 |
+
try:
|
| 469 |
+
return await CallbackQuery.edit_message_text(
|
| 470 |
+
msg, reply_markup=upl
|
| 471 |
+
)
|
| 472 |
+
except MessageNotModified:
|
| 473 |
+
return
|
| 474 |
+
try:
|
| 475 |
+
await CallbackQuery.answer(_["set_cb_6"], show_alert=True)
|
| 476 |
+
except:
|
| 477 |
+
pass
|
| 478 |
+
if command == "AUTH":
|
| 479 |
+
is_non_admin = await is_nonadmin_chat(
|
| 480 |
+
CallbackQuery.message.chat.id
|
| 481 |
+
)
|
| 482 |
+
if not is_non_admin:
|
| 483 |
+
await add_nonadmin_chat(CallbackQuery.message.chat.id)
|
| 484 |
+
buttons = auth_users_markup(_)
|
| 485 |
+
else:
|
| 486 |
+
await remove_nonadmin_chat(CallbackQuery.message.chat.id)
|
| 487 |
+
buttons = auth_users_markup(_, True)
|
| 488 |
+
try:
|
| 489 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 490 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 491 |
+
)
|
| 492 |
+
except MessageNotModified:
|
| 493 |
+
return
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
## Clean Mode
|
| 497 |
+
|
| 498 |
+
|
| 499 |
+
@app.on_callback_query(
|
| 500 |
+
filters.regex(
|
| 501 |
+
pattern=r"^(CLEANMODE|COMMANDELMODE|SUGGESTIONCHANGE)$"
|
| 502 |
+
)
|
| 503 |
+
& ~BANNED_USERS
|
| 504 |
+
)
|
| 505 |
+
@ActualAdminCB
|
| 506 |
+
async def cleanmode_mark(client, CallbackQuery, _):
|
| 507 |
+
command = CallbackQuery.matches[0].group(1)
|
| 508 |
+
try:
|
| 509 |
+
await CallbackQuery.answer(_["set_cb_6"], show_alert=True)
|
| 510 |
+
except:
|
| 511 |
+
pass
|
| 512 |
+
if command == "CLEANMODE":
|
| 513 |
+
sta = None
|
| 514 |
+
if await is_commanddelete_on(CallbackQuery.message.chat.id):
|
| 515 |
+
sta = True
|
| 516 |
+
sug = None
|
| 517 |
+
if await is_suggestion(CallbackQuery.message.chat.id):
|
| 518 |
+
sug = True
|
| 519 |
+
cle = None
|
| 520 |
+
if await is_cleanmode_on(CallbackQuery.message.chat.id):
|
| 521 |
+
await cleanmode_off(CallbackQuery.message.chat.id)
|
| 522 |
+
else:
|
| 523 |
+
await cleanmode_on(CallbackQuery.message.chat.id)
|
| 524 |
+
cle = True
|
| 525 |
+
buttons = cleanmode_settings_markup(
|
| 526 |
+
_, status=cle, dels=sta, sug=sug
|
| 527 |
+
)
|
| 528 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 529 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 530 |
+
)
|
| 531 |
+
if command == "COMMANDELMODE":
|
| 532 |
+
cle = None
|
| 533 |
+
sta = None
|
| 534 |
+
if await is_cleanmode_on(CallbackQuery.message.chat.id):
|
| 535 |
+
cle = True
|
| 536 |
+
sug = None
|
| 537 |
+
if await is_suggestion(CallbackQuery.message.chat.id):
|
| 538 |
+
sug = True
|
| 539 |
+
if await is_commanddelete_on(CallbackQuery.message.chat.id):
|
| 540 |
+
await commanddelete_off(CallbackQuery.message.chat.id)
|
| 541 |
+
else:
|
| 542 |
+
await commanddelete_on(CallbackQuery.message.chat.id)
|
| 543 |
+
sta = True
|
| 544 |
+
buttons = cleanmode_settings_markup(
|
| 545 |
+
_, status=cle, dels=sta, sug=sug
|
| 546 |
+
)
|
| 547 |
+
if command == "SUGGESTIONCHANGE":
|
| 548 |
+
cle = None
|
| 549 |
+
sta = None
|
| 550 |
+
if await is_cleanmode_on(CallbackQuery.message.chat.id):
|
| 551 |
+
cle = True
|
| 552 |
+
if await is_commanddelete_on(CallbackQuery.message.chat.id):
|
| 553 |
+
sta = True
|
| 554 |
+
if await is_suggestion(CallbackQuery.message.chat.id):
|
| 555 |
+
await suggestion_off(CallbackQuery.message.chat.id)
|
| 556 |
+
sug = False
|
| 557 |
+
else:
|
| 558 |
+
await suggestion_on(CallbackQuery.message.chat.id)
|
| 559 |
+
sug = True
|
| 560 |
+
buttons = cleanmode_settings_markup(
|
| 561 |
+
_, status=cle, dels=sta, sug=sug
|
| 562 |
+
)
|
| 563 |
+
try:
|
| 564 |
+
return await CallbackQuery.edit_message_reply_markup(
|
| 565 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 566 |
+
)
|
| 567 |
+
except MessageNotModified:
|
| 568 |
+
return
|
YukkiMusic/plugins/bot/start.py
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
|
| 12 |
+
from pyrogram import filters
|
| 13 |
+
from pyrogram.types import (InlineKeyboardButton,
|
| 14 |
+
InlineKeyboardMarkup, Message)
|
| 15 |
+
from youtubesearchpython.__future__ import VideosSearch
|
| 16 |
+
|
| 17 |
+
import config
|
| 18 |
+
from config import BANNED_USERS
|
| 19 |
+
from config.config import OWNER_ID
|
| 20 |
+
from strings import get_command, get_string
|
| 21 |
+
from YukkiMusic import Telegram, YouTube, app
|
| 22 |
+
from YukkiMusic.misc import SUDOERS
|
| 23 |
+
from YukkiMusic.plugins.play.playlist import del_plist_msg
|
| 24 |
+
from YukkiMusic.plugins.sudo.sudoers import sudoers_list
|
| 25 |
+
from YukkiMusic.utils.database import (add_served_chat,
|
| 26 |
+
add_served_user,
|
| 27 |
+
blacklisted_chats,
|
| 28 |
+
get_assistant, get_lang,
|
| 29 |
+
get_userss, is_on_off,
|
| 30 |
+
is_served_private_chat)
|
| 31 |
+
from YukkiMusic.utils.decorators.language import LanguageStart
|
| 32 |
+
from YukkiMusic.utils.inline import (help_pannel, private_panel,
|
| 33 |
+
start_pannel)
|
| 34 |
+
|
| 35 |
+
loop = asyncio.get_running_loop()
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
@app.on_message(
|
| 39 |
+
filters.command(get_command("START_COMMAND"))
|
| 40 |
+
& filters.private
|
| 41 |
+
& ~BANNED_USERS
|
| 42 |
+
)
|
| 43 |
+
@LanguageStart
|
| 44 |
+
async def start_comm(client, message: Message, _):
|
| 45 |
+
await add_served_user(message.from_user.id)
|
| 46 |
+
if len(message.text.split()) > 1:
|
| 47 |
+
name = message.text.split(None, 1)[1]
|
| 48 |
+
if name[0:4] == "help":
|
| 49 |
+
keyboard = help_pannel(_)
|
| 50 |
+
return await message.reply_text(
|
| 51 |
+
_["help_1"], reply_markup=keyboard
|
| 52 |
+
)
|
| 53 |
+
if name[0:4] == "song":
|
| 54 |
+
return await message.reply_text(_["song_2"])
|
| 55 |
+
if name[0:3] == "sta":
|
| 56 |
+
m = await message.reply_text(
|
| 57 |
+
"🔎 Fetching your personal stats.!"
|
| 58 |
+
)
|
| 59 |
+
stats = await get_userss(message.from_user.id)
|
| 60 |
+
tot = len(stats)
|
| 61 |
+
if not stats:
|
| 62 |
+
await asyncio.sleep(1)
|
| 63 |
+
return await m.edit(_["ustats_1"])
|
| 64 |
+
|
| 65 |
+
def get_stats():
|
| 66 |
+
msg = ""
|
| 67 |
+
limit = 0
|
| 68 |
+
results = {}
|
| 69 |
+
for i in stats:
|
| 70 |
+
top_list = stats[i]["spot"]
|
| 71 |
+
results[str(i)] = top_list
|
| 72 |
+
list_arranged = dict(
|
| 73 |
+
sorted(
|
| 74 |
+
results.items(),
|
| 75 |
+
key=lambda item: item[1],
|
| 76 |
+
reverse=True,
|
| 77 |
+
)
|
| 78 |
+
)
|
| 79 |
+
if not results:
|
| 80 |
+
return m.edit(_["ustats_1"])
|
| 81 |
+
tota = 0
|
| 82 |
+
videoid = None
|
| 83 |
+
for vidid, count in list_arranged.items():
|
| 84 |
+
tota += count
|
| 85 |
+
if limit == 10:
|
| 86 |
+
continue
|
| 87 |
+
if limit == 0:
|
| 88 |
+
videoid = vidid
|
| 89 |
+
limit += 1
|
| 90 |
+
details = stats.get(vidid)
|
| 91 |
+
title = (details["title"][:35]).title()
|
| 92 |
+
if vidid == "telegram":
|
| 93 |
+
msg += f"🔗[Telegram Files and Audios](https://t.me/telegram) ** played {count} times**\n\n"
|
| 94 |
+
else:
|
| 95 |
+
msg += f"🔗 [{title}](https://www.youtube.com/watch?v={vidid}) ** played {count} times**\n\n"
|
| 96 |
+
msg = _["ustats_2"].format(tot, tota, limit) + msg
|
| 97 |
+
return videoid, msg
|
| 98 |
+
|
| 99 |
+
try:
|
| 100 |
+
videoid, msg = await loop.run_in_executor(
|
| 101 |
+
None, get_stats
|
| 102 |
+
)
|
| 103 |
+
except Exception as e:
|
| 104 |
+
print(e)
|
| 105 |
+
return
|
| 106 |
+
thumbnail = await YouTube.thumbnail(videoid, True)
|
| 107 |
+
await m.delete()
|
| 108 |
+
await message.reply_photo(photo=thumbnail, caption=msg)
|
| 109 |
+
return
|
| 110 |
+
if name[0:3] == "sud":
|
| 111 |
+
await sudoers_list(client=client, message=message, _=_)
|
| 112 |
+
if await is_on_off(config.LOG):
|
| 113 |
+
sender_id = message.from_user.id
|
| 114 |
+
sender_name = message.from_user.first_name
|
| 115 |
+
return await app.send_message(
|
| 116 |
+
config.LOG_GROUP_ID,
|
| 117 |
+
f"{message.from_user.mention} has just started bot to check <code>SUDOLIST</code>\n\n**USER ID:** {sender_id}\n**USER NAME:** {sender_name}",
|
| 118 |
+
)
|
| 119 |
+
return
|
| 120 |
+
if name[0:3] == "lyr":
|
| 121 |
+
query = (str(name)).replace("lyrics_", "", 1)
|
| 122 |
+
lyrical = config.lyrical
|
| 123 |
+
lyrics = lyrical.get(query)
|
| 124 |
+
if lyrics:
|
| 125 |
+
return await Telegram.send_split_text(message, lyrics)
|
| 126 |
+
else:
|
| 127 |
+
return await message.reply_text(
|
| 128 |
+
"Failed to get lyrics."
|
| 129 |
+
)
|
| 130 |
+
if name[0:3] == "del":
|
| 131 |
+
await del_plist_msg(client=client, message=message, _=_)
|
| 132 |
+
if name[0:3] == "inf":
|
| 133 |
+
m = await message.reply_text("🔎 Fetching Info!")
|
| 134 |
+
query = (str(name)).replace("info_", "", 1)
|
| 135 |
+
query = f"https://www.youtube.com/watch?v={query}"
|
| 136 |
+
results = VideosSearch(query, limit=1)
|
| 137 |
+
for result in (await results.next())["result"]:
|
| 138 |
+
title = result["title"]
|
| 139 |
+
duration = result["duration"]
|
| 140 |
+
views = result["viewCount"]["short"]
|
| 141 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[
|
| 142 |
+
0
|
| 143 |
+
]
|
| 144 |
+
channellink = result["channel"]["link"]
|
| 145 |
+
channel = result["channel"]["name"]
|
| 146 |
+
link = result["link"]
|
| 147 |
+
published = result["publishedTime"]
|
| 148 |
+
searched_text = f"""
|
| 149 |
+
🔍__**Video Track Information**__
|
| 150 |
+
|
| 151 |
+
❇️**Title:** {title}
|
| 152 |
+
|
| 153 |
+
⏳**Duration:** {duration} Mins
|
| 154 |
+
👀**Views:** `{views}`
|
| 155 |
+
⏰**Published Time:** {published}
|
| 156 |
+
🎥**Channel Name:** {channel}
|
| 157 |
+
📎**Channel Link:** [Visit From Here]({channellink})
|
| 158 |
+
🔗**Video Link:** [Link]({link})
|
| 159 |
+
|
| 160 |
+
⚡️ __Searched Powered By {config.MUSIC_BOT_NAME}__"""
|
| 161 |
+
key = InlineKeyboardMarkup(
|
| 162 |
+
[
|
| 163 |
+
[
|
| 164 |
+
InlineKeyboardButton(
|
| 165 |
+
text="🎥 Watch ", url=f"{link}"
|
| 166 |
+
),
|
| 167 |
+
InlineKeyboardButton(
|
| 168 |
+
text="🔄 Close", callback_data="close"
|
| 169 |
+
),
|
| 170 |
+
],
|
| 171 |
+
]
|
| 172 |
+
)
|
| 173 |
+
await m.delete()
|
| 174 |
+
await app.send_photo(
|
| 175 |
+
message.chat.id,
|
| 176 |
+
photo=thumbnail,
|
| 177 |
+
caption=searched_text,
|
| 178 |
+
reply_markup=key,
|
| 179 |
+
)
|
| 180 |
+
if await is_on_off(config.LOG):
|
| 181 |
+
sender_id = message.from_user.id
|
| 182 |
+
sender_name = message.from_user.first_name
|
| 183 |
+
return await app.send_message(
|
| 184 |
+
config.LOG_GROUP_ID,
|
| 185 |
+
f"{message.from_user.mention} has just started bot to check <code>VIDEO INFORMATION</code>\n\n**USER ID:** {sender_id}\n**USER NAME:** {sender_name}",
|
| 186 |
+
)
|
| 187 |
+
else:
|
| 188 |
+
try:
|
| 189 |
+
await app.resolve_peer(OWNER_ID[0])
|
| 190 |
+
OWNER = OWNER_ID[0]
|
| 191 |
+
except:
|
| 192 |
+
OWNER = None
|
| 193 |
+
out = private_panel(_, app.username, OWNER)
|
| 194 |
+
if config.START_IMG_URL:
|
| 195 |
+
try:
|
| 196 |
+
await message.reply_photo(
|
| 197 |
+
photo=config.START_IMG_URL,
|
| 198 |
+
caption=_["start_2"].format(
|
| 199 |
+
config.MUSIC_BOT_NAME
|
| 200 |
+
),
|
| 201 |
+
reply_markup=InlineKeyboardMarkup(out),
|
| 202 |
+
)
|
| 203 |
+
except:
|
| 204 |
+
await message.reply_text(
|
| 205 |
+
_["start_2"].format(config.MUSIC_BOT_NAME),
|
| 206 |
+
reply_markup=InlineKeyboardMarkup(out),
|
| 207 |
+
)
|
| 208 |
+
else:
|
| 209 |
+
await message.reply_text(
|
| 210 |
+
_["start_2"].format(config.MUSIC_BOT_NAME),
|
| 211 |
+
reply_markup=InlineKeyboardMarkup(out),
|
| 212 |
+
)
|
| 213 |
+
if await is_on_off(config.LOG):
|
| 214 |
+
sender_id = message.from_user.id
|
| 215 |
+
sender_name = message.from_user.first_name
|
| 216 |
+
return await app.send_message(
|
| 217 |
+
config.LOG_GROUP_ID,
|
| 218 |
+
f"{message.from_user.mention} has just started Bot.\n\n**USER ID:** {sender_id}\n**USER NAME:** {sender_name}",
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
@app.on_message(
|
| 223 |
+
filters.command(get_command("START_COMMAND"))
|
| 224 |
+
& filters.group
|
| 225 |
+
& ~BANNED_USERS
|
| 226 |
+
)
|
| 227 |
+
@LanguageStart
|
| 228 |
+
async def testbot(client, message: Message, _):
|
| 229 |
+
out = start_pannel(_)
|
| 230 |
+
return await message.reply_text(
|
| 231 |
+
_["start_1"].format(
|
| 232 |
+
message.chat.title, config.MUSIC_BOT_NAME
|
| 233 |
+
),
|
| 234 |
+
reply_markup=InlineKeyboardMarkup(out),
|
| 235 |
+
)
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
welcome_group = 2
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
@app.on_message(filters.new_chat_members, group=welcome_group)
|
| 242 |
+
async def welcome(client, message: Message):
|
| 243 |
+
chat_id = message.chat.id
|
| 244 |
+
|
| 245 |
+
if config.PRIVATE_BOT_MODE == str(True):
|
| 246 |
+
if not await is_served_private_chat(message.chat.id):
|
| 247 |
+
await message.reply_text(
|
| 248 |
+
"**Private Music Bot**\n\nOnly for authorized chats from the owner. Ask my owner to allow your chat first."
|
| 249 |
+
)
|
| 250 |
+
return await app.leave_chat(message.chat.id)
|
| 251 |
+
else:
|
| 252 |
+
await add_served_chat(chat_id)
|
| 253 |
+
for member in message.new_chat_members:
|
| 254 |
+
try:
|
| 255 |
+
language = await get_lang(message.chat.id)
|
| 256 |
+
_ = get_string(language)
|
| 257 |
+
if member.id == app.id:
|
| 258 |
+
chat_type = message.chat.type
|
| 259 |
+
|
| 260 |
+
if chat_type != "SUPERGROUP":
|
| 261 |
+
await message.reply_text(_["start_6"])
|
| 262 |
+
return await app.leave_chat(message.chat.id)
|
| 263 |
+
if chat_id in await blacklisted_chats():
|
| 264 |
+
await message.reply_text(
|
| 265 |
+
_["start_7"].format(
|
| 266 |
+
f"https://t.me/{app.username}?start=sudolist"
|
| 267 |
+
)
|
| 268 |
+
)
|
| 269 |
+
return await app.leave_chat(chat_id)
|
| 270 |
+
userbot = await get_assistant(message.chat.id)
|
| 271 |
+
out = start_pannel(_)
|
| 272 |
+
await message.reply_text(
|
| 273 |
+
_["start_3"].format(
|
| 274 |
+
config.MUSIC_BOT_NAME,
|
| 275 |
+
userbot.username,
|
| 276 |
+
userbot.id,
|
| 277 |
+
),
|
| 278 |
+
reply_markup=InlineKeyboardMarkup(out),
|
| 279 |
+
)
|
| 280 |
+
if member.id in config.OWNER_ID:
|
| 281 |
+
return await message.reply_text(
|
| 282 |
+
_["start_4"].format(
|
| 283 |
+
config.MUSIC_BOT_NAME, member.mention
|
| 284 |
+
)
|
| 285 |
+
)
|
| 286 |
+
if member.id in SUDOERS:
|
| 287 |
+
return await message.reply_text(
|
| 288 |
+
_["start_5"].format(
|
| 289 |
+
config.MUSIC_BOT_NAME, member.mention
|
| 290 |
+
)
|
| 291 |
+
)
|
| 292 |
+
return
|
| 293 |
+
except:
|
| 294 |
+
return
|
YukkiMusic/plugins/devs/dev.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
#
|
| 10 |
+
# This aeval and sh module is taken from < https://github.com/TheHamkerCat/WilliamButcherBot >
|
| 11 |
+
# Credit goes to TheHamkerCat.
|
| 12 |
+
#
|
| 13 |
+
|
| 14 |
+
import os
|
| 15 |
+
import re
|
| 16 |
+
import subprocess
|
| 17 |
+
import sys
|
| 18 |
+
import traceback
|
| 19 |
+
from inspect import getfullargspec
|
| 20 |
+
from io import StringIO
|
| 21 |
+
from time import time
|
| 22 |
+
|
| 23 |
+
from pyrogram import filters
|
| 24 |
+
from pyrogram.types import (InlineKeyboardButton,
|
| 25 |
+
InlineKeyboardMarkup, Message)
|
| 26 |
+
|
| 27 |
+
from YukkiMusic import app
|
| 28 |
+
from YukkiMusic.misc import SUDOERS
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
async def aexec(code, client, message):
|
| 32 |
+
exec(
|
| 33 |
+
"async def __aexec(client, message): "
|
| 34 |
+
+ "".join(f"\n {a}" for a in code.split("\n"))
|
| 35 |
+
)
|
| 36 |
+
return await locals()["__aexec"](client, message)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
async def edit_or_reply(msg: Message, **kwargs):
|
| 40 |
+
func = msg.edit_text if msg.from_user.is_self else msg.reply
|
| 41 |
+
spec = getfullargspec(func.__wrapped__).args
|
| 42 |
+
await func(**{k: v for k, v in kwargs.items() if k in spec})
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
@app.on_message(
|
| 46 |
+
filters.command("eval")
|
| 47 |
+
& SUDOERS
|
| 48 |
+
& ~filters.forwarded
|
| 49 |
+
& ~filters.via_bot
|
| 50 |
+
)
|
| 51 |
+
async def executor(client, message):
|
| 52 |
+
if len(message.command) < 2:
|
| 53 |
+
return await edit_or_reply(
|
| 54 |
+
message, text="__Nigga Give me some command to execute.__"
|
| 55 |
+
)
|
| 56 |
+
try:
|
| 57 |
+
cmd = message.text.split(" ", maxsplit=1)[1]
|
| 58 |
+
except IndexError:
|
| 59 |
+
return await message.delete()
|
| 60 |
+
t1 = time()
|
| 61 |
+
old_stderr = sys.stderr
|
| 62 |
+
old_stdout = sys.stdout
|
| 63 |
+
redirected_output = sys.stdout = StringIO()
|
| 64 |
+
redirected_error = sys.stderr = StringIO()
|
| 65 |
+
stdout, stderr, exc = None, None, None
|
| 66 |
+
try:
|
| 67 |
+
await aexec(cmd, client, message)
|
| 68 |
+
except Exception:
|
| 69 |
+
exc = traceback.format_exc()
|
| 70 |
+
stdout = redirected_output.getvalue()
|
| 71 |
+
stderr = redirected_error.getvalue()
|
| 72 |
+
sys.stdout = old_stdout
|
| 73 |
+
sys.stderr = old_stderr
|
| 74 |
+
evaluation = ""
|
| 75 |
+
if exc:
|
| 76 |
+
evaluation = exc
|
| 77 |
+
elif stderr:
|
| 78 |
+
evaluation = stderr
|
| 79 |
+
elif stdout:
|
| 80 |
+
evaluation = stdout
|
| 81 |
+
else:
|
| 82 |
+
evaluation = "Success"
|
| 83 |
+
final_output = f"**OUTPUT**:\n```{evaluation.strip()}```"
|
| 84 |
+
if len(final_output) > 4096:
|
| 85 |
+
filename = "output.txt"
|
| 86 |
+
with open(filename, "w+", encoding="utf8") as out_file:
|
| 87 |
+
out_file.write(str(evaluation.strip()))
|
| 88 |
+
t2 = time()
|
| 89 |
+
keyboard = InlineKeyboardMarkup(
|
| 90 |
+
[
|
| 91 |
+
[
|
| 92 |
+
InlineKeyboardButton(
|
| 93 |
+
text="⏳",
|
| 94 |
+
callback_data=f"runtime {t2-t1} Seconds",
|
| 95 |
+
)
|
| 96 |
+
]
|
| 97 |
+
]
|
| 98 |
+
)
|
| 99 |
+
await message.reply_document(
|
| 100 |
+
document=filename,
|
| 101 |
+
caption=f"**INPUT:**\n`{cmd[0:980]}`\n\n**OUTPUT:**\n`Attached Document`",
|
| 102 |
+
quote=False,
|
| 103 |
+
reply_markup=keyboard,
|
| 104 |
+
)
|
| 105 |
+
await message.delete()
|
| 106 |
+
os.remove(filename)
|
| 107 |
+
else:
|
| 108 |
+
t2 = time()
|
| 109 |
+
keyboard = InlineKeyboardMarkup(
|
| 110 |
+
[
|
| 111 |
+
[
|
| 112 |
+
InlineKeyboardButton(
|
| 113 |
+
text="⏳",
|
| 114 |
+
callback_data=f"runtime {round(t2-t1, 3)} Seconds",
|
| 115 |
+
),
|
| 116 |
+
InlineKeyboardButton(
|
| 117 |
+
text="🗑",
|
| 118 |
+
callback_data=f"forceclose abc|{message.from_user.id}",
|
| 119 |
+
),
|
| 120 |
+
]
|
| 121 |
+
]
|
| 122 |
+
)
|
| 123 |
+
await edit_or_reply(
|
| 124 |
+
message, text=final_output, reply_markup=keyboard
|
| 125 |
+
)
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
@app.on_callback_query(filters.regex(r"runtime"))
|
| 129 |
+
async def runtime_func_cq(_, cq):
|
| 130 |
+
runtime = cq.data.split(None, 1)[1]
|
| 131 |
+
await cq.answer(runtime, show_alert=True)
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
@app.on_callback_query(filters.regex("forceclose"))
|
| 135 |
+
async def forceclose_command(_, CallbackQuery):
|
| 136 |
+
callback_data = CallbackQuery.data.strip()
|
| 137 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 138 |
+
query, user_id = callback_request.split("|")
|
| 139 |
+
if CallbackQuery.from_user.id != int(user_id):
|
| 140 |
+
try:
|
| 141 |
+
return await CallbackQuery.answer(
|
| 142 |
+
"You're not allowed to close this.", show_alert=True
|
| 143 |
+
)
|
| 144 |
+
except:
|
| 145 |
+
return
|
| 146 |
+
await CallbackQuery.message.delete()
|
| 147 |
+
try:
|
| 148 |
+
await CallbackQuery.answer()
|
| 149 |
+
except:
|
| 150 |
+
return
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
@app.on_message(
|
| 154 |
+
filters.command("sh")
|
| 155 |
+
& SUDOERS
|
| 156 |
+
& ~filters.forwarded
|
| 157 |
+
& ~filters.via_bot
|
| 158 |
+
)
|
| 159 |
+
async def shellrunner(client, message):
|
| 160 |
+
if len(message.command) < 2:
|
| 161 |
+
return await edit_or_reply(
|
| 162 |
+
message, text="**Usage:**\n/sh git pull"
|
| 163 |
+
)
|
| 164 |
+
text = message.text.split(None, 1)[1]
|
| 165 |
+
if "\n" in text:
|
| 166 |
+
code = text.split("\n")
|
| 167 |
+
output = ""
|
| 168 |
+
for x in code:
|
| 169 |
+
shell = re.split(
|
| 170 |
+
""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
|
| 171 |
+
)
|
| 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 |
+
await edit_or_reply(
|
| 181 |
+
message, text=f"**ERROR:**\n```{err}```"
|
| 182 |
+
)
|
| 183 |
+
output += f"**{code}**\n"
|
| 184 |
+
output += process.stdout.read()[:-1].decode("utf-8")
|
| 185 |
+
output += "\n"
|
| 186 |
+
else:
|
| 187 |
+
shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
|
| 188 |
+
for a in range(len(shell)):
|
| 189 |
+
shell[a] = shell[a].replace('"', "")
|
| 190 |
+
try:
|
| 191 |
+
process = subprocess.Popen(
|
| 192 |
+
shell,
|
| 193 |
+
stdout=subprocess.PIPE,
|
| 194 |
+
stderr=subprocess.PIPE,
|
| 195 |
+
)
|
| 196 |
+
except Exception as err:
|
| 197 |
+
print(err)
|
| 198 |
+
exc_type, exc_obj, exc_tb = sys.exc_info()
|
| 199 |
+
errors = traceback.format_exception(
|
| 200 |
+
etype=exc_type,
|
| 201 |
+
value=exc_obj,
|
| 202 |
+
tb=exc_tb,
|
| 203 |
+
)
|
| 204 |
+
return await edit_or_reply(
|
| 205 |
+
message, text=f"**ERROR:**\n```{''.join(errors)}```"
|
| 206 |
+
)
|
| 207 |
+
output = process.stdout.read()[:-1].decode("utf-8")
|
| 208 |
+
if str(output) == "\n":
|
| 209 |
+
output = None
|
| 210 |
+
if output:
|
| 211 |
+
if len(output) > 4096:
|
| 212 |
+
with open("output.txt", "w+") as file:
|
| 213 |
+
file.write(output)
|
| 214 |
+
await client.send_document(
|
| 215 |
+
message.chat.id,
|
| 216 |
+
"output.txt",
|
| 217 |
+
reply_to_message_id=message.message_id,
|
| 218 |
+
caption="`Output`",
|
| 219 |
+
)
|
| 220 |
+
return os.remove("output.txt")
|
| 221 |
+
await edit_or_reply(
|
| 222 |
+
message, text=f"**OUTPUT:**\n```{output}```"
|
| 223 |
+
)
|
| 224 |
+
else:
|
| 225 |
+
await edit_or_reply(message, text="**OUTPUT: **\n`No output`")
|
YukkiMusic/plugins/misc/autoleave.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
from datetime import datetime
|
| 12 |
+
|
| 13 |
+
import config
|
| 14 |
+
from YukkiMusic import app
|
| 15 |
+
from YukkiMusic.core.call import Yukki, autoend
|
| 16 |
+
from YukkiMusic.utils.database import (get_client, is_active_chat,
|
| 17 |
+
is_autoend)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
async def auto_leave():
|
| 21 |
+
if config.AUTO_LEAVING_ASSISTANT == str(True):
|
| 22 |
+
while not await asyncio.sleep(
|
| 23 |
+
config.AUTO_LEAVE_ASSISTANT_TIME
|
| 24 |
+
):
|
| 25 |
+
from YukkiMusic.core.userbot import assistants
|
| 26 |
+
|
| 27 |
+
for num in assistants:
|
| 28 |
+
client = await get_client(num)
|
| 29 |
+
left = 0
|
| 30 |
+
try:
|
| 31 |
+
async for i in client.iter_dialogs():
|
| 32 |
+
chat_type = i.chat.type
|
| 33 |
+
if chat_type in [
|
| 34 |
+
"supergroup",
|
| 35 |
+
"group",
|
| 36 |
+
"channel",
|
| 37 |
+
]:
|
| 38 |
+
chat_id = i.chat.id
|
| 39 |
+
if (
|
| 40 |
+
chat_id != config.LOG_GROUP_ID
|
| 41 |
+
and chat_id != -1001190342892
|
| 42 |
+
and chat_id != -1001733534088
|
| 43 |
+
and chat_id != -1001443281821
|
| 44 |
+
):
|
| 45 |
+
if left == 20:
|
| 46 |
+
continue
|
| 47 |
+
if not await is_active_chat(chat_id):
|
| 48 |
+
try:
|
| 49 |
+
await client.leave_chat(
|
| 50 |
+
chat_id
|
| 51 |
+
)
|
| 52 |
+
left += 1
|
| 53 |
+
except:
|
| 54 |
+
continue
|
| 55 |
+
except:
|
| 56 |
+
pass
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
asyncio.create_task(auto_leave())
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
async def auto_end():
|
| 63 |
+
while not await asyncio.sleep(5):
|
| 64 |
+
if not await is_autoend():
|
| 65 |
+
continue
|
| 66 |
+
for chat_id in autoend:
|
| 67 |
+
timer = autoend.get(chat_id)
|
| 68 |
+
if not timer:
|
| 69 |
+
continue
|
| 70 |
+
if datetime.now() > timer:
|
| 71 |
+
if not await is_active_chat(chat_id):
|
| 72 |
+
autoend[chat_id] = {}
|
| 73 |
+
continue
|
| 74 |
+
autoend[chat_id] = {}
|
| 75 |
+
try:
|
| 76 |
+
await Yukki.stop_stream(chat_id)
|
| 77 |
+
except:
|
| 78 |
+
continue
|
| 79 |
+
try:
|
| 80 |
+
await app.send_message(
|
| 81 |
+
chat_id,
|
| 82 |
+
"Bot has left voice chat due to inactivity to avoid overload on servers. No-one was listening to the bot on voice chat.",
|
| 83 |
+
)
|
| 84 |
+
except:
|
| 85 |
+
continue
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
asyncio.create_task(auto_end())
|
YukkiMusic/plugins/misc/cleanmode.py
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
from datetime import datetime, timedelta
|
| 12 |
+
|
| 13 |
+
from pyrogram import filters
|
| 14 |
+
from pyrogram.errors import FloodWait
|
| 15 |
+
from pyrogram.raw import types
|
| 16 |
+
|
| 17 |
+
import config
|
| 18 |
+
from config import adminlist, chatstats, clean, userstats
|
| 19 |
+
from strings import get_command
|
| 20 |
+
from YukkiMusic import app, userbot
|
| 21 |
+
from YukkiMusic.misc import SUDOERS
|
| 22 |
+
from YukkiMusic.utils.database import (get_active_chats,
|
| 23 |
+
get_authuser_names, get_client,
|
| 24 |
+
get_particular_top,
|
| 25 |
+
get_served_chats,
|
| 26 |
+
get_served_users, get_user_top,
|
| 27 |
+
is_cleanmode_on, set_queries,
|
| 28 |
+
update_particular_top,
|
| 29 |
+
update_user_top)
|
| 30 |
+
from YukkiMusic.utils.decorators.language import language
|
| 31 |
+
from YukkiMusic.utils.formatters import alpha_to_int
|
| 32 |
+
|
| 33 |
+
BROADCAST_COMMAND = get_command("BROADCAST_COMMAND")
|
| 34 |
+
AUTO_DELETE = config.CLEANMODE_DELETE_MINS
|
| 35 |
+
AUTO_SLEEP = 5
|
| 36 |
+
IS_BROADCASTING = False
|
| 37 |
+
cleanmode_group = 15
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
@app.on_raw_update(group=cleanmode_group)
|
| 41 |
+
async def clean_mode(client, update, users, chats):
|
| 42 |
+
global IS_BROADCASTING
|
| 43 |
+
if IS_BROADCASTING:
|
| 44 |
+
return
|
| 45 |
+
try:
|
| 46 |
+
if not isinstance(update, types.UpdateReadChannelOutbox):
|
| 47 |
+
return
|
| 48 |
+
except:
|
| 49 |
+
return
|
| 50 |
+
if users:
|
| 51 |
+
return
|
| 52 |
+
if chats:
|
| 53 |
+
return
|
| 54 |
+
message_id = update.max_id
|
| 55 |
+
chat_id = int(f"-100{update.channel_id}")
|
| 56 |
+
if not await is_cleanmode_on(chat_id):
|
| 57 |
+
return
|
| 58 |
+
if chat_id not in clean:
|
| 59 |
+
clean[chat_id] = []
|
| 60 |
+
time_now = datetime.now()
|
| 61 |
+
put = {
|
| 62 |
+
"msg_id": message_id,
|
| 63 |
+
"timer_after": time_now + timedelta(minutes=AUTO_DELETE),
|
| 64 |
+
}
|
| 65 |
+
clean[chat_id].append(put)
|
| 66 |
+
await set_queries(1)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
@app.on_message(filters.command(BROADCAST_COMMAND) & SUDOERS)
|
| 70 |
+
@language
|
| 71 |
+
async def braodcast_message(client, message, _):
|
| 72 |
+
global IS_BROADCASTING
|
| 73 |
+
if message.reply_to_message:
|
| 74 |
+
x = message.reply_to_message.message_id
|
| 75 |
+
y = message.chat.id
|
| 76 |
+
else:
|
| 77 |
+
if len(message.command) < 2:
|
| 78 |
+
return await message.reply_text(_["broad_5"])
|
| 79 |
+
query = message.text.split(None, 1)[1]
|
| 80 |
+
if "-pin" in query:
|
| 81 |
+
query = query.replace("-pin", "")
|
| 82 |
+
if "-nobot" in query:
|
| 83 |
+
query = query.replace("-nobot", "")
|
| 84 |
+
if "-pinloud" in query:
|
| 85 |
+
query = query.replace("-pinloud", "")
|
| 86 |
+
if "-assistant" in query:
|
| 87 |
+
query = query.replace("-assistant", "")
|
| 88 |
+
if "-user" in query:
|
| 89 |
+
query = query.replace("-user", "")
|
| 90 |
+
if query == "":
|
| 91 |
+
return await message.reply_text(_["broad_6"])
|
| 92 |
+
|
| 93 |
+
IS_BROADCASTING = True
|
| 94 |
+
|
| 95 |
+
# Bot broadcast inside chats
|
| 96 |
+
if "-nobot" not in message.text:
|
| 97 |
+
sent = 0
|
| 98 |
+
pin = 0
|
| 99 |
+
chats = []
|
| 100 |
+
schats = await get_served_chats()
|
| 101 |
+
for chat in schats:
|
| 102 |
+
chats.append(int(chat["chat_id"]))
|
| 103 |
+
for i in chats:
|
| 104 |
+
if i == -1001733534088:
|
| 105 |
+
continue
|
| 106 |
+
try:
|
| 107 |
+
m = (
|
| 108 |
+
await app.forward_messages(i, y, x)
|
| 109 |
+
if message.reply_to_message
|
| 110 |
+
else await app.send_message(i, text=query)
|
| 111 |
+
)
|
| 112 |
+
if "-pin" in message.text:
|
| 113 |
+
try:
|
| 114 |
+
await m.pin(disable_notification=True)
|
| 115 |
+
pin += 1
|
| 116 |
+
except Exception:
|
| 117 |
+
continue
|
| 118 |
+
elif "-pinloud" in message.text:
|
| 119 |
+
try:
|
| 120 |
+
await m.pin(disable_notification=False)
|
| 121 |
+
pin += 1
|
| 122 |
+
except Exception:
|
| 123 |
+
continue
|
| 124 |
+
sent += 1
|
| 125 |
+
except FloodWait as e:
|
| 126 |
+
flood_time = int(e.x)
|
| 127 |
+
if flood_time > 200:
|
| 128 |
+
continue
|
| 129 |
+
await asyncio.sleep(flood_time)
|
| 130 |
+
except Exception:
|
| 131 |
+
continue
|
| 132 |
+
try:
|
| 133 |
+
await message.reply_text(_["broad_1"].format(sent, pin))
|
| 134 |
+
except:
|
| 135 |
+
pass
|
| 136 |
+
|
| 137 |
+
# Bot broadcasting to users
|
| 138 |
+
if "-user" in message.text:
|
| 139 |
+
susr = 0
|
| 140 |
+
served_users = []
|
| 141 |
+
susers = await get_served_users()
|
| 142 |
+
for user in susers:
|
| 143 |
+
served_users.append(int(user["user_id"]))
|
| 144 |
+
for i in served_users:
|
| 145 |
+
try:
|
| 146 |
+
m = (
|
| 147 |
+
await app.forward_messages(i, y, x)
|
| 148 |
+
if message.reply_to_message
|
| 149 |
+
else await app.send_message(i, text=query)
|
| 150 |
+
)
|
| 151 |
+
susr += 1
|
| 152 |
+
except FloodWait as e:
|
| 153 |
+
flood_time = int(e.x)
|
| 154 |
+
if flood_time > 200:
|
| 155 |
+
continue
|
| 156 |
+
await asyncio.sleep(flood_time)
|
| 157 |
+
except Exception:
|
| 158 |
+
pass
|
| 159 |
+
try:
|
| 160 |
+
await message.reply_text(_["broad_7"].format(susr))
|
| 161 |
+
except:
|
| 162 |
+
pass
|
| 163 |
+
|
| 164 |
+
# Bot broadcasting by assistant
|
| 165 |
+
if "-assistant" in message.text:
|
| 166 |
+
aw = await message.reply_text(_["broad_2"])
|
| 167 |
+
text = _["broad_3"]
|
| 168 |
+
from YukkiMusic.core.userbot import assistants
|
| 169 |
+
|
| 170 |
+
for num in assistants:
|
| 171 |
+
sent = 0
|
| 172 |
+
client = await get_client(num)
|
| 173 |
+
async for dialog in client.iter_dialogs():
|
| 174 |
+
if dialog.chat.id == -1001733534088:
|
| 175 |
+
continue
|
| 176 |
+
try:
|
| 177 |
+
await client.forward_messages(
|
| 178 |
+
dialog.chat.id, y, x
|
| 179 |
+
) if message.reply_to_message else await client.send_message(
|
| 180 |
+
dialog.chat.id, text=query
|
| 181 |
+
)
|
| 182 |
+
sent += 1
|
| 183 |
+
except FloodWait as e:
|
| 184 |
+
flood_time = int(e.x)
|
| 185 |
+
if flood_time > 200:
|
| 186 |
+
continue
|
| 187 |
+
await asyncio.sleep(flood_time)
|
| 188 |
+
except Exception as e:
|
| 189 |
+
print(e)
|
| 190 |
+
continue
|
| 191 |
+
text += _["broad_4"].format(num, sent)
|
| 192 |
+
try:
|
| 193 |
+
await aw.edit_text(text)
|
| 194 |
+
except:
|
| 195 |
+
pass
|
| 196 |
+
IS_BROADCASTING = False
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
async def auto_clean():
|
| 200 |
+
while not await asyncio.sleep(AUTO_SLEEP):
|
| 201 |
+
try:
|
| 202 |
+
for chat_id in chatstats:
|
| 203 |
+
for dic in chatstats[chat_id]:
|
| 204 |
+
vidid = dic["vidid"]
|
| 205 |
+
title = dic["title"]
|
| 206 |
+
chatstats[chat_id].pop(0)
|
| 207 |
+
spot = await get_particular_top(chat_id, vidid)
|
| 208 |
+
if spot:
|
| 209 |
+
spot = spot["spot"]
|
| 210 |
+
next_spot = spot + 1
|
| 211 |
+
new_spot = {"spot": next_spot, "title": title}
|
| 212 |
+
await update_particular_top(
|
| 213 |
+
chat_id, vidid, new_spot
|
| 214 |
+
)
|
| 215 |
+
else:
|
| 216 |
+
next_spot = 1
|
| 217 |
+
new_spot = {"spot": next_spot, "title": title}
|
| 218 |
+
await update_particular_top(
|
| 219 |
+
chat_id, vidid, new_spot
|
| 220 |
+
)
|
| 221 |
+
for user_id in userstats:
|
| 222 |
+
for dic in userstats[user_id]:
|
| 223 |
+
vidid = dic["vidid"]
|
| 224 |
+
title = dic["title"]
|
| 225 |
+
userstats[user_id].pop(0)
|
| 226 |
+
spot = await get_user_top(user_id, vidid)
|
| 227 |
+
if spot:
|
| 228 |
+
spot = spot["spot"]
|
| 229 |
+
next_spot = spot + 1
|
| 230 |
+
new_spot = {"spot": next_spot, "title": title}
|
| 231 |
+
await update_user_top(
|
| 232 |
+
user_id, vidid, new_spot
|
| 233 |
+
)
|
| 234 |
+
else:
|
| 235 |
+
next_spot = 1
|
| 236 |
+
new_spot = {"spot": next_spot, "title": title}
|
| 237 |
+
await update_user_top(
|
| 238 |
+
user_id, vidid, new_spot
|
| 239 |
+
)
|
| 240 |
+
except:
|
| 241 |
+
continue
|
| 242 |
+
try:
|
| 243 |
+
for chat_id in clean:
|
| 244 |
+
if chat_id == config.LOG_GROUP_ID:
|
| 245 |
+
continue
|
| 246 |
+
for x in clean[chat_id]:
|
| 247 |
+
if datetime.now() > x["timer_after"]:
|
| 248 |
+
try:
|
| 249 |
+
await app.delete_messages(
|
| 250 |
+
chat_id, x["msg_id"]
|
| 251 |
+
)
|
| 252 |
+
except FloodWait as e:
|
| 253 |
+
await asyncio.sleep(e.x)
|
| 254 |
+
except:
|
| 255 |
+
continue
|
| 256 |
+
else:
|
| 257 |
+
continue
|
| 258 |
+
except:
|
| 259 |
+
continue
|
| 260 |
+
try:
|
| 261 |
+
served_chats = await get_active_chats()
|
| 262 |
+
for chat_id in served_chats:
|
| 263 |
+
if chat_id not in adminlist:
|
| 264 |
+
adminlist[chat_id] = []
|
| 265 |
+
admins = await app.get_chat_members(
|
| 266 |
+
chat_id, filter="administrators"
|
| 267 |
+
)
|
| 268 |
+
for user in admins:
|
| 269 |
+
if user.can_manage_voice_chats:
|
| 270 |
+
adminlist[chat_id].append(user.user.id)
|
| 271 |
+
authusers = await get_authuser_names(chat_id)
|
| 272 |
+
for user in authusers:
|
| 273 |
+
user_id = await alpha_to_int(user)
|
| 274 |
+
adminlist[chat_id].append(user_id)
|
| 275 |
+
except:
|
| 276 |
+
continue
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
asyncio.create_task(auto_clean())
|
YukkiMusic/plugins/misc/seeker.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
|
| 3 |
+
#
|
| 4 |
+
# This file is part of < https://github.com/TeamYukki/YukkiMusicBot > project,
|
| 5 |
+
# and is released under the "GNU v3.0 License Agreement".
|
| 6 |
+
# Please see < https://github.com/TeamYukki/YukkiMusicBot/blob/master/LICENSE >
|
| 7 |
+
#
|
| 8 |
+
# All rights reserved.
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
|
| 12 |
+
from pyrogram.types import InlineKeyboardMarkup
|
| 13 |
+
|
| 14 |
+
from strings import get_string
|
| 15 |
+
from YukkiMusic.misc import db
|
| 16 |
+
from YukkiMusic.utils.database import (get_active_chats, get_lang,
|
| 17 |
+
is_music_playing)
|
| 18 |
+
from YukkiMusic.utils.formatters import seconds_to_min
|
| 19 |
+
from YukkiMusic.utils.inline import (stream_markup_timer,
|
| 20 |
+
telegram_markup_timer)
|
| 21 |
+
|
| 22 |
+
from ..admins.callback import wrong
|
| 23 |
+
|
| 24 |
+
checker = {}
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
async def timer():
|
| 28 |
+
while not await asyncio.sleep(1):
|
| 29 |
+
active_chats = await get_active_chats()
|
| 30 |
+
for chat_id in active_chats:
|
| 31 |
+
if not await is_music_playing(chat_id):
|
| 32 |
+
continue
|
| 33 |
+
playing = db.get(chat_id)
|
| 34 |
+
if not playing:
|
| 35 |
+
continue
|
| 36 |
+
file_path = playing[0]["file"]
|
| 37 |
+
if "index_" in file_path or "live_" in file_path:
|
| 38 |
+
continue
|
| 39 |
+
duration = int(playing[0]["seconds"])
|
| 40 |
+
if duration == 0:
|
| 41 |
+
continue
|
| 42 |
+
db[chat_id][0]["played"] += 1
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
asyncio.create_task(timer())
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
async def markup_timer():
|
| 49 |
+
while not await asyncio.sleep(4):
|
| 50 |
+
active_chats = await get_active_chats()
|
| 51 |
+
for chat_id in active_chats:
|
| 52 |
+
try:
|
| 53 |
+
if not await is_music_playing(chat_id):
|
| 54 |
+
continue
|
| 55 |
+
playing = db.get(chat_id)
|
| 56 |
+
if not playing:
|
| 57 |
+
continue
|
| 58 |
+
duration_seconds = int(playing[0]["seconds"])
|
| 59 |
+
if duration_seconds == 0:
|
| 60 |
+
continue
|
| 61 |
+
try:
|
| 62 |
+
mystic = playing[0]["mystic"]
|
| 63 |
+
markup = playing[0]["markup"]
|
| 64 |
+
except:
|
| 65 |
+
continue
|
| 66 |
+
try:
|
| 67 |
+
check = wrong[chat_id][mystic.message_id]
|
| 68 |
+
if check is False:
|
| 69 |
+
continue
|
| 70 |
+
except:
|
| 71 |
+
pass
|
| 72 |
+
try:
|
| 73 |
+
language = await get_lang(chat_id)
|
| 74 |
+
_ = get_string(language)
|
| 75 |
+
except:
|
| 76 |
+
_ = get_string("en")
|
| 77 |
+
try:
|
| 78 |
+
buttons = (
|
| 79 |
+
stream_markup_timer(
|
| 80 |
+
_,
|
| 81 |
+
playing[0]["vidid"],
|
| 82 |
+
chat_id,
|
| 83 |
+
seconds_to_min(playing[0]["played"]),
|
| 84 |
+
playing[0]["dur"],
|
| 85 |
+
)
|
| 86 |
+
if markup == "stream"
|
| 87 |
+
else telegram_markup_timer(
|
| 88 |
+
_,
|
| 89 |
+
chat_id,
|
| 90 |
+
seconds_to_min(playing[0]["played"]),
|
| 91 |
+
playing[0]["dur"],
|
| 92 |
+
)
|
| 93 |
+
)
|
| 94 |
+
await mystic.edit_reply_markup(
|
| 95 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
| 96 |
+
)
|
| 97 |
+
except:
|
| 98 |
+
continue
|
| 99 |
+
except:
|
| 100 |
+
continue
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
asyncio.create_task(markup_timer())
|