From 7de1250940a116bf6e2975d7dd8dd7cccbd18097 Mon Sep 17 00:00:00 2001 From: Shikhar Date: Sat, 18 Dec 2021 16:51:26 +0530 Subject: [PATCH 1/6] Multi-Assistant Release --- README.md | 12 +- Yukki/Core/Clients/cli.py | 10 +- Yukki/Core/Logger/Log.py | 3 +- Yukki/Core/PyTgCalls/Yukki.py | 355 ++++++++++++++++++++++++++--- Yukki/Database/__init__.py | 1 + Yukki/Database/assistant.py | 2 +- Yukki/Database/start.py | 37 +++ Yukki/Decorators/assistant.py | 28 ++- Yukki/Inline/__init__.py | 4 +- Yukki/Inline/others.py | 2 +- Yukki/Inline/start.py | 44 ++-- Yukki/Plugins/Admins.py | 34 +-- Yukki/Plugins/Assistant.py | 378 ++++++++++++++++--------------- Yukki/Plugins/Auth.py | 2 +- Yukki/Plugins/Callback.py | 47 +--- Yukki/Plugins/Developer.py | 235 ++++++++----------- Yukki/Plugins/Lyrics.py | 3 +- Yukki/Plugins/Multi-Assistant.py | 104 +++++++++ Yukki/Plugins/Playlist.py | 16 +- Yukki/Plugins/Start.py | 116 ++++++---- Yukki/Plugins/Stats.py | 100 +++++++- Yukki/Plugins/SudoUsers.py | 2 +- Yukki/Plugins/Voicechat.py | 59 +++-- Yukki/Utilities/assistant.py | 35 +++ Yukki/Utilities/stream.py | 34 +-- Yukki/Utilities/thumbnails.py | 20 +- Yukki/__init__.py | 131 +++++++++-- Yukki/__main__.py | 98 +++++++- app.json | 24 +- config.py | 6 +- 30 files changed, 1345 insertions(+), 597 deletions(-) create mode 100644 Yukki/Database/start.py create mode 100644 Yukki/Plugins/Multi-Assistant.py create mode 100644 Yukki/Utilities/assistant.py diff --git a/README.md b/README.md index 67cfd15..28ad4e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

⭐️ Yukki Music Bot ⭐️

+

⭐️ Yukki Music Bot [ Multi-Assistant ]⭐️

A Telegram Music Bot written in Python using Pyrogram and Py-Tgcalls

