├── start
├── Utils
├── Query.jpg
├── ayiin.jpg
├── black.PNG
├── blue.PNG
├── green.PNG
├── grey.PNG
├── icon.gif
├── pink.PNG
├── red.PNG
├── Result.JPEG
├── orange.PNG
├── yellow.PNG
├── Playlist.jpg
├── Telegram.JPEG
└── finalfont.ttf
├── heroku.yml
├── Ayiin
├── Database
│ ├── .DS_Store
│ ├── onoff.py
│ ├── pmpermit.py
│ ├── blacklistchat.py
│ ├── sudo.py
│ ├── theme.py
│ ├── gban.py
│ ├── chats.py
│ ├── start.py
│ ├── assistant.py
│ ├── __init__.py
│ ├── videocalls.py
│ ├── queue.py
│ ├── auth.py
│ └── playlist.py
├── Utilities
│ ├── heroku.py
│ ├── formatters.py
│ ├── theme.py
│ ├── ping.py
│ ├── url.py
│ ├── assistant.py
│ ├── paste.py
│ ├── changers.py
│ ├── tasks.py
│ ├── thumbnails.py
│ ├── youtube.py
│ ├── inline.py
│ ├── chat.py
│ ├── stream.py
│ ├── timer.py
│ └── videostream.py
├── Plugins
│ ├── __init__.py
│ ├── Ping.py
│ ├── Watcher.py
│ ├── Speedtest.py
│ ├── Theme.py
│ ├── Blacklist.py
│ ├── Multi-Assistant
│ │ └── Assistant.py
│ ├── Lyrics.py
│ ├── Assistant.py
│ ├── Auth.py
│ ├── Song.py
│ ├── Developer.py
│ ├── Stream.py
│ └── Voicechat.py
├── Inline
│ ├── __init__.py
│ ├── song.py
│ ├── others.py
│ ├── videocalls.py
│ ├── stats.py
│ ├── playlist.py
│ ├── start.py
│ └── play.py
├── Core
│ ├── PyTgCalls
│ │ ├── Converter.py
│ │ ├── Queues.py
│ │ ├── Tgdownloader.py
│ │ └── Downloader.py
│ └── Clients
│ │ └── cli.py
├── Decorators
│ ├── logger.py
│ ├── permission.py
│ ├── checker.py
│ ├── admins.py
│ └── assistant.py
└── __init__.py
├── .dockerignore
├── .gitignore
├── Dockerfile
├── requirements.txt
├── sample.env
├── gen_session.py
├── config.py
├── README.md
└── app.json
/start:
--------------------------------------------------------------------------------
1 | python3 -m Ayiin
2 |
--------------------------------------------------------------------------------
/Utils/Query.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/Query.jpg
--------------------------------------------------------------------------------
/Utils/ayiin.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/ayiin.jpg
--------------------------------------------------------------------------------
/Utils/black.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/black.PNG
--------------------------------------------------------------------------------
/Utils/blue.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/blue.PNG
--------------------------------------------------------------------------------
/Utils/green.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/green.PNG
--------------------------------------------------------------------------------
/Utils/grey.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/grey.PNG
--------------------------------------------------------------------------------
/Utils/icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/icon.gif
--------------------------------------------------------------------------------
/Utils/pink.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/pink.PNG
--------------------------------------------------------------------------------
/Utils/red.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/red.PNG
--------------------------------------------------------------------------------
/Utils/Result.JPEG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/Result.JPEG
--------------------------------------------------------------------------------
/Utils/orange.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/orange.PNG
--------------------------------------------------------------------------------
/Utils/yellow.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/yellow.PNG
--------------------------------------------------------------------------------
/Utils/Playlist.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/Playlist.jpg
--------------------------------------------------------------------------------
/Utils/Telegram.JPEG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/Telegram.JPEG
--------------------------------------------------------------------------------
/Utils/finalfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Utils/finalfont.ttf
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | worker: Dockerfile
4 | run:
5 | worker: bash start
6 |
--------------------------------------------------------------------------------
/Ayiin/Database/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AyiinXd/YinsMusic/HEAD/Ayiin/Database/.DS_Store
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .env
2 | *.log
3 | .git/
4 | .idea/
5 | README.md
6 | downloads/
7 | raw_files/
8 | .gitignore
9 | __pycache__/
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
2 | *.log
3 | venv/
4 | .idea/
5 | *.session
6 | raw_files/
7 | downloads/
8 | __pycache__/
9 | *.session-journal
10 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/heroku.py:
--------------------------------------------------------------------------------
1 | import socket
2 |
3 | from config import HEROKU_API_KEY
4 |
5 |
6 | async def is_heroku():
7 | return "heroku" in socket.getfqdn()
8 |
9 |
10 | async def user_input(input):
11 | if " " in input or "\n" in input:
12 | return str(input.split(maxsplit=1)[1].strip())
13 | return ""
14 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nikolaik/python-nodejs:latest
2 | RUN apt-get update \
3 | && apt-get install -y --no-install-recommends ffmpeg \
4 | && apt-get clean \
5 | && rm -rf /var/lib/apt/lists/*
6 | COPY . /app/
7 | WORKDIR /app/
8 | RUN pip3 install --no-cache-dir --upgrade --requirement requirements.txt
9 | CMD bash start
10 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/formatters.py:
--------------------------------------------------------------------------------
1 | def bytes(size: float) -> str:
2 | """humanize size"""
3 | if not size:
4 | return ""
5 | power = 1024
6 | t_n = 0
7 | power_dict = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
8 | while size > power:
9 | size /= power
10 | t_n += 1
11 | return "{:.2f} {}B".format(size, power_dict[t_n])
12 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohttp
2 | aiofiles
3 | asyncio
4 | ffmpeg-python
5 | pillow
6 | pyrogram==1.4.12
7 | hachoir
8 | lyricsgenius
9 | py-tgcalls==0.8.5
10 | wget
11 | python-dotenv
12 | youtube-search-python
13 | youtube-search
14 | speedtest-cli
15 | motor
16 | psutil
17 | requests
18 | rich
19 | dnspython
20 | yt-dlp==2021.11.10.1
21 | tgcrypto
22 | gitpython
23 | heroku3
24 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/__init__.py:
--------------------------------------------------------------------------------
1 | import glob
2 | from os.path import basename, dirname, isfile
3 |
4 |
5 | def __list_all_modules():
6 | mod_paths = glob.glob(dirname(__file__) + "/*.py")
7 |
8 | all_modules = [
9 | basename(f)[:-3]
10 | for f in mod_paths
11 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
12 | ]
13 |
14 | return all_modules
15 |
16 |
17 | ALL_MODULES = sorted(__list_all_modules())
18 | __all__ = ALL_MODULES + ["ALL_MODULES"]
19 |
--------------------------------------------------------------------------------
/sample.env:
--------------------------------------------------------------------------------
1 | STRING_SESSION1 = PYROGRAMSESSION
2 | API_ID = 6
3 | API_HASH = eb06d4abfb49dc3eeb1aeb98ae0f581e
4 | BOT_TOKEN = 504729834470:AAHidqz_M26xIem_Cn4Hs3BHrIokG1W43bo
5 | SUDO_USERS = 18920183 39103921
6 | MONGO_DB_URI = mongodb+srv://a:a@a.a.mongodb.net/a?retryWrites=a&w=majority
7 | LOG_GROUP_ID = -1003209382042
8 | MUSIC_BOT_NAME = Ayiin
9 | OWNER_ID = 482049203
10 | DURATION_LIMIT = 90
11 | SUPPORT_CHANNEL = https://t.me/AyiinSupport
12 | SUPPORT_GROUP = https://t.me/AyiinXdSupport
13 | ASSISTANT_PREFIX = !
14 |
--------------------------------------------------------------------------------
/gen_session.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from pyrogram import Client as c
3 |
4 | API_ID = input("\nEnter Your API_ID:\n > ")
5 | API_HASH = input("\nEnter Your API_HASH:\n > ")
6 |
7 | print("\n\n Enter Phone number when asked.\n\n")
8 |
9 | i = c(":memory:", api_id=API_ID, api_hash=API_HASH)
10 |
11 |
12 | async def main():
13 | await i.start()
14 | ss = await i.export_session_string()
15 | print("\nHERE IS YOUR STRING SESSION, COPY IT, DON'T SHARE!!\n")
16 | print(f"\n{ss}\n")
17 |
18 |
19 | asyncio.run(main())
20 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/theme.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | from Ayiin.Database import get_theme
4 |
5 | themes = [
6 | "blue",
7 | "black",
8 | "red",
9 | "green",
10 | "grey",
11 | "orange",
12 | "pink",
13 | "yellow",
14 | ]
15 |
16 |
17 | async def check_theme(chat_id: int):
18 | _theme = await get_theme(chat_id, "theme")
19 | if not _theme:
20 | theme = random.choice(themes)
21 | else:
22 | theme = _theme["theme"]
23 | if theme == "Random":
24 | theme = random.choice(themes)
25 | return theme
26 |
--------------------------------------------------------------------------------
/Ayiin/Database/onoff.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | onoffdb = db.onoffper
6 |
7 |
8 | async def is_on_off(on_off: int) -> bool:
9 | onoff = await onoffdb.find_one({"on_off": on_off})
10 | if not onoff:
11 | return False
12 | return True
13 |
14 |
15 | async def add_on(on_off: int):
16 | is_on = await is_on_off(on_off)
17 | if is_on:
18 | return
19 | return await onoffdb.insert_one({"on_off": on_off})
20 |
21 |
22 | async def add_off(on_off: int):
23 | is_off = await is_on_off(on_off)
24 | if not is_off:
25 | return
26 | return await onoffdb.delete_one({"on_off": on_off})
27 |
--------------------------------------------------------------------------------
/Ayiin/Database/pmpermit.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | pmpermitdb = db.permit
6 |
7 |
8 | async def is_pmpermit_approved(user_id: int) -> bool:
9 | user = await pmpermitdb.find_one({"user_id": user_id})
10 | if not user:
11 | return False
12 | return True
13 |
14 |
15 | async def approve_pmpermit(user_id: int):
16 | is_pmpermit = await is_pmpermit_approved(user_id)
17 | if is_pmpermit:
18 | return
19 | return await pmpermitdb.insert_one({"user_id": user_id})
20 |
21 |
22 | async def disapprove_pmpermit(user_id: int):
23 | is_pmpermit = await is_pmpermit_approved(user_id)
24 | if not is_pmpermit:
25 | return
26 | return await pmpermitdb.delete_one({"user_id": user_id})
27 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/ping.py:
--------------------------------------------------------------------------------
1 | def get_readable_time(seconds: int) -> str:
2 | count = 0
3 | ping_time = ""
4 | time_list = []
5 | time_suffix_list = ["s", "m", "h", "days"]
6 | while count < 4:
7 | count += 1
8 | if count < 3:
9 | remainder, result = divmod(seconds, 60)
10 | else:
11 | remainder, result = divmod(seconds, 24)
12 | if seconds == 0 and remainder == 0:
13 | break
14 | time_list.append(int(result))
15 | seconds = int(remainder)
16 | for i in range(len(time_list)):
17 | time_list[i] = str(time_list[i]) + time_suffix_list[i]
18 | if len(time_list) == 4:
19 | ping_time += time_list.pop() + ", "
20 | time_list.reverse()
21 | ping_time += ":".join(time_list)
22 | return ping_time
23 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/url.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | from pyrogram.types import Message
4 |
5 |
6 | def get_url(message_1: Message) -> Union[str, None]:
7 | messages = [message_1]
8 | if message_1.reply_to_message:
9 | messages.append(message_1.reply_to_message)
10 | text = ""
11 | offset = None
12 | length = None
13 | for message in messages:
14 | if offset:
15 | break
16 | if message.entities:
17 | for entity in message.entities:
18 | if entity.type == "url":
19 | text = message.text or message.caption
20 | offset, length = entity.offset, entity.length
21 | break
22 | if offset in (None,):
23 | return None
24 | return text[offset : offset + length]
25 |
--------------------------------------------------------------------------------
/Ayiin/Database/blacklistchat.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | blacklist_chatdb = db.blacklistChat
6 |
7 |
8 | async def blacklisted_chats() -> list:
9 | chats = blacklist_chatdb.find({"chat_id": {"$lt": 0}})
10 | return [
11 | chat["chat_id"] for chat in await chats.to_list(length=1000000000)
12 | ]
13 |
14 |
15 | async def blacklist_chat(chat_id: int) -> bool:
16 | if not await blacklist_chatdb.find_one({"chat_id": chat_id}):
17 | await blacklist_chatdb.insert_one({"chat_id": chat_id})
18 | return True
19 | return False
20 |
21 |
22 | async def whitelist_chat(chat_id: int) -> bool:
23 | if await blacklist_chatdb.find_one({"chat_id": chat_id}):
24 | await blacklist_chatdb.delete_one({"chat_id": chat_id})
25 | return True
26 | return False
27 |
--------------------------------------------------------------------------------
/Ayiin/Database/sudo.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | sudoersdb = db.sudoers
6 |
7 |
8 | async def get_sudoers() -> list:
9 | sudoers = await sudoersdb.find_one({"sudo": "sudo"})
10 | if not sudoers:
11 | return []
12 | return sudoers["sudoers"]
13 |
14 |
15 | async def add_sudo(user_id: int) -> bool:
16 | sudoers = await get_sudoers()
17 | sudoers.append(user_id)
18 | await sudoersdb.update_one(
19 | {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True
20 | )
21 | return True
22 |
23 |
24 | async def remove_sudo(user_id: int) -> bool:
25 | sudoers = await get_sudoers()
26 | sudoers.remove(user_id)
27 | await sudoersdb.update_one(
28 | {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True
29 | )
30 | return True
31 |
--------------------------------------------------------------------------------
/Ayiin/Database/theme.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | themedb = db.notes
6 |
7 |
8 | async def _get_theme(chat_id: int) -> Dict[str, int]:
9 | _notes = await themedb.find_one({"chat_id": chat_id})
10 | if not _notes:
11 | return {}
12 | return _notes["notes"]
13 |
14 |
15 | async def get_theme(chat_id: int, name: str) -> Union[bool, dict]:
16 | name = name.lower().strip()
17 | _notes = await _get_theme(chat_id)
18 | if name in _notes:
19 | return _notes[name]
20 | else:
21 | return False
22 |
23 |
24 | async def save_theme(chat_id: int, name: str, note: dict):
25 | name = name.lower().strip()
26 | _notes = await _get_theme(chat_id)
27 | _notes[name] = note
28 | await themedb.update_one(
29 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
30 | )
31 |
--------------------------------------------------------------------------------
/Ayiin/Database/gban.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | gbansdb = db.gban
6 |
7 |
8 | async def get_gbans_count() -> int:
9 | users = gbansdb.find({"user_id": {"$gt": 0}})
10 | users = await users.to_list(length=100000)
11 | return len(users)
12 |
13 |
14 | async def is_gbanned_user(user_id: int) -> bool:
15 | user = await gbansdb.find_one({"user_id": user_id})
16 | if not user:
17 | return False
18 | return True
19 |
20 |
21 | async def add_gban_user(user_id: int):
22 | is_gbanned = await is_gbanned_user(user_id)
23 | if is_gbanned:
24 | return
25 | return await gbansdb.insert_one({"user_id": user_id})
26 |
27 |
28 | async def remove_gban_user(user_id: int):
29 | is_gbanned = await is_gbanned_user(user_id)
30 | if not is_gbanned:
31 | return
32 | return await gbansdb.delete_one({"user_id": user_id})
33 |
--------------------------------------------------------------------------------
/Ayiin/Inline/__init__.py:
--------------------------------------------------------------------------------
1 | from .others import download_markup, others_markup
2 | from .play import (audio_markup, audio_markup2, audio_timer_markup_start,
3 | primary_markup, search_markup, search_markup2,
4 | secondary_markup, secondary_markup2, timer_markup,
5 | url_markup, url_markup2)
6 | from .playlist import (add_genre_markup, check_genre_markup, check_markup,
7 | delete_playlist_markuup, fetch_playlist,
8 | paste_queue_markup, play_genre_playlist,
9 | playlist_markup, third_playlist_markup)
10 | from .song import song_download_markup, song_markup
11 | from .start import (custommarkup, dashmarkup, private_panel, setting_markup,
12 | setting_markup2, start_pannel, usermarkup, volmarkup)
13 | from .stats import stats1, stats2, stats3, stats4, stats5, stats6, stats7
14 | from .videocalls import choose_markup, livestream_markup, stream_quality_markup
15 |
--------------------------------------------------------------------------------
/Ayiin/Database/chats.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | chatsdb = db.chats
6 |
7 |
8 | async def get_served_chats() -> list:
9 | chats = chatsdb.find({"chat_id": {"$lt": 0}})
10 | if not chats:
11 | return []
12 | chats_list = []
13 | for chat in await chats.to_list(length=1000000000):
14 | chats_list.append(chat)
15 | return chats_list
16 |
17 |
18 | async def is_served_chat(chat_id: int) -> bool:
19 | chat = await chatsdb.find_one({"chat_id": chat_id})
20 | if not chat:
21 | return False
22 | return True
23 |
24 |
25 | async def add_served_chat(chat_id: int):
26 | is_served = await is_served_chat(chat_id)
27 | if is_served:
28 | return
29 | return await chatsdb.insert_one({"chat_id": chat_id})
30 |
31 |
32 | async def remove_served_chat(chat_id: int):
33 | is_served = await is_served_chat(chat_id)
34 | if not is_served:
35 | return
36 | return await chatsdb.delete_one({"chat_id": chat_id})
37 |
--------------------------------------------------------------------------------
/Ayiin/Database/start.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | assisdb = db.start
6 |
7 |
8 | async def get_start_names(chat_id: int) -> List[str]:
9 | _notes = []
10 | for note in await _get_start(chat_id):
11 | _notes.append(note)
12 | return _notes
13 |
14 |
15 | async def _get_start(chat_id: int) -> Dict[str, int]:
16 | _notes = await assisdb.find_one({"chat_id": chat_id})
17 | if not _notes:
18 | return {}
19 | return _notes["notes"]
20 |
21 |
22 | async def get_start(chat_id: int, name: str) -> Union[bool, dict]:
23 | name = name.lower().strip()
24 | _notes = await _get_start(chat_id)
25 | if name in _notes:
26 | return _notes[name]
27 | else:
28 | return False
29 |
30 |
31 | async def save_start(chat_id: int, name: str, note: dict):
32 | name = name.lower().strip()
33 | _notes = await _get_start(chat_id)
34 | _notes[name] = note
35 | await assisdb.update_one(
36 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
37 | )
38 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/assistant.py:
--------------------------------------------------------------------------------
1 | from Ayiin import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5,
2 | ASSID1, ASSID2, ASSID3, ASSID4, ASSID5, ASSNAME1, ASSNAME2,
3 | ASSNAME3, ASSNAME4, ASSNAME5, ASSUSERNAME1, ASSUSERNAME2,
4 | ASSUSERNAME3, ASSUSERNAME4, ASSUSERNAME5)
5 |
6 |
7 | async def get_assistant_details(assistant: int):
8 | if int(assistant) == 1:
9 | x = ASSID1
10 | y = ASSNAME1
11 | z = ASSUSERNAME1
12 | a = ASS_CLI_1
13 | elif int(assistant) == 2:
14 | x = ASSID2
15 | y = ASSNAME2
16 | z = ASSUSERNAME2
17 | a = ASS_CLI_2
18 | elif int(assistant) == 3:
19 | x = ASSID3
20 | y = ASSNAME3
21 | z = ASSUSERNAME3
22 | a = ASS_CLI_3
23 | elif int(assistant) == 4:
24 | x = ASSID4
25 | y = ASSNAME4
26 | z = ASSUSERNAME4
27 | a = ASS_CLI_4
28 | elif int(assistant) == 5:
29 | x = ASSID5
30 | y = ASSNAME5
31 | z = ASSUSERNAME5
32 | a = ASS_CLI_5
33 | return x, y, z, a
34 |
--------------------------------------------------------------------------------
/Ayiin/Database/assistant.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | assisdb = db.assistantmultimode
6 |
7 |
8 | async def get_as_names(chat_id: int) -> List[str]:
9 | _notes = []
10 | for note in await _get_assistant(chat_id):
11 | _notes.append(note)
12 | return _notes
13 |
14 |
15 | async def _get_assistant(chat_id: int) -> Dict[str, int]:
16 | _notes = await assisdb.find_one({"chat_id": chat_id})
17 | if not _notes:
18 | return {}
19 | return _notes["notes"]
20 |
21 |
22 | async def get_assistant(chat_id: int, name: str) -> Union[bool, dict]:
23 | name = name.lower().strip()
24 | _notes = await _get_assistant(chat_id)
25 | if name in _notes:
26 | return _notes[name]
27 | else:
28 | return False
29 |
30 |
31 | async def save_assistant(chat_id: int, name: str, note: dict):
32 | name = name.lower().strip()
33 | _notes = await _get_assistant(chat_id)
34 | _notes[name] = note
35 | await assisdb.update_one(
36 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
37 | )
38 |
--------------------------------------------------------------------------------
/Ayiin/Core/PyTgCalls/Converter.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from os import path
3 |
4 |
5 | class FFmpegReturnCodeError(Exception):
6 | pass
7 |
8 |
9 | async def convert(file_path: str) -> str:
10 | out = path.basename(file_path)
11 | out = out.split(".")
12 | out[-1] = "raw"
13 | out = ".".join(out)
14 | out = path.basename(out)
15 | out = path.join("raw_files", out)
16 |
17 | if path.isfile(out):
18 | return out
19 |
20 | try:
21 | proc = await asyncio.create_subprocess_shell(
22 | cmd=(
23 | "ffmpeg "
24 | "-y -i "
25 | f"{file_path} "
26 | "-f s16le "
27 | "-ac 1 "
28 | "-ar 48000 "
29 | "-acodec "
30 | "pcm_s16le "
31 | f"{out}"
32 | ),
33 | stdin=asyncio.subprocess.PIPE,
34 | stderr=asyncio.subprocess.PIPE,
35 | )
36 |
37 | await proc.communicate()
38 |
39 | if proc.returncode != 0:
40 | raise FFmpegReturnCodeError("FFmpeg did not return 0")
41 |
42 | return out
43 | except:
44 | raise FFmpegReturnCodeError("FFmpeg did not return 0")
45 |
--------------------------------------------------------------------------------
/Ayiin/Core/PyTgCalls/Queues.py:
--------------------------------------------------------------------------------
1 | from asyncio import Queue as _Queue
2 | from asyncio import QueueEmpty as Empty
3 | from typing import Dict
4 |
5 |
6 | class Queue(_Queue):
7 | _queue: list = []
8 |
9 | def clear(self):
10 | self._queue.clear()
11 |
12 |
13 | queues: Dict[int, Queue] = {}
14 |
15 |
16 | async def put(chat_id: int, **kwargs) -> int:
17 | if chat_id not in queues:
18 | queues[chat_id] = Queue()
19 | await queues[chat_id].put({**kwargs})
20 | return queues[chat_id].qsize()
21 |
22 |
23 | def get(chat_id: int) -> Dict[str, str]:
24 | if chat_id in queues:
25 | try:
26 | return queues[chat_id].get_nowait()
27 | except Empty:
28 | return {}
29 | return {}
30 |
31 |
32 | def is_empty(chat_id: int) -> bool:
33 | if chat_id in queues:
34 | return queues[chat_id].empty()
35 | return True
36 |
37 |
38 | def task_done(chat_id: int):
39 | if chat_id in queues:
40 | try:
41 | queues[chat_id].task_done()
42 | except ValueError:
43 | pass
44 |
45 |
46 | def clear(chat_id: int):
47 | if chat_id in queues:
48 | if queues[chat_id].empty():
49 | raise Empty
50 | else:
51 | queues[chat_id].clear()
52 | raise Empty
53 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/paste.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import socket
3 | from asyncio import get_running_loop
4 | from functools import partial
5 |
6 | from Ayiin import aiohttpsession as session
7 |
8 |
9 | def _netcat(host, port, content):
10 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
11 | s.connect((host, port))
12 | s.sendall(content.encode())
13 | s.shutdown(socket.SHUT_WR)
14 | while True:
15 | data = s.recv(4096).decode("utf-8").strip("\n\x00")
16 | if not data:
17 | break
18 | return data
19 | s.close()
20 |
21 |
22 | async def paste_queue(content):
23 | loop = get_running_loop()
24 | link = await loop.run_in_executor(
25 | None, partial(_netcat, "ezup.dev", 9999, content)
26 | )
27 | return link
28 |
29 |
30 | async def isPreviewUp(preview: str) -> bool:
31 | for _ in range(7):
32 | try:
33 | async with session.head(preview, timeout=2) as resp:
34 | status, size = resp.status, resp.content_length
35 | except asyncio.exceptions.TimeoutError:
36 | return False
37 | if status == 404 or (status == 200 and size == 0):
38 | await asyncio.sleep(0.4)
39 | else:
40 | return True if status == 200 else False
41 | return False
42 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Ping.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | from datetime import datetime
4 |
5 | import psutil
6 | from pyrogram import Client, filters
7 | from pyrogram.types import Message
8 |
9 | from Ayiin import BOT_USERNAME, MUSIC_BOT_NAME, app, boottime
10 | from Ayiin.Utilities.ping import get_readable_time
11 |
12 | __MODULE__ = "Ping"
13 | __HELP__ = """
14 |
15 | /ping - Check if Bot is alive or not.
16 | """
17 |
18 |
19 | async def bot_sys_stats():
20 | bot_uptime = int(time.time() - boottime)
21 | cpu = psutil.cpu_percent(interval=0.5)
22 | mem = psutil.virtual_memory().percent
23 | disk = psutil.disk_usage("/").percent
24 | stats = f"""
25 | Uptime: {get_readable_time((bot_uptime))}
26 | CPU: {cpu}%
27 | RAM: {mem}%
28 | Disk: {disk}%"""
29 | return stats
30 |
31 |
32 | @app.on_message(filters.command(["ping", f"ping@{BOT_USERNAME}"]))
33 | async def ping(_, message):
34 | start = datetime.now()
35 | response = await message.reply_photo(
36 | photo="Utils/ayiin.jpg",
37 | caption=">> Pong!",
38 | )
39 | uptime = await bot_sys_stats()
40 | end = datetime.now()
41 | resp = (end - start).microseconds / 1000
42 | await response.edit_text(
43 | f"**Pong!**\n`⚡{resp} ms`\n\n{MUSIC_BOT_NAME} System Stats:{uptime}"
44 | )
45 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Watcher.py:
--------------------------------------------------------------------------------
1 | from pyrogram import filters
2 |
3 | from Ayiin import LOG_GROUP_ID, OWNER_ID, SUDOERS, app
4 | from Ayiin.Database import is_gbanned_user, is_on_off
5 |
6 |
7 | @app.on_message(filters.private & ~filters.user(SUDOERS))
8 | async def bot_forward(client, message):
9 | if await is_on_off(5):
10 | if message.text == "/start":
11 | return
12 | try:
13 | await app.forward_messages(
14 | chat_id=LOG_GROUP_ID,
15 | from_chat_id=message.from_user.id,
16 | message_ids=message.message_id,
17 | )
18 | except Exception as err:
19 | print(err)
20 | return
21 | else:
22 | return
23 |
24 |
25 | chat_watcher_group = 5
26 |
27 |
28 | @app.on_message(group=chat_watcher_group)
29 | async def chat_watcher_func(_, message):
30 | try:
31 | userid = message.from_user.id
32 | except Exception:
33 | return
34 | checking = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
35 | if await is_gbanned_user(userid):
36 | try:
37 | await message.chat.ban_member(userid)
38 | except Exception:
39 | return
40 | await message.reply_text(
41 | f"{checking} is globally banned by Sudo Users and has been kicked out of the chat.\n\n**Possible Reason:** Potential Spammer and Abuser."
42 | )
43 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/changers.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 |
4 | async def int_to_alpha(user_id: int) -> str:
5 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
6 | text = ""
7 | user_id = str(user_id)
8 | for i in user_id:
9 | text += alphabet[int(i)]
10 | return text
11 |
12 |
13 | async def alpha_to_int(user_id_alphabet: str) -> int:
14 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
15 | user_id = ""
16 | for i in user_id_alphabet:
17 | index = alphabet.index(i)
18 | user_id += str(index)
19 | user_id = int(user_id)
20 | return user_id
21 |
22 |
23 | def time_to_seconds(time):
24 | stringt = str(time)
25 | return sum(
26 | int(x) * 60 ** i for i, x in enumerate(reversed(stringt.split(":")))
27 | )
28 |
29 |
30 | def seconds_to_min(seconds):
31 | if seconds is not None:
32 | seconds = int(seconds)
33 | d, h, m, s = (
34 | seconds // (3600 * 24),
35 | seconds // 3600 % 24,
36 | seconds % 3600 // 60,
37 | seconds % 3600 % 60,
38 | )
39 | if d > 0:
40 | return "{:02d}:{:02d}:{:02d}:{:02d}".format(d, h, m, s)
41 | elif h > 0:
42 | return "{:02d}:{:02d}:{:02d}".format(h, m, s)
43 | elif m > 0:
44 | return "{:02d}:{:02d}".format(m, s)
45 | elif s > 0:
46 | return "00:{:02d}".format(s)
47 | return "-"
48 |
--------------------------------------------------------------------------------
/Ayiin/Decorators/logger.py:
--------------------------------------------------------------------------------
1 | from config import LOG_GROUP_ID
2 | from Ayiin.Core.Clients.cli import LOG_CLIENT
3 | from Ayiin.Database import is_on_off
4 |
5 |
6 | def logging(mystic):
7 | async def wrapper(_, message):
8 | if await is_on_off(5):
9 | if message.chat.username:
10 | chatusername = f"@{message.chat.username}"
11 | else:
12 | chatusername = "Private Group"
13 | try:
14 | query = message.text.split(None, 1)[1]
15 | what = "Query Given"
16 | except:
17 | try:
18 | if not message.reply_to_message:
19 | what = "Command Given Only"
20 | else:
21 | what = "Replied to any file."
22 | except:
23 | what = "Command"
24 | logger_text = f"""
25 | __**New {what}**__
26 |
27 | **Chat:** {message.chat.title} [`{message.chat.id}`]
28 | **User:** {message.from_user.mention}
29 | **Username:** @{message.from_user.username}
30 | **User ID:** `{message.from_user.id}`
31 | **Chat Link:** {chatusername}
32 | **Query:** {message.text}"""
33 | if LOG_CLIENT != "None":
34 | await LOG_CLIENT.send_message(
35 | LOG_GROUP_ID,
36 | f"{logger_text}",
37 | disable_web_page_preview=True,
38 | )
39 | return await mystic(_, message)
40 |
41 | return wrapper
42 |
--------------------------------------------------------------------------------
/Ayiin/Database/__init__.py:
--------------------------------------------------------------------------------
1 | from .assistant import (_get_assistant, get_as_names, get_assistant,
2 | save_assistant)
3 | from .auth import (_get_authusers, add_nonadmin_chat, delete_authuser,
4 | get_authuser, get_authuser_count, get_authuser_names,
5 | is_nonadmin_chat, remove_nonadmin_chat, save_authuser)
6 | from .blacklistchat import blacklist_chat, blacklisted_chats, whitelist_chat
7 | from .chats import (add_served_chat, get_served_chats, is_served_chat,
8 | remove_served_chat)
9 | from .gban import (add_gban_user, get_gbans_count, is_gbanned_user,
10 | remove_gban_user)
11 | from .onoff import add_off, add_on, is_on_off
12 | from .playlist import (_get_playlists, delete_playlist, get_playlist,
13 | get_playlist_names, save_playlist)
14 | from .pmpermit import (approve_pmpermit, disapprove_pmpermit,
15 | is_pmpermit_approved)
16 | from .queue import (add_active_chat, get_active_chats, is_active_chat,
17 | is_music_playing, music_off, music_on, remove_active_chat)
18 | from .start import _get_start, get_start, get_start_names, save_start
19 | from .sudo import add_sudo, get_sudoers, remove_sudo
20 | from .theme import _get_theme, get_theme, save_theme
21 | from .videocalls import (add_active_video_chat, get_active_video_chats,
22 | get_video_limit, is_active_video_chat,
23 | remove_active_video_chat, set_video_limit)
24 |
--------------------------------------------------------------------------------
/Ayiin/Database/videocalls.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | videodb = db.Ayiinvideocalls
6 |
7 |
8 | ## limit
9 |
10 |
11 | async def get_video_limit(chat_id: int) -> str:
12 | limit = await videodb.find_one({"chat_id": chat_id})
13 | if not limit:
14 | return ""
15 | return limit["limit"]
16 |
17 |
18 | async def set_video_limit(chat_id: int, limit: str):
19 | return await videodb.update_one(
20 | {"chat_id": chat_id}, {"$set": {"limit": limit}}, upsert=True
21 | )
22 |
23 |
24 | ## Queue Chats Video
25 |
26 |
27 | async def get_active_video_chats() -> list:
28 | chats = videodb.find({"chat_id": {"$lt": 0}})
29 | if not chats:
30 | return []
31 | chats_list = []
32 | for chat in await chats.to_list(length=1000000000):
33 | chats_list.append(chat)
34 | return chats_list
35 |
36 |
37 | async def is_active_video_chat(chat_id: int) -> bool:
38 | chat = await videodb.find_one({"chat_id": chat_id})
39 | if not chat:
40 | return False
41 | return True
42 |
43 |
44 | async def add_active_video_chat(chat_id: int):
45 | is_served = await is_active_video_chat(chat_id)
46 | if is_served:
47 | return
48 | return await videodb.insert_one({"chat_id": chat_id})
49 |
50 |
51 | async def remove_active_video_chat(chat_id: int):
52 | is_served = await is_active_video_chat(chat_id)
53 | if not is_served:
54 | return
55 | return await videodb.delete_one({"chat_id": chat_id})
56 |
--------------------------------------------------------------------------------
/Ayiin/Decorators/permission.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import BOT_ID, app
4 |
5 |
6 | def PermissionCheck(mystic):
7 | async def wrapper(_, message):
8 | if message.chat.type == "private":
9 | return await mystic(_, message)
10 | a = await app.get_chat_member(message.chat.id, BOT_ID)
11 | if a.status != "administrator":
12 | return await message.reply_text(
13 | "I need to be admin with some permissions:\n"
14 | + "\n- **can_manage_voice_chats:** To manage voice chats"
15 | + "\n- **can_delete_messages:** To delete Bot's Searched Waste"
16 | + "\n- **can_invite_users**: For inviting assistant to chat."
17 | )
18 | if not a.can_manage_voice_chats:
19 | await message.reply_text(
20 | "I don't have the required permission to perform this action."
21 | + "\n**Permission:** __MANAGE VOICE CHATS__"
22 | )
23 | return
24 | if not a.can_delete_messages:
25 | await message.reply_text(
26 | "I don't have the required permission to perform this action."
27 | + "\n**Permission:** __DELETE MESSAGES__"
28 | )
29 | return
30 | if not a.can_invite_users:
31 | await message.reply_text(
32 | "I don't have the required permission to perform this action."
33 | + "\n**Permission:** __INVITE USERS VIA LINK__"
34 | )
35 | return
36 | return await mystic(_, message)
37 |
38 | return wrapper
39 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Speedtest.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import speedtest
4 | import wget
5 | from pyrogram import Client, filters
6 | from pyrogram.types import Message
7 |
8 | from Ayiin import BOT_ID, SUDOERS, app
9 | from Ayiin.Utilities.formatters import bytes
10 |
11 | __MODULE__ = "Speedtest"
12 | __HELP__ = """
13 |
14 | /speedtest
15 | - Check Server Latency and Speed.
16 |
17 | """
18 |
19 |
20 | @app.on_message(filters.command("speedtest") & ~filters.edited)
21 | async def statsguwid(_, message):
22 | m = await message.reply_text("Running Speed test")
23 | try:
24 | test = speedtest.Speedtest()
25 | test.get_best_server()
26 | m = await m.edit("Running Download SpeedTest")
27 | test.download()
28 | m = await m.edit("Running Upload SpeedTest")
29 | test.upload()
30 | test.results.share()
31 | result = test.results.dict()
32 | except Exception as e:
33 | return await m.edit(e)
34 | m = await m.edit("Sharing SpeedTest Results")
35 | path = wget.download(result["share"])
36 |
37 | output = f"""**Speedtest Results**
38 |
39 | **Client:**
40 | **__ISP:__** {result['client']['isp']}
41 | **__Country:__** {result['client']['country']}
42 |
43 | **Server:**
44 | **__Name:__** {result['server']['name']}
45 | **__Country:__** {result['server']['country']}, {result['server']['cc']}
46 | **__Sponsor:__** {result['server']['sponsor']}
47 | **__Latency:__** {result['server']['latency']}
48 | **__Ping:__** {result['ping']}"""
49 | msg = await app.send_photo(
50 | chat_id=message.chat.id, photo=path, caption=output
51 | )
52 | os.remove(path)
53 | await m.delete()
54 |
--------------------------------------------------------------------------------
/Ayiin/Inline/song.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 |
5 | def song_markup(videoid, duration, user_id, query, query_type):
6 | buttons = [
7 | [
8 | InlineKeyboardButton(
9 | text="❮",
10 | callback_data=f"song_right B|{query_type}|{query}|{user_id}",
11 | ),
12 | InlineKeyboardButton(
13 | text="𝙳𝙾𝚆𝙽𝙻𝙾𝙰𝙳",
14 | callback_data=f"qwertyuiopasdfghjkl {videoid}|{user_id}",
15 | ),
16 | InlineKeyboardButton(
17 | text="❯",
18 | callback_data=f"song_right F|{query_type}|{query}|{user_id}",
19 | ),
20 | ],
21 | [
22 | InlineKeyboardButton(
23 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
24 | callback_data=f"forceclose {query}|{user_id}",
25 | )
26 | ],
27 | ]
28 | return buttons
29 |
30 |
31 | def song_download_markup(videoid, user_id):
32 | buttons = [
33 | [
34 | InlineKeyboardButton(
35 | text="☟︎︎︎ 𝙶𝙴𝚃 𝙰𝚄𝙳𝙸𝙾",
36 | callback_data=f"gets audio|{videoid}|{user_id}",
37 | ),
38 | InlineKeyboardButton(
39 | text="☟︎︎︎ 𝙶𝙴𝚃 𝚅𝙸𝙳𝙴𝙾",
40 | callback_data=f"gets video|{videoid}|{user_id}",
41 | ),
42 | ],
43 | [
44 | InlineKeyboardButton(
45 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
46 | callback_data=f"forceclose {videoid}|{user_id}",
47 | )
48 | ],
49 | ]
50 | return buttons
51 |
--------------------------------------------------------------------------------
/Ayiin/Database/queue.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | pytgdb = db.pytg
6 | admindb = db.admin
7 |
8 |
9 | ## Queue Chats Audio
10 |
11 |
12 | async def get_active_chats() -> list:
13 | chats = pytgdb.find({"chat_id": {"$lt": 0}})
14 | if not chats:
15 | return []
16 | chats_list = []
17 | for chat in await chats.to_list(length=1000000000):
18 | chats_list.append(chat)
19 | return chats_list
20 |
21 |
22 | async def is_active_chat(chat_id: int) -> bool:
23 | chat = await pytgdb.find_one({"chat_id": chat_id})
24 | if not chat:
25 | return False
26 | return True
27 |
28 |
29 | async def add_active_chat(chat_id: int):
30 | is_served = await is_active_chat(chat_id)
31 | if is_served:
32 | return
33 | return await pytgdb.insert_one({"chat_id": chat_id})
34 |
35 |
36 | async def remove_active_chat(chat_id: int):
37 | is_served = await is_active_chat(chat_id)
38 | if not is_served:
39 | return
40 | return await pytgdb.delete_one({"chat_id": chat_id})
41 |
42 |
43 | ## Music Playing or Paused
44 |
45 |
46 | async def is_music_playing(chat_id: int) -> bool:
47 | chat = await admindb.find_one({"chat_id_toggle": chat_id})
48 | if not chat:
49 | return True
50 | return False
51 |
52 |
53 | async def music_on(chat_id: int):
54 | is_on = await is_music_playing(chat_id)
55 | if is_on:
56 | return
57 | return await admindb.delete_one({"chat_id_toggle": chat_id})
58 |
59 |
60 | async def music_off(chat_id: int):
61 | is_on = await is_music_playing(chat_id)
62 | if not is_on:
63 | return
64 | return await admindb.insert_one({"chat_id_toggle": chat_id})
65 |
--------------------------------------------------------------------------------
/Ayiin/Core/Clients/cli.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client
2 |
3 | from config import (API_HASH, API_ID, BOT_TOKEN, LOG_SESSION, STRING1, STRING2,
4 | STRING3, STRING4, STRING5)
5 |
6 | app = Client(
7 | "AyiinMusic",
8 | API_ID,
9 | API_HASH,
10 | bot_token=BOT_TOKEN,
11 | )
12 |
13 |
14 | if not STRING1:
15 | ASS_CLI_1 = None
16 | else:
17 | ASS_CLI_1 = Client(
18 | api_id=API_ID,
19 | api_hash=API_HASH,
20 | session_name=STRING1,
21 | plugins=dict(root="Ayiin.Plugins.Multi-Assistant"),
22 | )
23 |
24 |
25 | if not STRING2:
26 | ASS_CLI_2 = None
27 | else:
28 | ASS_CLI_2 = Client(
29 | api_id=API_ID,
30 | api_hash=API_HASH,
31 | session_name=STRING2,
32 | plugins=dict(root="Ayiin.Plugins.Multi-Assistant"),
33 | )
34 |
35 |
36 | if not STRING3:
37 | ASS_CLI_3 = None
38 | else:
39 | ASS_CLI_3 = Client(
40 | api_id=API_ID,
41 | api_hash=API_HASH,
42 | session_name=STRING3,
43 | plugins=dict(root="Ayiin.Plugins.Multi-Assistant"),
44 | )
45 |
46 |
47 | if not STRING4:
48 | ASS_CLI_4 = None
49 | else:
50 | ASS_CLI_4 = Client(
51 | api_id=API_ID,
52 | api_hash=API_HASH,
53 | session_name=STRING4,
54 | plugins=dict(root="Ayiin.Plugins.Multi-Assistant"),
55 | )
56 |
57 |
58 | if not STRING5:
59 | ASS_CLI_5 = None
60 | else:
61 | ASS_CLI_5 = Client(
62 | api_id=API_ID,
63 | api_hash=API_HASH,
64 | session_name=STRING5,
65 | plugins=dict(root="Ayiin.Plugins.Multi-Assistant"),
66 | )
67 |
68 |
69 | if not LOG_SESSION:
70 | LOG_CLIENT = None
71 | else:
72 | LOG_CLIENT = Client(LOG_SESSION, API_ID, API_HASH)
73 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/tasks.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from asyncio import Lock, create_task
3 | from time import time
4 |
5 | from pyrogram import filters
6 | from pyrogram.types import Message
7 |
8 | tasks = {}
9 | TASKS_LOCK = Lock()
10 | arrow = lambda x: (x.text if x else "") + "\n`→`"
11 |
12 | import shlex
13 | from typing import Tuple
14 |
15 |
16 | async def install_requirements(cmd: str) -> Tuple[str, str, int, int]:
17 | args = shlex.split(cmd)
18 | process = await asyncio.create_subprocess_exec(
19 | *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
20 | )
21 | stdout, stderr = await process.communicate()
22 | return (
23 | stdout.decode("utf-8", "replace").strip(),
24 | stderr.decode("utf-8", "replace").strip(),
25 | process.returncode,
26 | process.pid,
27 | )
28 |
29 |
30 | def all_tasks():
31 | return tasks
32 |
33 |
34 | async def add_task(
35 | taskFunc,
36 | task_name,
37 | *args,
38 | **kwargs,
39 | ):
40 |
41 | async with TASKS_LOCK:
42 | global tasks
43 |
44 | task_id = (list(tasks.keys())[-1] + 1) if tasks else 0
45 |
46 | task = create_task(
47 | taskFunc(*args, **kwargs),
48 | name=task_name,
49 | )
50 | tasks[task_id] = task, int(time())
51 | return task, task_id
52 |
53 |
54 | async def rm_task(task_id=None):
55 | global tasks
56 |
57 | async with TASKS_LOCK:
58 | for key, value in list(tasks.items()):
59 | if value[0].done() or value[0].cancelled():
60 | del tasks[key]
61 |
62 | if (task_id is not None) and (task_id in tasks):
63 | task = tasks[task_id][0]
64 |
65 | if not task.done():
66 | task.cancel()
67 |
68 | del tasks[task_id]
69 |
--------------------------------------------------------------------------------
/Ayiin/Core/PyTgCalls/Tgdownloader.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | from datetime import datetime, timedelta
4 |
5 | from pyrogram.errors.exceptions import FloodWait
6 |
7 | from Ayiin import MUSIC_BOT_NAME, app, db_mem
8 | from Ayiin.Utilities.formatters import bytes
9 | from Ayiin.Utilities.ping import get_readable_time
10 |
11 |
12 | async def telegram_download(message, mystic):
13 | ### Download Media From Telegram by AyiinMusic
14 | left_time = {}
15 | speed_counter = {}
16 |
17 | async def progress(current, total):
18 | if current == total:
19 | return
20 | current_time = time.time()
21 | start_time = speed_counter.get(message.message_id)
22 | check_time = current_time - start_time
23 | if datetime.now() > left_time.get(message.message_id):
24 | percentage = current * 100 / total
25 | percentage = round(percentage, 2)
26 | speed = current / check_time
27 | eta = get_readable_time(int((total - current) / speed))
28 | if not eta:
29 | eta = "0 sec"
30 | total_size = bytes(total)
31 | completed_size = bytes(current)
32 | speed = bytes(speed)
33 | text = f"""
34 | **{MUSIC_BOT_NAME} Telegram Media Downloader**
35 |
36 | **Total FileSize:** {total_size}
37 | **Completed:** {completed_size}
38 | **Percentage:** {percentage}%
39 |
40 | **Speed:** {speed}/s
41 | **ETA:** {eta}"""
42 | try:
43 | await mystic.edit(text)
44 | except FloodWait as e:
45 | await asyncio.sleep(e.x)
46 | left_time[message.message_id] = datetime.now() + timedelta(
47 | seconds=5
48 | )
49 |
50 | speed_counter[message.message_id] = time.time()
51 | left_time[message.message_id] = datetime.now()
52 | X = await app.download_media(message.reply_to_message, progress=progress)
53 | return X
54 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Theme.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from pyrogram import Client, filters
4 |
5 | from Ayiin import BOT_USERNAME, MUSIC_BOT_NAME, app, db
6 | from Ayiin.Database import _get_theme, get_theme, save_theme
7 | from Ayiin.Decorators.permission import PermissionCheck
8 |
9 | themes = [
10 | "blue",
11 | "black",
12 | "red",
13 | "green",
14 | "grey",
15 | "orange",
16 | "pink",
17 | "yellow",
18 | "Random",
19 | ]
20 |
21 | themes2 = [
22 | "blue",
23 | "black",
24 | "red",
25 | "green",
26 | "grey",
27 | "orange",
28 | "pink",
29 | "yellow",
30 | ]
31 |
32 | __MODULE__ = "Theme"
33 | __HELP__ = """
34 |
35 |
36 | /settheme
37 | - Set a theme for thumbnails.
38 |
39 | /theme
40 | - Check Theme for your chat.
41 | """
42 |
43 |
44 | @app.on_message(
45 | filters.command(["settheme", f"settheme@{BOT_USERNAME}"]) & filters.group
46 | )
47 | async def settheme(_, message):
48 | usage = f"This isn't a theme.\n\nSelect from them\n{' | '.join(themes)}\n\nUse 'Random' to get random choice of themes"
49 | if len(message.command) != 2:
50 | return await message.reply_text(usage)
51 | theme = message.text.split(None, 1)[1].strip()
52 | if theme not in themes:
53 | return await message.reply_text(usage)
54 | note = {
55 | "theme": theme,
56 | }
57 | await save_theme(message.chat.id, "theme", note)
58 | await message.reply_text(f"Changed thumbnail theme to {theme}")
59 |
60 |
61 | @app.on_message(filters.command("theme"))
62 | @PermissionCheck
63 | async def theme_func(_, message):
64 | await message.delete()
65 | _note = await get_theme(message.chat.id, "theme")
66 | if not _note:
67 | theme = "Random"
68 | else:
69 | theme = _note["theme"]
70 | await message.reply_text(
71 | f"**{MUSIC_BOT_NAME} Thumbnails Theme**\n\n**Current Theme:-** {theme}\n\n**Available Themes:-** {' | '.join(themes2)} \n\nUse /settheme to change theme."
72 | )
73 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | from os import getenv
2 |
3 | from dotenv import load_dotenv
4 |
5 | load_dotenv()
6 |
7 | # VARS
8 |
9 | get_queue = {}
10 | BOT_TOKEN = getenv("BOT_TOKEN")
11 | API_ID = int(getenv("API_ID", ""))
12 | API_HASH = getenv("API_HASH")
13 | DURATION_LIMIT_MIN = int(getenv("DURATION_LIMIT", "10"))
14 | ASSISTANT_PREFIX = list(getenv("ASSISTANT_PREFIX", ".").split())
15 | MONGO_DB_URI = getenv("MONGO_DB_URI")
16 | SUDO_USERS = list(map(int, getenv("SUDO_USERS", "").split()))
17 | OWNER_ID = list(map(int, getenv("OWNER_ID", "").split()))
18 | LOG_GROUP_ID = int(getenv("LOG_GROUP_ID", ""))
19 | MUSIC_BOT_NAME = getenv("MUSIC_BOT_NAME")
20 | HEROKU_API_KEY = getenv("HEROKU_API_KEY")
21 | HEROKU_APP_NAME = getenv("HEROKU_APP_NAME")
22 |
23 | UPSTREAM_REPO = getenv(
24 | "UPSTREAM_REPO", "https://github.com/AyiinXd/MultiAssistant"
25 | )
26 | UPSTREAM_BRANCH = getenv("UPSTREAM_BRANCH", "master")
27 |
28 | if str(getenv("SUPPORT_CHANNEL")).strip() == "":
29 | SUPPORT_CHANNEL = None
30 | else:
31 | SUPPORT_CHANNEL = str(getenv("SUPPORT_CHANNEL"))
32 | if str(getenv("SUPPORT_GROUP")).strip() == "":
33 | SUPPORT_GROUP = None
34 | else:
35 | SUPPORT_GROUP = str(getenv("SUPPORT_GROUP"))
36 |
37 |
38 | if str(getenv("STRING_SESSION1")).strip() == "":
39 | STRING1 = str(None)
40 | else:
41 | STRING1 = str(getenv("STRING_SESSION1"))
42 |
43 | if str(getenv("STRING_SESSION2")).strip() == "":
44 | STRING2 = str(None)
45 | else:
46 | STRING2 = str(getenv("STRING_SESSION2"))
47 |
48 | if str(getenv("STRING_SESSION3")).strip() == "":
49 | STRING3 = str(None)
50 | else:
51 | STRING3 = str(getenv("STRING_SESSION3"))
52 |
53 | if str(getenv("STRING_SESSION4")).strip() == "":
54 | STRING4 = str(None)
55 | else:
56 | STRING4 = str(getenv("STRING_SESSION4"))
57 |
58 | if str(getenv("STRING_SESSION5")).strip() == "":
59 | STRING5 = str(None)
60 | else:
61 | STRING5 = str(getenv("STRING_SESSION5"))
62 |
63 | if str(getenv("LOG_SESSION")).strip() == "":
64 | LOG_SESSION = str(None)
65 | else:
66 | LOG_SESSION = str(getenv("LOG_SESSION"))
67 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/thumbnails.py:
--------------------------------------------------------------------------------
1 | import os
2 | import random
3 | from os import path
4 |
5 | import aiofiles
6 | import aiohttp
7 | from PIL import Image, ImageDraw, ImageFont
8 |
9 |
10 | def changeImageSize(maxWidth, maxHeight, image):
11 | widthRatio = maxWidth / image.size[0]
12 | heightRatio = maxHeight / image.size[1]
13 | newWidth = int(widthRatio * image.size[0])
14 | newHeight = int(heightRatio * image.size[1])
15 | newImage = image.resize((newWidth, newHeight))
16 | return newImage
17 |
18 |
19 | async def gen_thumb(thumbnail, title, userid, theme, ctitle):
20 | async with aiohttp.ClientSession() as session:
21 | async with session.get(thumbnail) as resp:
22 | if resp.status == 200:
23 | f = await aiofiles.open(f"cache/thumb{userid}.jpg", mode="wb")
24 | await f.write(await resp.read())
25 | await f.close()
26 | image1 = Image.open(f"cache/thumb{userid}.jpg")
27 | image2 = Image.open(f"Utils/{theme}.PNG")
28 | image3 = changeImageSize(1280, 720, image1)
29 | image4 = changeImageSize(1280, 720, image2)
30 | image5 = image3.convert("RGBA")
31 | image6 = image4.convert("RGBA")
32 | Image.alpha_composite(image5, image6).save(f"cache/temp{userid}.png")
33 | img = Image.open(f"cache/temp{userid}.png")
34 | draw = ImageDraw.Draw(img)
35 | font = ImageFont.truetype("Utils/finalfont.ttf", 85)
36 | font2 = ImageFont.truetype("Utils/finalfont.ttf", 60)
37 | draw.text(
38 | (20, 45),
39 | f"Playing on: {ctitle[:14]}...",
40 | fill="white",
41 | stroke_width=1,
42 | stroke_fill="white",
43 | font=font2,
44 | )
45 | draw.text(
46 | (25, 595),
47 | f"{title[:27]}...",
48 | fill="white",
49 | stroke_width=2,
50 | stroke_fill="white",
51 | font=font,
52 | )
53 | img.save(f"cache/final{userid}.png")
54 | os.remove(f"cache/temp{userid}.png")
55 | os.remove(f"cache/thumb{userid}.jpg")
56 | final = f"cache/final{userid}.png"
57 | return final
58 |
--------------------------------------------------------------------------------
/Ayiin/Inline/others.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 | from Ayiin import db_mem
5 |
6 |
7 | def others_markup(videoid, user_id):
8 | if videoid not in db_mem:
9 | db_mem[videoid] = {}
10 | db_mem[videoid]["check"] = 1
11 | buttons = [
12 | [
13 | InlineKeyboardButton(
14 | text="🔎 𝚂𝙴𝙰𝚁𝙲𝙷 𝙻𝚈𝚁𝙸𝙲𝚂",
15 | callback_data=f"lyrics {videoid}|{user_id}",
16 | )
17 | ],
18 | [
19 | InlineKeyboardButton(
20 | text="✚ 𝚈𝙾𝚄𝚁 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
21 | callback_data=f"your_playlist {videoid}|{user_id}",
22 | ),
23 | InlineKeyboardButton(
24 | text="✚ 𝙶𝚁𝙾𝚄𝙿 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
25 | callback_data=f"group_playlist {videoid}|{user_id}",
26 | ),
27 | ],
28 | [
29 | InlineKeyboardButton(
30 | text="☟︎︎︎ 𝙳𝙾𝚆𝙽𝙻𝙾𝙰𝙳 𝙰𝚄𝙳𝙸𝙾/𝚅𝙸𝙳𝙴𝙾",
31 | callback_data=f"audio_video_download {videoid}|{user_id}",
32 | )
33 | ],
34 | [
35 | InlineKeyboardButton(
36 | text="❮ 𝙶𝙾 𝙱𝙰𝙲𝙺",
37 | callback_data=f"pr_go_back_timer {videoid}|{user_id}",
38 | ),
39 | InlineKeyboardButton(
40 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
41 | callback_data=f"close",
42 | ),
43 | ],
44 | ]
45 | return buttons
46 |
47 |
48 | def download_markup(videoid, user_id):
49 | buttons = [
50 | [
51 | InlineKeyboardButton(
52 | text="☟︎︎︎ 𝙶𝙴𝚃 𝙰𝚄𝙳𝙸𝙾",
53 | callback_data=f"gets audio|{videoid}|{user_id}",
54 | ),
55 | InlineKeyboardButton(
56 | text="☟︎︎︎ 𝙶𝙴𝚃 𝚅𝙸𝙳𝙴𝙾",
57 | callback_data=f"gets video|{videoid}|{user_id}",
58 | ),
59 | ],
60 | [
61 | InlineKeyboardButton(
62 | text="❮ 𝙶𝙾 𝙱𝙰𝙲𝙺", callback_data=f"goback {videoid}|{user_id}"
63 | ),
64 | InlineKeyboardButton(text="•Cʟᴏsᴇ•", callback_data=f"close"),
65 | ],
66 | ]
67 | return buttons
68 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/youtube.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from youtubesearchpython import VideosSearch
4 |
5 | from Ayiin.Utilities.changers import time_to_seconds
6 |
7 |
8 | def get_yt_info_id(videoid):
9 | url = f"https://www.youtube.com/watch?v={videoid}"
10 | results = VideosSearch(url, limit=1)
11 | for result in results.result()["result"]:
12 | title = result["title"]
13 | duration_min = result["duration"]
14 | thumbnail = result["thumbnails"][0]["url"].split("?")[0]
15 | if str(duration_min) == "None":
16 | duration_sec = 0
17 | else:
18 | duration_sec = int(time_to_seconds(duration_min))
19 | return title, duration_min, duration_sec, thumbnail
20 |
21 |
22 | def get_yt_info_query(query: str):
23 | results = VideosSearch(query, limit=1)
24 | for result in results.result()["result"]:
25 | title = result["title"]
26 | duration_min = result["duration"]
27 | thumbnail = result["thumbnails"][0]["url"].split("?")[0]
28 | videoid = result["id"]
29 | if str(duration_min) == "None":
30 | duration_sec = 0
31 | else:
32 | duration_sec = int(time_to_seconds(duration_min))
33 | return title, duration_min, duration_sec, thumbnail, videoid
34 |
35 |
36 | def get_yt_info_query_slider(query: str, query_type: int):
37 | a = VideosSearch(query, limit=10)
38 | result = (a.result()).get("result")
39 | title = result[query_type]["title"]
40 | duration_min = result[query_type]["duration"]
41 | videoid = result[query_type]["id"]
42 | thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
43 | if str(duration_min) == "None":
44 | duration_sec = 0
45 | else:
46 | duration_sec = int(time_to_seconds(duration_min))
47 | return title, duration_min, duration_sec, thumbnail, videoid
48 |
49 |
50 | async def get_m3u8(videoid):
51 | link = f"https://www.youtube.com/watch?v={videoid}"
52 | proc = await asyncio.create_subprocess_exec(
53 | "yt-dlp",
54 | "-g",
55 | "-f",
56 | "best[height<=?720][width<=?1280]",
57 | f"{link}",
58 | stdout=asyncio.subprocess.PIPE,
59 | stderr=asyncio.subprocess.PIPE,
60 | )
61 | stdout, stderr = await proc.communicate()
62 | if stdout:
63 | return 1, stdout.decode().split("\n")[0]
64 | else:
65 | return 0, stderr.decode()
66 |
--------------------------------------------------------------------------------
/Ayiin/Decorators/checker.py:
--------------------------------------------------------------------------------
1 | from Ayiin import BOT_USERNAME, LOG_GROUP_ID, app
2 | from Ayiin.Database import blacklisted_chats, is_gbanned_user, is_on_off
3 |
4 |
5 | def checker(mystic):
6 | async def wrapper(_, message):
7 | if message.sender_chat:
8 | return await message.reply_text(
9 | "You're an __Anonymous Admin__ in this Chat Group!\nRevert back to User Account From Admin Rights."
10 | )
11 | blacklisted_chats_list = await blacklisted_chats()
12 | if message.chat.id in blacklisted_chats_list:
13 | await message.reply_text(
14 | f"**Blacklisted Chat**\n\nYour chat has been blacklisted by Sudo Users.Ask any __SUDO USER__ to whitelist.\nCheck Sudo Users List [From Here](https://t.me/{BOT_USERNAME}?start=sudolist)"
15 | )
16 | return await app.leave_chat(message.chat.id)
17 | if await is_on_off(1):
18 | if int(message.chat.id) != int(LOG_GROUP_ID):
19 | return await message.reply_text(
20 | f"Bot is under Maintenance. Sorry for the inconvenience!"
21 | )
22 | if await is_gbanned_user(message.from_user.id):
23 | return await message.reply_text(
24 | f"**Gbanned User**\n\nYou're gbanned from using Bot.Ask any __SUDO USER__ to ungban.\nCheck Sudo Users List [From Here](https://t.me/{BOT_USERNAME}?start=sudolist)"
25 | )
26 | return await mystic(_, message)
27 |
28 | return wrapper
29 |
30 |
31 | def checkerCB(mystic):
32 | async def wrapper(_, CallbackQuery):
33 | blacklisted_chats_list = await blacklisted_chats()
34 | if CallbackQuery.message.chat.id in blacklisted_chats_list:
35 | return await CallbackQuery.answer(
36 | "Blacklisted Chat", show_alert=True
37 | )
38 | if await is_on_off(1):
39 | if int(CallbackQuery.message.chat.id) != int(LOG_GROUP_ID):
40 | return await CallbackQuery.answer(
41 | "Bot is under Maintenance. Sorry for the inconvenience!",
42 | show_alert=True,
43 | )
44 | if await is_gbanned_user(CallbackQuery.from_user.id):
45 | return await CallbackQuery.answer(
46 | "You're Gbanned", show_alert=True
47 | )
48 | return await mystic(_, CallbackQuery)
49 |
50 | return wrapper
51 |
--------------------------------------------------------------------------------
/Ayiin/Inline/videocalls.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 |
5 | def choose_markup(videoid, duration, user_id):
6 | buttons = [
7 | [
8 | InlineKeyboardButton(
9 | text="⍟ 𝙼𝚄𝚂𝙸𝙲 ⍟",
10 | callback_data=f"MusicStream {videoid}|{duration}|{user_id}",
11 | ),
12 | InlineKeyboardButton(
13 | text="⍟ 𝚅𝙸𝙳𝙴𝙾 ⍟",
14 | callback_data=f"Choose {videoid}|{duration}|{user_id}",
15 | ),
16 | ],
17 | [
18 | InlineKeyboardButton(
19 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
20 | callback_data=f"forceclose {videoid}|{user_id}",
21 | )
22 | ],
23 | ]
24 | return buttons
25 |
26 |
27 | def livestream_markup(quality, videoid, duration, user_id):
28 | buttons = [
29 | [
30 | InlineKeyboardButton(
31 | text="⍟ 𝙻𝙸𝚅𝙴 ⍟",
32 | callback_data=f"LiveStream {quality}|{videoid}|{duration}|{user_id}",
33 | ),
34 | InlineKeyboardButton(
35 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
36 | callback_data=f"forceclose {videoid}|{user_id}",
37 | ),
38 | ],
39 | ]
40 | return buttons
41 |
42 |
43 | def stream_quality_markup(videoid, duration, user_id):
44 | buttons = [
45 | [
46 | InlineKeyboardButton(
47 | text="📽 360P",
48 | callback_data=f"VideoStream 360|{videoid}|{duration}|{user_id}",
49 | ),
50 | InlineKeyboardButton(
51 | text="📽 720P",
52 | callback_data=f"VideoStream 720|{videoid}|{duration}|{user_id}",
53 | ),
54 | InlineKeyboardButton(
55 | text="📽 480P",
56 | callback_data=f"VideoStream 480|{videoid}|{duration}|{user_id}",
57 | ),
58 | ],
59 | [
60 | InlineKeyboardButton(
61 | text="❮ 𝙶𝙾 𝙱𝙰𝙲𝙺",
62 | callback_data=f"gback_list_chose_stream {videoid}|{duration}|{user_id}",
63 | ),
64 | InlineKeyboardButton(
65 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
66 | callback_data=f"forceclose {videoid}|{user_id}",
67 | ),
68 | ],
69 | ]
70 | return buttons
71 |
--------------------------------------------------------------------------------
/Ayiin/Database/auth.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | authdb = db.adminauth
6 |
7 |
8 | async def is_nonadmin_chat(user_id: int) -> bool:
9 | user = await authdb.find_one({"user_id": user_id})
10 | if not user:
11 | return False
12 | return True
13 |
14 |
15 | async def add_nonadmin_chat(user_id: int):
16 | is_gbanned = await is_nonadmin_chat(user_id)
17 | if is_gbanned:
18 | return
19 | return await authdb.insert_one({"user_id": user_id})
20 |
21 |
22 | async def remove_nonadmin_chat(user_id: int):
23 | is_gbanned = await is_nonadmin_chat(user_id)
24 | if not is_gbanned:
25 | return
26 | return await authdb.delete_one({"user_id": user_id})
27 |
28 |
29 | ## Save Auth User
30 |
31 | authuserdb = db.authuser
32 |
33 |
34 | async def get_authuser_count() -> dict:
35 | chats = authuserdb.find({"chat_id": {"$lt": 0}})
36 | if not chats:
37 | return {}
38 | chats_count = 0
39 | notes_count = 0
40 | for chat in await chats.to_list(length=1000000000):
41 | notes_name = await get_authuser_names(chat["chat_id"])
42 | notes_count += len(notes_name)
43 | chats_count += 1
44 | return {"chats_count": chats_count, "notes_count": notes_count}
45 |
46 |
47 | async def _get_authusers(chat_id: int) -> Dict[str, int]:
48 | _notes = await authuserdb.find_one({"chat_id": chat_id})
49 | if not _notes:
50 | return {}
51 | return _notes["notes"]
52 |
53 |
54 | async def get_authuser_names(chat_id: int) -> List[str]:
55 | _notes = []
56 | for note in await _get_authusers(chat_id):
57 | _notes.append(note)
58 | return _notes
59 |
60 |
61 | async def get_authuser(chat_id: int, name: str) -> Union[bool, dict]:
62 | name = name
63 | _notes = await _get_authusers(chat_id)
64 | if name in _notes:
65 | return _notes[name]
66 | else:
67 | return False
68 |
69 |
70 | async def save_authuser(chat_id: int, name: str, note: dict):
71 | name = name
72 | _notes = await _get_authusers(chat_id)
73 | _notes[name] = note
74 |
75 | await authuserdb.update_one(
76 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
77 | )
78 |
79 |
80 | async def delete_authuser(chat_id: int, name: str) -> bool:
81 | notesd = await _get_authusers(chat_id)
82 | name = name
83 | if name in notesd:
84 | del notesd[name]
85 | await authuserdb.update_one(
86 | {"chat_id": chat_id}, {"$set": {"notes": notesd}}, upsert=True
87 | )
88 | return True
89 | return False
90 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Blacklist.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from pyrogram.types import Message
3 |
4 | from Ayiin import SUDOERS, app
5 | from Ayiin.Database import blacklist_chat, blacklisted_chats, whitelist_chat
6 |
7 | __MODULE__ = "Blacklist"
8 | __HELP__ = """
9 |
10 |
11 | /blacklistedchat
12 | - Check Blacklisted Chats of Bot.
13 |
14 |
15 | **Note:**
16 | Only for Sudo Users.
17 |
18 |
19 | /blacklistchat [CHAT_ID]
20 | - Blacklist any chat from using Music Bot
21 |
22 |
23 | /whitelistchat [CHAT_ID]
24 | - Whitelist any blacklisted chat from using Music Bot
25 |
26 | """
27 |
28 |
29 | @app.on_message(filters.command("blacklistchat") & filters.user(SUDOERS))
30 | async def blacklist_chat_func(_, message: Message):
31 | if len(message.command) != 2:
32 | return await message.reply_text(
33 | "**Usage:**\n/blacklistchat [CHAT_ID]"
34 | )
35 | chat_id = int(message.text.strip().split()[1])
36 | if chat_id in await blacklisted_chats():
37 | return await message.reply_text("Chat is already blacklisted.")
38 | blacklisted = await blacklist_chat(chat_id)
39 | if blacklisted:
40 | return await message.reply_text(
41 | "Chat has been successfully blacklisted"
42 | )
43 | await message.reply_text("Something wrong happened, check logs.")
44 |
45 |
46 | @app.on_message(filters.command("whitelistchat") & filters.user(SUDOERS))
47 | async def whitelist_chat_func(_, message: Message):
48 | if len(message.command) != 2:
49 | return await message.reply_text(
50 | "**Usage:**\n/whitelistchat [CHAT_ID]"
51 | )
52 | chat_id = int(message.text.strip().split()[1])
53 | if chat_id not in await blacklisted_chats():
54 | return await message.reply_text("Chat is already whitelisted.")
55 | whitelisted = await whitelist_chat(chat_id)
56 | if whitelisted:
57 | return await message.reply_text(
58 | "Chat has been successfully whitelisted"
59 | )
60 | await message.reply_text("Something wrong happened, check logs.")
61 |
62 |
63 | @app.on_message(filters.command("blacklistedchat"))
64 | async def blacklisted_chats_func(_, message: Message):
65 | text = "**Blacklisted Chats:**\n\n"
66 | j = 0
67 | for count, chat_id in enumerate(await blacklisted_chats(), 1):
68 | try:
69 | title = (await app.get_chat(chat_id)).title
70 | except Exception:
71 | title = "Private"
72 | j = 1
73 | text += f"**{count}. {title}** [`{chat_id}`]\n"
74 | if j == 0:
75 | await message.reply_text("No Blacklisted Chats")
76 | else:
77 | await message.reply_text(text)
78 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/inline.py:
--------------------------------------------------------------------------------
1 | from math import ceil
2 |
3 | from pyrogram.types import InlineKeyboardButton
4 |
5 | from Ayiin import MOD_LOAD, MOD_NOLOAD
6 |
7 |
8 | class EqInlineKeyboardButton(InlineKeyboardButton):
9 | def __eq__(self, other):
10 | return self.text == other.text
11 |
12 | def __lt__(self, other):
13 | return self.text < other.text
14 |
15 | def __gt__(self, other):
16 | return self.text > other.text
17 |
18 |
19 | def paginate_modules(page_n, module_dict, prefix, chat=None):
20 | if not chat:
21 | modules = sorted(
22 | [
23 | EqInlineKeyboardButton(
24 | x.__MODULE__,
25 | callback_data="{}_module({})".format(
26 | prefix, x.__MODULE__.lower()
27 | ),
28 | )
29 | for x in module_dict.values()
30 | ]
31 | )
32 | else:
33 | modules = sorted(
34 | [
35 | EqInlineKeyboardButton(
36 | x.__MODULE__,
37 | callback_data="{}_module({},{})".format(
38 | prefix, chat, x.__MODULE__.lower()
39 | ),
40 | )
41 | for x in module_dict.values()
42 | ]
43 | )
44 |
45 | pairs = list(zip(modules[::3], modules[1::3], modules[2::3]))
46 | i = 0
47 | for m in pairs:
48 | for _ in m:
49 | i += 1
50 | if len(modules) - i == 1:
51 | pairs.append((modules[-1],))
52 | elif len(modules) - i == 2:
53 | pairs.append(
54 | (
55 | modules[-2],
56 | modules[-1],
57 | )
58 | )
59 |
60 | COLUMN_SIZE = 3
61 |
62 | max_num_pages = ceil(len(pairs) / COLUMN_SIZE)
63 | modulo_page = page_n % max_num_pages
64 |
65 | # can only have a certain amount of buttons side by side
66 | if len(pairs) > COLUMN_SIZE:
67 | pairs = pairs[
68 | modulo_page * COLUMN_SIZE : COLUMN_SIZE * (modulo_page + 1)
69 | ] + [
70 | (
71 | EqInlineKeyboardButton(
72 | "❮",
73 | callback_data="{}_prev({})".format(prefix, modulo_page),
74 | ),
75 | EqInlineKeyboardButton(
76 | "Close",
77 | callback_data="close",
78 | ),
79 | EqInlineKeyboardButton(
80 | "❯",
81 | callback_data="{}_next({})".format(prefix, modulo_page),
82 | ),
83 | )
84 | ]
85 |
86 | return pairs
87 |
88 |
89 | def is_module_loaded(name):
90 | return (not MOD_LOAD or name in MOD_LOAD) and name not in MOD_NOLOAD
91 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/chat.py:
--------------------------------------------------------------------------------
1 | async def specialfont_to_normal(ctitle):
2 | string = ctitle
3 | font1 = list("𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ")
4 | font2 = list("𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅")
5 | font3 = list("𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩")
6 | font4 = list("𝒜𝐵𝒞𝒟𝐸𝐹𝒢𝐻𝐼𝒥𝒦𝐿𝑀𝒩𝒪𝒫𝒬𝑅𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵")
7 | font5 = list("𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ")
8 | font6 = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
9 | font26 = list("𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙")
10 | font27 = list("𝗔𝗕𝗖𝗗𝗘𝗙𝗚𝗛𝗜𝗝𝗞𝗟𝗠𝗡𝗢𝗣𝗤𝗥𝗦𝗧𝗨𝗩𝗪𝗫𝗬𝗭")
11 | font28 = list("𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡")
12 | font29 = list("𝘼𝘽𝘾𝘿𝙀𝙁𝙂𝙃𝙄𝙅𝙆𝙇𝙈𝙉𝙊𝙋𝙌𝙍𝙎𝙏𝙐𝙑𝙒𝙓𝙔𝙕")
13 | font30 = list("𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉")
14 | font1L = list("𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷")
15 | font2L = list("𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟")
16 | font3L = list("𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃")
17 | font4L = list("𝒶𝒷𝒸𝒹𝑒𝒻𝑔𝒽𝒾𝒿𝓀𝓁𝓂𝓃𝑜𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏")
18 | font5L = list("𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫")
19 | font6L = list("abcdefghijklmnopqrstuvwxyz")
20 | font27L = list("𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳")
21 | font28L = list("𝗮𝗯𝗰𝗱𝗲𝗳𝗴𝗵𝗶𝗷𝗸𝗹𝗺𝗻𝗼𝗽𝗾𝗿𝘀𝘁𝘂𝘃𝘄𝘅𝘆𝘇")
22 | font29L = list("𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻")
23 | font30L = list("𝙖𝙗𝙘𝙙𝙚𝙛𝙜𝙝𝙞𝙟𝙠𝙡𝙢𝙣𝙤𝙥𝙦𝙧𝙨𝙩𝙪𝙫𝙬𝙭𝙮𝙯")
24 | font31L = list("𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣")
25 | normal = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
26 | normalL = list("abcdefghijklmnopqrstuvwxyz")
27 | cout = 0
28 | for XCB in font1:
29 | string = string.replace(font1[cout], normal[cout])
30 | string = string.replace(font2[cout], normal[cout])
31 | string = string.replace(font3[cout], normal[cout])
32 | string = string.replace(font4[cout], normal[cout])
33 | string = string.replace(font5[cout], normal[cout])
34 | string = string.replace(font6[cout], normal[cout])
35 | string = string.replace(font26[cout], normal[cout])
36 | string = string.replace(font27[cout], normal[cout])
37 | string = string.replace(font28[cout], normal[cout])
38 | string = string.replace(font29[cout], normal[cout])
39 | string = string.replace(font30[cout], normal[cout])
40 | string = string.replace(font1L[cout], normalL[cout])
41 | string = string.replace(font2L[cout], normalL[cout])
42 | string = string.replace(font3L[cout], normalL[cout])
43 | string = string.replace(font4L[cout], normalL[cout])
44 | string = string.replace(font5L[cout], normalL[cout])
45 | string = string.replace(font6L[cout], normalL[cout])
46 | string = string.replace(font27L[cout], normalL[cout])
47 | string = string.replace(font28L[cout], normalL[cout])
48 | string = string.replace(font29L[cout], normalL[cout])
49 | string = string.replace(font30L[cout], normalL[cout])
50 | string = string.replace(font31L[cout], normalL[cout])
51 | cout += 1
52 | return string
53 |
--------------------------------------------------------------------------------
/Ayiin/Database/playlist.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import db
4 |
5 | playlistdb_lofi = db.playlistlofi
6 | playlistdb_rock = db.playlistrock
7 | playlistdb_sad = db.playlistsad
8 | playlistdb_party = db.playlistparty
9 | playlistdb_bollywood = db.playlistbollywood
10 | playlistdb_hollywood = db.playlisthollywood
11 | playlistdb_punjabi = db.playlistpunjabi
12 | playlistdb_others = db.playlistothers
13 |
14 |
15 | async def _get_playlists(chat_id: int, type: str) -> Dict[str, int]:
16 | if type == "Lofi":
17 | xd = playlistdb_lofi
18 | elif type == "Weeb":
19 | xd = playlistdb_rock
20 | elif type == "Sad":
21 | xd = playlistdb_sad
22 | elif type == "Party":
23 | xd = playlistdb_party
24 | elif type == "Bollywood":
25 | xd = playlistdb_bollywood
26 | elif type == "Hollywood":
27 | xd = playlistdb_hollywood
28 | elif type == "Punjabi":
29 | xd = playlistdb_punjabi
30 | elif type == "Others":
31 | xd = playlistdb_others
32 | _notes = await xd.find_one({"chat_id": chat_id})
33 | if not _notes:
34 | return {}
35 | return _notes["notes"]
36 |
37 |
38 | async def get_playlist_names(chat_id: int, type: str) -> List[str]:
39 | _notes = []
40 | for note in await _get_playlists(chat_id, type):
41 | _notes.append(note)
42 | return _notes
43 |
44 |
45 | async def get_playlist(
46 | chat_id: int, name: str, type: str
47 | ) -> Union[bool, dict]:
48 | name = name
49 | _notes = await _get_playlists(chat_id, type)
50 | if name in _notes:
51 | return _notes[name]
52 | else:
53 | return False
54 |
55 |
56 | async def save_playlist(chat_id: int, name: str, note: dict, type: str):
57 | name = name
58 | _notes = await _get_playlists(chat_id, type)
59 | _notes[name] = note
60 | if type == "Lofi":
61 | xd = playlistdb_lofi
62 | elif type == "Weeb":
63 | xd = playlistdb_rock
64 | elif type == "Sad":
65 | xd = playlistdb_sad
66 | elif type == "Party":
67 | xd = playlistdb_party
68 | elif type == "Bollywood":
69 | xd = playlistdb_bollywood
70 | elif type == "Hollywood":
71 | xd = playlistdb_hollywood
72 | elif type == "Punjabi":
73 | xd = playlistdb_punjabi
74 | elif type == "Others":
75 | xd = playlistdb_others
76 | await xd.update_one(
77 | {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
78 | )
79 |
80 |
81 | async def delete_playlist(chat_id: int, name: str, type: str) -> bool:
82 | notesd = await _get_playlists(chat_id, type)
83 | name = name
84 | if type == "Lofi":
85 | xd = playlistdb_lofi
86 | elif type == "Weeb":
87 | xd = playlistdb_rock
88 | elif type == "Sad":
89 | xd = playlistdb_sad
90 | elif type == "Party":
91 | xd = playlistdb_party
92 | elif type == "Bollywood":
93 | xd = playlistdb_bollywood
94 | elif type == "Hollywood":
95 | xd = playlistdb_hollywood
96 | elif type == "Punjabi":
97 | xd = playlistdb_punjabi
98 | elif type == "Others":
99 | xd = playlistdb_others
100 | if name in notesd:
101 | del notesd[name]
102 | await xd.update_one(
103 | {"chat_id": chat_id}, {"$set": {"notes": notesd}}, upsert=True
104 | )
105 | return True
106 | return False
107 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Multi-Assistant/Assistant.py:
--------------------------------------------------------------------------------
1 | from inspect import getfullargspec
2 |
3 | from pyrogram import Client, filters
4 | from pyrogram.raw.functions.messages import DeleteHistory
5 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
6 | InlineKeyboardMarkup, InlineQueryResultArticle,
7 | InlineQueryResultPhoto, InputTextMessageContent,
8 | Message)
9 |
10 | from Ayiin import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4, ASS_CLI_5,
11 | ASSISTANT_PREFIX, BOT_ID, BOT_USERNAME, LOG_GROUP_ID,
12 | MUSIC_BOT_NAME, SUDOERS, app)
13 | from Ayiin.Database import (approve_pmpermit, disapprove_pmpermit, is_on_off,
14 | is_pmpermit_approved)
15 |
16 | flood = {}
17 |
18 |
19 | @Client.on_message(
20 | filters.command("block", prefixes=ASSISTANT_PREFIX)
21 | & filters.user(SUDOERS)
22 | & ~filters.user("me")
23 | & ~filters.me
24 | & ~filters.via_bot
25 | )
26 | async def block_user_func(client, message):
27 | if not message.reply_to_message:
28 | return await eor(message, text="Reply to a user's message to block.")
29 | user_id = message.reply_to_message.from_user.id
30 | await eor(message, text="Successfully blocked the user")
31 | await client.block_user(user_id)
32 |
33 |
34 | @Client.on_message(
35 | filters.command("unblock", prefixes=ASSISTANT_PREFIX)
36 | & filters.user(SUDOERS)
37 | & ~filters.user("me")
38 | & ~filters.me
39 | & ~filters.via_bot
40 | )
41 | async def unblock_user_func(client, message):
42 | if not message.reply_to_message:
43 | return await eor(
44 | message, text="Reply to a user's message to unblock."
45 | )
46 | user_id = message.reply_to_message.from_user.id
47 | await client.unblock_user(user_id)
48 | await eor(message, text="Successfully Unblocked the user")
49 |
50 |
51 | @Client.on_message(
52 | filters.command("pfp", prefixes=ASSISTANT_PREFIX)
53 | & filters.user(SUDOERS)
54 | & ~filters.user("me")
55 | & ~filters.me
56 | & ~filters.via_bot
57 | )
58 | async def set_pfp(client, message):
59 | if not message.reply_to_message or not message.reply_to_message.photo:
60 | return await eor(message, text="Reply to a photo.")
61 | photo = await message.reply_to_message.download()
62 | try:
63 | await client.set_profile_photo(photo=photo)
64 | await eor(message, text="Successfully Changed PFP.")
65 | except Exception as e:
66 | await eor(message, text=e)
67 |
68 |
69 | @Client.on_message(
70 | filters.command("bio", prefixes=ASSISTANT_PREFIX)
71 | & filters.user(SUDOERS)
72 | & ~filters.user("me")
73 | & ~filters.me
74 | & ~filters.via_bot
75 | )
76 | async def set_bio(client, message):
77 | if len(message.command) == 1:
78 | return await eor(message, text="Give some text to set as bio.")
79 | elif len(message.command) > 1:
80 | bio = message.text.split(None, 1)[1]
81 | try:
82 | await client.update_profile(bio=bio)
83 | await eor(message, text="Changed Bio.")
84 | except Exception as e:
85 | await eor(message, text=e)
86 | else:
87 | return await eor(message, text="Give some text to set as bio.")
88 |
89 |
90 | async def eor(msg: Message, **kwargs):
91 | func = (
92 | (msg.edit_text if msg.from_user.is_self else msg.reply)
93 | if msg.from_user
94 | else msg.reply
95 | )
96 | spec = getfullargspec(func.__wrapped__).args
97 | return await func(**{k: v for k, v in kwargs.items() if k in spec})
98 |
--------------------------------------------------------------------------------
/Ayiin/Decorators/admins.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List, Union
2 |
3 | from Ayiin import SUDOERS, app
4 | from Ayiin.Database import (_get_authusers, add_nonadmin_chat, delete_authuser,
5 | get_authuser, get_authuser_count,
6 | get_authuser_names, is_nonadmin_chat,
7 | remove_nonadmin_chat, save_authuser)
8 | from Ayiin.Utilities.changers import int_to_alpha
9 |
10 |
11 | def AdminRightsCheck(mystic):
12 | async def wrapper(_, message):
13 | if message.sender_chat:
14 | return await message.reply_text(
15 | "You're an __Anonymous Admin__!\nRevert back to User Account."
16 | )
17 | is_non_admin = await is_nonadmin_chat(message.chat.id)
18 | if not is_non_admin:
19 | member = await app.get_chat_member(
20 | message.chat.id, message.from_user.id
21 | )
22 | if not member.can_manage_voice_chats:
23 | if message.from_user.id not in SUDOERS:
24 | token = await int_to_alpha(message.from_user.id)
25 | _check = await get_authuser_names(message.chat.id)
26 | if token not in _check:
27 | return await message.reply(
28 | "You don't have the required permission to perform this action.\n\n__REQUIRES ADMIN WITH MANAGE VC RIGHTS__"
29 | )
30 | return await mystic(_, message)
31 |
32 | return wrapper
33 |
34 |
35 | def AdminActual(mystic):
36 | async def wrapper(_, message):
37 | if message.sender_chat:
38 | return await message.reply_text(
39 | "You're an __Anonymous Admin__!\nRevert back to User Account."
40 | )
41 | member = await app.get_chat_member(
42 | message.chat.id, message.from_user.id
43 | )
44 | if not member.can_manage_voice_chats:
45 | return await message.reply(
46 | "You don't have the required permission to perform this action.\n\n__REQUIRES ADMIN WITH MANAGE VC RIGHTS__"
47 | )
48 | return await mystic(_, message)
49 |
50 | return wrapper
51 |
52 |
53 | def AdminRightsCheckCB(mystic):
54 | async def wrapper(_, CallbackQuery):
55 | is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
56 | if not is_non_admin:
57 | a = await app.get_chat_member(
58 | CallbackQuery.message.chat.id, CallbackQuery.from_user.id
59 | )
60 | if not a.can_manage_voice_chats:
61 | if CallbackQuery.from_user.id not in SUDOERS:
62 | token = await int_to_alpha(CallbackQuery.from_user.id)
63 | _check = await get_authuser_names(
64 | CallbackQuery.from_user.id
65 | )
66 | if token not in _check:
67 | return await CallbackQuery.answer(
68 | "You don't have the required permission to perform this action.\nPermission: MANAGE VOICE CHATS",
69 | show_alert=True,
70 | )
71 | return await mystic(_, CallbackQuery)
72 |
73 | return wrapper
74 |
75 |
76 | def ActualAdminCB(mystic):
77 | async def wrapper(_, CallbackQuery):
78 | a = await app.get_chat_member(
79 | CallbackQuery.message.chat.id, CallbackQuery.from_user.id
80 | )
81 | if not a.can_manage_voice_chats:
82 | return await CallbackQuery.answer(
83 | "You don't have the required permission to perform this action.\nPermission: MANAGE VOICE CHATS",
84 | show_alert=True,
85 | )
86 | return await mystic(_, CallbackQuery)
87 |
88 | return wrapper
89 |
--------------------------------------------------------------------------------
/Ayiin/Core/PyTgCalls/Downloader.py:
--------------------------------------------------------------------------------
1 | from os import path
2 |
3 | from yt_dlp import YoutubeDL
4 |
5 | from Ayiin import MUSIC_BOT_NAME
6 |
7 | ytdl = YoutubeDL(
8 | {
9 | "outtmpl": "downloads/%(id)s.%(ext)s",
10 | "format": "bestaudio/best",
11 | "geo_bypass": True,
12 | "nocheckcertificate": True,
13 | "quiet": True,
14 | "no_warnings": True,
15 | }
16 | )
17 |
18 |
19 | def download(videoid: str, mystic, title) -> str:
20 | flex = {}
21 | url = f"https://www.youtube.com/watch?v={videoid}"
22 |
23 | def my_hook(d):
24 | if d["status"] == "downloading":
25 | percentage = d["_percent_str"]
26 | per = (str(percentage)).replace(".", "", 1).replace("%", "", 1)
27 | per = int(per)
28 | eta = d["eta"]
29 | speed = d["_speed_str"]
30 | size = d["_total_bytes_str"]
31 | bytesx = d["total_bytes"]
32 | if str(bytesx) in flex:
33 | pass
34 | else:
35 | flex[str(bytesx)] = 1
36 | if flex[str(bytesx)] == 1:
37 | flex[str(bytesx)] += 1
38 | try:
39 | if eta > 2:
40 | mystic.edit(
41 | f"**{MUSIC_BOT_NAME} Downloader**\n\n**Title:** {title[:50]}:\n**FileSize:** {size}\n\n**Downloaded:**\n**Speed:** {speed}\n**ETA:** {eta} Seconds\n\n\n{percentage} ▓▓▓▓▓▓▓▓▓▓▓▓ 100%"
42 | )
43 | except Exception as e:
44 | pass
45 | if per > 250:
46 | if flex[str(bytesx)] == 2:
47 | flex[str(bytesx)] += 1
48 | if eta > 2:
49 | mystic.edit(
50 | f"**{MUSIC_BOT_NAME}Downloader**\n\n**Title:** {title[:50]}:\n**FileSize:** {size}\n\n**Downloaded:**\n**Speed:** {speed}\n**ETA:** {eta} Seconds\n\n\n{percentage} ███▓▓▓▓▓▓▓▓▓ 100%"
51 | )
52 | if per > 500:
53 | if flex[str(bytesx)] == 3:
54 | flex[str(bytesx)] += 1
55 | if eta > 2:
56 | mystic.edit(
57 | f"**{MUSIC_BOT_NAME} Downloader**\n\n**Title:** {title[:50]}:\n**FileSize:** {size}\n\n**Downloaded:**\n**Speed:** {speed}\n**ETA:** {eta} Seconds\n\n\n{percentage} ██████▓▓▓▓▓▓ 100%"
58 | )
59 | if per > 800:
60 | if flex[str(bytesx)] == 4:
61 | flex[str(bytesx)] += 1
62 | if eta > 2:
63 | mystic.edit(
64 | f"**{MUSIC_BOT_NAME} Downloader**\n\n**Title:** {title[:50]}:\n**FileSize:** {size}\n\n**Downloaded:**\n**Speed:** {speed}\n**ETA:** {eta} Seconds\n\n\n{percentage} ██████████▓▓ 100%"
65 | )
66 | if d["status"] == "finished":
67 | try:
68 | taken = d["_elapsed_str"]
69 | except Exception as e:
70 | taken = "00:00"
71 | size = d["_total_bytes_str"]
72 | mystic.edit(
73 | f"**{MUSIC_BOT_NAME} Downloader**\n\n**Title:** {title[:50]}:\n\n100% ████████████100%\n\n**Time Taken:** {taken} Seconds\n\nConverting Audio[FFmpeg Process]"
74 | )
75 |
76 | ydl_optssx = {
77 | "format": "bestaudio/best",
78 | "outtmpl": "downloads/%(id)s.%(ext)s",
79 | "geo_bypass": True,
80 | "nocheckcertificate": True,
81 | "quiet": True,
82 | "no_warnings": True,
83 | }
84 | try:
85 | x = YoutubeDL(ydl_optssx)
86 | x.add_progress_hook(my_hook)
87 | dloader = x.download([url])
88 | except Exception as y_e:
89 | return print(y_e)
90 | else:
91 | dloader
92 | info = x.extract_info(url, False)
93 | xyz = path.join("downloads", f"{info['id']}.{info['ext']}")
94 | return xyz
95 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Lyrics.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 |
4 | import lyricsgenius
5 | from pyrogram import Client, filters
6 | from pyrogram.types import Message
7 | from youtubesearchpython import VideosSearch
8 |
9 | from Ayiin import MUSIC_BOT_NAME, app
10 |
11 | __MODULE__ = "Lyrics"
12 | __HELP__ = """
13 |
14 | /Lyrics [Music Name]
15 | - Searches Lyrics for the particular Music on web.
16 |
17 | **Note**:
18 | Inline button of Lyrics has some bugs. Searches only 50% results. You can use command instead if you want lyrics for any playing music.
19 |
20 | """
21 |
22 |
23 | @app.on_callback_query(filters.regex(pattern=r"lyrics"))
24 | async def lyricssex(_, CallbackQuery):
25 | callback_data = CallbackQuery.data.strip()
26 | callback_request = callback_data.split(None, 1)[1]
27 | try:
28 | id, user_id = callback_request.split("|")
29 | except Exception as e:
30 | return await CallbackQuery.message.edit(
31 | f"Error Occured\n**Possible reason could be**:{e}"
32 | )
33 | url = f"https://www.youtube.com/watch?v={id}"
34 | print(url)
35 | try:
36 | results = VideosSearch(url, limit=1)
37 | for result in results.result()["result"]:
38 | title = result["title"]
39 | except Exception as e:
40 | return await CallbackQuery.answer(
41 | "Sound not found. Youtube issues.", show_alert=True
42 | )
43 | x = "OXaVabSRKQLqwpiYOn-E4Y7k3wj-TNdL5RfDPXlnXhCErbcqVvdCF-WnMR5TBctI"
44 | y = lyricsgenius.Genius(x)
45 | t = re.sub(r"[^\w]", " ", title)
46 | y.verbose = False
47 | S = y.search_song(t, get_full_info=False)
48 | if S is None:
49 | return await CallbackQuery.answer(
50 | "Lyrics not found :p", show_alert=True
51 | )
52 | await CallbackQuery.message.delete()
53 | userid = CallbackQuery.from_user.id
54 | usr = f"[{CallbackQuery.from_user.first_name}](tg://user?id={userid})"
55 | xxx = f"""
56 | **Lyrics Search Powered By {MUSIC_BOT_NAME}**
57 |
58 | **Searched By:-** {usr}
59 | **Searched Song:-** __{title}__
60 |
61 | **Found Lyrics For:-** __{S.title}__
62 | **Artist:-** {S.artist}
63 |
64 | **__Lyrics:__**
65 |
66 | {S.lyrics}"""
67 | if len(xxx) > 4096:
68 | filename = "lyrics.txt"
69 | with open(filename, "w+", encoding="utf8") as out_file:
70 | out_file.write(str(xxx.strip()))
71 | await CallbackQuery.message.reply_document(
72 | document=filename,
73 | caption=f"**OUTPUT:**\n\n`Lyrics`",
74 | quote=False,
75 | )
76 | os.remove(filename)
77 | else:
78 | await CallbackQuery.message.reply_text(xxx)
79 |
80 |
81 | @app.on_message(filters.command("lyrics"))
82 | async def lrsearch(_, message: Message):
83 | if len(message.command) < 2:
84 | return await message.reply_text("**Usage:**\n\n/lyrics [ Music Name]")
85 | m = await message.reply_text("Searching Lyrics")
86 | query = message.text.split(None, 1)[1]
87 | x = "OXaVabSRKQLqwpiYOn-E4Y7k3wj-TNdL5RfDPXlnXhCErbcqVvdCF-WnMR5TBctI"
88 | y = lyricsgenius.Genius(x)
89 | y.verbose = False
90 | S = y.search_song(query, get_full_info=False)
91 | if S is None:
92 | return await m.edit("Lyrics not found :p")
93 | xxx = f"""
94 | **Lyrics Search Powered By {MUSIC_BOT_NAME}**
95 |
96 | **Searched Song:-** __{query}__
97 | **Found Lyrics For:-** __{S.title}__
98 | **Artist:-** {S.artist}
99 |
100 | **__Lyrics:__**
101 |
102 | {S.lyrics}"""
103 | if len(xxx) > 4096:
104 | await m.delete()
105 | filename = "lyrics.txt"
106 | with open(filename, "w+", encoding="utf8") as out_file:
107 | out_file.write(str(xxx.strip()))
108 | await message.reply_document(
109 | document=filename,
110 | caption=f"**OUTPUT:**\n\n`Lyrics`",
111 | quote=False,
112 | )
113 | os.remove(filename)
114 | else:
115 | await m.edit(xxx)
116 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |

2 |
3 |
4 | A Telegram Music+video Bot written in Python using Pyrogram and Py-Tgcalls
5 |
6 |
7 | Ready-To-Use Bot •
8 | Support Channel •
9 | Support Chat
10 |
11 |
12 | # Ayiin Music Bot
13 | A Powerful Telegram Music+Video Bot by which you can stream songs, videos and even live streams in your group calls via various sources. It comes with user friendly and easy to use yet elegant features.
14 |
15 |
16 |
17 | ## TUTORIAL LINK DEPLOY
18 | ```
19 | - Pertama fork repositori ini.
20 | - Kemudian Salin Link Fork Repo Anda.
21 | - Dan Klik Tombol Dibawah Ini.
22 | - ☟︎︎︎ ☟︎︎︎ ☟︎︎︎ ☟︎︎︎
23 | ```
24 |
25 |
26 | [](https://ayiin.vercel.app)
27 |
28 |
29 | > Click on buttons to expand!
30 |
31 | 🔗 Requirements
32 |
33 |
34 | - [Python3.9](https://www.python.org/downloads/release/python-390/)
35 | - [Telegram API Key](https://docs.pyrogram.org/intro/setup#api-keys)
36 | - [Telegram Bot Token](https://t.me/botfather)
37 | - [MongoDB URI](https://telegra.ph/How-To-get-Mongodb-URI-04-06)
38 | - [Pyrogram String Session](https://notreallyshikhar.gitbook.io/AyiinMusic/deployment/string-session)
39 |
40 |
41 |
42 |
43 | 🔗 String Session
44 |
45 |
46 | > You'll need a [API_ID](https://notreallyshikar.gitbook.io/AyiinMusic/vars/mandatory-vars#1.-api_id) & [API_HASH](https://notreallyshikhar.gitbook.io/AyiinMusic/vars/mandatory-vars#2.-api_hash) in order to generate pyrogram session.
47 | > Always remeber to use good API combo else your account could be deleted.
48 |
49 | Generate Session via Repl:
50 | 
51 |
52 | Generate Session via Telegram StringGen Bot:
53 | 
54 |
55 |
56 |
57 |
58 |
59 | 🔗 Deploy to VPS
60 |
61 |
62 | > Checkout [Docs](https://notreallyshikhar.gitbook.io/AyiinMusic/deployment/local-hosting-or-vps) for Detailed Explanation on VPS Deploy
63 |
64 |
65 | ```console
66 | ayiin@ayiin~ $ git clone https://github.com/AyiinXd/AyiinMusic
67 | ayiin@ayiin~ $ cd AyiinMusic
68 | ayiin@ayiin~ $ pip3 install -U -r requirements.txt
69 | ayiin@ayiin~ $ nano sample.env
70 | ayiin@ayiin~ $ cp sample.env .env
71 | ```
72 | > Edit .env with your values and then start bot with
73 | ```console
74 | ayiin@ayiin~ $ screen -S AyiinMusic
75 | ayiin@ayiin~ $ python3 -m Ayiin
76 | ```
77 |
78 | > Not Getting VPS Method? [Watch Tutorial](https://t.me/OfficialYukki/2275)
79 |
80 |
81 | ## Contact & Support
82 |
83 | - [Telegram Channel](https://t.me/AyiinSupport)
84 | - [Telegram Support Group](https://t.me/AyiinXdSupport)
85 | - [Contact Owner](https://t.me/AyiinXd)
86 |
87 |
88 | ## License
89 |
90 | Distributed under the [GNU General Public License v3.0 License.](https://github.com/AyiinXd/AyiinMusic/blob/main/LICENSE) See `LICENSE.md` for more information.
91 |
92 | ## Acknowledgements
93 |
94 | Special thanks to these amazing projects/people which/who help power Ayiin Music Bot:
95 |
96 | - [Pyrogram](https://github.com/pyrogram/pyrogram)
97 | - [Py-Tgcalls](https://github.com/pytgcalls/pytgcalls)
98 | - [CallsMusic Team](https://github.com/Callsmusic)
99 | - [TheHamkerCat](https://github.com/TheHamkerCat)
100 | - [Charon Baglari](https://github.com/XCBv021)
101 | - [AyiinXd](https://github.com/AyiinXd)
102 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Assistant.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | from pyrogram import filters
4 | from pyrogram.raw.functions.messages import DeleteHistory
5 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
6 | InlineKeyboardMarkup, InlineQueryResultArticle,
7 | InlineQueryResultPhoto, InputTextMessageContent,
8 | Message)
9 |
10 | from Ayiin import ASSISTANT_PREFIX, SUDOERS, app, random_assistant
11 | from Ayiin.Database import get_assistant, save_assistant
12 | from Ayiin.Utilities.assistant import get_assistant_details
13 |
14 | __MODULE__ = "Assistant"
15 | __HELP__ = f"""
16 |
17 |
18 | /checkassistant
19 | - Check the alloted assistant of your chat
20 |
21 |
22 | **Note:**
23 | - Only for Sudo Users
24 |
25 | {ASSISTANT_PREFIX[0]}block [ Reply to a User Message]
26 | - Blocks the User from Assistant Account.
27 |
28 | {ASSISTANT_PREFIX[0]}unblock [ Reply to a User Message]
29 | - Unblocks the User from Assistant Account.
30 |
31 | {ASSISTANT_PREFIX[0]}approve [ Reply to a User Message]
32 | - Approves the User for DM.
33 |
34 | {ASSISTANT_PREFIX[0]}disapprove [ Reply to a User Message]
35 | - Disapproves the User for DM.
36 |
37 | {ASSISTANT_PREFIX[0]}pfp [ Reply to a Photo]
38 | - Changes Assistant account PFP.
39 |
40 | {ASSISTANT_PREFIX[0]}bio [Bio text]
41 | - Changes Bio of Assistant Account.
42 |
43 | /changeassistant [ASS NUMBER]
44 | - Change the previoius alloted assistant to new one.
45 |
46 | /setassistant [ASS NUMBER or Random]
47 | - Set a assistant account for chat.
48 | """
49 |
50 |
51 | ass_num_list = ["1", "2", "3", "4", "5"]
52 |
53 |
54 | @app.on_message(filters.command("changeassistant") & filters.user(SUDOERS))
55 | async def assis_change(_, message: Message):
56 | usage = f"**Usage:**\n/changeassistant [ASS_NO]\n\nSelect from them\n{' | '.join(ass_num_list)}"
57 | if len(message.command) != 2:
58 | return await message.reply_text(usage)
59 | num = message.text.split(None, 1)[1].strip()
60 | if num not in ass_num_list:
61 | return await message.reply_text(usage)
62 | ass_num = int(message.text.strip().split()[1])
63 | _assistant = await get_assistant(message.chat.id, "assistant")
64 | if not _assistant:
65 | return await message.reply_text(
66 | "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /setassistant"
67 | )
68 | else:
69 | ass = _assistant["saveassistant"]
70 | assis = {
71 | "saveassistant": ass_num,
72 | }
73 | await save_assistant(message.chat.id, "assistant", assis)
74 | await message.reply_text(
75 | f"**Changed Assistant**\n\nChanged Assistant Account from **{ass}** to Assistant Number **{ass_num}**"
76 | )
77 |
78 |
79 | ass_num_list2 = ["1", "2", "3", "4", "5", "Random"]
80 |
81 |
82 | @app.on_message(filters.command("setassistant") & filters.user(SUDOERS))
83 | async def assis_change(_, message: Message):
84 | 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"
85 | if len(message.command) != 2:
86 | return await message.reply_text(usage)
87 | query = message.text.split(None, 1)[1].strip()
88 | if query not in ass_num_list2:
89 | return await message.reply_text(usage)
90 | if str(query) == "Random":
91 | ran_ass = random.choice(random_assistant)
92 | else:
93 | ran_ass = int(message.text.strip().split()[1])
94 | _assistant = await get_assistant(message.chat.id, "assistant")
95 | if not _assistant:
96 | await message.reply_text(
97 | f"**__Ayiin Music Bot Assistant Alloted__**\n\nAssistant No. **{ran_ass}**"
98 | )
99 | assis = {
100 | "saveassistant": ran_ass,
101 | }
102 | await save_assistant(message.chat.id, "assistant", assis)
103 | else:
104 | ass = _assistant["saveassistant"]
105 | return await message.reply_text(
106 | f"Pre-Saved Assistant Number {ass} Found.\n\nYou can change Assistant Via /changeassistant"
107 | )
108 |
109 |
110 | @app.on_message(filters.command("checkassistant") & filters.group)
111 | async def check_ass(_, message: Message):
112 | _assistant = await get_assistant(message.chat.id, "assistant")
113 | if not _assistant:
114 | return await message.reply_text(
115 | "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play"
116 | )
117 | else:
118 | ass = _assistant["saveassistant"]
119 | return await message.reply_text(
120 | f"Pre-Saved Assistant Found\n\nAssistanty Number {ass} "
121 | )
122 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AyiinMusic",
3 | "description": "A Telegram Music Bot with proper functions written in Python with Pyrogram and Py-Tgcalls.",
4 | "logo": "https://upload.wikimedia.org/wikipedia/commons/c/c3/Python-logo-notext.svg",
5 | "keywords": [
6 | "python3",
7 | "telegram",
8 | "bot",
9 | "Ayiin",
10 | "AyiinMusic",
11 | "telegram-bot",
12 | "pyrogram"
13 | ],
14 | "stack": "container",
15 | "env": {
16 | "API_ID": {
17 | "description": "Get this value from https://my.telegram.org",
18 | "value": "",
19 | "required": true
20 | },
21 | "API_HASH": {
22 | "description": "Get this value from https://my.telegram.org",
23 | "value": "",
24 | "required": true
25 | },
26 | "BOT_TOKEN": {
27 | "description": "A Bot's token from Botfather",
28 | "value": "",
29 | "required": true
30 | },
31 | "DURATION_LIMIT": {
32 | "description": "Duration Limit for Playout (In Mins).. Example: 60",
33 | "value": "60",
34 | "required": true
35 | },
36 | "ASSISTANT_PREFIX": {
37 | "description": "Prefix for Assistant Commands.",
38 | "value": ".",
39 | "required": true
40 | },
41 | "MONGO_DB_URI": {
42 | "description": "Mongo DB URL",
43 | "value": "",
44 | "required": true
45 | },
46 | "MUSIC_BOT_NAME": {
47 | "description": "A name for your Music Bot.",
48 | "value": "",
49 | "required": true
50 | },
51 | "SUPPORT_CHANNEL": {
52 | "description": "Support Channel Link if you have any, Leave blank if no support. Your link must start with https://t.me/",
53 | "value": "",
54 | "required": false
55 | },
56 | "SUPPORT_GROUP": {
57 | "description": "Support Group Link if you have any, Leave blank if no support. Your link must start with https://t.me/",
58 | "value": "",
59 | "required": false
60 | },
61 | "OWNER_ID": {
62 | "description": "The user id(s) of user(s) whom you would like to add as a OWNER. Multiple values shall be seperated with a space.",
63 | "value": "",
64 | "required": true
65 | },
66 | "STRING_SESSION1": {
67 | "description": "A Pyrogram String Session. One Assistant is Compulsory.",
68 | "value": "",
69 | "required": true
70 | },
71 | "STRING_SESSION2": {
72 | "description": "A Pyrogram String Session. Leave blank if you dont want Multi-Assistant",
73 | "value": "",
74 | "required": false
75 | },
76 | "STRING_SESSION3": {
77 | "description": "A Pyrogram String Session. Leave blank if you dont want Multi-Assistant",
78 | "value": "",
79 | "required": false
80 | },
81 | "STRING_SESSION4": {
82 | "description": "A Pyrogram String Session. Leave blank if you dont want Multi-Assistant",
83 | "value": "",
84 | "required": false
85 | },
86 | "STRING_SESSION5": {
87 | "description": "A Pyrogram String Session. Leave blank if you dont want Multi-Assistant",
88 | "value": "",
89 | "required": false
90 | },
91 | "HEROKU_API_KEY": {
92 | "description": "Your Heroku account's API key",
93 | "value": "",
94 | "required": false
95 | },
96 | "HEROKU_APP_NAME": {
97 | "description": "Your heroku app/bot's name",
98 | "value": "",
99 | "required": false
100 | },
101 | "LOG_GROUP_ID": {
102 | "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.",
103 | "value": "",
104 | "required": true
105 | },
106 | "SUDO_USERS": {
107 | "description": "The user id(s) of user(s) whom you would like to add as a SUDO. Multiple values shall be seperated with a space.",
108 | "value": "",
109 | "required": true
110 | },
111 | "LOG_SESSION": {
112 | "description": "A Pyrogram String Session for LOGGING or u can also add STRING_SESSION1 Also.",
113 | "value": "",
114 | "required": true
115 | },
116 | "UPSTREAM_REPO": {
117 | "description": "If you dont know this, Leave as it is",
118 | "value": "https://github.com/AyiinXd/AyiinMusic",
119 | "required": true
120 | },
121 | "UPSTREAM_BRANCH": {
122 | "description": "Repo's Branch Name",
123 | "value": "master",
124 | "required": true
125 | }
126 | },
127 | "buildpacks": [
128 | {
129 | "url": "heroku/python"
130 | },
131 | {
132 | "url": "heroku/nodejs"
133 | },
134 | {
135 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git"
136 | }
137 | ],
138 | "formation": {
139 | "worker": {
140 | "quantity": 1,
141 | "size": "free"
142 | }
143 | },
144 | "stack": "container"
145 | }
146 |
--------------------------------------------------------------------------------
/Ayiin/Decorators/assistant.py:
--------------------------------------------------------------------------------
1 | import random
2 | from typing import Dict, List, Union
3 |
4 | from pyrogram import filters
5 | from pyrogram.errors import UserAlreadyParticipant, UserNotParticipant
6 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
7 | InlineKeyboardMarkup, InputMediaPhoto, Message)
8 |
9 | from Ayiin import BOT_ID, MUSIC_BOT_NAME, app, random_assistant
10 | from Ayiin.Database import get_assistant, save_assistant
11 | from Ayiin.Utilities.assistant import get_assistant_details
12 |
13 |
14 | @app.on_callback_query(filters.regex("unban_assistant"))
15 | async def unban_assistant_(_, CallbackQuery):
16 | callback_data = CallbackQuery.data.strip()
17 | callback_request = callback_data.split(None, 1)[1]
18 | query, user_id = callback_request.split("|")
19 | a = await app.get_chat_member(CallbackQuery.message.chat.id, BOT_ID)
20 | if not a.can_restrict_members:
21 | return await CallbackQuery.answer(
22 | "I am not having ban/unban user permission. Ask any admin to unban the assistant.",
23 | show_alert=True,
24 | )
25 | else:
26 | try:
27 | await app.unban_chat_member(
28 | CallbackQuery.message.chat.id, user_id
29 | )
30 | except:
31 | return await CallbackQuery.answer(
32 | "Failed to unban",
33 | show_alert=True,
34 | )
35 | return await CallbackQuery.edit_message_text(
36 | "Assistant Unbanned. Try Playing Now."
37 | )
38 |
39 |
40 | def AssistantAdd(mystic):
41 | async def wrapper(_, message):
42 | _assistant = await get_assistant(message.chat.id, "assistant")
43 | if not _assistant:
44 | ran_ass = random.choice(random_assistant)
45 | assis = {
46 | "saveassistant": ran_ass,
47 | }
48 | await save_assistant(message.chat.id, "assistant", assis)
49 | else:
50 | ran_ass = _assistant["saveassistant"]
51 | if ran_ass not in random_assistant:
52 | ran_ass = random.choice(random_assistant)
53 | assis = {
54 | "saveassistant": ran_ass,
55 | }
56 | await save_assistant(message.chat.id, "assistant", assis)
57 | ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details(
58 | ran_ass
59 | )
60 | try:
61 | b = await app.get_chat_member(message.chat.id, ASS_ID)
62 | key = InlineKeyboardMarkup(
63 | [
64 | [
65 | InlineKeyboardButton(
66 | text="🗑 Unban Assistant",
67 | callback_data=f"unban_assistant a|{ASS_ID}",
68 | )
69 | ],
70 | ]
71 | )
72 | if b.status == "kicked":
73 | return await message.reply_text(
74 | f"Assistant Account[{ASS_ID}] is banned.\nUnban it first to use Music Bot\n\nUsername: @{ASS_USERNAME}",
75 | reply_markup=key,
76 | )
77 | if b.status == "banned":
78 | return await message.reply_text(
79 | f"Assistant Account[{ASS_ID}] is banned.\nUnban it first to use Music Bot\n\nUsername: @{ASS_USERNAME}",
80 | reply_markup=key,
81 | )
82 | except UserNotParticipant:
83 | if message.chat.username:
84 | try:
85 | await ASS_ACC.join_chat(message.chat.username)
86 | except UserAlreadyParticipant:
87 | pass
88 | except Exception as e:
89 | await message.reply_text(
90 | f"__Assistant Failed To Join__\n\n**Reason**: {e}"
91 | )
92 | return
93 | else:
94 | try:
95 | invitelink = await app.export_chat_invite_link(
96 | message.chat.id
97 | )
98 | if invitelink.startswith("https://t.me/+"):
99 | invitelink = invitelink.replace(
100 | "https://t.me/+", "https://t.me/joinchat/"
101 | )
102 | await ASS_ACC.join_chat(invitelink)
103 | await message.reply(
104 | f"{ASS_NAME} Joined Successfully",
105 | )
106 | except UserAlreadyParticipant:
107 | pass
108 | except Exception as e:
109 | await message.reply_text(
110 | f"__Assistant Failed To Join__\n\n**Reason**: {e}"
111 | )
112 | return
113 | return await mystic(_, message)
114 |
115 | return wrapper
116 |
--------------------------------------------------------------------------------
/Ayiin/Inline/stats.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 | stats1 = InlineKeyboardMarkup(
5 | [
6 | [
7 | InlineKeyboardButton(
8 | text="System Stats", callback_data=f"sys_stats"
9 | ),
10 | InlineKeyboardButton(
11 | text="Storage Stats", callback_data=f"sto_stats"
12 | ),
13 | ],
14 | [
15 | InlineKeyboardButton(
16 | text="Bot Stats", callback_data=f"bot_stats"
17 | ),
18 | InlineKeyboardButton(
19 | text="MongoDB Stats", callback_data=f"mongo_stats"
20 | ),
21 | ],
22 | [
23 | InlineKeyboardButton(
24 | text="Assistant Stats", callback_data=f"assis_stats"
25 | )
26 | ],
27 | ]
28 | )
29 |
30 | stats2 = InlineKeyboardMarkup(
31 | [
32 | [
33 | InlineKeyboardButton(
34 | text="General Stats", callback_data=f"gen_stats"
35 | ),
36 | InlineKeyboardButton(
37 | text="Storage Stats", callback_data=f"sto_stats"
38 | ),
39 | ],
40 | [
41 | InlineKeyboardButton(
42 | text="Bot Stats", callback_data=f"bot_stats"
43 | ),
44 | InlineKeyboardButton(
45 | text="MongoDB Stats", callback_data=f"mongo_stats"
46 | ),
47 | ],
48 | [
49 | InlineKeyboardButton(
50 | text="Assistant Stats", callback_data=f"assis_stats"
51 | )
52 | ],
53 | ]
54 | )
55 |
56 | stats3 = InlineKeyboardMarkup(
57 | [
58 | [
59 | InlineKeyboardButton(
60 | text="System Stats", callback_data=f"sys_stats"
61 | ),
62 | InlineKeyboardButton(
63 | text="General Stats", callback_data=f"gen_stats"
64 | ),
65 | ],
66 | [
67 | InlineKeyboardButton(
68 | text="Bot Stats", callback_data=f"bot_stats"
69 | ),
70 | InlineKeyboardButton(
71 | text="MongoDB Stats", callback_data=f"mongo_stats"
72 | ),
73 | ],
74 | [
75 | InlineKeyboardButton(
76 | text="Assistant Stats", callback_data=f"assis_stats"
77 | )
78 | ],
79 | ]
80 | )
81 |
82 | stats4 = InlineKeyboardMarkup(
83 | [
84 | [
85 | InlineKeyboardButton(
86 | text="System Stats", callback_data=f"sys_stats"
87 | ),
88 | InlineKeyboardButton(
89 | text="Storage Stats", callback_data=f"sto_stats"
90 | ),
91 | ],
92 | [
93 | InlineKeyboardButton(
94 | text="General Stats", callback_data=f"gen_stats"
95 | ),
96 | InlineKeyboardButton(
97 | text="MongoDB Stats", callback_data=f"mongo_stats"
98 | ),
99 | ],
100 | [
101 | InlineKeyboardButton(
102 | text="Assistant Stats", callback_data=f"assis_stats"
103 | )
104 | ],
105 | ]
106 | )
107 |
108 | stats5 = InlineKeyboardMarkup(
109 | [
110 | [
111 | InlineKeyboardButton(
112 | text="System Stats", callback_data=f"sys_stats"
113 | ),
114 | InlineKeyboardButton(
115 | text="Storage Stats", callback_data=f"sto_stats"
116 | ),
117 | ],
118 | [
119 | InlineKeyboardButton(
120 | text="Bot Stats", callback_data=f"bot_stats"
121 | ),
122 | InlineKeyboardButton(
123 | text="General Stats", callback_data=f"gen_stats"
124 | ),
125 | ],
126 | [
127 | InlineKeyboardButton(
128 | text="Assistant Stats", callback_data=f"assis_stats"
129 | )
130 | ],
131 | ]
132 | )
133 |
134 | stats6 = InlineKeyboardMarkup(
135 | [
136 | [
137 | InlineKeyboardButton(
138 | text="System Stats", callback_data=f"sys_stats"
139 | ),
140 | InlineKeyboardButton(
141 | text="Storage Stats", callback_data=f"sto_stats"
142 | ),
143 | ],
144 | [
145 | InlineKeyboardButton(
146 | text="Bot Stats", callback_data=f"bot_stats"
147 | ),
148 | InlineKeyboardButton(
149 | text="MongoDB Stats", callback_data=f"mongo_stats"
150 | ),
151 | ],
152 | [
153 | InlineKeyboardButton(
154 | text="General Stats", callback_data=f"gen_stats"
155 | )
156 | ],
157 | ]
158 | )
159 |
160 |
161 | stats7 = InlineKeyboardMarkup(
162 | [
163 | [
164 | InlineKeyboardButton(
165 | text="Getting Assistant Stats....",
166 | callback_data=f"wait_stats",
167 | )
168 | ]
169 | ]
170 | )
171 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Auth.py:
--------------------------------------------------------------------------------
1 | from pyrogram import Client, filters
2 | from pyrogram.types import Message
3 |
4 | from Ayiin import SUDOERS, app
5 | from Ayiin.Database import (_get_authusers, delete_authuser, get_authuser,
6 | get_authuser_count, get_authuser_names,
7 | save_authuser)
8 | from Ayiin.Decorators.admins import AdminActual
9 | from Ayiin.Utilities.changers import (alpha_to_int, int_to_alpha,
10 | time_to_seconds)
11 |
12 | __MODULE__ = "Auth Users"
13 | __HELP__ = """
14 |
15 | **Note:**
16 | -Auth users can skip, pause, stop, resume Voice Chats even without Admin Rights.
17 |
18 |
19 | /auth [Username or Reply to a Message]
20 | - Add a user to AUTH LIST of the group.
21 |
22 | /unauth [Username or Reply to a Message]
23 | - Remove a user from AUTH LIST of the group.
24 |
25 | /authusers
26 | - Check AUTH LIST of the group.
27 | """
28 |
29 |
30 | @app.on_message(filters.command("auth") & filters.group)
31 | @AdminActual
32 | async def auth(_, message: Message):
33 | if not message.reply_to_message:
34 | if len(message.command) != 2:
35 | await message.reply_text(
36 | "Reply to a user's message or give username/user_id."
37 | )
38 | return
39 | user = message.text.split(None, 1)[1]
40 | if "@" in user:
41 | user = user.replace("@", "")
42 | user = await app.get_users(user)
43 | user_id = message.from_user.id
44 | token = await int_to_alpha(user.id)
45 | from_user_name = message.from_user.first_name
46 | from_user_id = message.from_user.id
47 | _check = await get_authuser_names(message.chat.id)
48 | count = 0
49 | for smex in _check:
50 | count += 1
51 | if int(count) == 20:
52 | return await message.reply_text(
53 | "You can only have 20 Users In Your Groups Authorised Users List (AUL)"
54 | )
55 | if token not in _check:
56 | assis = {
57 | "auth_user_id": user.id,
58 | "auth_name": user.first_name,
59 | "admin_id": from_user_id,
60 | "admin_name": from_user_name,
61 | }
62 | await save_authuser(message.chat.id, token, assis)
63 | await message.reply_text(
64 | f"Added to Authorised Users List of this group."
65 | )
66 | return
67 | else:
68 | await message.reply_text(f"Already in the Authorised Users List.")
69 | return
70 | from_user_id = message.from_user.id
71 | user_id = message.reply_to_message.from_user.id
72 | user_name = message.reply_to_message.from_user.first_name
73 | token = await int_to_alpha(user_id)
74 | from_user_name = message.from_user.first_name
75 | _check = await get_authuser_names(message.chat.id)
76 | count = 0
77 | for smex in _check:
78 | count += 1
79 | if int(count) == 20:
80 | return await message.reply_text(
81 | "You can only have 20 Users In Your Groups Authorised Users List (AUL)"
82 | )
83 | if token not in _check:
84 | assis = {
85 | "auth_user_id": user_id,
86 | "auth_name": user_name,
87 | "admin_id": from_user_id,
88 | "admin_name": from_user_name,
89 | }
90 | await save_authuser(message.chat.id, token, assis)
91 | await message.reply_text(
92 | f"Added to Authorised Users List of this group."
93 | )
94 | return
95 | else:
96 | await message.reply_text(f"Already in the Authorised Users List.")
97 |
98 |
99 | @app.on_message(filters.command("unauth") & filters.group)
100 | @AdminActual
101 | async def whitelist_chat_func(_, message: Message):
102 | if not message.reply_to_message:
103 | if len(message.command) != 2:
104 | await message.reply_text(
105 | "Reply to a user's message or give username/user_id."
106 | )
107 | return
108 | user = message.text.split(None, 1)[1]
109 | if "@" in user:
110 | user = user.replace("@", "")
111 | user = await app.get_users(user)
112 | token = await int_to_alpha(user.id)
113 | deleted = await delete_authuser(message.chat.id, token)
114 | if deleted:
115 | return await message.reply_text(
116 | f"Removed from Authorised Users List of this Group."
117 | )
118 | else:
119 | return await message.reply_text(f"Not an Authorised User.")
120 | user_id = message.reply_to_message.from_user.id
121 | token = await int_to_alpha(user_id)
122 | deleted = await delete_authuser(message.chat.id, token)
123 | if deleted:
124 | return await message.reply_text(
125 | f"Removed from Authorised Users List of this Group."
126 | )
127 | else:
128 | return await message.reply_text(f"Not an Authorised User.")
129 |
130 |
131 | @app.on_message(filters.command("authusers") & filters.group)
132 | async def authusers(_, message: Message):
133 | _playlist = await get_authuser_names(message.chat.id)
134 | if not _playlist:
135 | return await message.reply_text(
136 | f"No Authorised Users in this Group.\n\nAdd Auth users by /auth and remove by /unauth."
137 | )
138 | else:
139 | j = 0
140 | m = await message.reply_text(
141 | "Fetching Authorised Users... Please Wait"
142 | )
143 | msg = f"**Authorised Users List[AUL]:**\n\n"
144 | for note in _playlist:
145 | _note = await get_authuser(message.chat.id, note)
146 | user_id = _note["auth_user_id"]
147 | user_name = _note["auth_name"]
148 | admin_id = _note["admin_id"]
149 | admin_name = _note["admin_name"]
150 | try:
151 | user = await app.get_users(user_id)
152 | user = user.first_name
153 | j += 1
154 | except Exception:
155 | continue
156 | msg += f"{j}➤ {user}[`{user_id}`]\n"
157 | msg += f" ┗ Added By:- {admin_name}[`{admin_id}`]\n\n"
158 | await m.edit_text(msg)
159 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Song.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from os import path
3 |
4 | from pyrogram import filters
5 | from pyrogram.types import (InlineKeyboardMarkup, InputMediaPhoto, Message,
6 | Voice)
7 | from youtube_search import YoutubeSearch
8 |
9 | from Ayiin import (BOT_USERNAME, DURATION_LIMIT, DURATION_LIMIT_MIN,
10 | MUSIC_BOT_NAME, app, db_mem)
11 | from Ayiin.Decorators.permission import PermissionCheck
12 | from Ayiin.Inline import song_download_markup, song_markup
13 | from Ayiin.Utilities.url import get_url
14 | from Ayiin.Utilities.youtube import get_yt_info_query, get_yt_info_query_slider
15 |
16 | loop = asyncio.get_event_loop()
17 |
18 | __MODULE__ = "Song"
19 | __HELP__ = """
20 |
21 |
22 | /song [Youtube URL or Search Query]
23 | - Download the particular query in audio or video format.
24 |
25 |
26 |
27 | """
28 |
29 |
30 | @app.on_message(
31 | filters.command(["song", f"song@{BOT_USERNAME}"])
32 | )
33 | @PermissionCheck
34 | async def play(_, message: Message):
35 | if message.chat.type == "private":
36 | pass
37 | else:
38 | if message.sender_chat:
39 | return await message.reply_text(
40 | "You're an __Anonymous Admin__ in this Chat Group!\nRevert back to User Account From Admin Rights."
41 | )
42 | try:
43 | await message.delete()
44 | except:
45 | pass
46 | url = get_url(message)
47 | if url:
48 | mystic = await message.reply_text("🔄 Processing URL... Please Wait!")
49 | query = message.text.split(None, 1)[1]
50 | (
51 | title,
52 | duration_min,
53 | duration_sec,
54 | thumb,
55 | videoid,
56 | ) = await loop.run_in_executor(None, get_yt_info_query, query)
57 | if str(duration_min) == "None":
58 | return await mystic.edit("Sorry! Its a Live Video")
59 | await mystic.delete()
60 | buttons = song_download_markup(videoid, message.from_user.id)
61 | return await message.reply_photo(
62 | photo=thumb,
63 | caption=f"📎Title: **{title}\n\n⏳Duration:** {duration_min} Mins\n\n__[Get Additional Information About Video](https://t.me/{BOT_USERNAME}?start=info_{videoid})__",
64 | reply_markup=InlineKeyboardMarkup(buttons),
65 | )
66 | else:
67 | if len(message.command) < 2:
68 | await message.reply_text(
69 | "**Usage:**\n\n/song [Youtube Url or Music Name]\n\nDownloads the Particular Query."
70 | )
71 | return
72 | mystic = await message.reply_text("🔍 Searching Your Query...")
73 | query = message.text.split(None, 1)[1]
74 | (
75 | title,
76 | duration_min,
77 | duration_sec,
78 | thumb,
79 | videoid,
80 | ) = await loop.run_in_executor(None, get_yt_info_query, query)
81 | if str(duration_min) == "None":
82 | return await mystic.edit("Sorry! Its a Live Video")
83 | await mystic.delete()
84 | buttons = song_markup(
85 | videoid, duration_min, message.from_user.id, query, 0
86 | )
87 | return await message.reply_photo(
88 | photo=thumb,
89 | caption=f"📎Title: **{title}\n\n⏳Duration:** {duration_min} Mins\n\n__[Get Additional Information About Video](https://t.me/{BOT_USERNAME}?start=info_{videoid})__",
90 | reply_markup=InlineKeyboardMarkup(buttons),
91 | )
92 |
93 |
94 | @app.on_callback_query(filters.regex("qwertyuiopasdfghjkl"))
95 | async def qwertyuiopasdfghjkl(_, CallbackQuery):
96 | print("234")
97 | await CallbackQuery.answer()
98 | callback_data = CallbackQuery.data.strip()
99 | callback_request = callback_data.split(None, 1)[1]
100 | userid = CallbackQuery.from_user.id
101 | videoid, user_id = callback_request.split("|")
102 | buttons = song_download_markup(videoid, user_id)
103 | await CallbackQuery.edit_message_reply_markup(
104 | reply_markup=InlineKeyboardMarkup(buttons)
105 | )
106 |
107 |
108 | @app.on_callback_query(filters.regex(pattern=r"song_right"))
109 | async def song_right(_, CallbackQuery):
110 | callback_data = CallbackQuery.data.strip()
111 | callback_request = callback_data.split(None, 1)[1]
112 | what, type, query, user_id = callback_request.split("|")
113 | if CallbackQuery.from_user.id != int(user_id):
114 | return await CallbackQuery.answer(
115 | "Search Your Own Music. You're not allowed to use this button.",
116 | show_alert=True,
117 | )
118 | what = str(what)
119 | type = int(type)
120 | if what == "F":
121 | if type == 9:
122 | query_type = 0
123 | else:
124 | query_type = int(type + 1)
125 | await CallbackQuery.answer("Getting Next Result", show_alert=True)
126 | (
127 | title,
128 | duration_min,
129 | duration_sec,
130 | thumb,
131 | videoid,
132 | ) = await loop.run_in_executor(
133 | None, get_yt_info_query_slider, query, query_type
134 | )
135 | buttons = song_markup(
136 | videoid, duration_min, user_id, query, query_type
137 | )
138 | med = InputMediaPhoto(
139 | media=thumb,
140 | caption=f"📎Title: **{title}\n\n⏳Duration:** {duration_min} Mins\n\n__[Get Additional Information About Video](https://t.me/{BOT_USERNAME}?start=info_{videoid})__",
141 | )
142 | return await CallbackQuery.edit_message_media(
143 | media=med, reply_markup=InlineKeyboardMarkup(buttons)
144 | )
145 | if what == "B":
146 | if type == 0:
147 | query_type = 9
148 | else:
149 | query_type = int(type - 1)
150 | await CallbackQuery.answer("Getting Previous Result", show_alert=True)
151 | (
152 | title,
153 | duration_min,
154 | duration_sec,
155 | thumb,
156 | videoid,
157 | ) = await loop.run_in_executor(
158 | None, get_yt_info_query_slider, query, query_type
159 | )
160 | buttons = song_markup(
161 | videoid, duration_min, user_id, query, query_type
162 | )
163 | med = InputMediaPhoto(
164 | media=thumb,
165 | caption=f"📎Title: **{title}\n\n⏳Duration:** {duration_min} Mins\n\n__[Get Additional Information About Video](https://t.me/{BOT_USERNAME}?start=info_{videoid})__",
166 | )
167 | return await CallbackQuery.edit_message_media(
168 | media=med, reply_markup=InlineKeyboardMarkup(buttons)
169 | )
170 |
--------------------------------------------------------------------------------
/Ayiin/Inline/playlist.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 |
5 | def check_markup(user_name, user_id, videoid):
6 | buttons = [
7 | [
8 | InlineKeyboardButton(
9 | text=f"𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
10 | callback_data=f"playlist_check {user_id}|𝙶𝚁𝙾𝚄𝙿|{videoid}",
11 | ),
12 | InlineKeyboardButton(
13 | text=f"{user_name[:8]}'s 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
14 | callback_data=f"playlist_check {user_id}|𝙿𝙴𝚁𝚂𝙾𝙽𝙰𝙻|{videoid}",
15 | ),
16 | ],
17 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close")],
18 | ]
19 | return buttons
20 |
21 |
22 | def playlist_markup(user_name, user_id, videoid):
23 | buttons = [
24 | [
25 | InlineKeyboardButton(
26 | text=f"𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
27 | callback_data=f"show_genre {user_id}|𝙶𝚁𝙾𝚄𝙿|{videoid}",
28 | ),
29 | InlineKeyboardButton(
30 | text=f"{user_name[:8]}'s 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
31 | callback_data=f"show_genre {user_id}|𝙿𝙴𝚁𝚂𝙾𝙽𝙰𝙻|{videoid}",
32 | ),
33 | ],
34 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close")],
35 | ]
36 | return buttons
37 |
38 |
39 | def play_genre_playlist(user_id, type, videoid):
40 | buttons = [
41 | [
42 | InlineKeyboardButton(
43 | text=f"𝙳𝙹",
44 | callback_data=f"play_playlist {user_id}|{type}|𝙱𝙾𝙻𝙻𝚈𝚆𝙾𝙾𝙳",
45 | ),
46 | InlineKeyboardButton(
47 | text=f"𝚂𝙻𝙴𝙴𝙿",
48 | callback_data=f"play_playlist {user_id}|{type}|𝙷𝙾𝙻𝙻𝚈𝚆𝙾𝙾𝙳",
49 | ),
50 | ],
51 | [
52 | InlineKeyboardButton(
53 | text=f"𝚂𝙰𝙳",
54 | callback_data=f"play_playlist {user_id}|{type}|𝙿𝙰𝚁𝚃𝚈",
55 | ),
56 | InlineKeyboardButton(
57 | text=f"𝙿𝙰𝚁𝚃𝚈",
58 | callback_data=f"play_playlist {user_id}|{type}|𝙻𝙾𝙵𝙸",
59 | ),
60 | ],
61 | [
62 | InlineKeyboardButton(
63 | text="⍟ 𝙱𝙰𝙲𝙺 ⍟",
64 | callback_data=f"main_playlist {videoid}|{type}|{user_id}",
65 | ),
66 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close"),
67 | ],
68 | ]
69 | return buttons
70 |
71 |
72 | def add_genre_markup(user_id, type, videoid):
73 | buttons = [
74 | [
75 | InlineKeyboardButton(
76 | text=f"✚ 𝙳𝙹",
77 | callback_data=f"add_playlist {videoid}|{type}|𝚆𝙴𝙴𝙱",
78 | ),
79 | InlineKeyboardButton(
80 | text=f"✚ 𝙿𝙰𝚁𝚃𝚈",
81 | callback_data=f"add_playlist {videoid}|{type}|𝚂𝙰𝙳",
82 | ),
83 | ],
84 | [
85 | InlineKeyboardButton(
86 | text=f"✚ 𝚂𝙰𝙳",
87 | callback_data=f"add_playlist {videoid}|{type}|𝙿𝙰𝚁𝚃𝚈",
88 | ),
89 | InlineKeyboardButton(
90 | text=f"✚ 𝚂𝙻𝙴𝙴𝙿",
91 | callback_data=f"add_playlist {videoid}|{type}|𝙻𝙾𝙵𝙸",
92 | ),
93 | ],
94 | [
95 | InlineKeyboardButton(
96 | text="⍟ 𝙱𝙰𝙲𝙺 ⍟", callback_data=f"goback {videoid}|{user_id}"
97 | ),
98 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close"),
99 | ],
100 | ]
101 | return buttons
102 |
103 |
104 | def check_genre_markup(type, videoid, user_id):
105 | buttons = [
106 | [
107 | InlineKeyboardButton(
108 | text=f"𝙳𝙹", callback_data=f"check_playlist {type}|𝚆𝙴𝙴𝙱"
109 | ),
110 | InlineKeyboardButton(
111 | text=f"𝙿𝙰𝚁𝚃𝚈", callback_data=f"check_playlist {type}|𝚂𝙰𝙳"
112 | ),
113 | ],
114 | [
115 | InlineKeyboardButton(
116 | text=f"𝚂𝙰𝙳", callback_data=f"check_playlist {type}|𝙿𝙰𝚁𝚃𝚈"
117 | ),
118 | InlineKeyboardButton(
119 | text=f"𝚂𝙻𝙴𝙴𝙿", callback_data=f"check_playlist {type}|𝙻𝙾𝙵𝙸"
120 | ),
121 | ],
122 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close")],
123 | ]
124 | return buttons
125 |
126 |
127 | def third_playlist_markup(user_name, user_id, third_name, userid, videoid):
128 | buttons = [
129 | [
130 | InlineKeyboardButton(
131 | text=f"𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
132 | callback_data=f"show_genre {user_id}|Group|{videoid}",
133 | ),
134 | InlineKeyboardButton(
135 | text=f"{user_name[:8]}'s 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
136 | callback_data=f"show_genre {user_id}|Personal|{videoid}",
137 | ),
138 | ],
139 | [
140 | InlineKeyboardButton(
141 | text=f"{third_name[:16]}'s 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
142 | callback_data=f"show_genre {userid}|third|{videoid}",
143 | ),
144 | ],
145 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close")],
146 | ]
147 | return buttons
148 |
149 |
150 | def paste_queue_markup(url):
151 | buttons = [
152 | [
153 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
154 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
155 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
156 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
157 | ],
158 | [InlineKeyboardButton(text="𝙲𝙷𝙴𝙲𝙺𝙾𝚄𝚃 𝚀𝚄𝙴𝚄𝙴𝙳 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃", url=f"{url}")],
159 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close")],
160 | ]
161 | return buttons
162 |
163 |
164 | def fetch_playlist(user_name, type, genre, user_id, url):
165 | buttons = [
166 | [
167 | InlineKeyboardButton(
168 | text=f"𝙿𝙻𝙰𝚈 {user_name[:10]}'s {genre} 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃",
169 | callback_data=f"play_playlist {user_id}|{type}|{genre}",
170 | ),
171 | ],
172 | [InlineKeyboardButton(text="𝙲𝙷𝙴𝙲𝙺𝙾𝚄𝚃 𝙿𝙻𝙰𝚈𝙻𝙸𝚂𝚃", url=f"{url}")],
173 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close")],
174 | ]
175 | return buttons
176 |
177 |
178 | def delete_playlist_markuup(type, genre):
179 | buttons = [
180 | [
181 | InlineKeyboardButton(
182 | text=f"𝚈𝙴𝚂 𝙳𝙴𝙻𝙴𝚃𝙴!",
183 | callback_data=f"delete_playlist {type}|{genre}",
184 | ),
185 | InlineKeyboardButton(text="⍟ 𝙽𝙾 ⍟", callback_data=f"close"),
186 | ],
187 | ]
188 | return buttons
189 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Developer.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import subprocess
4 | import sys
5 | import traceback
6 | from html import escape
7 | from inspect import getfullargspec
8 | from io import StringIO
9 | from time import time
10 |
11 | from pyrogram import filters
12 | from pyrogram.errors import MessageNotModified
13 | from pyrogram.types import (InlineKeyboardButton, InlineKeyboardMarkup,
14 | Message, ReplyKeyboardMarkup)
15 |
16 | from Ayiin import SUDOERS, app
17 | from Ayiin.Utilities.tasks import add_task, rm_task
18 |
19 | # Eval and Sh module from WBB
20 |
21 | __MODULE__ = "Broadcast"
22 | __HELP__ = """
23 | **Note:**
24 | Only for Sudo Users.
25 |
26 |
27 | /broadcast [Message or Reply to a Message]
28 | - Broadcast any message to Bot's Served Chats.
29 |
30 |
31 | /broadcast_pin [Message or Reply to a Message]
32 | - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Disabled Notifications].
33 |
34 |
35 | /broadcast_pin_loud [Message or Reply to a Message]
36 | - Broadcast any message to Bot's Served Chats with message getting Pinned in chat [Enabled Notifications].
37 | """
38 |
39 |
40 | async def aexec(code, client, message):
41 | exec(
42 | "async def __aexec(client, message): "
43 | + "".join(f"\n {a}" for a in code.split("\n"))
44 | )
45 | return await locals()["__aexec"](client, message)
46 |
47 |
48 | async def edit_or_reply(msg: Message, **kwargs):
49 | func = msg.edit_text if msg.from_user.is_self else msg.reply
50 | spec = getfullargspec(func.__wrapped__).args
51 | await func(**{k: v for k, v in kwargs.items() if k in spec})
52 |
53 |
54 | @app.on_message(
55 | filters.user(SUDOERS)
56 | & ~filters.forwarded
57 | & ~filters.via_bot
58 | & filters.command("eval")
59 | )
60 | async def executor(client, message):
61 | if len(message.command) < 2:
62 | return await edit_or_reply(
63 | message, text="__Nigga Give me some command to execute.__"
64 | )
65 | try:
66 | cmd = message.text.split(" ", maxsplit=1)[1]
67 | except IndexError:
68 | return await message.delete()
69 | t1 = time()
70 | old_stderr = sys.stderr
71 | old_stdout = sys.stdout
72 | redirected_output = sys.stdout = StringIO()
73 | redirected_error = sys.stderr = StringIO()
74 | stdout, stderr, exc = None, None, None
75 | try:
76 | await aexec(cmd, client, message)
77 | except Exception:
78 | exc = traceback.format_exc()
79 | stdout = redirected_output.getvalue()
80 | stderr = redirected_error.getvalue()
81 | sys.stdout = old_stdout
82 | sys.stderr = old_stderr
83 | evaluation = ""
84 | if exc:
85 | evaluation = exc
86 | elif stderr:
87 | evaluation = stderr
88 | elif stdout:
89 | evaluation = stdout
90 | else:
91 | evaluation = "Success"
92 | final_output = f"**OUTPUT**:\n```{evaluation.strip()}```"
93 | if len(final_output) > 4096:
94 | filename = "output.txt"
95 | with open(filename, "w+", encoding="utf8") as out_file:
96 | out_file.write(str(evaluation.strip()))
97 | t2 = time()
98 | keyboard = InlineKeyboardMarkup(
99 | [
100 | [
101 | InlineKeyboardButton(
102 | text="⏳", callback_data=f"runtime {t2-t1} Seconds"
103 | )
104 | ]
105 | ]
106 | )
107 | await message.reply_document(
108 | document=filename,
109 | caption=f"**INPUT:**\n`{cmd[0:980]}`\n\n**OUTPUT:**\n`Attached Document`",
110 | quote=False,
111 | reply_markup=keyboard,
112 | )
113 | await message.delete()
114 | os.remove(filename)
115 | else:
116 | t2 = time()
117 | keyboard = InlineKeyboardMarkup(
118 | [
119 | [
120 | InlineKeyboardButton(
121 | text="⏳",
122 | callback_data=f"runtime {round(t2-t1, 3)} Seconds",
123 | ),
124 | InlineKeyboardButton(
125 | text="🗑",
126 | callback_data=f"forceclose abc|{message.from_user.id}",
127 | ),
128 | ]
129 | ]
130 | )
131 | await edit_or_reply(message, text=final_output, reply_markup=keyboard)
132 |
133 |
134 | @app.on_callback_query(filters.regex(r"runtime"))
135 | async def runtime_func_cq(_, cq):
136 | runtime = cq.data.split(None, 1)[1]
137 | await cq.answer(runtime, show_alert=True)
138 |
139 |
140 | @app.on_message(
141 | filters.user(SUDOERS)
142 | & ~filters.forwarded
143 | & ~filters.via_bot
144 | & filters.command("sh"),
145 | )
146 | async def shellrunner(client, message):
147 | if len(message.command) < 2:
148 | return await edit_or_reply(message, text="**Usage:**\n/sh git pull")
149 | text = message.text.split(None, 1)[1]
150 | if "\n" in text:
151 | code = text.split("\n")
152 | output = ""
153 | for x in code:
154 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
155 | try:
156 | process = subprocess.Popen(
157 | shell,
158 | stdout=subprocess.PIPE,
159 | stderr=subprocess.PIPE,
160 | )
161 | except Exception as err:
162 | print(err)
163 | await edit_or_reply(message, text=f"**ERROR:**\n```{err}```")
164 | output += f"**{code}**\n"
165 | output += process.stdout.read()[:-1].decode("utf-8")
166 | output += "\n"
167 | else:
168 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
169 | for a in range(len(shell)):
170 | shell[a] = shell[a].replace('"', "")
171 | try:
172 | process = subprocess.Popen(
173 | shell,
174 | stdout=subprocess.PIPE,
175 | stderr=subprocess.PIPE,
176 | )
177 | except Exception as err:
178 | print(err)
179 | exc_type, exc_obj, exc_tb = sys.exc_info()
180 | errors = traceback.format_exception(
181 | etype=exc_type,
182 | value=exc_obj,
183 | tb=exc_tb,
184 | )
185 | return await edit_or_reply(
186 | message, text=f"**ERROR:**\n```{''.join(errors)}```"
187 | )
188 | output = process.stdout.read()[:-1].decode("utf-8")
189 | if str(output) == "\n":
190 | output = None
191 | if output:
192 | if len(output) > 4096:
193 | with open("output.txt", "w+") as file:
194 | file.write(output)
195 | await app.send_document(
196 | message.chat.id,
197 | "output.txt",
198 | reply_to_message_id=message.message_id,
199 | caption="`Output`",
200 | )
201 | return os.remove("output.txt")
202 | await edit_or_reply(message, text=f"**OUTPUT:**\n```{output}```")
203 | else:
204 | await edit_or_reply(message, text="**OUTPUT: **\n`No output`")
205 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/stream.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | import shutil
4 |
5 | from pyrogram.types import InlineKeyboardMarkup
6 |
7 | from config import get_queue
8 | from Ayiin import BOT_USERNAME, db_mem
9 | from Ayiin.Core.PyTgCalls import Queues
10 | from Ayiin.Core.PyTgCalls.Ayiin import join_stream
11 | from Ayiin.Database import (add_active_chat, add_active_video_chat,
12 | is_active_chat, music_off, music_on)
13 | from Ayiin.Inline import (audio_markup, audio_markup2, primary_markup,
14 | secondary_markup)
15 | from Ayiin.Utilities.timer import start_timer
16 |
17 | loop = asyncio.get_event_loop()
18 |
19 |
20 | async def start_stream(
21 | CallbackQuery,
22 | file,
23 | videoid,
24 | thumb,
25 | title,
26 | duration_min,
27 | duration_sec,
28 | mystic,
29 | ):
30 | global get_queue
31 | if CallbackQuery.message.chat.id not in db_mem:
32 | db_mem[CallbackQuery.message.chat.id] = {}
33 | wtfbro = db_mem[CallbackQuery.message.chat.id]
34 | wtfbro["live_check"] = False
35 | if await is_active_chat(CallbackQuery.message.chat.id):
36 | position = await Queues.put(CallbackQuery.message.chat.id, file=file)
37 | _path_ = (
38 | (str(file))
39 | .replace("_", "", 1)
40 | .replace("/", "", 1)
41 | .replace(".", "", 1)
42 | )
43 | buttons = secondary_markup(videoid, CallbackQuery.from_user.id)
44 | if file not in db_mem:
45 | db_mem[file] = {}
46 | cpl = f"cache/{_path_}final.png"
47 | shutil.copyfile(thumb, cpl)
48 | wtfbro = db_mem[file]
49 | wtfbro["title"] = title
50 | wtfbro["duration"] = duration_min
51 | wtfbro["username"] = CallbackQuery.from_user.mention
52 | wtfbro["videoid"] = videoid
53 | got_queue = get_queue.get(CallbackQuery.message.chat.id)
54 | title = title
55 | user = CallbackQuery.from_user.first_name
56 | duration = duration_min
57 | to_append = [title, user, duration]
58 | got_queue.append(to_append)
59 | final_output = await CallbackQuery.message.reply_photo(
60 | photo=thumb,
61 | caption=(
62 | f"🎬__Song:__ [{title[:25]}](https://www.youtube.com/watch?v={videoid}) \n⏳__Duration:__ {duration_min} \n💡__Info:__ [Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n👤__Requested by:__ {CallbackQuery.from_user.mention} \n🚧__Queued at:__ #{position}!"
63 | ),
64 | reply_markup=InlineKeyboardMarkup(buttons),
65 | )
66 | await mystic.delete()
67 | await CallbackQuery.message.delete()
68 | os.remove(thumb)
69 | return
70 | else:
71 | if not await join_stream(CallbackQuery.message.chat.id, file):
72 | return await mystic.edit("Error Joining Voice Chat.")
73 | get_queue[CallbackQuery.message.chat.id] = []
74 | got_queue = get_queue.get(CallbackQuery.message.chat.id)
75 | title = title
76 | user = CallbackQuery.from_user.first_name
77 | duration = duration_min
78 | to_append = [title, user, duration]
79 | got_queue.append(to_append)
80 | await music_on(CallbackQuery.message.chat.id)
81 | await add_active_chat(CallbackQuery.message.chat.id)
82 | buttons = primary_markup(
83 | videoid, CallbackQuery.from_user.id, duration_min, duration_min
84 | )
85 | await mystic.delete()
86 | cap = f"🎥__Playing:__ [{title[:25]}](https://www.youtube.com/watch?v={videoid}) \n💡__Info:__ [Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n👤**__Requested by:__** {CallbackQuery.from_user.mention}"
87 | final_output = await CallbackQuery.message.reply_photo(
88 | photo=thumb,
89 | reply_markup=InlineKeyboardMarkup(buttons),
90 | caption=cap,
91 | )
92 | os.remove(thumb)
93 | await CallbackQuery.message.delete()
94 | await start_timer(
95 | videoid,
96 | duration_min,
97 | duration_sec,
98 | final_output,
99 | CallbackQuery.message.chat.id,
100 | CallbackQuery.from_user.id,
101 | 0,
102 | )
103 |
104 |
105 | async def start_stream_audio(
106 | message, file, videoid, title, duration_min, duration_sec, mystic
107 | ):
108 | global get_queue
109 | if message.chat.id not in db_mem:
110 | db_mem[message.chat.id] = {}
111 | wtfbro = db_mem[message.chat.id]
112 | wtfbro["live_check"] = False
113 | if message.chat.username:
114 | link = f"https://t.me/{message.chat.username}/{message.reply_to_message.message_id}"
115 | else:
116 | xf = str((message.chat.id))[4:]
117 | link = f"https://t.me/c/{xf}/{message.reply_to_message.message_id}"
118 | if await is_active_chat(message.chat.id):
119 | position = await Queues.put(message.chat.id, file=file)
120 | if file not in db_mem:
121 | db_mem[file] = {}
122 | db_mem[file]["title"] = title
123 | db_mem[file]["duration"] = duration_min
124 | db_mem[file]["username"] = message.from_user.mention
125 | db_mem[file]["videoid"] = videoid
126 | got_queue = get_queue.get(message.chat.id)
127 | title = title
128 | user = message.from_user.first_name
129 | duration = duration_min
130 | to_append = [title, user, duration]
131 | got_queue.append(to_append)
132 | final_output = await message.reply_photo(
133 | photo="Utils/Telegram.JPEG",
134 | caption=(
135 | f"🎬__Audio:__ [Given Audio Via Telegram]({link})\n⏳__Duration:__ {duration_min} \n👤__Requested by:__ {message.from_user.mention} \n🚧__Queued at:__ #{position}!"
136 | ),
137 | reply_markup=audio_markup2,
138 | )
139 | await mystic.delete()
140 | return
141 | else:
142 | if not await join_stream(message.chat.id, file):
143 | return await mystic.edit(
144 | "Error Joining Voice Chat. Make sure Voice Chat is Enabled."
145 | )
146 | get_queue[message.chat.id] = []
147 | got_queue = get_queue.get(message.chat.id)
148 | title = title
149 | user = message.from_user.first_name
150 | duration = duration_min
151 | to_append = [title, user, duration]
152 | got_queue.append(to_append)
153 | await music_on(message.chat.id)
154 | await add_active_chat(message.chat.id)
155 | buttons = audio_markup(
156 | videoid, message.from_user.id, duration_min, duration_min
157 | )
158 | await mystic.delete()
159 | cap = f"🎥__Playing:__ [Given Audio Via Telegram]({link})\n👤**__Requested by:__** {message.from_user.mention}"
160 | final_output = await message.reply_photo(
161 | photo="Utils/Telegram.JPEG",
162 | reply_markup=InlineKeyboardMarkup(buttons),
163 | caption=cap,
164 | )
165 | await start_timer(
166 | videoid,
167 | duration_min,
168 | duration_sec,
169 | final_output,
170 | message.chat.id,
171 | message.from_user.id,
172 | 1,
173 | )
174 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Stream.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | from os import path
3 |
4 | from pyrogram import filters
5 | from pyrogram.types import (InlineKeyboardMarkup, InputMediaPhoto,
6 | KeyboardButton, Message, ReplyKeyboardMarkup,
7 | ReplyKeyboardRemove, Voice)
8 | from youtube_search import YoutubeSearch
9 | from youtubesearchpython import VideosSearch
10 |
11 | from Ayiin import (BOT_USERNAME, DURATION_LIMIT, DURATION_LIMIT_MIN,
12 | MUSIC_BOT_NAME, app, db_mem)
13 | from Ayiin.Core.PyTgCalls.Converter import convert
14 | from Ayiin.Core.PyTgCalls.Downloader import download
15 | from Ayiin.Database import (get_active_video_chats, get_video_limit,
16 | is_active_video_chat, is_on_off)
17 | from Ayiin.Decorators.assistant import AssistantAdd
18 | from Ayiin.Decorators.checker import checker
19 | from Ayiin.Decorators.permission import PermissionCheck
20 | from Ayiin.Inline import (choose_markup, livestream_markup, playlist_markup,
21 | search_markup, search_markup2, stream_quality_markup,
22 | url_markup, url_markup2)
23 | from Ayiin.Utilities.changers import seconds_to_min, time_to_seconds
24 | from Ayiin.Utilities.chat import specialfont_to_normal
25 | from Ayiin.Utilities.theme import check_theme
26 | from Ayiin.Utilities.thumbnails import gen_thumb
27 | from Ayiin.Utilities.url import get_url
28 | from Ayiin.Utilities.videostream import start_live_stream, start_video_stream
29 | from Ayiin.Utilities.youtube import (get_m3u8, get_yt_info_id,
30 | get_yt_info_query,
31 | get_yt_info_query_slider)
32 |
33 | loop = asyncio.get_event_loop()
34 |
35 | __MODULE__ = "VideoCalls"
36 | __HELP__ = f"""
37 |
38 | /play [Reply to any Video] or [YT Link] or [Music Name]
39 | - Stream Video on Voice Chat
40 |
41 | **For Sudo User:-**
42 |
43 | /set_video_limit [Number of Chats]
44 | - Set a maximum Number of Chats allowed for Video Calls at a time.
45 |
46 |
47 | """
48 |
49 |
50 | @app.on_callback_query(filters.regex(pattern=r"Ayiin"))
51 | async def choose_playmode(_, CallbackQuery):
52 | await CallbackQuery.answer()
53 | callback_data = CallbackQuery.data.strip()
54 | callback_request = callback_data.split(None, 1)[1]
55 | videoid, duration, user_id = callback_request.split("|")
56 | if CallbackQuery.from_user.id != int(user_id):
57 | return await CallbackQuery.answer(
58 | "This is not for you! Search You Own Song.", show_alert=True
59 | )
60 | buttons = choose_markup(videoid, duration, user_id)
61 | await CallbackQuery.edit_message_reply_markup(
62 | reply_markup=InlineKeyboardMarkup(buttons)
63 | )
64 |
65 |
66 | @app.on_callback_query(filters.regex(pattern=r"Choose"))
67 | async def quality_markup(_, CallbackQuery):
68 | limit = await get_video_limit(141414)
69 | if not limit:
70 | await CallbackQuery.message.delete()
71 | return await CallbackQuery.message.reply_text(
72 | "**No Limit Defined for Video Calls**\n\nSet a Limit for Number of Maximum Video Calls allowed on Bot by /set_video_limit [Sudo Users Only]"
73 | )
74 | count = len(await get_active_video_chats())
75 | if int(count) == int(limit):
76 | if await is_active_video_chat(CallbackQuery.message.chat.id):
77 | pass
78 | else:
79 | return await CallbackQuery.answer(
80 | "Sorry! Bot only allows limited number of video calls due to CPU overload issues. Other chats are using video call right now. Try switching to audio or try again later",
81 | show_alert=True,
82 | )
83 | if CallbackQuery.message.chat.id not in db_mem:
84 | db_mem[CallbackQuery.message.chat.id] = {}
85 | try:
86 | read1 = db_mem[CallbackQuery.message.chat.id]["live_check"]
87 | if read1:
88 | return await CallbackQuery.answer(
89 | "Live Streaming Playing...Stop it to play music",
90 | show_alert=True,
91 | )
92 | else:
93 | pass
94 | except:
95 | pass
96 | await CallbackQuery.answer()
97 | callback_data = CallbackQuery.data.strip()
98 | callback_request = callback_data.split(None, 1)[1]
99 | videoid, duration, user_id = callback_request.split("|")
100 | if CallbackQuery.from_user.id != int(user_id):
101 | return await CallbackQuery.answer(
102 | "This is not for you! Search You Own Song.", show_alert=True
103 | )
104 | buttons = stream_quality_markup(videoid, duration, user_id)
105 | await CallbackQuery.edit_message_reply_markup(
106 | reply_markup=InlineKeyboardMarkup(buttons)
107 | )
108 |
109 |
110 | @app.on_callback_query(filters.regex(pattern=r"LiveStream"))
111 | async def Live_Videos_Stream(_, CallbackQuery):
112 | limit = await get_video_limit(141414)
113 | if not limit:
114 | await CallbackQuery.message.delete()
115 | return await CallbackQuery.message.reply_text(
116 | "**No Limit Defined for Video Calls**\n\nSet a Limit for Number of Maximum Video Calls allowed on Bot by /set_video_limit [Sudo Users Only]"
117 | )
118 | count = len(await get_active_video_chats())
119 | if int(count) == int(limit):
120 | if await is_active_video_chat(CallbackQuery.message.chat.id):
121 | pass
122 | else:
123 | return await CallbackQuery.answer(
124 | "Sorry! Bot only allows limited number of video calls due to CPU overload issues. Other chats are using video call right now. Try switching to audio or try again later",
125 | show_alert=True,
126 | )
127 | if CallbackQuery.message.chat.id not in db_mem:
128 | db_mem[CallbackQuery.message.chat.id] = {}
129 | callback_data = CallbackQuery.data.strip()
130 | callback_request = callback_data.split(None, 1)[1]
131 | chat_id = CallbackQuery.message.chat.id
132 | chat_title = CallbackQuery.message.chat.title
133 | quality, videoid, duration, user_id = callback_request.split("|")
134 | if CallbackQuery.from_user.id != int(user_id):
135 | return await CallbackQuery.answer(
136 | "This is not for you! Search You Own Song.", show_alert=True
137 | )
138 | await CallbackQuery.message.delete()
139 | title, duration_min, duration_sec, thumbnail = get_yt_info_id(videoid)
140 | await CallbackQuery.answer()
141 | theme = await check_theme(chat_id)
142 | chat_title = await specialfont_to_normal(chat_title)
143 | thumb = await gen_thumb(thumbnail, title, user_id, theme, chat_title)
144 | nrs, ytlink = await get_m3u8(videoid)
145 | if nrs == 0:
146 | return await CallbackQuery.message.reply_text(
147 | "Video Formats not Found.."
148 | )
149 | await start_live_stream(
150 | CallbackQuery,
151 | quality,
152 | ytlink,
153 | thumb,
154 | title,
155 | duration_min,
156 | duration_sec,
157 | videoid,
158 | )
159 |
160 |
161 | @app.on_callback_query(filters.regex(pattern=r"VideoStream"))
162 | async def Videos_Stream(_, CallbackQuery):
163 | if CallbackQuery.message.chat.id not in db_mem:
164 | db_mem[CallbackQuery.message.chat.id] = {}
165 | callback_data = CallbackQuery.data.strip()
166 | callback_request = callback_data.split(None, 1)[1]
167 | chat_id = CallbackQuery.message.chat.id
168 | chat_title = CallbackQuery.message.chat.title
169 | quality, videoid, duration, user_id = callback_request.split("|")
170 | if CallbackQuery.from_user.id != int(user_id):
171 | return await CallbackQuery.answer(
172 | "This is not for you! Search You Own Song.", show_alert=True
173 | )
174 | if str(duration) == "None":
175 | buttons = livestream_markup(quality, videoid, duration, user_id)
176 | return await CallbackQuery.edit_message_text(
177 | "**Live Stream Detected**\n\nWant to play live stream? This will stop the current playing musics(if any) and will start streaming live video.",
178 | reply_markup=InlineKeyboardMarkup(buttons),
179 | )
180 | await CallbackQuery.message.delete()
181 | title, duration_min, duration_sec, thumbnail = get_yt_info_id(videoid)
182 | if duration_sec > DURATION_LIMIT:
183 | return await CallbackQuery.message.reply_text(
184 | f"**Duration Limit Exceeded**\n\n**Allowed Duration: **{DURATION_LIMIT_MIN} minute(s)\n**Received Duration:** {duration_min} minute(s)"
185 | )
186 | await CallbackQuery.answer()
187 | theme = await check_theme(chat_id)
188 | chat_title = await specialfont_to_normal(chat_title)
189 | thumb = await gen_thumb(thumbnail, title, user_id, theme, chat_title)
190 | nrs, ytlink = await get_m3u8(videoid)
191 | if nrs == 0:
192 | return await CallbackQuery.message.reply_text(
193 | "Video Formats not Found.."
194 | )
195 | await start_video_stream(
196 | CallbackQuery,
197 | quality,
198 | ytlink,
199 | thumb,
200 | title,
201 | duration_min,
202 | duration_sec,
203 | videoid,
204 | )
205 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/timer.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | from datetime import datetime, timedelta
4 |
5 | from pyrogram.errors import FloodWait, MessageNotModified
6 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
7 | InlineKeyboardMarkup, InputMediaPhoto, Message)
8 |
9 | from Ayiin import db_mem
10 | from Ayiin.Database import is_active_chat, is_music_playing
11 | from Ayiin.Inline import audio_timer_markup_start, timer_markup
12 |
13 |
14 | async def start_timer(
15 | videoid, duration_min, duration_sec, finaltext, chat_id, user_id, aud
16 | ):
17 | left_time = {}
18 | db_mem[chat_id]["videoid"] = videoid
19 | db_mem[chat_id]["left"] = duration_min
20 | db_mem[chat_id]["total"] = duration_min
21 | user_input_time = int(duration_sec - 8)
22 | left_time[videoid] = datetime.now()
23 | try:
24 | if 0 < user_input_time <= 7:
25 | while user_input_time:
26 | if await is_active_chat(chat_id):
27 | if db_mem[chat_id]["videoid"] == videoid:
28 | if await is_music_playing(chat_id):
29 | if datetime.now() > left_time.get(videoid):
30 | s = user_input_time % 60
31 | c_t = "00:{:02d}".format(s)
32 | if aud == 0:
33 | buttons = timer_markup(
34 | videoid, user_id, c_t, duration_min
35 | )
36 | else:
37 | buttons = audio_timer_markup_start(
38 | videoid, user_id, c_t, duration_min
39 | )
40 | user_input_time -= 1
41 | db_mem[chat_id]["left"] = c_t
42 | try:
43 | if db_mem[videoid]["check"] == 2:
44 | await finaltext.edit_reply_markup(
45 | reply_markup=InlineKeyboardMarkup(
46 | buttons
47 | )
48 | )
49 | except FloodWait as e:
50 | await asyncio.sleep(e.x)
51 | user_input_time -= e.x
52 | left_time[
53 | videoid
54 | ] = datetime.now() + timedelta(
55 | milliseconds=550
56 | )
57 | else:
58 | break
59 | else:
60 | break
61 | elif 7 < user_input_time < 60:
62 | while user_input_time > 0:
63 | if await is_active_chat(chat_id):
64 | if db_mem[chat_id]["videoid"] == videoid:
65 | if await is_music_playing(chat_id):
66 | if datetime.now() > left_time.get(videoid):
67 | s = user_input_time % 60
68 | c_t = "00:{:02d}".format(s)
69 | user_input_time -= 4
70 | if aud == 0:
71 | buttons = timer_markup(
72 | videoid, user_id, c_t, duration_min
73 | )
74 | else:
75 | buttons = audio_timer_markup_start(
76 | videoid, user_id, c_t, duration_min
77 | )
78 | db_mem[chat_id]["left"] = c_t
79 | try:
80 | if db_mem[videoid]["check"] == 2:
81 | await finaltext.edit_reply_markup(
82 | reply_markup=InlineKeyboardMarkup(
83 | buttons
84 | )
85 | )
86 | except FloodWait as e:
87 | await asyncio.sleep(e.x)
88 | user_input_time -= e.x
89 | left_time[
90 | videoid
91 | ] = datetime.now() + timedelta(
92 | milliseconds=3500
93 | )
94 | else:
95 | break
96 | else:
97 | break
98 | elif 60 <= user_input_time < 3600:
99 | while user_input_time > 0:
100 | if await is_active_chat(chat_id):
101 | if db_mem[chat_id]["videoid"] == videoid:
102 | if await is_music_playing(chat_id):
103 | if datetime.now() > left_time.get(videoid):
104 | m = user_input_time % 3600 // 60
105 | s = user_input_time % 60
106 | c_t = "{:02d}:{:02d}".format(m, s)
107 | user_input_time -= 6
108 | if aud == 0:
109 | buttons = timer_markup(
110 | videoid, user_id, c_t, duration_min
111 | )
112 | else:
113 | buttons = audio_timer_markup_start(
114 | videoid, user_id, c_t, duration_min
115 | )
116 | db_mem[chat_id]["left"] = c_t
117 | try:
118 | if db_mem[videoid]["check"] == 2:
119 | await finaltext.edit_reply_markup(
120 | reply_markup=InlineKeyboardMarkup(
121 | buttons
122 | )
123 | )
124 | except FloodWait as e:
125 | await asyncio.sleep(e.x)
126 | user_input_time -= e.x
127 | left_time[
128 | videoid
129 | ] = datetime.now() + timedelta(
130 | milliseconds=5300
131 | )
132 | else:
133 | break
134 | else:
135 | break
136 | elif 3600 <= user_input_time < 86400:
137 | while user_input_time > 0:
138 | if await is_active_chat(chat_id):
139 | if db_mem[chat_id]["videoid"] == videoid:
140 | if await is_music_playing(chat_id):
141 | if datetime.now() > left_time.get(videoid):
142 | h = user_input_time % (3600 * 24) // 3600
143 | m = user_input_time % 3600 // 60
144 | s = user_input_time % 60
145 | c_t = "{:02d}:{:02d}:{:02d}".format(h, m, s)
146 | user_input_time -= 10
147 | if aud == 0:
148 | buttons = timer_markup(
149 | videoid, user_id, c_t, duration_min
150 | )
151 | else:
152 | buttons = audio_timer_markup_start(
153 | videoid, user_id, c_t, duration_min
154 | )
155 | db_mem[chat_id]["left"] = c_t
156 | try:
157 | if db_mem[videoid]["check"] == 2:
158 | await finaltext.edit_reply_markup(
159 | reply_markup=InlineKeyboardMarkup(
160 | buttons
161 | )
162 | )
163 | except FloodWait as e:
164 | await asyncio.sleep(e.x)
165 | user_input_time -= e.x
166 | left_time[
167 | videoid
168 | ] = datetime.now() + timedelta(
169 | milliseconds=9100
170 | )
171 | else:
172 | break
173 | else:
174 | break
175 | else:
176 | return
177 | except Exception as e:
178 | print(e)
179 | return
180 |
--------------------------------------------------------------------------------
/Ayiin/Utilities/videostream.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | import shutil
4 | from asyncio import QueueEmpty
5 |
6 | from pyrogram.types import InlineKeyboardMarkup
7 | from pyrogram.types.messages_and_media import message
8 |
9 | from config import get_queue
10 | from Ayiin import BOT_USERNAME, db_mem
11 | from Ayiin.Core.PyTgCalls import Queues
12 | from Ayiin.Core.PyTgCalls.Ayiin import (join_live_stream, join_video_stream,
13 | stop_stream)
14 | from Ayiin.Database import (add_active_chat, add_active_video_chat,
15 | is_active_chat, music_off, music_on,
16 | remove_active_chat)
17 | from Ayiin.Inline import (audio_markup, audio_markup2, primary_markup,
18 | secondary_markup, secondary_markup2)
19 | from Ayiin.Utilities.timer import start_timer
20 |
21 | loop = asyncio.get_event_loop()
22 |
23 |
24 | async def start_stream_video(message, file, title, mystic):
25 | global get_queue
26 | if message.chat.id not in db_mem:
27 | db_mem[message.chat.id] = {}
28 | wtfbro = db_mem[message.chat.id]
29 | wtfbro["live_check"] = False
30 | if message.chat.username:
31 | link = f"https://t.me/{message.chat.username}/{message.reply_to_message.message_id}"
32 | else:
33 | xf = str((message.chat.id))[4:]
34 | link = f"https://t.me/c/{xf}/{message.reply_to_message.message_id}"
35 | if await is_active_chat(message.chat.id):
36 | file = f"s1s_1080_+_{file}"
37 | position = await Queues.put(message.chat.id, file=file)
38 | if file not in db_mem:
39 | db_mem[file] = {}
40 | wtfbro = db_mem[file]
41 | wtfbro["chat_title"] = message.chat.title
42 | wtfbro["duration"] = 0
43 | wtfbro["username"] = message.from_user.mention
44 | wtfbro["videoid"] = "videoid"
45 | wtfbro["user_id"] = message.from_user.id
46 | got_queue = get_queue.get(message.chat.id)
47 | title = title
48 | user = message.from_user.first_name
49 | duration = 0
50 | to_append = [title, user, duration]
51 | got_queue.append(to_append)
52 | final_output = await message.reply_photo(
53 | photo="Utils/Telegram.JPEG",
54 | caption=(
55 | f"🎬__Video:__ [Given Video Via Telegram]({link})\n\n👤__Requested by:__ {message.from_user.mention} \n🚧__Queued at:__ #{position}!"
56 | ),
57 | reply_markup=audio_markup2,
58 | )
59 | await mystic.delete()
60 | return
61 | else:
62 | if not await join_video_stream(message.chat.id, file, 720):
63 | return await mystic.edit(
64 | "Error Joining Voice Chat. Make sure Voice Chat is Enabled."
65 | )
66 | get_queue[message.chat.id] = []
67 | got_queue = get_queue.get(message.chat.id)
68 | title = title
69 | user = message.from_user.first_name
70 | duration = 0
71 | to_append = [title, user, duration]
72 | got_queue.append(to_append)
73 | await music_on(message.chat.id)
74 | await add_active_chat(message.chat.id)
75 | await add_active_video_chat(message.chat.id)
76 | buttons = secondary_markup2("Smex1", message.from_user.id)
77 | await mystic.delete()
78 | cap = f"🎥__Playing:__ [Given Video Via Telegram]({link})\n👤**__Requested by:__** {message.from_user.mention}"
79 | final_output = await message.reply_photo(
80 | photo="Utils/Telegram.JPEG",
81 | reply_markup=InlineKeyboardMarkup(buttons),
82 | caption=cap,
83 | )
84 |
85 |
86 | async def start_live_stream(
87 | CallbackQuery,
88 | quality,
89 | link,
90 | thumb,
91 | title,
92 | duration_min,
93 | duration_sec,
94 | videoid,
95 | ):
96 | global get_queue
97 | if CallbackQuery.message.chat.id not in db_mem:
98 | db_mem[CallbackQuery.message.chat.id] = {}
99 | wtfbro = db_mem[CallbackQuery.message.chat.id]
100 | wtfbro["live_check"] = True
101 | if await is_active_chat(CallbackQuery.message.chat.id):
102 | try:
103 | Queues.clear(CallbackQuery.message.chat.id)
104 | except QueueEmpty:
105 | pass
106 | await remove_active_chat(CallbackQuery.message.chat.id)
107 | try:
108 | await stop_stream(CallbackQuery.message.chat.id)
109 | except:
110 | pass
111 | if not await join_live_stream(
112 | CallbackQuery.message.chat.id, link, quality
113 | ):
114 | return await CallbackQuery.message.reply_text(
115 | f"Error Joining Voice Chat."
116 | )
117 | await music_on(CallbackQuery.message.chat.id)
118 | await add_active_chat(CallbackQuery.message.chat.id)
119 | await add_active_video_chat(CallbackQuery.message.chat.id)
120 | buttons = secondary_markup2(videoid, CallbackQuery.from_user.id)
121 | cap = f"**Live Streaming**\n\n🎥__Playing:__ [{title[:25]}](https://www.youtube.com/watch?v={videoid}) \n💡__Info:__ [Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n👤**__Requested by:__** {CallbackQuery.from_user.mention}"
122 | final_output = await CallbackQuery.message.reply_photo(
123 | photo=thumb,
124 | reply_markup=InlineKeyboardMarkup(buttons),
125 | caption=cap,
126 | )
127 | os.remove(thumb)
128 | await CallbackQuery.message.delete()
129 |
130 |
131 | async def start_video_stream(
132 | CallbackQuery,
133 | quality,
134 | link,
135 | thumb,
136 | title,
137 | duration_min,
138 | duration_sec,
139 | videoid,
140 | ):
141 | global get_queue
142 | if CallbackQuery.message.chat.id not in db_mem:
143 | db_mem[CallbackQuery.message.chat.id] = {}
144 | wtfbro = db_mem[CallbackQuery.message.chat.id]
145 | wtfbro["live_check"] = False
146 | if await is_active_chat(CallbackQuery.message.chat.id):
147 | file = f"s1s_{quality}_+_{videoid}"
148 | position = await Queues.put(CallbackQuery.message.chat.id, file=file)
149 | _path_ = (
150 | (str(file))
151 | .replace("_", "", 1)
152 | .replace("/", "", 1)
153 | .replace(".", "", 1)
154 | )
155 | buttons = secondary_markup(videoid, CallbackQuery.from_user.id)
156 | if file not in db_mem:
157 | db_mem[file] = {}
158 | cpl = f"cache/{_path_}final.png"
159 | shutil.copyfile(thumb, cpl)
160 | wtfbro = db_mem[file]
161 | wtfbro["chat_title"] = CallbackQuery.message.chat.title
162 | wtfbro["duration"] = duration_min
163 | wtfbro["username"] = CallbackQuery.from_user.mention
164 | wtfbro["videoid"] = videoid
165 | wtfbro["user_id"] = CallbackQuery.from_user.id
166 | got_queue = get_queue.get(CallbackQuery.message.chat.id)
167 | title = title
168 | user = CallbackQuery.from_user.first_name
169 | duration = duration_min
170 | to_append = [title, user, duration]
171 | got_queue.append(to_append)
172 | final_output = await CallbackQuery.message.reply_photo(
173 | photo=thumb,
174 | caption=(
175 | f"🎬Video:__ [{title[:25]}](https://www.youtube.com/watch?v={videoid}) \n⏳__Duration:__ {duration_min} \n💡__Info:__ [Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n👤__Requested by:__ {CallbackQuery.from_user.mention} \n🚧__ Video Queued at:__ #{position}!"
176 | ),
177 | reply_markup=InlineKeyboardMarkup(buttons),
178 | )
179 | await CallbackQuery.message.delete()
180 | os.remove(thumb)
181 | return
182 | else:
183 | if not await join_video_stream(
184 | CallbackQuery.message.chat.id, link, quality
185 | ):
186 | return await CallbackQuery.message.reply_text(
187 | f"Error Joining Voice Chat."
188 | )
189 | get_queue[CallbackQuery.message.chat.id] = []
190 | got_queue = get_queue.get(CallbackQuery.message.chat.id)
191 | title = title
192 | user = CallbackQuery.from_user.first_name
193 | duration = duration_min
194 | to_append = [title, user, duration]
195 | got_queue.append(to_append)
196 | await music_on(CallbackQuery.message.chat.id)
197 | await add_active_video_chat(CallbackQuery.message.chat.id)
198 | await add_active_chat(CallbackQuery.message.chat.id)
199 |
200 | buttons = primary_markup(
201 | videoid, CallbackQuery.from_user.id, duration_min, duration_min
202 | )
203 | cap = f"**Video Streaming**\n\n🎥__Playing:__ [{title[:25]}](https://www.youtube.com/watch?v={videoid}) \n💡__Info:__ [Get Additional Information](https://t.me/{BOT_USERNAME}?start=info_{videoid})\n👤**__Requested by:__** {CallbackQuery.from_user.mention}"
204 | final_output = await CallbackQuery.message.reply_photo(
205 | photo=thumb,
206 | reply_markup=InlineKeyboardMarkup(buttons),
207 | caption=cap,
208 | )
209 | os.remove(thumb)
210 | await CallbackQuery.message.delete()
211 | await start_timer(
212 | videoid,
213 | duration_min,
214 | duration_sec,
215 | final_output,
216 | CallbackQuery.message.chat.id,
217 | CallbackQuery.from_user.id,
218 | 0,
219 | )
220 |
--------------------------------------------------------------------------------
/Ayiin/__init__.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | import time
4 | from os import listdir, mkdir
5 |
6 | import heroku3
7 | from aiohttp import ClientSession
8 | from git import Repo
9 | from git.exc import GitCommandError, InvalidGitRepositoryError
10 | from motor.motor_asyncio import AsyncIOMotorClient as Bot
11 | from rich.console import Console
12 | from rich.table import Table
13 |
14 | from config import (ASSISTANT_PREFIX, DURATION_LIMIT_MIN, LOG_GROUP_ID,
15 | LOG_SESSION)
16 | from config import MONGO_DB_URI as mango
17 | from config import (MUSIC_BOT_NAME, OWNER_ID, STRING1, STRING2, STRING3,
18 | STRING4, STRING5, SUDO_USERS, UPSTREAM_BRANCH,
19 | UPSTREAM_REPO, get_queue)
20 | from Ayiin.Core.Clients.cli import (ASS_CLI_1, ASS_CLI_2, ASS_CLI_3, ASS_CLI_4,
21 | ASS_CLI_5, LOG_CLIENT, app)
22 | from Ayiin.Utilities.changers import time_to_seconds
23 | from Ayiin.Utilities.tasks import install_requirements
24 |
25 | loop = asyncio.get_event_loop()
26 | console = Console()
27 |
28 |
29 | ### Heroku Shit
30 | UPSTREAM_BRANCH = UPSTREAM_BRANCH
31 | UPSTREAM_REPO = UPSTREAM_REPO
32 |
33 | ### Modules
34 | MOD_LOAD = []
35 | MOD_NOLOAD = []
36 |
37 | ### Mongo DB
38 | MONGODB_CLI = Bot(mango)
39 | db = MONGODB_CLI.Ayiin
40 |
41 | ### Boot Time
42 | boottime = time.time()
43 |
44 | ### Clients
45 | app = app
46 | ASS_CLI_1 = ASS_CLI_1
47 | ASS_CLI_2 = ASS_CLI_2
48 | ASS_CLI_3 = ASS_CLI_3
49 | ASS_CLI_4 = ASS_CLI_4
50 | ASS_CLI_5 = ASS_CLI_5
51 | LOG_CLIENT = LOG_CLIENT
52 | aiohttpsession = ClientSession()
53 |
54 | ### Config
55 | SUDOERS = SUDO_USERS
56 | OWNER_ID = OWNER_ID
57 | LOG_GROUP_ID = LOG_GROUP_ID
58 | MUSIC_BOT_NAME = MUSIC_BOT_NAME
59 | DURATION_LIMIT = int(time_to_seconds(f"{DURATION_LIMIT_MIN}:00"))
60 | ASSISTANT_PREFIX = ASSISTANT_PREFIX
61 |
62 | ### Bot Info
63 | BOT_ID = 0
64 | BOT_NAME = ""
65 | BOT_USERNAME = ""
66 |
67 | ### Assistant Info
68 | ASSIDS = []
69 | ASSID1 = 0
70 | ASSNAME1 = ""
71 | ASSUSERNAME1 = ""
72 | ASSMENTION1 = ""
73 | ASSID2 = 0
74 | ASSNAME2 = ""
75 | ASSUSERNAME2 = ""
76 | ASSMENTION2 = ""
77 | ASSID3 = 0
78 | ASSNAME3 = ""
79 | ASSUSERNAME3 = ""
80 | ASSMENTION3 = ""
81 | ASSID4 = 0
82 | ASSNAME4 = ""
83 | ASSUSERNAME4 = ""
84 | ASSMENTION4 = ""
85 | ASSID5 = 0
86 | ASSNAME5 = ""
87 | ASSUSERNAME5 = ""
88 | ASSMENTION5 = ""
89 | random_assistant = []
90 |
91 |
92 | async def initiate_bot():
93 | global SUDOERS, OWNER_ID, ASSIDS
94 | global BOT_ID, BOT_NAME, BOT_USERNAME
95 | global ASSID1, ASSNAME1, ASSMENTION1, ASSUSERNAME1
96 | global ASSID2, ASSNAME2, ASSMENTION2, ASSUSERNAME2
97 | global ASSID3, ASSNAME3, ASSMENTION3, ASSUSERNAME3
98 | global ASSID4, ASSNAME4, ASSMENTION4, ASSUSERNAME4
99 | global ASSID5, ASSNAME5, ASSMENTION5, ASSUSERNAME5
100 | global Heroku_cli, Heroku_app
101 | os.system("clear")
102 | header = Table(show_header=True, header_style="bold yellow")
103 | header.add_column(
104 | "\x41\x79\x69\x69\x6e\x20\x4d\x75\x73\x69\x63\x20\x3a\x20\x54\x68\x65\x20\x4d\x6f\x73\x74\x20\x41\x64\x76\x61\x6e\x63\x65\x64\x20\x4d\x75\x73\x69\x63\x20\x42\x6f\x74"
105 | )
106 | console.print(header)
107 | with console.status(
108 | "[magenta] Ayiin Music Booting...",
109 | ) as status:
110 | console.print("┌ [red]Booting Up The Clients...\n")
111 | await app.start()
112 | console.print("└ [green]Booted Bot Client")
113 | console.print("\n┌ [red]Booting Up The Assistant Clients...")
114 | if STRING1 != "None":
115 | await ASS_CLI_1.start()
116 | random_assistant.append(1)
117 | console.print("├ [yellow]Booted Assistant Client")
118 | if STRING2 != "None":
119 | await ASS_CLI_2.start()
120 | random_assistant.append(2)
121 | console.print("├ [yellow]Booted Assistant Client 2")
122 | if STRING3 != "None":
123 | await ASS_CLI_3.start()
124 | random_assistant.append(3)
125 | console.print("├ [yellow]Booted Assistant Client 3")
126 | if STRING4 != "None":
127 | await ASS_CLI_4.start()
128 | random_assistant.append(4)
129 | console.print("├ [yellow]Booted Assistant Client 4")
130 | if STRING5 != "None":
131 | await ASS_CLI_5.start()
132 | random_assistant.append(5)
133 | console.print("├ [yellow]Booted Assistant Client 5")
134 | console.print("└ [green]Assistant Clients Booted Successfully!")
135 | if LOG_SESSION != "None":
136 | console.print("\n┌ [red]Booting Logger Client")
137 | await LOG_CLIENT.start()
138 | console.print("└ [green]Logger Client Booted Successfully!")
139 | if "raw_files" not in listdir():
140 | mkdir("raw_files")
141 | if "downloads" not in listdir():
142 | mkdir("downloads")
143 | if "cache" not in listdir():
144 | mkdir("cache")
145 | if "search" not in listdir():
146 | mkdir("search")
147 | console.print("\n┌ [red]Loading Clients Information...")
148 | getme = await app.get_me()
149 | BOT_ID = getme.id
150 | if getme.last_name:
151 | BOT_NAME = getme.first_name + " " + getme.last_name
152 | else:
153 | BOT_NAME = getme.first_name
154 | BOT_USERNAME = getme.username
155 | if STRING1 != "None":
156 | getme1 = await ASS_CLI_1.get_me()
157 | ASSID1 = getme1.id
158 | ASSIDS.append(ASSID1)
159 | ASSNAME1 = (
160 | f"{getme1.first_name} {getme1.last_name}"
161 | if getme1.last_name
162 | else getme1.first_name
163 | )
164 | ASSUSERNAME1 = getme1.username
165 | ASSMENTION1 = getme1.mention
166 | if STRING2 != "None":
167 | getme2 = await ASS_CLI_2.get_me()
168 | ASSID2 = getme2.id
169 | ASSIDS.append(ASSID2)
170 | ASSNAME2 = (
171 | f"{getme2.first_name} {getme2.last_name}"
172 | if getme2.last_name
173 | else getme2.first_name
174 | )
175 | ASSUSERNAME2 = getme2.username
176 | ASSMENTION2 = getme2.mention
177 | if STRING3 != "None":
178 | getme3 = await ASS_CLI_3.get_me()
179 | ASSID3 = getme3.id
180 | ASSIDS.append(ASSID3)
181 | ASSNAME3 = (
182 | f"{getme3.first_name} {getme3.last_name}"
183 | if getme3.last_name
184 | else getme3.first_name
185 | )
186 | ASSUSERNAME3 = getme3.username
187 | ASSMENTION3 = getme3.mention
188 | if STRING4 != "None":
189 | getme4 = await ASS_CLI_4.get_me()
190 | ASSID4 = getme4.id
191 | ASSIDS.append(ASSID4)
192 | ASSNAME4 = (
193 | f"{getme4.first_name} {getme4.last_name}"
194 | if getme4.last_name
195 | else getme4.first_name
196 | )
197 | ASSUSERNAME4 = getme4.username
198 | ASSMENTION4 = getme4.mention
199 | if STRING5 != "None":
200 | getme5 = await ASS_CLI_5.get_me()
201 | ASSID5 = getme5.id
202 | ASSIDS.append(ASSID5)
203 | ASSNAME5 = (
204 | f"{getme5.first_name} {getme5.last_name}"
205 | if getme5.last_name
206 | else getme5.first_name
207 | )
208 | ASSUSERNAME5 = getme5.username
209 | ASSMENTION5 = getme5.mention
210 | console.print("└ [green]Loaded Clients Information!")
211 | console.print("\n┌ [red]Loading Sudo Users...")
212 | sudoersdb = db.sudoers
213 | sudoers = await sudoersdb.find_one({"sudo": "sudo"})
214 | sudoers = [] if not sudoers else sudoers["sudoers"]
215 | for user_id in SUDOERS:
216 | if user_id not in sudoers:
217 | sudoers.append(user_id)
218 | await sudoersdb.update_one(
219 | {"sudo": "sudo"},
220 | {"$set": {"sudoers": sudoers}},
221 | upsert=True,
222 | )
223 | SUDOERS = (SUDOERS + sudoers + OWNER_ID) if sudoers else SUDOERS
224 | console.print("└ [green]Loaded Sudo Users Successfully!\n")
225 | try:
226 | repo = Repo()
227 | except GitCommandError:
228 | console.print("┌ [red] Checking Git Updates!")
229 | console.print("└ [red]Git Command Error\n")
230 | return
231 | except InvalidGitRepositoryError:
232 | console.print("┌ [red] Checking Git Updates!")
233 | repo = Repo.init()
234 | if "origin" in repo.remotes:
235 | origin = repo.remote("origin")
236 | else:
237 | origin = repo.create_remote("origin", UPSTREAM_REPO)
238 | origin.fetch()
239 | repo.create_head(UPSTREAM_BRANCH, origin.refs[UPSTREAM_BRANCH])
240 | repo.heads[UPSTREAM_BRANCH].set_tracking_branch(
241 | origin.refs[UPSTREAM_BRANCH]
242 | )
243 | repo.heads[UPSTREAM_BRANCH].checkout(True)
244 | try:
245 | repo.create_remote("origin", UPSTREAM_REPO)
246 | except BaseException:
247 | pass
248 | nrs = repo.remote("origin")
249 | nrs.fetch(UPSTREAM_BRANCH)
250 | try:
251 | nrs.pull(UPSTREAM_BRANCH)
252 | except GitCommandError:
253 | repo.git.reset("--hard", "FETCH_HEAD")
254 | await install_requirements(
255 | "pip3 install --no-cache-dir -r requirements.txt"
256 | )
257 | console.print("└ [red]Git Client Update Completed\n")
258 |
259 |
260 | loop.run_until_complete(initiate_bot())
261 |
262 |
263 | def init_db():
264 | global db_mem
265 | db_mem = {}
266 |
267 |
268 | init_db()
269 |
--------------------------------------------------------------------------------
/Ayiin/Inline/start.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 | from config import MUSIC_BOT_NAME, SUPPORT_CHANNEL, SUPPORT_GROUP
5 | from Ayiin import BOT_USERNAME
6 |
7 |
8 | def setting_markup2():
9 | buttons = [
10 | [
11 | InlineKeyboardButton(text="🔈 Quality", callback_data="AQ"),
12 | InlineKeyboardButton(text="🎚 Volume", callback_data="AV"),
13 | ],
14 | [
15 | InlineKeyboardButton(
16 | text="👥 Users", callback_data="AU"
17 | ),
18 | InlineKeyboardButton(
19 | text="💻 Dashboard", callback_data="Dashboard"
20 | ),
21 | ],
22 | [
23 | InlineKeyboardButton(text="•Cʟᴏsᴇ•", callback_data="close"),
24 | ],
25 | ]
26 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
27 |
28 |
29 | def start_pannel():
30 | if not SUPPORT_CHANNEL and not SUPPORT_GROUP:
31 | buttons = [
32 | [
33 | InlineKeyboardButton(
34 | text="🗂 Helper Commands", callback_data="yins"
35 | ),
36 | ],
37 | [
38 | InlineKeyboardButton(
39 | text="🔧 Settings", callback_data="settingm"
40 | )
41 | ],
42 | ]
43 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
44 | if not SUPPORT_CHANNEL and SUPPORT_GROUP:
45 | buttons = [
46 | [
47 | InlineKeyboardButton(
48 | text="🗂 Helper Commands", callback_data="yins"
49 | ),
50 | ],
51 | [
52 | InlineKeyboardButton(
53 | text="🔧 Settings", callback_data="settingm"
54 | )
55 | ],
56 | [
57 | InlineKeyboardButton(
58 | text="📨Group", url=f"{SUPPORT_GROUP}"
59 | ),
60 | ],
61 | ]
62 | return f"🎛 **This is {MUSIC_BOT_NAME}*", buttons
63 | if SUPPORT_CHANNEL and not SUPPORT_GROUP:
64 | buttons = [
65 | [
66 | InlineKeyboardButton(
67 | text="🗂 Helper Commands", callback_data="yins"
68 | ),
69 | ],
70 | [
71 | InlineKeyboardButton(
72 | text="🔧 Settings", callback_data="settingm"
73 | )
74 | ],
75 | [
76 | InlineKeyboardButton(
77 | text="📨Channel", url=f"{SUPPORT_CHANNEL}"
78 | ),
79 | ],
80 | ]
81 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
82 | if SUPPORT_CHANNEL and SUPPORT_GROUP:
83 | buttons = [
84 | [
85 | InlineKeyboardButton(
86 | text="🗂 Helper Commands", callback_data="yins"
87 | ),
88 | ],
89 | [
90 | InlineKeyboardButton(
91 | text="🔧 Settings", callback_data="settingm"
92 | )
93 | ],
94 | [
95 | InlineKeyboardButton(
96 | text="📨Channel", url=f"{SUPPORT_CHANNEL}"
97 | ),
98 | InlineKeyboardButton(
99 | text="📨Group", url=f"{SUPPORT_GROUP}"
100 | ),
101 | ],
102 | ]
103 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
104 |
105 |
106 | def private_panel():
107 | if not SUPPORT_CHANNEL and not SUPPORT_GROUP:
108 | buttons = [
109 | [
110 | InlineKeyboardButton(
111 | text="🗂 Helper Commands", callback_data="yins"
112 | ),
113 | ],
114 | [
115 | InlineKeyboardButton(
116 | "➕ Add me to your Group ➕",
117 | url=f"https://t.me/{BOT_USERNAME}?startgroup=true",
118 | )
119 | ],
120 | ]
121 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
122 | if not SUPPORT_CHANNEL and SUPPORT_GROUP:
123 | buttons = [
124 | [
125 | InlineKeyboardButton(
126 | text="🗂 Helper Commands", callback_data="yins"
127 | ),
128 | ],
129 | [
130 | InlineKeyboardButton(
131 | "➕ Add me to your Group ➕",
132 | url=f"https://t.me/{BOT_USERNAME}?startgroup=true",
133 | )
134 | ],
135 | [
136 | InlineKeyboardButton(
137 | text="📨Group", url=f"{SUPPORT_GROUP}"
138 | ),
139 | ],
140 | ]
141 | return f"🎛 **This is {MUSIC_BOT_NAME}*", buttons
142 | if SUPPORT_CHANNEL and not SUPPORT_GROUP:
143 | buttons = [
144 | [
145 | InlineKeyboardButton(
146 | text="🗂 Helper Commands", callback_data="yins"
147 | ),
148 | ],
149 | [
150 | InlineKeyboardButton(
151 | "➕ Add me to your Group ➕",
152 | url=f"https://t.me/{BOT_USERNAME}?startgroup=true",
153 | )
154 | ],
155 | [
156 | InlineKeyboardButton(
157 | text="📨Channel", url=f"{SUPPORT_CHANNEL}"
158 | ),
159 | ],
160 | ]
161 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
162 | if SUPPORT_CHANNEL and SUPPORT_GROUP:
163 | buttons = [
164 | [
165 | InlineKeyboardButton(
166 | text="🗂 Helper Commands ", callback_data="yins"
167 | ),
168 | ],
169 | [
170 | InlineKeyboardButton(
171 | "➕ Add me to your Group ➕",
172 | url=f"https://t.me/{BOT_USERNAME}?startgroup=true",
173 | )
174 | ],
175 | [
176 | InlineKeyboardButton(
177 | text="📨Channel", url=f"{SUPPORT_CHANNEL}"
178 | ),
179 | InlineKeyboardButton(
180 | text="📨Groups", url=f"{SUPPORT_GROUP}"
181 | ),
182 | ],
183 | ]
184 | return f"🎛 **This is {MUSIC_BOT_NAME}**", buttons
185 |
186 |
187 | def setting_markup():
188 | buttons = [
189 | [
190 | InlineKeyboardButton(text="🔈 Quality", callback_data="AQ"),
191 | InlineKeyboardButton(text="🎚 Volume", callback_data="AV"),
192 | ],
193 | [
194 | InlineKeyboardButton(
195 | text="👥 Users", callback_data="AU"
196 | ),
197 | InlineKeyboardButton(
198 | text="💻 Dashboard", callback_data="Dashboard"
199 | ),
200 | ],
201 | [
202 | InlineKeyboardButton(text="•Cʟᴏsᴇ•", callback_data="close"),
203 | InlineKeyboardButton(text="•Bᴀᴄᴋ•", callback_data="okaybhai"),
204 | ],
205 | ]
206 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
207 |
208 |
209 | def volmarkup():
210 | buttons = [
211 | [
212 | InlineKeyboardButton(
213 | text="🔄 Reset Audio Volume 🔄", callback_data="HV"
214 | )
215 | ],
216 | [
217 | InlineKeyboardButton(text="🔈 Low Vol", callback_data="LV"),
218 | InlineKeyboardButton(text="🔉 Medium Vol", callback_data="MV"),
219 | ],
220 | [
221 | InlineKeyboardButton(text="🔊 High Vol", callback_data="HV"),
222 | InlineKeyboardButton(text="🔈 Amplified Vol", callback_data="VAM"),
223 | ],
224 | [
225 | InlineKeyboardButton(
226 | text="🔽 Custom Volume 🔽", callback_data="Custommarkup"
227 | )
228 | ],
229 | [InlineKeyboardButton(text="•Bᴀᴄᴋ•", callback_data="settingm")],
230 | ]
231 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
232 |
233 |
234 | def custommarkup():
235 | buttons = [
236 | [
237 | InlineKeyboardButton(text="+10", callback_data="PTEN"),
238 | InlineKeyboardButton(text="-10", callback_data="MTEN"),
239 | ],
240 | [
241 | InlineKeyboardButton(text="+25", callback_data="PTF"),
242 | InlineKeyboardButton(text="-25", callback_data="MTF"),
243 | ],
244 | [
245 | InlineKeyboardButton(text="+50", callback_data="PFZ"),
246 | InlineKeyboardButton(text="-50", callback_data="MFZ"),
247 | ],
248 | [InlineKeyboardButton(text="🔼Custom Volume 🔼", callback_data="AV")],
249 | ]
250 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
251 |
252 |
253 | def usermarkup():
254 | buttons = [
255 | [
256 | InlineKeyboardButton(text="👥 Everyone", callback_data="EVE"),
257 | InlineKeyboardButton(text="🙍 Admins", callback_data="AMS"),
258 | ],
259 | [
260 | InlineKeyboardButton(
261 | text="📋 Users Lists", callback_data="USERLIST"
262 | )
263 | ],
264 | [InlineKeyboardButton(text="•Bᴀᴄᴋ•", callback_data="settingm")],
265 | ]
266 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
267 |
268 |
269 | def dashmarkup():
270 | buttons = [
271 | [
272 | InlineKeyboardButton(text="✔️ Uptime", callback_data="UPT"),
273 | InlineKeyboardButton(text="💾 Ram", callback_data="RAT"),
274 | ],
275 | [
276 | InlineKeyboardButton(text="💻 Cpu", callback_data="CPT"),
277 | InlineKeyboardButton(text="💽 Disk", callback_data="DIT"),
278 | ],
279 | [InlineKeyboardButton(text="•Bᴀᴄᴋ•", callback_data="settingm")],
280 | ]
281 | return f"🔧 **{MUSIC_BOT_NAME} Settings**", buttons
282 |
--------------------------------------------------------------------------------
/Ayiin/Inline/play.py:
--------------------------------------------------------------------------------
1 | from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
2 | InlineKeyboardMarkup, InputMediaPhoto, Message)
3 |
4 | from Ayiin import db_mem
5 |
6 |
7 | def url_markup(videoid, duration, user_id, query, query_type):
8 | buttons = [
9 | [
10 | InlineKeyboardButton(
11 | text="❮",
12 | callback_data=f"slider B|{query_type}|{query}|{user_id}",
13 | ),
14 | InlineKeyboardButton(
15 | text="🎵",
16 | callback_data=f"MusicStream {videoid}|{duration}|{user_id}",
17 | ),
18 | InlineKeyboardButton(
19 | text="🎥",
20 | callback_data=f"Choose {videoid}|{duration}|{user_id}",
21 | ),
22 | InlineKeyboardButton(
23 | text="❯",
24 | callback_data=f"slider F|{query_type}|{query}|{user_id}",
25 | ),
26 | ],
27 | [
28 | InlineKeyboardButton(
29 | text="⍟ 𝙼𝙾𝚁𝙴 ⍟",
30 | callback_data=f"Search {query}|{user_id}",
31 | ),
32 | InlineKeyboardButton(
33 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
34 | callback_data=f"forceclose {query}|{user_id}",
35 | ),
36 | ],
37 | ]
38 | return buttons
39 |
40 |
41 | def url_markup2(videoid, duration, user_id):
42 | buttons = [
43 | [
44 | InlineKeyboardButton(
45 | text="⍟ 𝙼𝚄𝚂𝙸𝙲 ⍟",
46 | callback_data=f"MusicStream {videoid}|{duration}|{user_id}",
47 | ),
48 | InlineKeyboardButton(
49 | text="⍟ 𝚅𝙸𝙳𝙴𝙾 ⍟",
50 | callback_data=f"Choose {videoid}|{duration}|{user_id}",
51 | ),
52 | ],
53 | [
54 | InlineKeyboardButton(
55 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟",
56 | callback_data=f"forceclose {videoid}|{user_id}",
57 | )
58 | ],
59 | ]
60 | return buttons
61 |
62 |
63 | def search_markup(
64 | ID1,
65 | ID2,
66 | ID3,
67 | ID4,
68 | ID5,
69 | duration1,
70 | duration2,
71 | duration3,
72 | duration4,
73 | duration5,
74 | user_id,
75 | query,
76 | ):
77 | buttons = [
78 | [
79 | InlineKeyboardButton(
80 | text="1️⃣", callback_data=f"Ayiin {ID1}|{duration1}|{user_id}"
81 | ),
82 | InlineKeyboardButton(
83 | text="2️⃣", callback_data=f"Ayiin {ID2}|{duration2}|{user_id}"
84 | ),
85 | InlineKeyboardButton(
86 | text="3️⃣", callback_data=f"Ayiin {ID3}|{duration3}|{user_id}"
87 | ),
88 | ],
89 | [
90 | InlineKeyboardButton(
91 | text="4️⃣", callback_data=f"Ayiin {ID4}|{duration4}|{user_id}"
92 | ),
93 | InlineKeyboardButton(
94 | text="5️⃣", callback_data=f"Ayiin {ID5}|{duration5}|{user_id}"
95 | ),
96 | ],
97 | [
98 | InlineKeyboardButton(
99 | text="❮❮", callback_data=f"popat 1|{query}|{user_id}"
100 | ),
101 | InlineKeyboardButton(
102 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"forceclose {query}|{user_id}"
103 | ),
104 | InlineKeyboardButton(
105 | text="❯❯", callback_data=f"popat 1|{query}|{user_id}"
106 | ),
107 | ],
108 | ]
109 | return buttons
110 |
111 |
112 | def search_markup2(
113 | ID6,
114 | ID7,
115 | ID8,
116 | ID9,
117 | ID10,
118 | duration6,
119 | duration7,
120 | duration8,
121 | duration9,
122 | duration10,
123 | user_id,
124 | query,
125 | ):
126 | buttons = [
127 | [
128 | InlineKeyboardButton(
129 | text="6️⃣",
130 | callback_data=f"Ayiin {ID6}|{duration6}|{user_id}",
131 | ),
132 | InlineKeyboardButton(
133 | text="7️⃣",
134 | callback_data=f"Ayiin {ID7}|{duration7}|{user_id}",
135 | ),
136 | InlineKeyboardButton(
137 | text="8️⃣",
138 | callback_data=f"Ayiin {ID8}|{duration8}|{user_id}",
139 | ),
140 | ],
141 | [
142 | InlineKeyboardButton(
143 | text="9️⃣",
144 | callback_data=f"Ayiin {ID9}|{duration9}|{user_id}",
145 | ),
146 | InlineKeyboardButton(
147 | text="🔟",
148 | callback_data=f"Ayiin {ID10}|{duration10}|{user_id}",
149 | ),
150 | ],
151 | [
152 | InlineKeyboardButton(
153 | text="❮❮", callback_data=f"popat 2|{query}|{user_id}"
154 | ),
155 | InlineKeyboardButton(
156 | text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"forceclose {query}|{user_id}"
157 | ),
158 | InlineKeyboardButton(
159 | text="❯❯", callback_data=f"popat 2|{query}|{user_id}"
160 | ),
161 | ],
162 | ]
163 | return buttons
164 |
165 |
166 | def secondary_markup(videoid, user_id):
167 | buttons = [
168 | [
169 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
170 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
171 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
172 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
173 | ],
174 | [
175 | InlineKeyboardButton(
176 | text="⍟ 𝙼𝙾𝚁𝙴 ⍟", callback_data=f"other {videoid}|{user_id}"
177 | ),
178 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close"),
179 | ],
180 | ]
181 | return buttons
182 |
183 |
184 | def secondary_markup2(videoid, user_id):
185 | buttons = [
186 | [
187 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
188 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
189 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
190 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
191 | ],
192 | [
193 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close"),
194 | ],
195 | ]
196 | return buttons
197 |
198 |
199 | def primary_markup(videoid, user_id, current_time, total_time):
200 | if videoid not in db_mem:
201 | db_mem[videoid] = {}
202 | db_mem[videoid]["check"] = 2
203 | buttons = [
204 | [
205 | InlineKeyboardButton(
206 | text=f"{total_time} ------------------ {current_time}",
207 | callback_data=f"timer_checkup_markup {videoid}|{user_id}",
208 | )
209 | ],
210 | [
211 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
212 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
213 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
214 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
215 | ],
216 | [
217 | InlineKeyboardButton(
218 | text="⍟ 𝙼𝙾𝚁𝙴 ⍟", callback_data=f"other {videoid}|{user_id}"
219 | ),
220 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close"),
221 | ],
222 | ]
223 | return buttons
224 |
225 |
226 | def timer_markup(videoid, user_id, current_time, total_time):
227 | buttons = [
228 | [
229 | InlineKeyboardButton(
230 | text=f"{total_time} ------------------ {current_time}",
231 | callback_data=f"timer_checkup_markup {videoid}|{user_id}",
232 | )
233 | ],
234 | [
235 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
236 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
237 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
238 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
239 | ],
240 | [
241 | InlineKeyboardButton(
242 | text="⍟ 𝙼𝙾𝚁𝙴 ⍟", callback_data=f"other {videoid}|{user_id}"
243 | ),
244 | InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close"),
245 | ],
246 | ]
247 | return buttons
248 |
249 |
250 | def audio_markup(videoid, user_id, current_time, total_time):
251 | if videoid not in db_mem:
252 | db_mem[videoid] = {}
253 | db_mem[videoid]["check"] = 2
254 | buttons = [
255 | [
256 | InlineKeyboardButton(
257 | text=f"{total_time} ------------------ {current_time}",
258 | callback_data=f"timer_checkup_markup {videoid}|{user_id}",
259 | )
260 | ],
261 | [
262 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
263 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
264 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
265 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
266 | ],
267 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close")],
268 | ]
269 | return buttons
270 |
271 |
272 | def audio_timer_markup_start(videoid, user_id, current_time, total_time):
273 | buttons = [
274 | [
275 | InlineKeyboardButton(
276 | text=f"{total_time} ------------------ {current_time}",
277 | callback_data=f"timer_checkup_markup {videoid}|{user_id}",
278 | )
279 | ],
280 | [
281 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
282 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
283 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
284 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
285 | ],
286 | [InlineKeyboardButton(text="⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data=f"close")],
287 | ]
288 | return buttons
289 |
290 |
291 | audio_markup2 = InlineKeyboardMarkup(
292 | [
293 | [
294 | InlineKeyboardButton(text="▶️", callback_data=f"resumecb"),
295 | InlineKeyboardButton(text="⏸️", callback_data=f"pausecb"),
296 | InlineKeyboardButton(text="⏭️", callback_data=f"skipcb"),
297 | InlineKeyboardButton(text="⏹️", callback_data=f"stopcb"),
298 | ],
299 | [InlineKeyboardButton("⍟ 𝙲𝙻𝙾𝚂𝙴 ⍟", callback_data="close")],
300 | ]
301 | )
302 |
--------------------------------------------------------------------------------
/Ayiin/Plugins/Voicechat.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | import shutil
4 | import subprocess
5 | from sys import version as pyver
6 |
7 | from pyrogram import Client, filters
8 | from pyrogram.types import (InlineKeyboardMarkup, InputMediaPhoto, Message,
9 | Voice)
10 |
11 | from config import get_queue
12 | from Ayiin import SUDOERS, app, db_mem, random_assistant
13 | from Ayiin.Database import (get_active_chats, get_active_video_chats,
14 | get_assistant, is_active_chat, save_assistant)
15 | from Ayiin.Decorators.checker import checker, checkerCB
16 | from Ayiin.Inline import primary_markup,choose_markup
17 | from Ayiin.Utilities.assistant import get_assistant_details
18 |
19 | loop = asyncio.get_event_loop()
20 |
21 | __MODULE__ = "Join/Leave"
22 | __HELP__ = """
23 |
24 | **Note:**
25 | Only for Sudo Users
26 |
27 |
28 | /joinassistant [Chat Username or Chat ID]
29 | - Join assistant to a group.
30 |
31 |
32 | /leaveassistant [Chat Username or Chat ID]
33 | - Assistant will leave the particular group.
34 |
35 |
36 | /leavebot [Chat Username or Chat ID]
37 | - Bot will leave the particular chat.
38 | """
39 |
40 | @app.on_callback_query(filters.regex("gback_list_chose_stream"))
41 | async def gback_list_chose_stream(_, CallbackQuery):
42 | await CallbackQuery.answer()
43 | callback_data = CallbackQuery.data.strip()
44 | callback_request = callback_data.split(None, 1)[1]
45 | videoid, duration, user_id = callback_request.split("|")
46 | if CallbackQuery.from_user.id != int(user_id):
47 | return await CallbackQuery.answer(
48 | "This is not for you! Search You Own Song.", show_alert=True
49 | )
50 | buttons = choose_markup(videoid, duration, user_id)
51 | await CallbackQuery.edit_message_reply_markup(
52 | reply_markup=InlineKeyboardMarkup(buttons)
53 | )
54 |
55 |
56 | @app.on_callback_query(filters.regex("pr_go_back_timer"))
57 | async def pr_go_back_timer(_, CallbackQuery):
58 | await CallbackQuery.answer()
59 | callback_data = CallbackQuery.data.strip()
60 | callback_request = callback_data.split(None, 1)[1]
61 | videoid, user_id = callback_request.split("|")
62 | if await is_active_chat(CallbackQuery.message.chat.id):
63 | if db_mem[CallbackQuery.message.chat.id]["videoid"] == videoid:
64 | dur_left = db_mem[CallbackQuery.message.chat.id]["left"]
65 | duration_min = db_mem[CallbackQuery.message.chat.id]["total"]
66 | buttons = primary_markup(videoid, user_id, dur_left, duration_min)
67 | await CallbackQuery.edit_message_reply_markup(
68 | reply_markup=InlineKeyboardMarkup(buttons)
69 | )
70 |
71 |
72 | @app.on_callback_query(filters.regex("timer_checkup_markup"))
73 | async def timer_checkup_markup(_, CallbackQuery):
74 | callback_data = CallbackQuery.data.strip()
75 | callback_request = callback_data.split(None, 1)[1]
76 | videoid, user_id = callback_request.split("|")
77 | if await is_active_chat(CallbackQuery.message.chat.id):
78 | if db_mem[CallbackQuery.message.chat.id]["videoid"] == videoid:
79 | dur_left = db_mem[CallbackQuery.message.chat.id]["left"]
80 | duration_min = db_mem[CallbackQuery.message.chat.id]["total"]
81 | return await CallbackQuery.answer(
82 | f"Remaining {dur_left} out of {duration_min} Mins.",
83 | show_alert=True,
84 | )
85 | return await CallbackQuery.answer(f"Not Playing.", show_alert=True)
86 | else:
87 | return await CallbackQuery.answer(
88 | f"No Active Voice Chat", show_alert=True
89 | )
90 |
91 |
92 | @app.on_message(filters.command("queue"))
93 | async def activevc(_, message: Message):
94 | global get_queue
95 | if await is_active_chat(message.chat.id):
96 | mystic = await message.reply_text("Please Wait... Getting Queue..")
97 | dur_left = db_mem[message.chat.id]["left"]
98 | duration_min = db_mem[message.chat.id]["total"]
99 | got_queue = get_queue.get(message.chat.id)
100 | if not got_queue:
101 | await mystic.edit(f"Nothing in Queue")
102 | fetched = []
103 | for get in got_queue:
104 | fetched.append(get)
105 |
106 | ### Results
107 | current_playing = fetched[0][0]
108 | user_name = fetched[0][1]
109 |
110 | msg = "**Queued List**\n\n"
111 | msg += "**Currently Playing:**"
112 | msg += "\n▶️" + current_playing[:30]
113 | msg += f"\n ╚By:- {user_name}"
114 | msg += f"\n ╚Duration:- Remaining `{dur_left}` out of `{duration_min}` Mins."
115 | fetched.pop(0)
116 | if fetched:
117 | msg += "\n\n"
118 | msg += "**Up Next In Queue:**"
119 | for song in fetched:
120 | name = song[0][:30]
121 | usr = song[1]
122 | dur = song[2]
123 | msg += f"\n⏸️{name}"
124 | msg += f"\n ╠Duration : {dur}"
125 | msg += f"\n ╚Requested by : {usr}\n"
126 | if len(msg) > 4096:
127 | await mystic.delete()
128 | filename = "queue.txt"
129 | with open(filename, "w+", encoding="utf8") as out_file:
130 | out_file.write(str(msg.strip()))
131 | await message.reply_document(
132 | document=filename,
133 | caption=f"**OUTPUT:**\n\n`Queued List`",
134 | quote=False,
135 | )
136 | os.remove(filename)
137 | else:
138 | await mystic.edit(msg)
139 | else:
140 | await message.reply_text(f"Nothing in Queue")
141 |
142 |
143 | @app.on_message(filters.command("activevc") & filters.user(SUDOERS))
144 | async def activevc(_, message: Message):
145 | served_chats = []
146 | try:
147 | chats = await get_active_chats()
148 | for chat in chats:
149 | served_chats.append(int(chat["chat_id"]))
150 | except Exception as e:
151 | await message.reply_text(f"**Error:-** {e}")
152 | text = ""
153 | j = 0
154 | for x in served_chats:
155 | try:
156 | title = (await app.get_chat(x)).title
157 | except Exception:
158 | title = "Private Group"
159 | if (await app.get_chat(x)).username:
160 | user = (await app.get_chat(x)).username
161 | text += (
162 | f"{j + 1}. [{title}](https://t.me/{user})[`{x}`]\n"
163 | )
164 | else:
165 | text += f"{j + 1}. {title} [`{x}`]\n"
166 | j += 1
167 | if not text:
168 | await message.reply_text("No Active Voice Chats")
169 | else:
170 | await message.reply_text(
171 | f"**Active Voice Chats:-**\n\n{text}",
172 | disable_web_page_preview=True,
173 | )
174 |
175 |
176 | @app.on_message(filters.command("activevideo") & filters.user(SUDOERS))
177 | async def activevi_(_, message: Message):
178 | served_chats = []
179 | try:
180 | chats = await get_active_video_chats()
181 | for chat in chats:
182 | served_chats.append(int(chat["chat_id"]))
183 | except Exception as e:
184 | await message.reply_text(f"**Error:-** {e}")
185 | text = ""
186 | j = 0
187 | for x in served_chats:
188 | try:
189 | title = (await app.get_chat(x)).title
190 | except Exception:
191 | title = "Private Group"
192 | if (await app.get_chat(x)).username:
193 | user = (await app.get_chat(x)).username
194 | text += (
195 | f"{j + 1}. [{title}](https://t.me/{user})[`{x}`]\n"
196 | )
197 | else:
198 | text += f"{j + 1}. {title} [`{x}`]\n"
199 | j += 1
200 | if not text:
201 | await message.reply_text("No Active Voice Chats")
202 | else:
203 | await message.reply_text(
204 | f"**Active Video Calls:-**\n\n{text}",
205 | disable_web_page_preview=True,
206 | )
207 |
208 |
209 | @app.on_message(filters.command("joinassistant") & filters.user(SUDOERS))
210 | async def basffy(_, message):
211 | if len(message.command) != 2:
212 | await message.reply_text(
213 | "**Usage:**\n/joinassistant [Chat Username or Chat ID]"
214 | )
215 | return
216 | chat = message.text.split(None, 2)[1]
217 | try:
218 | chat_id = (await app.get_chat(chat)).id
219 | except:
220 | return await message.reply_text(
221 | "Add Bot to this Chat First.. Unknown Chat for the bot"
222 | )
223 | _assistant = await get_assistant(chat_id, "assistant")
224 | if not _assistant:
225 | return await message.reply_text(
226 | "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play inside {Chat}'s Group"
227 | )
228 | else:
229 | ran_ass = _assistant["saveassistant"]
230 | ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details(
231 | ran_ass
232 | )
233 | try:
234 | await ASS_ACC.join_chat(chat_id)
235 | except Exception as e:
236 | await message.reply_text(f"Failed\n**Possible reason could be**:{e}")
237 | return
238 | await message.reply_text("Joined.")
239 |
240 |
241 | @app.on_message(filters.command("leavebot") & filters.user(SUDOERS))
242 | async def baaaf(_, message):
243 | if len(message.command) != 2:
244 | await message.reply_text(
245 | "**Usage:**\n/leavebot [Chat Username or Chat ID]"
246 | )
247 | return
248 | chat = message.text.split(None, 2)[1]
249 | try:
250 | await app.leave_chat(chat)
251 | except Exception as e:
252 | await message.reply_text(f"Failed\n**Possible reason could be**:{e}")
253 | print(e)
254 | return
255 | await message.reply_text("Bot has left the chat successfully")
256 |
257 |
258 | @app.on_message(filters.command("leaveassistant") & filters.user(SUDOERS))
259 | async def baujaf(_, message):
260 | if len(message.command) != 2:
261 | await message.reply_text(
262 | "**Usage:**\n/leave [Chat Username or Chat ID]"
263 | )
264 | return
265 | chat = message.text.split(None, 2)[1]
266 | try:
267 | chat_id = (await app.get_chat(chat)).id
268 | except:
269 | return await message.reply_text(
270 | "Add Bot to this Chat First.. Unknown Chat for the bot"
271 | )
272 | _assistant = await get_assistant(chat, "assistant")
273 | if not _assistant:
274 | return await message.reply_text(
275 | "No Pre-Saved Assistant Found.\n\nYou can set Assistant Via /play inside {Chat}'s Group"
276 | )
277 | else:
278 | ran_ass = _assistant["saveassistant"]
279 | ASS_ID, ASS_NAME, ASS_USERNAME, ASS_ACC = await get_assistant_details(
280 | ran_ass
281 | )
282 | try:
283 | await ASS_ACC.leave_chat(chat_id)
284 | except Exception as e:
285 | await message.reply_text(f"Failed\n**Possible reason could be**:{e}")
286 | return
287 | await message.reply_text("Left.")
288 |
--------------------------------------------------------------------------------