@@ -49,7 +49,7 @@ ```console -shikhar@MacBook~ $ git clone https://github.com/notreallyshikhar/YukkiMusicBot +shikhar@MacBook~ $ git clone -b Multi-Assistant https://github.com/notreallyshikhar/YukkiMusicBot shikhar@MacBook~ $ cd YukkiMusicBot shikhar@MacBook~ $ pip3 install -U -r requirements.txt shikhar@MacBook~ $ cp sample.env .env @@ -70,7 +70,7 @@ shikhar@MacBook~ $ bash start

- +

@@ -79,7 +79,7 @@ shikhar@MacBook~ $ bash start

- +

@@ -87,7 +87,7 @@ shikhar@MacBook~ $ bash start

```console -shikhar@MacBook~ $ git clone https://github.com/notreallyshikhar/YukkiMusicBot +shikhar@MacBook~ $ git clone -b Multi-Assistant https://github.com/notreallyshikhar/YukkiMusicBot shikhar@MacBook~ $ cd YukkiMusicBot shikhar@MacBook~ $ pip3 install pyrogram TgCrypto shikhar@MacBook~ $ python3 gen_session.py @@ -101,7 +101,7 @@ shikhar@MacBook~ $ python3 gen_session.py 1. `API_ID` : Assistant Account Telegram API_ID, get it from my.telegram.org 2. `API_HASH` : Assistant Account Telegram API_HASH, get it from my.telegram.org 3. `BOT_TOKEN` : Your Telegram Bot Token, get it from @Botfather (Make sure Inline is turned On) -4. `SESSION_STRING` : Pyrogram Session String of Assistant Account. +4. `SESSION_STRING1` - `SESSION_STRING5` : Pyrogram Session String of Assistant Accounts. 5. `MUSIC_BOT_NAME` : A name for your Music bot. 6. `MONGO_DB_URI` : MongoDB Database URL. 7. `LOG_GROUP_ID` : Chat ID where bot will log everything. Use Group Chats Only. diff --git a/Yukki/Core/Clients/cli.py b/Yukki/Core/Clients/cli.py index 93bb339..99a1308 100644 --- a/Yukki/Core/Clients/cli.py +++ b/Yukki/Core/Clients/cli.py @@ -1,6 +1,8 @@ -from config import API_HASH, API_ID, BOT_TOKEN, STRING from pyrogram import Client +from config import (API_HASH, API_ID, BOT_TOKEN, STRING1, STRING2, STRING3, + STRING4, STRING5) + app = Client( "YukkiMusicBot", API_ID, @@ -8,4 +10,8 @@ bot_token=BOT_TOKEN, ) -userbot = Client(STRING, API_ID, API_HASH) +ASS_CLI_1 = Client(STRING1, API_ID, API_HASH) +ASS_CLI_2 = Client(STRING2, API_ID, API_HASH) +ASS_CLI_3 = Client(STRING3, API_ID, API_HASH) +ASS_CLI_4 = Client(STRING4, API_ID, API_HASH) +ASS_CLI_5 = Client(STRING5, API_ID, API_HASH) diff --git a/Yukki/Core/Logger/Log.py b/Yukki/Core/Logger/Log.py index ea1902b..d67b7e9 100644 --- a/Yukki/Core/Logger/Log.py +++ b/Yukki/Core/Logger/Log.py @@ -1,6 +1,5 @@ from config import LOG_GROUP_ID as _channel_id_ - -from Yukki.Core.Clients.cli import app, userbot +from Yukki.Core.Clients.cli import app failure = "Make sure your bot is in your log channel and is promoted as an admin with full rights!" diff --git a/Yukki/Core/PyTgCalls/Yukki.py b/Yukki/Core/PyTgCalls/Yukki.py index ddec5d5..070ace3 100644 --- a/Yukki/Core/PyTgCalls/Yukki.py +++ b/Yukki/Core/PyTgCalls/Yukki.py @@ -3,20 +3,21 @@ import time from asyncio import QueueEmpty -from config import get_queue from pyrogram.errors import FloodWait, MessageNotModified from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, Message, ReplyKeyboardMarkup, ReplyKeyboardRemove) -from pytgcalls import PyTgCalls +from pytgcalls import PyTgCalls, StreamType from pytgcalls.types import Update from pytgcalls.types.input_stream import InputAudioStream, InputStream -from Yukki import MUSIC_BOT_NAME, app, db_mem, userbot +from config import get_queue +from Yukki import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5, + MUSIC_BOT_NAME, app, db_mem) from Yukki.Core.PyTgCalls import Queues from Yukki.Core.PyTgCalls.Converter import convert from Yukki.Core.PyTgCalls.Downloader import download -from Yukki.Database import remove_active_chat +from Yukki.Database import get_assistant, remove_active_chat from Yukki.Inline import (audio_markup, audio_timer_markup_start, primary_markup, timer_markup) from Yukki.Utilities.changers import time_to_seconds @@ -26,44 +27,210 @@ from Yukki.Utilities.timer import start_timer from Yukki.Utilities.youtube import get_yt_info_id -pytgcalls = PyTgCalls(userbot) +### Clients +pytgcalls1 = PyTgCalls(ASS_CLI_1) +pytgcalls2 = PyTgCalls(ASS_CLI_2) +pytgcalls3 = PyTgCalls(ASS_CLI_3) +pytgcalls4 = PyTgCalls(ASS_CLI_4) +pytgcalls5 = PyTgCalls(ASS_CLI_5) -@pytgcalls.on_kicked() -async def kicked_handler(_, chat_id: int): - try: - Queues.clear(chat_id) - except QueueEmpty: - pass - await remove_active_chat(chat_id) +### Multi Assistant start -@pytgcalls.on_closed_voice_chat() -async def closed_voice_chat_handler(_, chat_id: int): - try: - Queues.clear(chat_id) - except QueueEmpty: - pass - await remove_active_chat(chat_id) +async def join_stream(chat_id: int, file_path: str): + _assistant = await get_assistant(chat_id, "assistant") + assistant = _assistant["saveassistant"] + if int(assistant) == 1: + try: + await pytgcalls1.join_group_call( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + stream_type=StreamType().local_stream, + ) + return True + except: + return False + elif int(assistant) == 2: + try: + await pytgcalls2.join_group_call( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + stream_type=StreamType().local_stream, + ) + return True + except: + return False + elif int(assistant) == 3: + try: + await pytgcalls3.join_group_call( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + stream_type=StreamType().local_stream, + ) + return True + except: + return False + elif int(assistant) == 4: + try: + await pytgcalls4.join_group_call( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + stream_type=StreamType().local_stream, + ) + return True + except: + return False + elif int(assistant) == 5: + try: + await pytgcalls5.join_group_call( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + stream_type=StreamType().local_stream, + ) + return True + except: + return False + return False -@pytgcalls.on_left() -async def left_handler(_, chat_id: int): - try: - Queues.clear(chat_id) - except QueueEmpty: - pass - await remove_active_chat(chat_id) +### Multi Assistant Pause -@pytgcalls.on_stream_end() -async def stream_end_handler(_, update: Update): - chat_id = update.chat_id + +async def pause_stream(chat_id: int): + _assistant = await get_assistant(chat_id, "assistant") + assistant = _assistant["saveassistant"] + if int(assistant) == 1: + await pytgcalls1.pause_stream(chat_id) + elif int(assistant) == 2: + await pytgcalls2.pause_stream(chat_id) + elif int(assistant) == 3: + await pytgcalls3.pause_stream(chat_id) + elif int(assistant) == 4: + await pytgcalls4.pause_stream(chat_id) + elif int(assistant) == 5: + await pytgcalls5.pause_stream(chat_id) + + +### Multi Assistant Resume + + +async def resume_stream(chat_id: int): + _assistant = await get_assistant(chat_id, "assistant") + assistant = _assistant["saveassistant"] + if int(assistant) == 1: + await pytgcalls1.resume_stream(chat_id) + elif int(assistant) == 2: + await pytgcalls2.resume_stream(chat_id) + elif int(assistant) == 3: + await pytgcalls3.resume_stream(chat_id) + elif int(assistant) == 4: + await pytgcalls4.resume_stream(chat_id) + elif int(assistant) == 5: + await pytgcalls5.resume_stream(chat_id) + + +### Multi Assistant Stop + + +async def stop_stream(chat_id: int): + _assistant = await get_assistant(chat_id, "assistant") + assistant = _assistant["saveassistant"] + if int(assistant) == 1: + await pytgcalls1.leave_group_call(chat_id) + elif int(assistant) == 2: + await pytgcalls2.leave_group_call(chat_id) + elif int(assistant) == 3: + await pytgcalls3.leave_group_call(chat_id) + elif int(assistant) == 4: + await pytgcalls4.leave_group_call(chat_id) + elif int(assistant) == 5: + await pytgcalls5.leave_group_call(chat_id) + + +### Multi Assistant Skip + + +async def skip_stream(chat_id: int, file_path: str): + _assistant = await get_assistant(chat_id, "assistant") + assistant = _assistant["saveassistant"] + if int(assistant) == 1: + await pytgcalls1.change_stream( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + ) + elif int(assistant) == 2: + await pytgcalls2.change_stream( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + ) + elif int(assistant) == 3: + await pytgcalls3.change_stream( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + ) + elif int(assistant) == 4: + await pytgcalls4.change_stream( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + ) + elif int(assistant) == 5: + await pytgcalls5.change_stream( + chat_id, + InputStream( + InputAudioStream( + file_path, + ), + ), + ) + + +### Multi Assistant Playout End + + +async def playout_end(pytgclients, chat_id): try: Queues.task_done(chat_id) if Queues.is_empty(chat_id): await remove_active_chat(chat_id) - await pytgcalls.leave_group_call(chat_id) + await pytgcalls1.leave_group_call(chat_id) else: afk = Queues.get(chat_id)["file"] finxx = f"{afk[0]}{afk[1]}{afk[2]}" @@ -90,7 +257,7 @@ async def stream_end_handler(_, update: Update): None, download, afk, mystic, title ) raw_path = await convert(downloaded_file) - await pytgcalls.change_stream( + await pytgclients.change_stream( chat_id, InputStream( InputAudioStream( @@ -122,7 +289,7 @@ async def stream_end_handler(_, update: Update): videoid = afk else: videoid = afk - await pytgcalls.change_stream( + await pytgclients.change_stream( chat_id, InputStream( InputAudioStream( @@ -171,4 +338,126 @@ async def stream_end_handler(_, update: Update): print(e) -run = pytgcalls.run +### Multi Assistant Queue Clear + + +async def clear_queue(chat_id): + try: + Queues.clear(chat_id) + except QueueEmpty: + pass + await remove_active_chat(chat_id) + + +### Playout End For Client 1 +@pytgcalls1.on_stream_end() +async def stream_end_handler1(_, update: Update): + await playout_end(pytgcalls1, update.chat_id) + + +### Playout End For Client 2 +@pytgcalls2.on_stream_end() +async def stream_end_handler(_, update: Update): + await playout_end(pytgcalls2, update.chat_id) + + +### Playout End For Client 3 +@pytgcalls3.on_stream_end() +async def stream_end_handler3(_, update: Update): + await playout_end(pytgcalls3, update.chat_id) + + +### Playout End For Client 4 +@pytgcalls4.on_stream_end() +async def stream_end_handler(_, update: Update): + await playout_end(pytgcalls4, update.chat_id) + + +### Playout End For Client 5 +@pytgcalls5.on_stream_end() +async def stream_end_handler5(_, update: Update): + await playout_end(pytgcalls5, update.chat_id) + + +### Kicked Handlers + + +@pytgcalls1.on_kicked() +async def kicked_handler1(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls2.on_kicked() +async def kicked_handler2(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls3.on_kicked() +async def kicked_handle3(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls4.on_kicked() +async def kicked_handler4(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls5.on_kicked() +async def kicked_handler5(_, chat_id: int): + await clear_queue(chat_id) + + +### Closed Handlers + + +@pytgcalls1.on_closed_voice_chat() +async def closed_voice_chat_handler1(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls2.on_closed_voice_chat() +async def closed_voice_chat_handler2(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls3.on_closed_voice_chat() +async def closed_voice_chat_handler3(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls4.on_closed_voice_chat() +async def closed_voice_chat_handler4(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls5.on_closed_voice_chat() +async def closed_voice_chat_handler5(_, chat_id: int): + await clear_queue(chat_id) + + +### Left Handlers + + +@pytgcalls1.on_left() +async def left_handler1(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls2.on_left() +async def left_handler2(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls3.on_left() +async def left_handler3(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls4.on_left() +async def left_handler4(_, chat_id: int): + await clear_queue(chat_id) + + +@pytgcalls5.on_left() +async def left_handler5(_, chat_id: int): + await clear_queue(chat_id) diff --git a/Yukki/Database/__init__.py b/Yukki/Database/__init__.py index 3b5d83f..3f3da8f 100644 --- a/Yukki/Database/__init__.py +++ b/Yukki/Database/__init__.py @@ -15,5 +15,6 @@ is_pmpermit_approved) from .queue import (add_active_chat, get_active_chats, is_active_chat, is_music_playing, music_off, music_on, remove_active_chat) +from .start import _get_start, get_start, get_start_names, save_start from .sudo import add_sudo, get_sudoers, remove_sudo from .theme import _get_theme, get_theme, save_theme diff --git a/Yukki/Database/assistant.py b/Yukki/Database/assistant.py index f7017f8..aed2263 100644 --- a/Yukki/Database/assistant.py +++ b/Yukki/Database/assistant.py @@ -2,7 +2,7 @@ from Yukki import db -assisdb = db.assis +assisdb = db.multiassistant async def get_as_names(chat_id: int) -> List[str]: diff --git a/Yukki/Database/start.py b/Yukki/Database/start.py new file mode 100644 index 0000000..cba6ad0 --- /dev/null +++ b/Yukki/Database/start.py @@ -0,0 +1,37 @@ +from typing import Dict, List, Union + +from Yukki import db + +assisdb = db.start + + +async def get_start_names(chat_id: int) -> List[str]: + _notes = [] + for note in await _get_start(chat_id): + _notes.append(note) + return _notes + + +async def _get_start(chat_id: int) -> Dict[str, int]: + _notes = await assisdb.find_one({"chat_id": chat_id}) + if not _notes: + return {} + return _notes["notes"] + + +async def get_start(chat_id: int, name: str) -> Union[bool, dict]: + name = name.lower().strip() + _notes = await _get_start(chat_id) + if name in _notes: + return _notes[name] + else: + return False + + +async def save_start(chat_id: int, name: str, note: dict): + name = name.lower().strip() + _notes = await _get_start(chat_id) + _notes[name] = note + await assisdb.update_one( + {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True + ) diff --git a/Yukki/Decorators/assistant.py b/Yukki/Decorators/assistant.py index cea6b22..5397dcb 100644 --- a/Yukki/Decorators/assistant.py +++ b/Yukki/Decorators/assistant.py @@ -1,23 +1,37 @@ +import random from typing import Dict, List, Union from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant -from Yukki import (ASSID, ASSMENTION, ASSNAME, ASSUSERNAME, BOT_ID, app, - userbot) +from Yukki import MUSIC_BOT_NAME, app +from Yukki.Database import get_assistant, save_assistant +from Yukki.Utilities.assistant import get_assistant_details, random_assistant def AssistantAdd(mystic): async def wrapper(_, message): + _assistant = await get_assistant(message.chat.id, "assistant") + if not _assistant: + ran_ass = random.choice(random_assistant) + assis = { + "saveassistant": ran_ass, + } + await save_assistant(message.chat.id, "assistant", assis) + else: + ran_ass = _assistant["saveassistant"] + ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details( + ran_ass + ) try: - b = await app.get_chat_member(message.chat.id, ASSID) + b = await app.get_chat_member(message.chat.id, ASS_ID) if b.status == "kicked": return await message.reply_text( - f"Assistant Account[{ASSID}] is banned.\nUnban it first to use Music Bot\n\nUsername: @{ASSUSERNAME}" + f"Assistant Account[{ASS_ID}] is banned.\nUnban it first to use Music Bot\n\nUsername: @{ASS_USERNAME}" ) except UserNotParticipant: if message.chat.username: try: - await userbot.join_chat(message.chat.username) + await ASS_ACC.join_chat(message.chat.username) except UserAlreadyParticipant: pass except Exception as e: @@ -34,9 +48,9 @@ async def wrapper(_, message): invitelink = invitelink.replace( "https://t.me/+", "https://t.me/joinchat/" ) - await userbot.join_chat(invitelink) + await ASS_ACC.join_chat(invitelink) await message.reply( - f"{ASSMENTION} Joined Successfully", + f"{ASS_NAME} Joined Successfully", ) except UserAlreadyParticipant: pass diff --git a/Yukki/Inline/__init__.py b/Yukki/Inline/__init__.py index 544e227..84e3d7e 100644 --- a/Yukki/Inline/__init__.py +++ b/Yukki/Inline/__init__.py @@ -7,6 +7,6 @@ paste_queue_markup, play_genre_playlist, playlist_markup, third_playlist_markup) from .song import song_download_markup, song_markup -from .start import (custommarkup, dashmarkup, private_panel, setting_markup, setting_markup2, - start_pannel, usermarkup, volmarkup) +from .start import (custommarkup, dashmarkup, private_panel, setting_markup, + setting_markup2, start_pannel, usermarkup, volmarkup) from .stats import stats1, stats2, stats3, stats4, stats5, stats6, stats7 diff --git a/Yukki/Inline/others.py b/Yukki/Inline/others.py index b75bd4b..67ce692 100644 --- a/Yukki/Inline/others.py +++ b/Yukki/Inline/others.py @@ -39,7 +39,7 @@ def others_markup(videoid, user_id): InlineKeyboardButton( text="🗑 Close Menu", callback_data=f"close", - ) + ), ], ] return buttons diff --git a/Yukki/Inline/start.py b/Yukki/Inline/start.py index 3d9646b..b87991c 100644 --- a/Yukki/Inline/start.py +++ b/Yukki/Inline/start.py @@ -1,30 +1,9 @@ -from config import MUSIC_BOT_NAME, SUPPORT_CHANNEL, SUPPORT_GROUP from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message) +from config import MUSIC_BOT_NAME, SUPPORT_CHANNEL, SUPPORT_GROUP from Yukki import BOT_USERNAME -def setting_markup2(): - buttons = [ - [ - InlineKeyboardButton(text="🔈 Audio Quality", callback_data="AQ"), - InlineKeyboardButton(text="🎚 Audio Volume", callback_data="AV"), - ], - [ - InlineKeyboardButton( - text="👥 Authorized Users", callback_data="AU" - ), - InlineKeyboardButton( - text="💻 Dashboard", callback_data="Dashboard" - ), - ], - [ - InlineKeyboardButton(text="✖️ Close", callback_data="close"), - ], - ] - return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons - - def start_pannel(): if not SUPPORT_CHANNEL and not SUPPORT_GROUP: @@ -206,6 +185,27 @@ def setting_markup(): return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons +def setting_markup2(): + buttons = [ + [ + InlineKeyboardButton(text="🔈 Audio Quality", callback_data="AQ"), + InlineKeyboardButton(text="🎚 Audio Volume", callback_data="AV"), + ], + [ + InlineKeyboardButton( + text="👥 Authorized Users", callback_data="AU" + ), + InlineKeyboardButton( + text="💻 Dashboard", callback_data="Dashboard" + ), + ], + [ + InlineKeyboardButton(text="✖️ Close", callback_data="close"), + ], + ] + return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons + + def volmarkup(): buttons = [ [ diff --git a/Yukki/Plugins/Admins.py b/Yukki/Plugins/Admins.py index 4690ab5..164e5cc 100644 --- a/Yukki/Plugins/Admins.py +++ b/Yukki/Plugins/Admins.py @@ -3,18 +3,18 @@ import random from asyncio import QueueEmpty -from config import get_queue from pyrogram import filters from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, Message, ReplyKeyboardMarkup, ReplyKeyboardRemove) -from pytgcalls import StreamType -from pytgcalls.types.input_stream import InputAudioStream, InputStream +from config import get_queue from Yukki import BOT_USERNAME, MUSIC_BOT_NAME, app, db_mem -from Yukki.Core.PyTgCalls import Queues, Yukki +from Yukki.Core.PyTgCalls import Queues from Yukki.Core.PyTgCalls.Converter import convert from Yukki.Core.PyTgCalls.Downloader import download +from Yukki.Core.PyTgCalls.Yukki import (pause_stream, resume_stream, + skip_stream, stop_stream) from Yukki.Database import (is_active_chat, is_music_playing, music_off, music_on, remove_active_chat) from Yukki.Decorators.admins import AdminRightsCheck @@ -76,7 +76,7 @@ async def admins(_, message: Message): if not await is_music_playing(message.chat.id): return await message.reply_text("Music is already Paused.") await music_off(chat_id) - await Yukki.pytgcalls.pause_stream(chat_id) + await pause_stream(chat_id) await message.reply_text( f"🎧 Voicechat Paused by {message.from_user.mention}!" ) @@ -84,7 +84,7 @@ async def admins(_, message: Message): if await is_music_playing(message.chat.id): return await message.reply_text("Music is already Playing.") await music_on(chat_id) - await Yukki.pytgcalls.resume_stream(message.chat.id) + await resume_stream(chat_id) await message.reply_text( f"🎧 Voicechat Resumed by {message.from_user.mention}!" ) @@ -94,7 +94,7 @@ async def admins(_, message: Message): except QueueEmpty: pass await remove_active_chat(chat_id) - await Yukki.pytgcalls.leave_group_call(message.chat.id) + await stop_stream(chat_id) await message.reply_text( f"🎧 Voicechat End/Stopped by {message.from_user.mention}!" ) @@ -105,7 +105,7 @@ async def admins(_, message: Message): await message.reply_text( "No more music in __Queue__ \n\nLeaving Voice Chat" ) - await Yukki.pytgcalls.leave_group_call(message.chat.id) + await stop_stream(chat_id) return else: videoid = Queues.get(chat_id)["file"] @@ -131,14 +131,7 @@ async def admins(_, message: Message): None, download, videoid, mystic, title ) raw_path = await convert(downloaded_file) - await Yukki.pytgcalls.change_stream( - chat_id, - InputStream( - InputAudioStream( - raw_path, - ), - ), - ) + await skip_stream(chat_id, raw_path) theme = await check_theme(chat_id) chat_title = await specialfont_to_normal(message.chat.title) thumb = await gen_thumb( @@ -158,14 +151,7 @@ async def admins(_, message: Message): ) os.remove(thumb) else: - await Yukki.pytgcalls.change_stream( - chat_id, - InputStream( - InputAudioStream( - videoid, - ), - ), - ) + await skip_stream(chat_id, videoid) afk = videoid title = db_mem[videoid]["title"] duration_min = db_mem[videoid]["duration"] diff --git a/Yukki/Plugins/Assistant.py b/Yukki/Plugins/Assistant.py index f3fb2a4..64b5aeb 100644 --- a/Yukki/Plugins/Assistant.py +++ b/Yukki/Plugins/Assistant.py @@ -7,8 +7,9 @@ InlineQueryResultPhoto, InputTextMessageContent, Message) -from Yukki import (ASSID, ASSISTANT_PREFIX, ASSNAME, BOT_ID, BOT_USERNAME, - LOG_GROUP_ID, MUSIC_BOT_NAME, SUDOERS, app, userbot) +from Yukki import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5, + ASSISTANT_PREFIX, BOT_ID, BOT_USERNAME, LOG_GROUP_ID, + MUSIC_BOT_NAME, SUDOERS, app) from Yukki.Database import (approve_pmpermit, disapprove_pmpermit, is_pmpermit_approved) @@ -43,7 +44,7 @@ flood = {} -@userbot.on_message( +@ASS_CLI_1.on_message( filters.private & filters.incoming & ~filters.service @@ -53,11 +54,51 @@ & ~filters.via_bot & ~filters.user(SUDOERS) ) -async def awaiting_message(_, message): +@ASS_CLI_2.on_message( + filters.private + & filters.incoming + & ~filters.service + & ~filters.edited + & ~filters.me + & ~filters.bot + & ~filters.via_bot + & ~filters.user(SUDOERS) +) +@ASS_CLI_3.on_message( + filters.private + & filters.incoming + & ~filters.service + & ~filters.edited + & ~filters.me + & ~filters.bot + & ~filters.via_bot + & ~filters.user(SUDOERS) +) +@ASS_CLI_4.on_message( + filters.private + & filters.incoming + & ~filters.service + & ~filters.edited + & ~filters.me + & ~filters.bot + & ~filters.via_bot + & ~filters.user(SUDOERS) +) +@ASS_CLI_5.on_message( + filters.private + & filters.incoming + & ~filters.service + & ~filters.edited + & ~filters.me + & ~filters.bot + & ~filters.via_bot + & ~filters.user(SUDOERS) +) +async def awaiting_message(client, message): user_id = message.from_user.id if await is_pmpermit_approved(user_id): return - async for m in userbot.iter_history(user_id, limit=6): + async for m in client.iter_history(user_id, limit=6): if m.reply_markup: await m.delete() if str(user_id) in flood: @@ -66,28 +107,42 @@ async def awaiting_message(_, message): flood[str(user_id)] = 1 if flood[str(user_id)] > 5: await message.reply_text("Spam Detected. User Blocked") - await userbot.send_message( + await client.send_message( LOG_GROUP_ID, f"**Spam Detect Block On Assistant**\n\n- **Blocked User:** {message.from_user.mention}\n- **User ID:** {message.from_user.id}", ) - return await userbot.block_user(user_id) - results = await userbot.get_inline_bot_results( - BOT_ID, f"permit_to_pm {user_id}" - ) - await userbot.send_inline_bot_result( - user_id, - results.query_id, - results.results[0].id, - hide_via=True, + return await client.block_user(user_id) + await message.reply_text( + f"Hello, I am {MUSIC_BOT_NAME}'s Assistant.\n\nPlease dont spam here , else you'll get blocked.\nFor more Help start :- @{BOT_USERNAME}" ) -@userbot.on_message( +@ASS_CLI_1.on_message( + filters.command("approve", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_2.on_message( filters.command("approve", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def pm_approve(_, message): +@ASS_CLI_3.on_message( + filters.command("approve", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_4.on_message( + filters.command("approve", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_5.on_message( + filters.command("approve", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def pm_approve(client, message): if not message.reply_to_message: return await eor( message, text="Reply to a user's message to approve." @@ -99,12 +154,32 @@ async def pm_approve(_, message): await eor(message, text="User is approved to pm") -@userbot.on_message( +@ASS_CLI_1.on_message( + filters.command("disapprove", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_2.on_message( + filters.command("disapprove", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_3.on_message( filters.command("disapprove", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def pm_disapprove(_, message): +@ASS_CLI_4.on_message( + filters.command("disapprove", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_5.on_message( + filters.command("disapprove", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def pm_disapprove(client, message): if not message.reply_to_message: return await eor( message, text="Reply to a user's message to disapprove." @@ -112,7 +187,7 @@ async def pm_disapprove(_, message): user_id = message.reply_to_message.from_user.id if not await is_pmpermit_approved(user_id): await eor(message, text="User is already disapproved to pm") - async for m in userbot.iter_history(user_id, limit=6): + async for m in client.iter_history(user_id, limit=6): if m.reply_markup: try: await m.delete() @@ -123,208 +198,147 @@ async def pm_disapprove(_, message): await eor(message, text="User is disapproved to pm") -@userbot.on_message( +@ASS_CLI_1.on_message( + filters.command("block", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_2.on_message( + filters.command("block", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_3.on_message( + filters.command("block", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_4.on_message( filters.command("block", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def block_user_func(_, message): +@ASS_CLI_5.on_message( + filters.command("block", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def block_user_func(client, message): if not message.reply_to_message: return await eor(message, text="Reply to a user's message to block.") user_id = message.reply_to_message.from_user.id await eor(message, text="Successfully blocked the user") - await userbot.block_user(user_id) + await client.block_user(user_id) -@userbot.on_message( +@ASS_CLI_1.on_message( filters.command("unblock", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def unblock_user_func(_, message): +@ASS_CLI_2.on_message( + filters.command("unblock", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_3.on_message( + filters.command("unblock", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_4.on_message( + filters.command("unblock", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_5.on_message( + filters.command("unblock", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def unblock_user_func(client, message): if not message.reply_to_message: return await eor( message, text="Reply to a user's message to unblock." ) user_id = message.reply_to_message.from_user.id - await userbot.unblock_user(user_id) + await client.unblock_user(user_id) await eor(message, text="Successfully Unblocked the user") - -@userbot.on_message( +@ASS_CLI_1.on_message( filters.command("pfp", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def set_pfp(_, message): +@ASS_CLI_2.on_message( + filters.command("pfp", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_3.on_message( + filters.command("pfp", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_4.on_message( + filters.command("pfp", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_5.on_message( + filters.command("pfp", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def set_pfp(client, message): if not message.reply_to_message or not message.reply_to_message.photo: - return await eor(message, text="Reply to a photo.") + return await eor(message, text="Reply to a photo.") photo = await message.reply_to_message.download() - try: - await userbot.set_profile_photo(photo=photo) + try: + await client.set_profile_photo(photo=photo) await eor(message, text="Successfully Changed PFP.") except Exception as e: await eor(message, text=e) - - -@userbot.on_message( + + +@ASS_CLI_1.on_message( filters.command("bio", prefixes=ASSISTANT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot ) -async def set_bio(_, message): +@ASS_CLI_2.on_message( + filters.command("bio", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_3.on_message( + filters.command("bio", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_4.on_message( + filters.command("bio", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +@ASS_CLI_5.on_message( + filters.command("bio", prefixes=ASSISTANT_PREFIX) + & filters.user(SUDOERS) + & ~filters.via_bot +) +async def set_bio(client, message): if len(message.command) == 1: - return await eor(message , text="Give some text to set as bio.") + return await eor(message, text="Give some text to set as bio.") elif len(message.command) > 1: bio = message.text.split(None, 1)[1] - try: - await userbot.update_profile(bio=bio) - await eor(message , text="Changed Bio.") + try: + await client.update_profile(bio=bio) + await eor(message, text="Changed Bio.") except Exception as e: - await eor(message , text=e) + await eor(message, text=e) else: - return await eor(message , text="Give some text to set as bio.") - -flood2 = {} - -@app.on_callback_query(filters.regex("pmpermit")) -async def pmpermit_cq(_, cq): - user_id = cq.from_user.id - data, victim = ( - cq.data.split(None, 2)[1], - cq.data.split(None, 2)[2], - ) - if data == "approve": - if user_id != ASSID: - return await cq.answer("This Button Is Not For You") - await approve_pmpermit(int(victim)) - return await app.edit_inline_text( - cq.inline_message_id, "User Has Been Approved To PM." - ) - - if data == "block": - if user_id != ASSID: - return await cq.answer("This Button Is Not For You") - await cq.answer() - await app.edit_inline_text( - cq.inline_message_id, "Successfully blocked the user." - ) - await userbot.block_user(int(victim)) - return await userbot.send( - DeleteHistory( - peer=(await userbot.resolve_peer(victim)), - max_id=0, - revoke=False, - ) - ) - - if user_id == ASSID: - return await cq.answer("It's For The Other Person.") - - if data == "to_scam_you": - async for m in userbot.iter_history(user_id, limit=6): - if m.reply_markup: - await m.delete() - await userbot.send_message(user_id, "Blocked, Go scam someone else.") - await userbot.send_message( - LOG_GROUP_ID, - f"**Scam Block On Assistant**\n\n- **Blocked User:** {cq.from_user.mention}\n- **User ID:** {user_id}", - ) - await userbot.block_user(user_id) - await cq.answer() - if data == "for_pro": - async for m in userbot.iter_history(user_id, limit=6): - if m.reply_markup: - await m.delete() - await userbot.send_message(user_id, f"Blocked, No Promotions.") - await userbot.send_message( - LOG_GROUP_ID, - f"**Promotion Block On Assistant**\n\n- **Blocked User:** {cq.from_user.mention}\n- **User ID:** {user_id}", - ) - await userbot.block_user(user_id) - await cq.answer() - elif data == "approve_me": - await cq.answer() - if str(user_id) in flood2: - flood2[str(user_id)] += 1 - else: - flood2[str(user_id)] = 1 - if flood2[str(user_id)] > 5: - await userbot.send_message( - user_id, "SPAM DETECTED, USER BLOCKED." - ) - await userbot.send_message( - LOG_GROUP_ID, - f"**Spam Detect Block On Assistant**\n\n- **Blocked User:** {cq.from_user.mention}\n- **User ID:** {user_id}", - ) - return await userbot.block_user(user_id) - await userbot.send_message( - user_id, - "I'm busy right now, will approve you shortly, DO NOT SPAM.", - ) - - -async def pmpermit_func(answers, user_id, victim): - if user_id != ASSID: - return - caption = f"Hi, I'm {ASSNAME}, What are you here for?, You'll be blocked if you send more than 5 messages." - audio_markup2 = InlineKeyboardMarkup( - [ - [ - InlineKeyboardButton( - text=f"Add {MUSIC_BOT_NAME} To Your Group", - url=f"https://t.me/{BOT_USERNAME}?startgroup=true", - ), - ], - [ - InlineKeyboardButton( - text="To Scam You", - callback_data=f"pmpermit to_scam_you a", - ), - InlineKeyboardButton( - text="For Promotion", callback_data=f"pmpermit for_pro a" - ), - ], - [ - InlineKeyboardButton( - text="Approve me", callback_data=f"pmpermit approve_me a" - ), - InlineKeyboardButton( - text="Approve", callback_data=f"pmpermit approve {victim}" - ), - ], - [ - InlineKeyboardButton( - "Block & Delete", callback_data="pmpermit block {victim}" - ) - ], - ] - ) - answers.append( - InlineQueryResultArticle( - title="do_not_click_here", - reply_markup=audio_markup2, - input_message_content=InputTextMessageContent(caption), - ) - ) - return answers - - -@app.on_inline_query() -async def inline_query_handler(client, query): - try: - text = query.query.strip().lower() - answers = [] - if text.split()[0] == "permit_to_pm": - user_id = query.from_user.id - victim = text.split()[1] - answerss = await pmpermit_func(answers, user_id, victim) - await client.answer_inline_query( - query.id, results=answerss, cache_time=2 - ) - except: - return + return await eor(message, text="Give some text to set as bio.") async def eor(msg: Message, **kwargs): diff --git a/Yukki/Plugins/Auth.py b/Yukki/Plugins/Auth.py index f849663..78d0981 100644 --- a/Yukki/Plugins/Auth.py +++ b/Yukki/Plugins/Auth.py @@ -1,7 +1,7 @@ from pyrogram import Client, filters from pyrogram.types import Message -from Yukki import SUDOERS, app +from Yukki import app from Yukki.Database import (_get_authusers, delete_authuser, get_authuser, get_authuser_count, get_authuser_names, save_authuser) diff --git a/Yukki/Plugins/Callback.py b/Yukki/Plugins/Callback.py index 98510f5..db17996 100644 --- a/Yukki/Plugins/Callback.py +++ b/Yukki/Plugins/Callback.py @@ -3,16 +3,17 @@ import random from asyncio import QueueEmpty -from config import get_queue from pyrogram import filters from pyrogram.types import InlineKeyboardMarkup -from pytgcalls import StreamType -from pytgcalls.types.input_stream import InputAudioStream, InputStream +from config import get_queue from Yukki import BOT_USERNAME, MUSIC_BOT_NAME, app, db_mem -from Yukki.Core.PyTgCalls import Queues, Yukki +from Yukki.Core.PyTgCalls import Queues from Yukki.Core.PyTgCalls.Converter import convert from Yukki.Core.PyTgCalls.Downloader import download +from Yukki.Core.PyTgCalls.Yukki import (join_stream, pause_stream, + resume_stream, skip_stream, + stop_stream) from Yukki.Database import (_get_playlists, delete_playlist, get_playlist, get_playlist_names, is_active_chat, save_playlist) from Yukki.Database.queue import (add_active_chat, is_active_chat, @@ -65,7 +66,7 @@ async def admin_risghts(_, CallbackQuery): "Music is already Paused", show_alert=True ) await music_off(chat_id) - await Yukki.pytgcalls.pause_stream(chat_id) + await pause_stream(chat_id) await CallbackQuery.message.reply_text( f"🎧 Voicechat Paused by {CallbackQuery.from_user.mention}!", reply_markup=audio_markup2, @@ -78,7 +79,7 @@ async def admin_risghts(_, CallbackQuery): "Music is already Resumed.", show_alert=True ) await music_on(chat_id) - await Yukki.pytgcalls.resume_stream(chat_id) + await resume_stream(chat_id) await CallbackQuery.message.reply_text( f"🎧 Voicechat Resumed by {CallbackQuery.from_user.mention}!", reply_markup=audio_markup2, @@ -91,7 +92,7 @@ async def admin_risghts(_, CallbackQuery): except QueueEmpty: pass await remove_active_chat(chat_id) - await Yukki.pytgcalls.leave_group_call(chat_id) + await stop_stream(chat_id) await CallbackQuery.message.reply_text( f"🎧 Voicechat End/Stopped by {CallbackQuery.from_user.mention}!", reply_markup=audio_markup2, @@ -105,7 +106,7 @@ async def admin_risghts(_, CallbackQuery): await CallbackQuery.message.reply_text( f"No more music in __Queue__ \n\nLeaving Voice Chat..Button Used By :- {CallbackQuery.from_user.mention}" ) - await Yukki.pytgcalls.leave_group_call(chat_id) + await stop_stream(chat_id) await CallbackQuery.message.delete() await CallbackQuery.answer( "Skipped. No more music in Queue", show_alert=True @@ -139,14 +140,7 @@ async def admin_risghts(_, CallbackQuery): None, download, videoid, mystic, title ) raw_path = await convert(downloaded_file) - await Yukki.pytgcalls.change_stream( - chat_id, - InputStream( - InputAudioStream( - raw_path, - ), - ), - ) + await skip_stream(chat_id, raw_path) theme = await check_theme(chat_id) chat_title = await specialfont_to_normal( CallbackQuery.message.chat.title @@ -178,14 +172,7 @@ async def admin_risghts(_, CallbackQuery): else: await CallbackQuery.message.delete() await CallbackQuery.answer("Skipped!", show_alert=True) - await Yukki.pytgcalls.change_stream( - chat_id, - InputStream( - InputAudioStream( - videoid, - ), - ), - ) + await skip_stream(chat_id, videoid) afk = videoid title = db_mem[videoid]["title"] duration_min = db_mem[videoid]["duration"] @@ -318,17 +305,7 @@ async def play_playlist(_, CallbackQuery): None, download, videoid, mystic, title ) raw_path = await convert(downloaded_file) - try: - await Yukki.pytgcalls.join_group_call( - chat_id, - InputStream( - InputAudioStream( - raw_path, - ), - ), - stream_type=StreamType().local_stream, - ) - except Exception as e: + if not await join_stream(chat_id, raw_path): return await mystic.edit( "Error Joining Voice Chat. Make sure Voice Chat is Enabled." ) diff --git a/Yukki/Plugins/Developer.py b/Yukki/Plugins/Developer.py index 656be21..247aedf 100644 --- a/Yukki/Plugins/Developer.py +++ b/Yukki/Plugins/Developer.py @@ -3,7 +3,6 @@ import subprocess import sys import traceback -from asyncio import create_subprocess_shell, sleep, subprocess from html import escape from inspect import getfullargspec from io import StringIO @@ -11,46 +10,26 @@ from pyrogram import filters from pyrogram.errors import MessageNotModified -from pyrogram.types import Message, ReplyKeyboardMarkup +from pyrogram.types import (InlineKeyboardButton, InlineKeyboardMarkup, + Message, ReplyKeyboardMarkup) -from Yukki import SUDOERS, app, userbot +from Yukki import SUDOERS, app from Yukki.Utilities.tasks import add_task, rm_task # Eval and Sh module from WBB __MODULE__ = "Broadcast" __HELP__ = """ - **Note:** Only for Sudo Users. - - /broadcast [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats. - /broadcast_pin [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Disabled Notifications]. - /broadcast_pin_loud [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Enabled Notifications]. - """ -m = None -p = print -r = None -arrow = lambda x: (x.text if isinstance(x, Message) else "") + "\n`→`" - - -async def eor(msg: Message, **kwargs): - func = ( - (msg.edit_text if msg.from_user.is_self else msg.reply) - if msg.from_user - else msg.reply - ) - spec = getfullargspec(func.__wrapped__).args - return await func(**{k: v for k, v in kwargs.items() if k in spec}) - async def aexec(code, client, message): exec( @@ -60,82 +39,37 @@ async def aexec(code, client, message): return await locals()["__aexec"](client, message) -async def iter_edit(message: Message, text: str): - async for m in userbot.iter_history(message.chat.id): - - # If no replies found, reply - if m.message_id == message.message_id: - return 0 - - if not m.from_user or not m.text or not m.reply_to_message: - continue - - if ( - (m.reply_to_message.message_id == message.message_id) - and (m.from_user.id == message.from_user.id) - and ("→" in m.text) - ): - try: - return await m.edit(text) - except MessageNotModified: - return +async def edit_or_reply(msg: Message, **kwargs): + func = msg.edit_text if msg.from_user.is_self else msg.reply + spec = getfullargspec(func.__wrapped__).args + await func(**{k: v for k, v in kwargs.items() if k in spec}) @app.on_message( filters.user(SUDOERS) & ~filters.forwarded & ~filters.via_bot - & ~filters.edited - & filters.command("eval"), + & filters.command("eval") ) -async def executor(client, message: Message): - global m, p, r +async def executor(client, message): if len(message.command) < 2: - return await eor(message, text="Command needed to execute") - + return await edit_or_reply( + message, text="__Nigga Give me some command to execute.__" + ) try: cmd = message.text.split(" ", maxsplit=1)[1] except IndexError: return await message.delete() - - if message.chat.type == "channel": - return - - m = message - p = print - - # To prevent keyboard input attacks - if m.reply_to_message: - r = m.reply_to_message - if r.reply_markup and isinstance(r.reply_markup, ReplyKeyboardMarkup): - return await eor(m, text="INSECURE!") - status = None + t1 = time() old_stderr = sys.stderr old_stdout = sys.stdout redirected_output = sys.stdout = StringIO() redirected_error = sys.stderr = StringIO() stdout, stderr, exc = None, None, None try: - task, task_id = await add_task( - aexec, - "Eval", - cmd, - client, - m, - ) - - text = f"{arrow('')} Pending Task `{task_id}`" - if not message.edit_date: - status = await m.reply(text, quote=True) - - await task - except Exception as e: - e = traceback.format_exc() - print(e) - exc = e.splitlines()[-1] - - await rm_task() - + await aexec(cmd, client, message) + except Exception: + exc = traceback.format_exc() stdout = redirected_output.getvalue() stderr = redirected_error.getvalue() sys.stdout = old_stdout @@ -149,87 +83,116 @@ async def executor(client, message: Message): evaluation = stdout else: evaluation = "Success" - - final_output = f"**→**\n`{escape(evaluation.strip())}`" - - if len(final_output) > 4102: + final_output = f"**OUTPUT**:\n```{evaluation.strip()}```" + if len(final_output) > 4096: filename = "output.txt" with open(filename, "w+", encoding="utf8") as out_file: out_file.write(str(evaluation.strip())) + t2 = time() + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="⏳", callback_data=f"runtime {t2-t1} Seconds" + ) + ] + ] + ) await message.reply_document( document=filename, - caption="`→`\n **Attached Document**", + caption=f"**INPUT:**\n`{cmd[0:980]}`\n\n**OUTPUT:**\n`Attached Document`", quote=False, + reply_markup=keyboard, ) + await message.delete() os.remove(filename) - if status: - await status.delete() - return + else: + t2 = time() + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="⏳", + callback_data=f"runtime {round(t2-t1, 3)} Seconds", + ), + InlineKeyboardButton( + text="Delete Output", + callback_data=f"forceclose abc|{message.from_user.id}", + ), + ] + ] + ) + await edit_or_reply(message, text=final_output, reply_markup=keyboard) - # Edit the output if input is edited - if message.edit_date: - status_ = await iter_edit(message, final_output) - if status_ == 0: - return await message.reply(final_output, quote=True) - return - if not status.from_user: - status = await userbot.get_messages(status.chat.id, status.message_id) - await eor(status, text=final_output, quote=True) + +@app.on_callback_query(filters.regex(r"runtime")) +async def runtime_func_cq(_, cq): + runtime = cq.data.split(None, 1)[1] + await cq.answer(runtime, show_alert=True) @app.on_message( filters.user(SUDOERS) & ~filters.forwarded & ~filters.via_bot - & ~filters.edited & filters.command("sh"), ) -async def shellrunner(_, message: Message): +async def shellrunner(client, message): if len(message.command) < 2: - return await eor(message, text="**Usage:**\n/sh git pull") - - if message.reply_to_message: - r = message.reply_to_message - if r.reply_markup and isinstance( - r.reply_markup, - ReplyKeyboardMarkup, - ): - return await eor(message, text="INSECURE!") - output = "" + return await edit_or_reply(message, text="**Usage:**\n/sh git pull") text = message.text.split(None, 1)[1] if "\n" in text: code = text.split("\n") - shell = " ".join(code) + output = "" + for x in code: + shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x) + try: + process = subprocess.Popen( + shell, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + except Exception as err: + print(err) + await edit_or_reply(message, text=f"**ERROR:**\n```{err}```") + output += f"**{code}**\n" + output += process.stdout.read()[:-1].decode("utf-8") + output += "\n" else: - shell = text - process = await create_subprocess_shell( - shell, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - out, errorz = await process.communicate() - if errorz: - error = f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{errorz.decode('utf-8')}```" - return await eor(message, text=error) - output += out.decode("utf-8") - output += "\n" + shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text) + for a in range(len(shell)): + shell[a] = shell[a].replace('"', "") + try: + process = subprocess.Popen( + shell, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + except Exception as err: + print(err) + exc_type, exc_obj, exc_tb = sys.exc_info() + errors = traceback.format_exception( + etype=exc_type, + value=exc_obj, + tb=exc_tb, + ) + return await edit_or_reply( + message, text=f"**ERROR:**\n```{''.join(errors)}```" + ) + output = process.stdout.read()[:-1].decode("utf-8") if str(output) == "\n": output = None if output: - if len(f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{(output)}```") > 4118: + if len(output) > 4096: with open("output.txt", "w+") as file: file.write(output) - await message.reply_document( - "output.txt", caption=f"{escape(text)}" + await app.send_document( + message.chat.id, + "output.txt", + reply_to_message_id=message.message_id, + caption="`Output`", ) return os.remove("output.txt") - await eor( - message, - text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{(output)}```", - ) + await edit_or_reply(message, text=f"**OUTPUT:**\n```{output}```") else: - return await eor( - message, - text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`", - ) - + await edit_or_reply(message, text="**OUTPUT: **\n`No output`") diff --git a/Yukki/Plugins/Lyrics.py b/Yukki/Plugins/Lyrics.py index 11b4d1e..7fad26f 100644 --- a/Yukki/Plugins/Lyrics.py +++ b/Yukki/Plugins/Lyrics.py @@ -1,5 +1,5 @@ -import re import os +import re import lyricsgenius from pyrogram import Client, filters @@ -113,4 +113,3 @@ async def lrsearch(_, message: Message): os.remove(filename) else: await m.edit(xxx) - diff --git a/Yukki/Plugins/Multi-Assistant.py b/Yukki/Plugins/Multi-Assistant.py new file mode 100644 index 0000000..43c8102 --- /dev/null +++ b/Yukki/Plugins/Multi-Assistant.py @@ -0,0 +1,104 @@ +import random + +from pyrogram import filters +from pyrogram.raw.functions.messages import DeleteHistory +from pyrogram.types import (CallbackQuery, InlineKeyboardButton, + InlineKeyboardMarkup, InlineQueryResultArticle, + InlineQueryResultPhoto, InputTextMessageContent, + Message) + +from Yukki import SUDOERS, app +from Yukki.Database import get_assistant, save_assistant +from Yukki.Utilities.assistant import get_assistant_details, random_assistant + +__MODULE__ = "Multi Assistant" +__HELP__ = """ + + +/checkassistant +- Check the alloted assistant of your chat + + + +** For Sudo Users: ** + +/changeassistant [ASS NUMBER] +- Change the previoius alloted assistant to new one. + +/setassistant [ASS NUMBER or Random] +- Set a assistant account for chat. + +""" + + +ass_num_list = ["1", "2", "3", "4", "5"] + + +@app.on_message(filters.command("changeassistant") & filters.user(SUDOERS)) +async def assis_change(_, message: Message): + usage = f"**Usage:**\n/changeassistant [ASS_NO]\n\nSelect from them\n{' | '.join(ass_num_list)}" + if len(message.command) != 2: + return await message.reply_text(usage) + num = message.text.split(None, 1)[1].strip() + if num not in ass_num_list: + return await message.reply_text(usage) + ass_num = int(message.text.strip().split()[1]) + _assistant = await get_assistant(message.chat.id, "assistant") + if not _assistant: + return await message.reply_text( + "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /setassistant" + ) + else: + ass = _assistant["saveassistant"] + assis = { + "saveassistant": ass_num, + } + await save_assistant(message.chat.id, "assistant", assis) + await message.reply_text( + f"**Changed Assistant**\n\nChanged Assistant Account from **{ass}** to Assistant Number **{ass_num}**" + ) + + +ass_num_list2 = ["1", "2", "3", "4", "5", "Random"] + + +@app.on_message(filters.command("setassistant") & filters.user(SUDOERS)) +async def assis_change(_, message: Message): + usage = f"**Usage:**\n/setassistant [ASS_NO or Random]\n\nSelect from them\n{' | '.join(ass_num_list2)}\n\nUse 'Random' to set random Assistant" + if len(message.command) != 2: + return await message.reply_text(usage) + query = message.text.split(None, 1)[1].strip() + if query not in ass_num_list2: + return await message.reply_text(usage) + if str(query) == "Random": + ran_ass = random.choice(random_assistant) + else: + ran_ass = int(message.text.strip().split()[1]) + _assistant = await get_assistant(message.chat.id, "assistant") + if not _assistant: + await message.reply_text( + f"**__Yukki Music Bot Assistant Alloted__**\n\nAssistant No. **{ran_ass}**" + ) + assis = { + "saveassistant": ran_ass, + } + await save_assistant(message.chat.id, "assistant", assis) + else: + ass = _assistant["saveassistant"] + return await message.reply_text( + f"Pre-Saved Assistant Number {ass} Found.\n\nYou can change Assistant Via /changeassistant" + ) + + +@app.on_message(filters.command("checkassistant") & filters.group) +async def check_ass(_, message: Message): + _assistant = await get_assistant(message.chat.id, "assistant") + if not _assistant: + return await message.reply_text( + "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play" + ) + else: + ass = _assistant["saveassistant"] + return await message.reply_text( + f"Pre-Saved Assistant Found\n\nAssistanty Number {ass} " + ) diff --git a/Yukki/Plugins/Playlist.py b/Yukki/Plugins/Playlist.py index f10909f..9918832 100644 --- a/Yukki/Plugins/Playlist.py +++ b/Yukki/Plugins/Playlist.py @@ -7,7 +7,9 @@ from Yukki.Database import (_get_playlists, delete_playlist, get_playlist, get_playlist_names, save_playlist) from Yukki.Decorators.admins import AdminRightsCheck +from Yukki.Decorators.assistant import AssistantAdd from Yukki.Decorators.checker import checker, checkerCB +from Yukki.Decorators.permission import PermissionCheck from Yukki.Inline import (add_genre_markup, check_genre_markup, check_markup, delete_playlist_markuup, download_markup, others_markup, play_genre_playlist, playlist_markup, @@ -31,8 +33,10 @@ """ -@app.on_message(filters.command("playplaylist")) +@app.on_message(filters.command("playplaylist") & filters.group) @checker +@PermissionCheck +@AssistantAdd async def play_playlist_cmd(_, message): thumb = "Utils/Playlist.jpg" await message.delete() @@ -100,8 +104,10 @@ async def play_playlist_cmd(_, message): return -@app.on_message(filters.command("playlist")) +@app.on_message(filters.command("playlist") & filters.group) @checker +@PermissionCheck +@AssistantAdd async def playlist(_, message): thumb = "Utils/Playlist.jpg" user_id = message.from_user.id @@ -152,7 +158,7 @@ async def playlist(_, message): ] options_Genre = [ - "Weeb", + "Rock", "Sad", "Party", "Lofi", @@ -163,7 +169,7 @@ async def playlist(_, message): ] -@app.on_message(filters.command("delmyplaylist")) +@app.on_message(filters.command("delmyplaylist") & filters.group) async def del_cmd(_, message): usage = f"Usage:\n\n/delmyplaylist [Genre] [Numbers between 1-30] ( to delete a particular music in playlist )\n\nor\n\n/delmyplaylist [Genre] all ( to delete whole playlist )\n\n**Genres:-**\n{' | '.join(options_Genre)}" if len(message.command) < 3: @@ -210,7 +216,7 @@ async def del_cmd(_, message): await message.reply_text("You have no such music in Playlist.") -@app.on_message(filters.command("delgroupplaylist")) +@app.on_message(filters.command("delgroupplaylist") & filters.group) @AdminRightsCheck async def delgroupplaylist(_, message): usage = f"Usage:\n\n/delgroupplaylist [Genre] [Numbers between 1-30] ( to delete a particular music in playlist )\n\nor\n\n /delgroupplaylist [Genre] all ( to delete whole playlist )\n\n**Genres:-**\n{' | '.join(options_Genre)}" diff --git a/Yukki/Plugins/Start.py b/Yukki/Plugins/Start.py index 540a750..9773f15 100644 --- a/Yukki/Plugins/Start.py +++ b/Yukki/Plugins/Start.py @@ -1,4 +1,5 @@ import asyncio +import random import time from sys import version as pyver from typing import Dict, List, Union @@ -8,19 +9,21 @@ from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message) -from Yukki import ASSID, BOT_ID, MUSIC_BOT_NAME, OWNER_ID, SUDOERS, app +from Yukki import ASSIDS, BOT_ID, MUSIC_BOT_NAME, OWNER_ID, SUDOERS, app from Yukki import boottime as bot_start_time from Yukki import db from Yukki.Core.PyTgCalls import Yukki from Yukki.Database import (add_nonadmin_chat, add_served_chat, blacklisted_chats, get_assistant, get_authuser, - get_authuser_names, is_nonadmin_chat, + get_authuser_names, get_start, is_nonadmin_chat, is_served_chat, remove_active_chat, - remove_nonadmin_chat, save_assistant) + remove_nonadmin_chat, save_assistant, save_start) from Yukki.Decorators.admins import ActualAdminCB from Yukki.Decorators.permission import PermissionCheck -from Yukki.Inline import (custommarkup, dashmarkup, setting_markup, setting_markup2, - start_pannel, usermarkup, volmarkup) +from Yukki.Inline import (custommarkup, dashmarkup, setting_markup, + setting_markup2, start_pannel, usermarkup, + volmarkup) +from Yukki.Utilities.assistant import get_assistant_details, random_assistant from Yukki.Utilities.ping import get_readable_time welcome_group = 2 @@ -29,14 +32,15 @@ __HELP__ = """ -/start +/start - Start the Bot. -/help +/help - Get Commands Helper Menu. -/settings -- Get Settings DashBoard. +/settings +- Get Settings button. + """ @@ -47,13 +51,36 @@ async def welcome(_, message: Message): pass else: await add_served_chat(chat_id) - if chat_id in await blacklisted_chats(): - await message.reply_text( - f"Hushh, Your chat group[{message.chat.title}] has been blacklisted!\n\nAsk any Sudo User to whitelist your chat" - ) - await app.leave_chat(chat_id) for member in message.new_chat_members: try: + if member.id == BOT_ID: + if chat_id in await blacklisted_chats(): + await message.reply_text( + f"Hushh, Your chat group[{message.chat.title}] has been blacklisted!\n\nAsk any Sudo User to whitelist your chat" + ) + await app.leave_chat(chat_id) + _assistant = await get_assistant(message.chat.id, "assistant") + if not _assistant: + ran_ass = random.choice(random_assistant) + assis = { + "saveassistant": ran_ass, + } + await save_assistant(message.chat.id, "assistant", assis) + else: + ran_ass = _assistant["saveassistant"] + ( + ASS_ID, + ASS_NAME, + ASS_USERNAME, + ASS_ACC, + ) = await get_assistant_details(ran_ass) + out = start_pannel() + await message.reply_text( + f"Welcome To {MUSIC_BOT_NAME}\n\nPromote me as administrator in your group otherwise I will not function properly.\n\nAssistant Username:- @{ASS_USERNAME}\nAssistant ID:- {ASS_ID}", + reply_markup=InlineKeyboardMarkup(out[1]), + ) + if member.id in ASSIDS: + return await remove_active_chat(chat_id) if member.id in OWNER_ID: return await message.reply_text( f"{MUSIC_BOT_NAME}'s Owner[{member.mention}] has just joined your chat." @@ -62,15 +89,7 @@ async def welcome(_, message: Message): return await message.reply_text( f"A member of {MUSIC_BOT_NAME}'s Sudo User[{member.mention}] has just joined your chat." ) - if member.id == ASSID: - await remove_active_chat(chat_id) - if member.id == BOT_ID: - out = start_pannel() - await message.reply_text( - f"Welcome To {MUSIC_BOT_NAME}\n\nPromote me as administrator in your group otherwise I will not function properly.", - reply_markup=InlineKeyboardMarkup(out[1]), - ) - return + return except: return @@ -92,19 +111,22 @@ async def useradd(_, message: Message): @PermissionCheck async def settings(_, message: Message): c_id = message.chat.id - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") if not _check: assis = { "volume": 100, } - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) volume = 100 else: volume = _check["volume"] text, buttons = setting_markup2() await asyncio.gather( message.delete(), - message.reply_text(f"{text}\n\n**Group:** {message.chat.title}\n**Group ID:** {message.chat.id}\n**Volume Level:** {volume}%", reply_markup=InlineKeyboardMarkup(buttons)), + message.reply_text( + f"{text}\n\n**Group:** {message.chat.title}\n**Group ID:** {message.chat.id}\n**Volume Level:** {volume}%", + reply_markup=InlineKeyboardMarkup(buttons), + ), ) @@ -125,12 +147,12 @@ async def settingm(_, CallbackQuery): c_title = CallbackQuery.message.chat.title c_id = CallbackQuery.message.chat.id chat_id = CallbackQuery.message.chat.id - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") if not _check: assis = { "volume": 100, } - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) volume = 100 else: volume = _check["volume"] @@ -195,7 +217,7 @@ async def start_markup_check(_, CallbackQuery): if command == "AV": await CallbackQuery.answer("Bot Settings ...") text, buttons = volmarkup() - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", @@ -216,7 +238,7 @@ async def start_markup_check(_, CallbackQuery): if command == "Dashboard": await CallbackQuery.answer("Dashboard...") text, buttons = dashmarkup() - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n\nCheck {MUSIC_BOT_NAME}'s System Stats In the DashBoard Here! More Functions adding very soon! Keep on Checking Support Channel.", @@ -225,7 +247,7 @@ async def start_markup_check(_, CallbackQuery): if command == "Custommarkup": await CallbackQuery.answer("Bot Settings ...") text, buttons = custommarkup() - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", @@ -241,7 +263,7 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = volmarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", @@ -257,7 +279,7 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = volmarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", @@ -273,7 +295,7 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = volmarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", @@ -289,14 +311,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = volmarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "PTEN": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume + 10 if int(volume) > 200: @@ -311,14 +333,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "MTEN": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume - 10 if int(volume) > 200: @@ -333,14 +355,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "PTF": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume + 25 if int(volume) > 200: @@ -355,14 +377,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "MTF": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume - 25 if int(volume) > 200: @@ -377,14 +399,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "PFZ": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume + 50 if int(volume) > 200: @@ -399,14 +421,14 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", reply_markup=InlineKeyboardMarkup(buttons), ) if command == "MFZ": - _check = await get_assistant(c_id, "assistant") + _check = await get_start(c_id, "assistant") volume = _check["volume"] volume = volume - 50 if int(volume) > 200: @@ -421,7 +443,7 @@ async def start_markup_check(_, CallbackQuery): await CallbackQuery.answer("Setting Audio Changes ...") except: return await CallbackQuery.answer("No active Group Call...") - await save_assistant(c_id, "assistant", assis) + await save_start(c_id, "assistant", assis) text, buttons = custommarkup() await CallbackQuery.edit_message_text( text=f"{text}\n\n**Group:** {c_title}\n**Group ID:** {c_id}\n**Volume Level:** {volume}%\n**Audio Quality:** Default Best", diff --git a/Yukki/Plugins/Stats.py b/Yukki/Plugins/Stats.py index eedda10..751aa7c 100644 --- a/Yukki/Plugins/Stats.py +++ b/Yukki/Plugins/Stats.py @@ -11,14 +11,15 @@ import multiprocessing import psutil +from pymongo import MongoClient from pyrogram import Client from pyrogram import __version__ as pyrover from pyrogram import filters from pyrogram.types import Message -from pymongo import MongoClient + from config import MONGO_DB_URI -from Yukki import (BOT_ID, MUSIC_BOT_NAME, SUDOERS, app, boottime, - userbot) +from Yukki import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5, + BOT_ID, MUSIC_BOT_NAME, SUDOERS, app, boottime) from Yukki.Database import get_gbans_count, get_served_chats, get_sudoers from Yukki.Inline import (stats1, stats2, stats3, stats4, stats5, stats6, stats7) @@ -150,12 +151,16 @@ async def stats_markup(_, CallbackQuery): pymongo = MongoClient(MONGO_DB_URI) except Exception as e: print(e) - return await CallbackQuery.edit_message_text("Failed to get Mongo DB stats", reply_markup=stats5) + return await CallbackQuery.edit_message_text( + "Failed to get Mongo DB stats", reply_markup=stats5 + ) try: db = pymongo.Yukki except Exception as e: print(e) - return await CallbackQuery.edit_message_text("Failed to get Mongo DB stats", reply_markup=stats5) + return await CallbackQuery.edit_message_text( + "Failed to get Mongo DB stats", reply_markup=stats5 + ) call = db.command("dbstats") database = call["db"] datasize = call["dataSize"] / 1024 @@ -190,7 +195,11 @@ async def stats_markup(_, CallbackQuery): "Getting Assistant Stats.. Please Wait...", reply_markup=stats7 ) groups_ub = channels_ub = bots_ub = privates_ub = total_ub = 0 - async for i in userbot.iter_dialogs(): + groups_ub2 = channels_ub2 = bots_ub2 = privates_ub2 = total_ub2 = 0 + groups_ub3 = channels_ub3 = bots_ub3 = privates_ub3 = total_ub3 = 0 + groups_ub4 = channels_ub4 = bots_ub4 = privates_ub4 = total_ub4 = 0 + groups_ub5 = channels_ub5 = bots_ub5 = privates_ub5 = total_ub5 = 0 + async for i in ASS_CLI_1.iter_dialogs(): t = i.chat.type total_ub += 1 if t in ["supergroup", "group"]: @@ -202,14 +211,91 @@ async def stats_markup(_, CallbackQuery): elif t == "private": privates_ub += 1 + async for i in ASS_CLI_2.iter_dialogs(): + t = i.chat.type + total_ub2 += 1 + if t in ["supergroup", "group"]: + groups_ub2 += 1 + elif t == "channel": + channels_ub2 += 1 + elif t == "bot": + bots_ub2 += 1 + elif t == "private": + privates_ub2 += 1 + + async for i in ASS_CLI_3.iter_dialogs(): + t = i.chat.type + total_ub3 += 1 + if t in ["supergroup", "group"]: + groups_ub3 += 1 + elif t == "channel": + channels_ub3 += 1 + elif t == "bot": + bots_ub3 += 1 + elif t == "private": + privates_ub3 += 1 + + async for i in ASS_CLI_4.iter_dialogs(): + t = i.chat.type + total_ub4 += 1 + if t in ["supergroup", "group"]: + groups_ub4 += 1 + elif t == "channel": + channels_ub4 += 1 + elif t == "bot": + bots_ub4 += 1 + elif t == "private": + privates_ub4 += 1 + + async for i in ASS_CLI_5.iter_dialogs(): + t = i.chat.type + total_ub5 += 1 + if t in ["supergroup", "group"]: + groups_ub5 += 1 + elif t == "channel": + channels_ub5 += 1 + elif t == "bot": + bots_ub5 += 1 + elif t == "private": + privates_ub5 += 1 + smex = f""" [•]Assistant Stats +Assistant One: **Dialogs:** {total_ub} **Groups:** {groups_ub} **Channels:** {channels_ub} **Bots:** {bots_ub} -**Users:** {privates_ub}""" +**Users:** {privates_ub} + +Assistant Two: +**Dialogs:** {total_ub2} +**Groups:** {groups_ub2} +**Channels:** {channels_ub2} +**Bots:** {bots_ub2} +**Users:** {privates_ub2} + +Assistant Three: +**Dialogs:** {total_ub3} +**Groups:** {groups_ub3} +**Channels:** {channels_ub3} +**Bots:** {bots_ub3} +**Users:** {privates_ub3} + +Assistant Four: +**Dialogs:** {total_ub4} +**Groups:** {groups_ub4} +**Channels:** {channels_ub4} +**Bots:** {bots_ub4} +**Users:** {privates_ub4} + +Assistant Five: +**Dialogs:** {total_ub5} +**Groups:** {groups_ub5} +**Channels:** {channels_ub5} +**Bots:** {bots_ub5} +**Users:** {privates_ub5}""" await CallbackQuery.edit_message_text(smex, reply_markup=stats6) if command == "gen_stats": start = datetime.now() diff --git a/Yukki/Plugins/SudoUsers.py b/Yukki/Plugins/SudoUsers.py index 4cd746d..96d7d2e 100644 --- a/Yukki/Plugins/SudoUsers.py +++ b/Yukki/Plugins/SudoUsers.py @@ -4,11 +4,11 @@ import subprocess from sys import version as pyver -from config import OWNER_ID from pyrogram import Client, filters from pyrogram.errors import FloodWait from pyrogram.types import Message +from config import OWNER_ID from Yukki import BOT_ID, MUSIC_BOT_NAME, OWNER_ID, SUDOERS, app from Yukki.Database import (add_gban_user, add_off, add_on, add_sudo, get_active_chats, get_served_chats, get_sudoers, diff --git a/Yukki/Plugins/Voicechat.py b/Yukki/Plugins/Voicechat.py index ac421d8..1dc2bb6 100644 --- a/Yukki/Plugins/Voicechat.py +++ b/Yukki/Plugins/Voicechat.py @@ -4,17 +4,17 @@ import subprocess from sys import version as pyver -from config import get_queue from pyrogram import Client, filters -from pyrogram.types import Message +from pyrogram.types import (InlineKeyboardMarkup, InputMediaPhoto, Message, + Voice) -from Yukki import SUDOERS, app, db_mem, userbot -from Yukki.Database import get_active_chats, is_active_chat +from config import get_queue +from Yukki import SUDOERS, app, db_mem +from Yukki.Database import (get_active_chats, get_assistant, is_active_chat, + save_assistant) from Yukki.Decorators.checker import checker, checkerCB from Yukki.Inline import primary_markup - -from pyrogram.types import (InlineKeyboardMarkup, InputMediaPhoto, Message, - Voice) +from Yukki.Utilities.assistant import get_assistant_details, random_assistant loop = asyncio.get_event_loop() @@ -37,7 +37,6 @@ """ - @app.on_callback_query(filters.regex("pr_go_back_timer")) async def pr_go_back_timer(_, CallbackQuery): await CallbackQuery.answer() @@ -49,10 +48,10 @@ async def pr_go_back_timer(_, CallbackQuery): dur_left = db_mem[CallbackQuery.message.chat.id]["left"] duration_min = db_mem[CallbackQuery.message.chat.id]["total"] buttons = primary_markup(videoid, user_id, dur_left, duration_min) - await CallbackQuery.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(buttons)) - - - + await CallbackQuery.edit_message_reply_markup( + reply_markup=InlineKeyboardMarkup(buttons) + ) + @app.on_callback_query(filters.regex("timer_checkup_markup")) async def timer_checkup_markup(_, CallbackQuery): @@ -167,7 +166,23 @@ async def basffy(_, message): return chat = message.text.split(None, 2)[1] try: - await userbot.join_chat(chat) + chat_id = (await app.get_chat(chat)).id + except: + return await message.reply_text( + "Add Bot to this Chat First.. Unknown Chat for the bot" + ) + _assistant = await get_assistant(chat_id, "assistant") + if not _assistant: + return await message.reply_text( + "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play inside {Chat}'s Group" + ) + else: + ran_ass = _assistant["saveassistant"] + ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details( + ran_ass + ) + try: + await ASS_ACC.join_chat(chat_id) except Exception as e: await message.reply_text(f"Failed\n**Possible reason could be**:{e}") return @@ -200,7 +215,23 @@ async def baujaf(_, message): return chat = message.text.split(None, 2)[1] try: - await userbot.leave_chat(chat) + chat_id = (await app.get_chat(chat)).id + except: + return await message.reply_text( + "Add Bot to this Chat First.. Unknown Chat for the bot" + ) + _assistant = await get_assistant(chat, "assistant") + if not _assistant: + return await message.reply_text( + "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play inside {Chat}'s Group" + ) + else: + ran_ass = _assistant["saveassistant"] + ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details( + ran_ass + ) + try: + await ASS_ACC.leave_chat(chat_id) except Exception as e: await message.reply_text(f"Failed\n**Possible reason could be**:{e}") return diff --git a/Yukki/Utilities/assistant.py b/Yukki/Utilities/assistant.py new file mode 100644 index 0000000..df7d2d2 --- /dev/null +++ b/Yukki/Utilities/assistant.py @@ -0,0 +1,35 @@ +from Yukki import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5, + ASSID1, ASSID2, ASSID3, ASSID4, ASSID5, ASSNAME1, ASSNAME2, + ASSNAME3, ASSNAME4, ASSNAME5, ASSUSERNAME1, ASSUSERNAME2, + ASSUSERNAME3, ASSUSERNAME4, ASSUSERNAME5) + +random_assistant = ["5", "1", "2", "3", "4"] + + +async def get_assistant_details(assistant: int): + if int(assistant) == 1: + x = ASSID1 + y = ASSNAME1 + z = ASSUSERNAME1 + a = ASS_CLI_1 + elif int(assistant) == 2: + x = ASSID2 + y = ASSNAME2 + z = ASSUSERNAME2 + a = ASS_CLI_2 + elif int(assistant) == 3: + x = ASSID3 + y = ASSNAME3 + z = ASSUSERNAME3 + a = ASS_CLI_3 + elif int(assistant) == 4: + x = ASSID4 + y = ASSNAME4 + z = ASSUSERNAME4 + a = ASS_CLI_4 + elif int(assistant) == 5: + x = ASSID5 + y = ASSNAME5 + z = ASSUSERNAME5 + a = ASS_CLI_5 + return x, y, z, a diff --git a/Yukki/Utilities/stream.py b/Yukki/Utilities/stream.py index 1348265..86d188c 100644 --- a/Yukki/Utilities/stream.py +++ b/Yukki/Utilities/stream.py @@ -2,13 +2,12 @@ import os import shutil -from config import get_queue from pyrogram.types import InlineKeyboardMarkup -from pytgcalls import StreamType -from pytgcalls.types.input_stream import InputAudioStream, InputStream +from config import get_queue from Yukki import BOT_USERNAME, db_mem -from Yukki.Core.PyTgCalls import Queues, Yukki +from Yukki.Core.PyTgCalls import Queues +from Yukki.Core.PyTgCalls.Yukki import join_stream from Yukki.Database import (add_active_chat, is_active_chat, music_off, music_on) from Yukki.Inline import (audio_markup, audio_markup2, primary_markup, @@ -65,17 +64,7 @@ async def start_stream( os.remove(thumb) return else: - try: - await Yukki.pytgcalls.join_group_call( - CallbackQuery.message.chat.id, - InputStream( - InputAudioStream( - file, - ), - ), - stream_type=StreamType().local_stream, - ) - except Exception as e: + if not await join_stream(CallbackQuery.message.chat.id, file): return await mystic.edit( "Error Joining Voice Chat. Make sure Voice Chat is Enabled." ) @@ -144,21 +133,10 @@ async def start_stream_audio( await mystic.delete() return else: - try: - await Yukki.pytgcalls.join_group_call( - message.chat.id, - InputStream( - InputAudioStream( - file, - ), - ), - stream_type=StreamType().local_stream, - ) - except Exception as e: - await mystic.edit( + if not await join_stream(message.chat.id, file): + return await mystic.edit( "Error Joining Voice Chat. Make sure Voice Chat is Enabled." ) - return get_queue[message.chat.id] = [] got_queue = get_queue.get(message.chat.id) title = title diff --git a/Yukki/Utilities/thumbnails.py b/Yukki/Utilities/thumbnails.py index 413e5a9..df3b656 100644 --- a/Yukki/Utilities/thumbnails.py +++ b/Yukki/Utilities/thumbnails.py @@ -33,9 +33,23 @@ async def gen_thumb(thumbnail, title, userid, theme, ctitle): img = Image.open(f"cache/temp{userid}.png") draw = ImageDraw.Draw(img) font = ImageFont.truetype("Utils/finalfont.ttf", 85) - font2 = ImageFont.truetype("Utils/finalfont.ttf", 60) - draw.text((20, 45), f"Playing on: {ctitle[:14]}...", fill= "white", stroke_width = 1, stroke_fill="white", font=font2) - draw.text((25, 595), f"{title[:27]}...", fill="white", stroke_width = 2, stroke_fill="white" ,font=font) + font2 = ImageFont.truetype("Utils/finalfont.ttf", 60) + draw.text( + (20, 45), + f"Playing on: {ctitle[:14]}...", + fill="white", + stroke_width=1, + stroke_fill="white", + font=font2, + ) + draw.text( + (25, 595), + f"{title[:27]}...", + fill="white", + stroke_width=2, + stroke_fill="white", + font=font, + ) img.save(f"cache/final{userid}.png") os.remove(f"cache/temp{userid}.png") os.remove(f"cache/thumb{userid}.jpg") diff --git a/Yukki/__init__.py b/Yukki/__init__.py index 0bcea0a..1c69b36 100644 --- a/Yukki/__init__.py +++ b/Yukki/__init__.py @@ -4,14 +4,15 @@ from os import listdir, mkdir from aiohttp import ClientSession -from config import ASSISTANT_PREFIX, DURATION_LIMIT_MIN, LOG_GROUP_ID -from config import MONGO_DB_URI as mango -from config import MUSIC_BOT_NAME, OWNER_ID, SUDO_USERS, get_queue from motor.motor_asyncio import AsyncIOMotorClient as Bot from rich.console import Console from rich.table import Table -from Yukki.Core.Clients.cli import app, userbot +from config import ASSISTANT_PREFIX, DURATION_LIMIT_MIN, LOG_GROUP_ID +from config import MONGO_DB_URI as mango +from config import MUSIC_BOT_NAME, OWNER_ID, SUDO_USERS, get_queue +from Yukki.Core.Clients.cli import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, + ASS_CLI_4, ASS_CLI_5, app) from Yukki.Core.Logger.Log import (startup_delete_last, startup_edit_last, startup_send_new) from Yukki.Utilities.changers import time_to_seconds @@ -32,7 +33,11 @@ ### Clients app = app -userbot = userbot +ASS_CLI_1 = ASS_CLI_1 +ASS_CLI_2 = ASS_CLI_2 +ASS_CLI_3 = ASS_CLI_3 +ASS_CLI_4 = ASS_CLI_4 +ASS_CLI_5 = ASS_CLI_5 aiohttpsession = ClientSession() ### Config @@ -49,16 +54,36 @@ BOT_USERNAME = "" ### Assistant Info -ASSID = 0 -ASSNAME = "" -ASSUSERNAME = "" -ASSMENTION = "" +ASSID1 = 0 +ASSNAME1 = "" +ASSUSERNAME1 = "" +ASSMENTION1 = "" +ASSID2 = 0 +ASSNAME2 = "" +ASSUSERNAME2 = "" +ASSMENTION2 = "" +ASSID3 = 0 +ASSNAME3 = "" +ASSUSERNAME3 = "" +ASSMENTION3 = "" +ASSID4 = 0 +ASSNAME4 = "" +ASSUSERNAME4 = "" +ASSMENTION4 = "" +ASSID5 = 0 +ASSNAME5 = "" +ASSUSERNAME5 = "" +ASSMENTION5 = "" async def initiate_bot(): global SUDOERS, Imp_Modules, OWNER_ID global BOT_ID, BOT_NAME, BOT_USERNAME - global ASSID, ASSNAME, ASSMENTION, ASSUSERNAME + global ASSID1, ASSNAME1, ASSMENTION1, ASSUSERNAME1 + global ASSID2, ASSNAME2, ASSMENTION2, ASSUSERNAME2 + global ASSID3, ASSNAME3, ASSMENTION3, ASSUSERNAME3 + global ASSID4, ASSNAME4, ASSMENTION4, ASSUSERNAME4 + global ASSID5, ASSNAME5, ASSMENTION5, ASSUSERNAME5 os.system("clear") header = Table(show_header=True, header_style="bold yellow") header.add_column( @@ -66,12 +91,24 @@ async def initiate_bot(): ) console.print(header) with console.status( - "[magenta] Booting up The Yukki Music Bot...", + "[magenta] Booting up the Bot...", ) as status: console.print("┌ [red]Booting Up The Clients...\n") await app.start() - await userbot.start() - console.print("└ [green]Clients Booted Successfully!") + console.print("└ [green]Booted Bot Client") + console.print("\n┌ [red]Booting Up The Assistant Clients...") + await ASS_CLI_1.start() + console.print("├ [yellow]Booted Assistant Client 1") + await ASS_CLI_2.start() + console.print("├ [yellow]Booted Assistant Client 2") + await ASS_CLI_3.start() + console.print("├ [yellow]Booted Assistant Client 3") + await ASS_CLI_4.start() + console.print("├ [yellow]Booted Assistant Client 4") + await ASS_CLI_5.start() + console.print("├ [yellow]Booted Assistant Client 5") + await asyncio.sleep(0.5) + console.print("└ [green]Assistant Clients Booted Successfully!") initial = await startup_send_new("Starting Yukki Music Bot...") await asyncio.sleep(0.5) all_over = await startup_send_new("Checking Required Directories...") @@ -88,24 +125,62 @@ async def initiate_bot(): mkdir("search") console.print("└ [green]Directories Updated!") await asyncio.sleep(0.9) - ___ = await startup_edit_last(all_over, "Refurbishing Necessary Data...") + ___ = await startup_edit_last( + all_over, "Refurbishing Necessary Data..." + ) console.print("\n┌ [red]Refurbishing Necessities...") getme = await app.get_me() - getme1 = await userbot.get_me() + getme1 = await ASS_CLI_1.get_me() + getme2 = await ASS_CLI_2.get_me() + getme3 = await ASS_CLI_3.get_me() + getme4 = await ASS_CLI_4.get_me() + getme5 = await ASS_CLI_5.get_me() BOT_ID = getme.id - ASSID = getme1.id + ASSID1 = getme1.id + ASSID2 = getme2.id + ASSID3 = getme3.id + ASSID4 = getme4.id + ASSID5 = getme5.id if getme.last_name: BOT_NAME = getme.first_name + " " + getme.last_name else: BOT_NAME = getme.first_name BOT_USERNAME = getme.username - ASSNAME = ( + ASSNAME1 = ( f"{getme1.first_name} {getme1.last_name}" if getme1.last_name else getme1.first_name ) - ASSUSERNAME = getme1.username - ASSMENTION = getme1.mention + ASSUSERNAME1 = getme1.username + ASSMENTION1 = getme1.mention + ASSNAME2 = ( + f"{getme2.first_name} {getme2.last_name}" + if getme2.last_name + else getme2.first_name + ) + ASSUSERNAME2 = getme2.username + ASSMENTION2 = getme2.mention + ASSNAME3 = ( + f"{getme3.first_name} {getme3.last_name}" + if getme3.last_name + else getme3.first_name + ) + ASSUSERNAME3 = getme3.username + ASSMENTION3 = getme3.mention + ASSNAME4 = ( + f"{getme4.first_name} {getme4.last_name}" + if getme4.last_name + else getme4.first_name + ) + ASSUSERNAME4 = getme4.username + ASSMENTION4 = getme4.mention + ASSNAME5 = ( + f"{getme5.first_name} {getme5.last_name}" + if getme5.last_name + else getme5.first_name + ) + ASSUSERNAME5 = getme5.username + ASSMENTION5 = getme5.mention console.print("└ [green]Refurbished Successfully!") await asyncio.sleep(0.9) ____ok = await startup_edit_last(___, "Loading Sudo Users...") @@ -117,7 +192,9 @@ async def initiate_bot(): if user_id not in sudoers: sudoers.append(user_id) await sudoersdb.update_one( - {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True + {"sudo": "sudo"}, + {"$set": {"sudoers": sudoers}}, + upsert=True, ) SUDOERS = (SUDOERS + sudoers + OWNER_ID) if sudoers else SUDOERS await asyncio.sleep(1) @@ -128,8 +205,18 @@ async def initiate_bot(): loop.run_until_complete(initiate_bot()) -if ASSID not in SUDOERS: - SUDOERS.append(ASSID) +ASSIDS = [] + +if ASSID1 not in ASSIDS: + ASSIDS.append(ASSID1) +if ASSID2 not in ASSIDS: + ASSIDS.append(ASSID2) +if ASSID3 not in ASSIDS: + ASSIDS.append(ASSID3) +if ASSID4 not in ASSIDS: + ASSIDS.append(ASSID4) +if ASSID5 not in ASSIDS: + ASSIDS.append(ASSID5) def init_db(): diff --git a/Yukki/__main__.py b/Yukki/__main__.py index 310a10f..757f14c 100644 --- a/Yukki/__main__.py +++ b/Yukki/__main__.py @@ -3,18 +3,21 @@ import os import re -from config import LOG_GROUP_ID from pyrogram import filters from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup +from pytgcalls import idle from rich.console import Console from rich.table import Table from youtubesearchpython import VideosSearch -from Yukki import (ASSID, ASSMENTION, ASSNAME, ASSUSERNAME, BOT_ID, BOT_NAME, - BOT_USERNAME, SUDOERS, app, db, userbot) +from config import LOG_GROUP_ID +from Yukki import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5, + ASSID1, ASSID2, ASSID3, ASSID4, ASSID5, ASSNAME1, ASSNAME2, + ASSNAME3, ASSNAME4, ASSNAME5, BOT_ID, BOT_NAME, app) from Yukki.Core.Logger.Log import (startup_delete_last, startup_edit_last, startup_send_new) -from Yukki.Core.PyTgCalls.Yukki import run +from Yukki.Core.PyTgCalls.Yukki import (pytgcalls1, pytgcalls2, pytgcalls3, + pytgcalls4, pytgcalls5) from Yukki.Database import get_active_chats, get_sudoers, remove_active_chat from Yukki.Inline import private_panel from Yukki.Plugins import ALL_MODULES @@ -97,25 +100,98 @@ async def initiate_bot(): console.print(f"\n[red]Stopping Bot") return try: - await userbot.send_message( + await ASS_CLI_1.send_message( + LOG_GROUP_ID, + "Congrats!! Assistant Client 1 has started successfully!", + ) + except Exception as e: + print( + "Assistant Account 1 has failed to access the log Channel. Make sure that you have added your Assistant to your log channel and promoted as admin!" + ) + console.print(f"\n[red]Stopping Bot") + return + try: + await ASS_CLI_1.join_chat("OfficialYukki") + except: + pass + try: + await ASS_CLI_2.send_message( + LOG_GROUP_ID, + "Congrats!! Assistant Client 2 has started successfully!", + ) + except Exception as e: + print( + "Assistant Account 2 has failed to access the log Channel. Make sure that you have added your Assistant to your log channel and promoted as admin!" + ) + console.print(f"\n[red]Stopping Bot") + return + try: + await ASS_CLI_2.join_chat("OfficialYukki") + except: + pass + try: + await ASS_CLI_3.send_message( + LOG_GROUP_ID, + "Congrats!! Assistant Client 3 has started successfully!", + ) + except Exception as e: + print( + "Assistant Account 3 has failed to access the log Channel. Make sure that you have added your Assistant to your log channel and promoted as admin!" + ) + console.print(f"\n[red]Stopping Bot") + return + try: + await ASS_CLI_3.join_chat("OfficialYukki") + except: + pass + try: + await ASS_CLI_4.send_message( + LOG_GROUP_ID, + "Congrats!! Assistant Client 4 has started successfully!", + ) + except Exception as e: + print( + "Assistant Account 4 has failed to access the log Channel. Make sure that you have added your Assistant to your log channel and promoted as admin!" + ) + console.print(f"\n[red]Stopping Bot") + return + try: + await ASS_CLI_4.join_chat("OfficialYukki") + except: + pass + try: + await ASS_CLI_5.send_message( LOG_GROUP_ID, - "Congrats!! Assistant has started successfully!", + "Congrats!! Assistant Client 5 has started successfully!", ) except Exception as e: print( - "Assistant Account has failed to access the log Channel. Make sure that you have added your bot to your log channel and promoted as admin!" + "Assistant Account 5 has failed to access the log Channel. Make sure that you have added your Assistant to your log channel and promoted as admin!" ) console.print(f"\n[red]Stopping Bot") return try: - await userbot.join_chat("OfficialYukki") + await ASS_CLI_5.join_chat("OfficialYukki") except: pass console.print(f"\n┌[red] Bot Started as {BOT_NAME}!") console.print(f"├[green] ID :- {BOT_ID}!") - console.print(f"├[red] Assistant Started as {ASSNAME}!") - console.print(f"└[green] ID :- {ASSID}!") - await run() + console.print(f"├[red] Assistant 1 Started as {ASSNAME1}!") + console.print(f"├[green] ID :- {ASSID1}!") + console.print(f"├[red] Assistant 2 Started as {ASSNAME2}!") + console.print(f"├[green] ID :- {ASSID2}!") + console.print(f"├[red] Assistant 3 Started as {ASSNAME3}!") + console.print(f"├[green] ID :- {ASSID3}!") + console.print(f"├[red] Assistant 4 Started as {ASSNAME4}!") + console.print(f"├[green] ID :- {ASSID4}!") + console.print(f"├[red] Assistant 5 Started as {ASSNAME5}!") + console.print(f"└[green] ID :- {ASSID5}!") + await pytgcalls1.start() + await pytgcalls2.start() + await pytgcalls3.start() + await pytgcalls4.start() + await pytgcalls5.start() + await idle() console.print(f"\n[red]Stopping Bot") diff --git a/app.json b/app.json index cdef214..0f3caaf 100644 --- a/app.json +++ b/app.json @@ -65,8 +65,28 @@ "value": "", "required": true }, - "STRING_SESSION": { - "description": "A Pyrogram String Session.", + "STRING_SESSION1": { + "description": "A Pyrogram String Session of Assistant Account.", + "value": "", + "required": true + }, + "STRING_SESSION2": { + "description": "A Pyrogram String Session of Assistant Account.", + "value": "", + "required": true + }, + "STRING_SESSION3": { + "description": "A Pyrogram String Session of Assistant Account.", + "value": "", + "required": true + }, + "STRING_SESSION4": { + "description": "A Pyrogram String Session of Assistant Account.", + "value": "", + "required": true + }, + "STRING_SESSION5": { + "description": "A Pyrogram String Session of Assistant Account.", "value": "", "required": true }, diff --git a/config.py b/config.py index d4f1bcd..50f3f94 100644 --- a/config.py +++ b/config.py @@ -7,7 +7,11 @@ # VARS get_queue = {} -STRING = getenv("STRING_SESSION", "session") +STRING1 = getenv("STRING_SESSION1", "session") +STRING2 = getenv("STRING_SESSION2", "session") +STRING3 = getenv("STRING_SESSION3", "session") +STRING4 = getenv("STRING_SESSION4", "session") +STRING5 = getenv("STRING_SESSION5", "session") BOT_TOKEN = getenv("BOT_TOKEN") API_ID = int(getenv("API_ID", "")) API_HASH = getenv("API_HASH") From 6d6730f04384b89b3b044330db48ed74f070f1c0 Mon Sep 17 00:00:00 2001 From: Shikhar Date: Sat, 18 Dec 2021 16:56:53 +0530 Subject: [PATCH 2/6] Multi-Assistant Release --- Yukki/Plugins/Developer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Yukki/Plugins/Developer.py b/Yukki/Plugins/Developer.py index 247aedf..ee544ad 100644 --- a/Yukki/Plugins/Developer.py +++ b/Yukki/Plugins/Developer.py @@ -22,11 +22,11 @@ __HELP__ = """ **Note:** Only for Sudo Users. -/broadcast [Message or Reply to a Message] +/broadcast [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats. -/broadcast_pin [Message or Reply to a Message] +/broadcast_pin [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Disabled Notifications]. -/broadcast_pin_loud [Message or Reply to a Message] +/broadcast_pin_loud [Message or Reply to a Message] - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Enabled Notifications]. """ @@ -116,7 +116,7 @@ async def executor(client, message): callback_data=f"runtime {round(t2-t1, 3)} Seconds", ), InlineKeyboardButton( - text="Delete Output", + text="🗑", callback_data=f"forceclose abc|{message.from_user.id}", ), ] From 47cd8bfe02c72c16d520052dcdcece8b76812e66 Mon Sep 17 00:00:00 2001 From: Shikhar Kumar Date: Sat, 18 Dec 2021 17:21:29 +0530 Subject: [PATCH 3/6] Update Yukki.py --- Yukki/Core/PyTgCalls/Yukki.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Yukki/Core/PyTgCalls/Yukki.py b/Yukki/Core/PyTgCalls/Yukki.py index 070ace3..688fb0d 100644 --- a/Yukki/Core/PyTgCalls/Yukki.py +++ b/Yukki/Core/PyTgCalls/Yukki.py @@ -230,7 +230,7 @@ async def playout_end(pytgclients, chat_id): Queues.task_done(chat_id) if Queues.is_empty(chat_id): await remove_active_chat(chat_id) - await pytgcalls1.leave_group_call(chat_id) + await pytgclients.leave_group_call(chat_id) else: afk = Queues.get(chat_id)["file"] finxx = f"{afk[0]}{afk[1]}{afk[2]}" From bec783e9e1cc8cb738c7e60acc455c45cf6cd5b0 Mon Sep 17 00:00:00 2001 From: Aarav Arora Date: Sat, 18 Dec 2021 18:46:33 +0530 Subject: [PATCH 4/6] Update sample.env --- sample.env | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sample.env b/sample.env index 281c848..745d1ce 100644 --- a/sample.env +++ b/sample.env @@ -1,4 +1,8 @@ -STRING_SESSION = "" # A pyrogram String Session +STRING_SESSION1 = "" # A pyrogram String Session +STRING_SESSION2 = "" # A pyrogram String Session +STRING_SESSION3 = "" # A pyrogram String Session +STRING_SESSION4 = "" # A pyrogram String Session +STRING_SESSION5 = "" # A pyrogram String Session BOT_TOKEN= "" Get a token from @botFather From f7b8220de7f2d7f6f40db3659e133bb31de8fa4c Mon Sep 17 00:00:00 2001 From: Aarav Arora Date: Sat, 18 Dec 2021 18:47:47 +0530 Subject: [PATCH 5/6] a --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28ad4e0..220c02f 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ shikhar@MacBook~ $ python3 gen_session.py 1. `API_ID` : Assistant Account Telegram API_ID, get it from my.telegram.org 2. `API_HASH` : Assistant Account Telegram API_HASH, get it from my.telegram.org 3. `BOT_TOKEN` : Your Telegram Bot Token, get it from @Botfather (Make sure Inline is turned On) -4. `SESSION_STRING1` - `SESSION_STRING5` : Pyrogram Session String of Assistant Accounts. +4. `STRING_SESSION1` - `STRING_SESSION5` : Pyrogram Session String of Assistant Accounts.[ look at sample.env] 5. `MUSIC_BOT_NAME` : A name for your Music bot. 6. `MONGO_DB_URI` : MongoDB Database URL. 7. `LOG_GROUP_ID` : Chat ID where bot will log everything. Use Group Chats Only. From 94ab1276b71051c7a7c80cb76c514232310d8512 Mon Sep 17 00:00:00 2001 From: Makoto XD <85411336+Makoto-XD@users.noreply.github.com> Date: Sat, 18 Dec 2021 20:46:46 +0530 Subject: [PATCH 6/6] now okay --- app.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app.json b/app.json index 0f3caaf..8bba974 100644 --- a/app.json +++ b/app.json @@ -73,22 +73,22 @@ "STRING_SESSION2": { "description": "A Pyrogram String Session of Assistant Account.", "value": "", - "required": true + "required": false }, "STRING_SESSION3": { "description": "A Pyrogram String Session of Assistant Account.", "value": "", - "required": true + "required": false }, "STRING_SESSION4": { "description": "A Pyrogram String Session of Assistant Account.", "value": "", - "required": true + "required": false }, "STRING_SESSION5": { "description": "A Pyrogram String Session of Assistant Account.", "value": "", - "required": true + "required": false }, "LOG_GROUP_ID": { "description": "Your Log Group ID, add your bot and promote as an admin with full rights!. Use only Group. Please don't use Channel ID.",