taslim19
commited on
Commit
·
80287e2
1
Parent(s):
f5c5d5b
Initial commit
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .dockerignore +10 -0
- .github/readme.md +1 -0
- .github/workflows/build.yml +11 -0
- .github/workflows/main.yml +47 -0
- .github/workflows/youtube_download.yml +27 -0
- .gitignore +11 -0
- .nixpacks.yml +4 -0
- Devine/__init__.py +24 -0
- Devine/__main__.py +74 -0
- Devine/core/bot.py +57 -0
- Devine/core/call.py +601 -0
- Devine/core/dir.py +20 -0
- Devine/core/git.py +80 -0
- Devine/core/mongo.py +14 -0
- Devine/core/userbot.py +170 -0
- Devine/logging.py +19 -0
- Devine/misc.py +75 -0
- Devine/modules/fonts.py +188 -0
- Devine/mongo/afkdb.py +32 -0
- Devine/mongo/readable_time.py +23 -0
- Devine/platforms/Apple.py +71 -0
- Devine/platforms/Carbon.py +106 -0
- Devine/platforms/Resso.py +54 -0
- Devine/platforms/Soundcloud.py +39 -0
- Devine/platforms/Spotify.py +98 -0
- Devine/platforms/Telegram.py +176 -0
- Devine/platforms/Youtube.py +407 -0
- Devine/platforms/__init__.py +7 -0
- Devine/plugins/Dev/fonts.py +196 -0
- Devine/plugins/Dev/groupdata.py +53 -0
- Devine/plugins/Dev/groupinfo.py +50 -0
- Devine/plugins/Dev/password.py +46 -0
- Devine/plugins/Dev/sangmeta.py +56 -0
- Devine/plugins/Dev/truth_and_dare.py +17 -0
- Devine/plugins/Dev/upload.py +79 -0
- Devine/plugins/Dev/write.py +24 -0
- Devine/plugins/__init__.py +19 -0
- Devine/plugins/admins/auth.py +89 -0
- Devine/plugins/admins/callback.py +397 -0
- Devine/plugins/admins/loop.py +46 -0
- Devine/plugins/admins/pause.py +21 -0
- Devine/plugins/admins/resume.py +21 -0
- Devine/plugins/admins/seek.py +75 -0
- Devine/plugins/admins/shuffle.py +33 -0
- Devine/plugins/admins/skip.py +232 -0
- Devine/plugins/admins/speed.py +112 -0
- Devine/plugins/admins/stop.py +23 -0
- Devine/plugins/bot/help.py +90 -0
- Devine/plugins/bot/inline.py +68 -0
- Devine/plugins/bot/settings.py +391 -0
.dockerignore
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.env
|
2 |
+
.cache
|
3 |
+
log.txt
|
4 |
+
.DS_Store
|
5 |
+
*.session
|
6 |
+
raw_files/
|
7 |
+
cache/
|
8 |
+
downloads/
|
9 |
+
__pycache__/
|
10 |
+
*.session-journal
|
.github/readme.md
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
.
|
.github/workflows/build.yml
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jobs:
|
2 |
+
build:
|
3 |
+
runs-on: ubuntu-latest
|
4 |
+
env:
|
5 |
+
GIT_PYTHON_REFRESH: 'quiet'
|
6 |
+
steps:
|
7 |
+
- name: Checkout code
|
8 |
+
uses: actions/checkout@v2
|
9 |
+
- name: Run your script
|
10 |
+
run: |
|
11 |
+
# Your commands here
|
.github/workflows/main.yml
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: CI
|
2 |
+
|
3 |
+
on: [push]
|
4 |
+
|
5 |
+
jobs:
|
6 |
+
build:
|
7 |
+
runs-on: ubuntu-latest
|
8 |
+
|
9 |
+
steps:
|
10 |
+
- name: Checkout code
|
11 |
+
uses: actions/checkout@v3
|
12 |
+
|
13 |
+
- name: Install Git
|
14 |
+
run: sudo apt-get install -y git
|
15 |
+
|
16 |
+
- name: Install Heroku CLI
|
17 |
+
run: |
|
18 |
+
curl https://cli-assets.heroku.com/install.sh | sh
|
19 |
+
heroku --version
|
20 |
+
|
21 |
+
- name: Setup Git for Heroku Deployment
|
22 |
+
run: |
|
23 |
+
git config --global user.name "devineparadox"
|
24 |
+
git config --global user.email "[email protected]"
|
25 |
+
|
26 |
+
- name: Pull latest changes
|
27 |
+
run: |
|
28 |
+
git pull origin main
|
29 |
+
|
30 |
+
- name: Commit changes
|
31 |
+
run: |
|
32 |
+
git add .
|
33 |
+
git commit -m "Automated commit for redeployment" || echo "No changes to commit"
|
34 |
+
|
35 |
+
- name: Push changes to Heroku
|
36 |
+
env:
|
37 |
+
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
|
38 |
+
run: |
|
39 |
+
git push heroku main
|
40 |
+
|
41 |
+
- name: Restart Heroku app
|
42 |
+
run: |
|
43 |
+
heroku restart --app ${{ secrets.HEROKU_APP_NAME }}
|
44 |
+
|
45 |
+
- name: Verify deployment
|
46 |
+
run: |
|
47 |
+
heroku logs --tail --app ${{ secrets.HEROKU_APP_NAME }}
|
.github/workflows/youtube_download.yml
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: YouTube Download
|
2 |
+
|
3 |
+
on:
|
4 |
+
workflow_dispatch:
|
5 |
+
push:
|
6 |
+
branches:
|
7 |
+
- main
|
8 |
+
|
9 |
+
jobs:
|
10 |
+
download:
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
|
13 |
+
steps:
|
14 |
+
- name: Checkout code
|
15 |
+
uses: actions/checkout@v3
|
16 |
+
|
17 |
+
- name: Install yt-dlp
|
18 |
+
run: |
|
19 |
+
sudo pip install yt-dlp
|
20 |
+
|
21 |
+
- name: Create cookies.txt from secret
|
22 |
+
run: |
|
23 |
+
echo "${{ secrets.COOKIES }}" > cookies.txt
|
24 |
+
|
25 |
+
- name: Download YouTube Video
|
26 |
+
run: |
|
27 |
+
yt-dlp --cookies cookies.txt "https://www.youtube.com/watch?v=zzwRbKI2pn4"
|
.gitignore
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.env
|
2 |
+
.cache
|
3 |
+
log.txt
|
4 |
+
.DS_Store
|
5 |
+
*.session
|
6 |
+
raw_files/
|
7 |
+
cache/
|
8 |
+
downloads/
|
9 |
+
__pycache__/
|
10 |
+
*.session-journal
|
11 |
+
|
.nixpacks.yml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: '1'
|
2 |
+
language: node
|
3 |
+
nodejs:
|
4 |
+
version: 16
|
Devine/__init__.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from Devine.core.bot import Anony
|
2 |
+
from Devine.core.dir import dirr
|
3 |
+
from Devine.core.userbot import Userbot
|
4 |
+
from Devine.misc import dbb, heroku
|
5 |
+
|
6 |
+
from .logging import LOGGER
|
7 |
+
|
8 |
+
dirr()
|
9 |
+
dbb()
|
10 |
+
heroku()
|
11 |
+
|
12 |
+
app = Anony()
|
13 |
+
userbot = Userbot()
|
14 |
+
|
15 |
+
|
16 |
+
from .platforms import *
|
17 |
+
|
18 |
+
Apple = AppleAPI()
|
19 |
+
Carbon = CarbonAPI()
|
20 |
+
SoundCloud = SoundAPI()
|
21 |
+
Spotify = SpotifyAPI()
|
22 |
+
Resso = RessoAPI()
|
23 |
+
Telegram = TeleAPI()
|
24 |
+
YouTube = YouTubeAPI()
|
Devine/__main__.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import importlib
|
3 |
+
|
4 |
+
from pyrogram import idle
|
5 |
+
from pytgcalls.exceptions import NoActiveGroupCall
|
6 |
+
|
7 |
+
import config
|
8 |
+
from Devine import LOGGER, app, userbot
|
9 |
+
from Devine.core.call import Anony
|
10 |
+
from Devine.misc import sudo
|
11 |
+
from Devine.plugins import ALL_MODULES
|
12 |
+
from Devine.utils.database import get_banned_users, get_gbanned
|
13 |
+
from config import BANNED_USERS
|
14 |
+
|
15 |
+
# Import redeploy command (relative import, considering the repo structure)
|
16 |
+
import sys
|
17 |
+
sys.path.append("..") # Add the parent directory to the Python path
|
18 |
+
from redeploy import redeploy # Now the redeploy.py can be imported
|
19 |
+
|
20 |
+
async def init():
|
21 |
+
if (
|
22 |
+
not config.STRING1
|
23 |
+
and not config.STRING2
|
24 |
+
and not config.STRING3
|
25 |
+
and not config.STRING4
|
26 |
+
and not config.STRING5
|
27 |
+
):
|
28 |
+
LOGGER(__name__).error("Assistant client variables not defined, exiting...")
|
29 |
+
return # Changed from exit() to return
|
30 |
+
await sudo()
|
31 |
+
try:
|
32 |
+
users = await get_gbanned()
|
33 |
+
for user_id in users:
|
34 |
+
BANNED_USERS.add(user_id)
|
35 |
+
users = await get_banned_users()
|
36 |
+
for user_id in users:
|
37 |
+
BANNED_USERS.add(user_id)
|
38 |
+
except Exception as e:
|
39 |
+
LOGGER(__name__).error(f"Error fetching banned users: {e}")
|
40 |
+
await app.start()
|
41 |
+
for all_module in ALL_MODULES:
|
42 |
+
importlib.import_module("Devine.plugins" + all_module)
|
43 |
+
LOGGER("Devine.plugins").info("Successfully Imported Modules...")
|
44 |
+
await userbot.start()
|
45 |
+
await Anony.start()
|
46 |
+
try:
|
47 |
+
await Anony.stream_call("https://telegra.ph//file/1df0320b93c2f3353c3e6.mp4")
|
48 |
+
except NoActiveGroupCall:
|
49 |
+
LOGGER("Devine").error(
|
50 |
+
"Please turn on the video chat of your log group/channel.\n\nStopping Bot..."
|
51 |
+
)
|
52 |
+
return # Changed from exit() to return
|
53 |
+
except Exception as e:
|
54 |
+
LOGGER("Devine").error(f"Error in streaming call: {e}")
|
55 |
+
await Anony.decorators()
|
56 |
+
LOGGER("Devine").info(
|
57 |
+
"Powered by @Devine_network."
|
58 |
+
)
|
59 |
+
await idle() # Keeps the bot running
|
60 |
+
await shutdown() # Proper shutdown sequence
|
61 |
+
|
62 |
+
|
63 |
+
async def shutdown():
|
64 |
+
LOGGER("Devine").info("Shutting down gracefully...")
|
65 |
+
try:
|
66 |
+
await app.stop()
|
67 |
+
await userbot.stop()
|
68 |
+
LOGGER("Devine").info("Stopping AnonX Music Bot...")
|
69 |
+
except Exception as e:
|
70 |
+
LOGGER("Devine").error(f"Error during shutdown: {e}")
|
71 |
+
|
72 |
+
|
73 |
+
if __name__ == "__main__":
|
74 |
+
asyncio.get_event_loop().run_until_complete(init())
|
Devine/core/bot.py
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import Client, errors
|
2 |
+
from pyrogram.enums import ChatMemberStatus, ParseMode
|
3 |
+
|
4 |
+
import config
|
5 |
+
|
6 |
+
from ..logging import LOGGER
|
7 |
+
|
8 |
+
|
9 |
+
class Anony(Client):
|
10 |
+
def __init__(self):
|
11 |
+
LOGGER(__name__).info(f"Starting Bot...")
|
12 |
+
super().__init__(
|
13 |
+
name="Devine",
|
14 |
+
api_id=config.API_ID,
|
15 |
+
api_hash=config.API_HASH,
|
16 |
+
bot_token=config.BOT_TOKEN,
|
17 |
+
in_memory=True,
|
18 |
+
parse_mode=ParseMode.HTML,
|
19 |
+
max_concurrent_transmissions=7,
|
20 |
+
)
|
21 |
+
|
22 |
+
async def start(self):
|
23 |
+
await super().start()
|
24 |
+
self.id = self.me.id
|
25 |
+
self.name = self.me.first_name + " " + (self.me.last_name or "")
|
26 |
+
self.username = self.me.username
|
27 |
+
self.mention = self.me.mention
|
28 |
+
|
29 |
+
try:
|
30 |
+
await self.send_message(
|
31 |
+
chat_id=config.LOGGER_ID,
|
32 |
+
text=f"<b>{self.mention} ɪs ᴀʟɪᴠᴇ <a href='https://telegra.ph//file/db4ac98cf05117a23561c.jpg' target='_blank'>🫧</a></b>\n\n"
|
33 |
+
f"<b>• ʙᴏᴛ ᴠᴇʀsɪᴏɴ ⌯</b> <code>𝟸.𝟷 ʀx</code>\n"
|
34 |
+
f"<b>• ᴘʏᴛʜᴏɴ ᴠᴇʀsɪᴏɴ ⌯</b> <code>𝟹.𝟷𝟶.𝟷𝟷</code>\n"
|
35 |
+
f"<b>• ᴘʏʀᴏɢʀᴀᴍ ᴠᴇʀsɪᴏɴ ⌯</b> <code>𝟸.𝟶.𝟷𝟶𝟼</code>"
|
36 |
+
)
|
37 |
+
except (errors.ChannelInvalid, errors.PeerIdInvalid):
|
38 |
+
LOGGER(__name__).error(
|
39 |
+
"Bot has failed to access the log channel. Make sure that you have added your bot to your log group/channel."
|
40 |
+
)
|
41 |
+
exit()
|
42 |
+
except Exception as ex:
|
43 |
+
LOGGER(__name__).error(
|
44 |
+
f"Bot has failed to access the log group/channel.\n Reason : {type(ex).__name__}."
|
45 |
+
)
|
46 |
+
exit()
|
47 |
+
|
48 |
+
a = await self.get_chat_member(config.LOGGER_ID, self.id)
|
49 |
+
if a.status != ChatMemberStatus.ADMINISTRATOR:
|
50 |
+
LOGGER(__name__).error(
|
51 |
+
"Please promote your bot as an admin in your log group/channel."
|
52 |
+
)
|
53 |
+
exit()
|
54 |
+
LOGGER(__name__).info(f"Bot Started as {self.name}")
|
55 |
+
|
56 |
+
async def stop(self):
|
57 |
+
await super().stop()
|
Devine/core/call.py
ADDED
@@ -0,0 +1,601 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import os
|
3 |
+
from datetime import datetime, timedelta
|
4 |
+
from typing import Union
|
5 |
+
|
6 |
+
from pyrogram import Client
|
7 |
+
from pyrogram.types import InlineKeyboardMarkup
|
8 |
+
from pytgcalls import PyTgCalls, StreamType
|
9 |
+
from pytgcalls.exceptions import (
|
10 |
+
AlreadyJoinedError,
|
11 |
+
NoActiveGroupCall,
|
12 |
+
TelegramServerError,
|
13 |
+
)
|
14 |
+
from pytgcalls.types import Update
|
15 |
+
from pytgcalls.types.input_stream import AudioPiped, AudioVideoPiped
|
16 |
+
from pytgcalls.types.input_stream.quality import HighQualityAudio, MediumQualityVideo
|
17 |
+
from pytgcalls.types.stream import StreamAudioEnded
|
18 |
+
|
19 |
+
import config
|
20 |
+
from Devine import LOGGER, YouTube, app
|
21 |
+
from Devine.misc import db
|
22 |
+
from Devine.utils.database import (
|
23 |
+
add_active_chat,
|
24 |
+
add_active_video_chat,
|
25 |
+
get_lang,
|
26 |
+
get_loop,
|
27 |
+
group_assistant,
|
28 |
+
is_autoend,
|
29 |
+
music_on,
|
30 |
+
remove_active_chat,
|
31 |
+
remove_active_video_chat,
|
32 |
+
set_loop,
|
33 |
+
)
|
34 |
+
from Devine.utils.exceptions import AssistantErr
|
35 |
+
from Devine.utils.formatters import check_duration, seconds_to_min, speed_converter
|
36 |
+
from Devine.utils.inline.play import stream_markup
|
37 |
+
from Devine.utils.stream.autoclear import auto_clean
|
38 |
+
from Devine.utils.thumbnails import get_thumb
|
39 |
+
from strings import get_string
|
40 |
+
|
41 |
+
autoend = {}
|
42 |
+
counter = {}
|
43 |
+
|
44 |
+
|
45 |
+
async def _clear_(chat_id):
|
46 |
+
db[chat_id] = []
|
47 |
+
await remove_active_video_chat(chat_id)
|
48 |
+
await remove_active_chat(chat_id)
|
49 |
+
|
50 |
+
|
51 |
+
class Call(PyTgCalls):
|
52 |
+
def __init__(self):
|
53 |
+
self.userbot1 = Client(
|
54 |
+
name="Devine1",
|
55 |
+
api_id=config.API_ID,
|
56 |
+
api_hash=config.API_HASH,
|
57 |
+
session_string=str(config.STRING1),
|
58 |
+
)
|
59 |
+
self.one = PyTgCalls(
|
60 |
+
self.userbot1,
|
61 |
+
cache_duration=100,
|
62 |
+
)
|
63 |
+
self.userbot2 = Client(
|
64 |
+
name="Devine2",
|
65 |
+
api_id=config.API_ID,
|
66 |
+
api_hash=config.API_HASH,
|
67 |
+
session_string=str(config.STRING2),
|
68 |
+
)
|
69 |
+
self.two = PyTgCalls(
|
70 |
+
self.userbot2,
|
71 |
+
cache_duration=100,
|
72 |
+
)
|
73 |
+
self.userbot3 = Client(
|
74 |
+
name="Devine3",
|
75 |
+
api_id=config.API_ID,
|
76 |
+
api_hash=config.API_HASH,
|
77 |
+
session_string=str(config.STRING3),
|
78 |
+
)
|
79 |
+
self.three = PyTgCalls(
|
80 |
+
self.userbot3,
|
81 |
+
cache_duration=100,
|
82 |
+
)
|
83 |
+
self.userbot4 = Client(
|
84 |
+
name="Devine5",
|
85 |
+
api_id=config.API_ID,
|
86 |
+
api_hash=config.API_HASH,
|
87 |
+
session_string=str(config.STRING4),
|
88 |
+
)
|
89 |
+
self.four = PyTgCalls(
|
90 |
+
self.userbot4,
|
91 |
+
cache_duration=100,
|
92 |
+
)
|
93 |
+
self.userbot5 = Client(
|
94 |
+
name="Devine5",
|
95 |
+
api_id=config.API_ID,
|
96 |
+
api_hash=config.API_HASH,
|
97 |
+
session_string=str(config.STRING5),
|
98 |
+
)
|
99 |
+
self.five = PyTgCalls(
|
100 |
+
self.userbot5,
|
101 |
+
cache_duration=100,
|
102 |
+
)
|
103 |
+
|
104 |
+
async def pause_stream(self, chat_id: int):
|
105 |
+
assistant = await group_assistant(self, chat_id)
|
106 |
+
await assistant.pause_stream(chat_id)
|
107 |
+
|
108 |
+
async def resume_stream(self, chat_id: int):
|
109 |
+
assistant = await group_assistant(self, chat_id)
|
110 |
+
await assistant.resume_stream(chat_id)
|
111 |
+
|
112 |
+
async def stop_stream(self, chat_id: int):
|
113 |
+
assistant = await group_assistant(self, chat_id)
|
114 |
+
try:
|
115 |
+
await _clear_(chat_id)
|
116 |
+
await assistant.leave_group_call(chat_id)
|
117 |
+
except:
|
118 |
+
pass
|
119 |
+
|
120 |
+
async def stop_stream_force(self, chat_id: int):
|
121 |
+
try:
|
122 |
+
if config.STRING1:
|
123 |
+
await self.one.leave_group_call(chat_id)
|
124 |
+
except:
|
125 |
+
pass
|
126 |
+
try:
|
127 |
+
if config.STRING2:
|
128 |
+
await self.two.leave_group_call(chat_id)
|
129 |
+
except:
|
130 |
+
pass
|
131 |
+
try:
|
132 |
+
if config.STRING3:
|
133 |
+
await self.three.leave_group_call(chat_id)
|
134 |
+
except:
|
135 |
+
pass
|
136 |
+
try:
|
137 |
+
if config.STRING4:
|
138 |
+
await self.four.leave_group_call(chat_id)
|
139 |
+
except:
|
140 |
+
pass
|
141 |
+
try:
|
142 |
+
if config.STRING5:
|
143 |
+
await self.five.leave_group_call(chat_id)
|
144 |
+
except:
|
145 |
+
pass
|
146 |
+
try:
|
147 |
+
await _clear_(chat_id)
|
148 |
+
except:
|
149 |
+
pass
|
150 |
+
|
151 |
+
async def speedup_stream(self, chat_id: int, file_path, speed, playing):
|
152 |
+
assistant = await group_assistant(self, chat_id)
|
153 |
+
if str(speed) != str("1.0"):
|
154 |
+
base = os.path.basename(file_path)
|
155 |
+
chatdir = os.path.join(os.getcwd(), "playback", str(speed))
|
156 |
+
if not os.path.isdir(chatdir):
|
157 |
+
os.makedirs(chatdir)
|
158 |
+
out = os.path.join(chatdir, base)
|
159 |
+
if not os.path.isfile(out):
|
160 |
+
if str(speed) == str("0.5"):
|
161 |
+
vs = 2.0
|
162 |
+
if str(speed) == str("0.75"):
|
163 |
+
vs = 1.35
|
164 |
+
if str(speed) == str("1.5"):
|
165 |
+
vs = 0.68
|
166 |
+
if str(speed) == str("2.0"):
|
167 |
+
vs = 0.5
|
168 |
+
proc = await asyncio.create_subprocess_shell(
|
169 |
+
cmd=(
|
170 |
+
"ffmpeg "
|
171 |
+
"-i "
|
172 |
+
f"{file_path} "
|
173 |
+
"-filter:v "
|
174 |
+
f"setpts={vs}*PTS "
|
175 |
+
"-filter:a "
|
176 |
+
f"atempo={speed} "
|
177 |
+
f"{out}"
|
178 |
+
),
|
179 |
+
stdin=asyncio.subprocess.PIPE,
|
180 |
+
stderr=asyncio.subprocess.PIPE,
|
181 |
+
)
|
182 |
+
await proc.communicate()
|
183 |
+
else:
|
184 |
+
pass
|
185 |
+
else:
|
186 |
+
out = file_path
|
187 |
+
dur = await asyncio.get_event_loop().run_in_executor(None, check_duration, out)
|
188 |
+
dur = int(dur)
|
189 |
+
played, con_seconds = speed_converter(playing[0]["played"], speed)
|
190 |
+
duration = seconds_to_min(dur)
|
191 |
+
stream = (
|
192 |
+
AudioVideoPiped(
|
193 |
+
out,
|
194 |
+
audio_parameters=HighQualityAudio(),
|
195 |
+
video_parameters=MediumQualityVideo(),
|
196 |
+
additional_ffmpeg_parameters=f"-ss {played} -to {duration}",
|
197 |
+
)
|
198 |
+
if playing[0]["streamtype"] == "video"
|
199 |
+
else AudioPiped(
|
200 |
+
out,
|
201 |
+
audio_parameters=HighQualityAudio(),
|
202 |
+
additional_ffmpeg_parameters=f"-ss {played} -to {duration}",
|
203 |
+
)
|
204 |
+
)
|
205 |
+
if str(db[chat_id][0]["file"]) == str(file_path):
|
206 |
+
await assistant.change_stream(chat_id, stream)
|
207 |
+
else:
|
208 |
+
raise AssistantErr("Umm")
|
209 |
+
if str(db[chat_id][0]["file"]) == str(file_path):
|
210 |
+
exis = (playing[0]).get("old_dur")
|
211 |
+
if not exis:
|
212 |
+
db[chat_id][0]["old_dur"] = db[chat_id][0]["dur"]
|
213 |
+
db[chat_id][0]["old_second"] = db[chat_id][0]["seconds"]
|
214 |
+
db[chat_id][0]["played"] = con_seconds
|
215 |
+
db[chat_id][0]["dur"] = duration
|
216 |
+
db[chat_id][0]["seconds"] = dur
|
217 |
+
db[chat_id][0]["speed_path"] = out
|
218 |
+
db[chat_id][0]["speed"] = speed
|
219 |
+
|
220 |
+
async def force_stop_stream(self, chat_id: int):
|
221 |
+
assistant = await group_assistant(self, chat_id)
|
222 |
+
try:
|
223 |
+
check = db.get(chat_id)
|
224 |
+
check.pop(0)
|
225 |
+
except:
|
226 |
+
pass
|
227 |
+
await remove_active_video_chat(chat_id)
|
228 |
+
await remove_active_chat(chat_id)
|
229 |
+
try:
|
230 |
+
await assistant.leave_group_call(chat_id)
|
231 |
+
except:
|
232 |
+
pass
|
233 |
+
|
234 |
+
async def skip_stream(
|
235 |
+
self,
|
236 |
+
chat_id: int,
|
237 |
+
link: str,
|
238 |
+
video: Union[bool, str] = None,
|
239 |
+
image: Union[bool, str] = None,
|
240 |
+
):
|
241 |
+
assistant = await group_assistant(self, chat_id)
|
242 |
+
if video:
|
243 |
+
stream = AudioVideoPiped(
|
244 |
+
link,
|
245 |
+
audio_parameters=HighQualityAudio(),
|
246 |
+
video_parameters=MediumQualityVideo(),
|
247 |
+
)
|
248 |
+
else:
|
249 |
+
stream = AudioPiped(link, audio_parameters=HighQualityAudio())
|
250 |
+
await assistant.change_stream(
|
251 |
+
chat_id,
|
252 |
+
stream,
|
253 |
+
)
|
254 |
+
|
255 |
+
async def seek_stream(self, chat_id, file_path, to_seek, duration, mode):
|
256 |
+
assistant = await group_assistant(self, chat_id)
|
257 |
+
stream = (
|
258 |
+
AudioVideoPiped(
|
259 |
+
file_path,
|
260 |
+
audio_parameters=HighQualityAudio(),
|
261 |
+
video_parameters=MediumQualityVideo(),
|
262 |
+
additional_ffmpeg_parameters=f"-ss {to_seek} -to {duration}",
|
263 |
+
)
|
264 |
+
if mode == "video"
|
265 |
+
else AudioPiped(
|
266 |
+
file_path,
|
267 |
+
audio_parameters=HighQualityAudio(),
|
268 |
+
additional_ffmpeg_parameters=f"-ss {to_seek} -to {duration}",
|
269 |
+
)
|
270 |
+
)
|
271 |
+
await assistant.change_stream(chat_id, stream)
|
272 |
+
|
273 |
+
async def stream_call(self, link):
|
274 |
+
assistant = await group_assistant(self, config.LOGGER_ID)
|
275 |
+
await assistant.join_group_call(
|
276 |
+
config.LOGGER_ID,
|
277 |
+
AudioVideoPiped(link),
|
278 |
+
stream_type=StreamType().pulse_stream,
|
279 |
+
)
|
280 |
+
await asyncio.sleep(0.2)
|
281 |
+
await assistant.leave_group_call(config.LOGGER_ID)
|
282 |
+
|
283 |
+
async def join_call(
|
284 |
+
self,
|
285 |
+
chat_id: int,
|
286 |
+
original_chat_id: int,
|
287 |
+
link,
|
288 |
+
video: Union[bool, str] = None,
|
289 |
+
image: Union[bool, str] = None,
|
290 |
+
):
|
291 |
+
assistant = await group_assistant(self, chat_id)
|
292 |
+
language = await get_lang(chat_id)
|
293 |
+
_ = get_string(language)
|
294 |
+
if video:
|
295 |
+
stream = AudioVideoPiped(
|
296 |
+
link,
|
297 |
+
audio_parameters=HighQualityAudio(),
|
298 |
+
video_parameters=MediumQualityVideo(),
|
299 |
+
)
|
300 |
+
else:
|
301 |
+
stream = (
|
302 |
+
AudioVideoPiped(
|
303 |
+
link,
|
304 |
+
audio_parameters=HighQualityAudio(),
|
305 |
+
video_parameters=MediumQualityVideo(),
|
306 |
+
)
|
307 |
+
if video
|
308 |
+
else AudioPiped(link, audio_parameters=HighQualityAudio())
|
309 |
+
)
|
310 |
+
try:
|
311 |
+
await assistant.join_group_call(
|
312 |
+
chat_id,
|
313 |
+
stream,
|
314 |
+
stream_type=StreamType().pulse_stream,
|
315 |
+
)
|
316 |
+
except NoActiveGroupCall:
|
317 |
+
raise AssistantErr(_["call_8"])
|
318 |
+
except AlreadyJoinedError:
|
319 |
+
raise AssistantErr(_["call_9"])
|
320 |
+
except TelegramServerError:
|
321 |
+
raise AssistantErr(_["call_10"])
|
322 |
+
await add_active_chat(chat_id)
|
323 |
+
await music_on(chat_id)
|
324 |
+
if video:
|
325 |
+
await add_active_video_chat(chat_id)
|
326 |
+
if await is_autoend():
|
327 |
+
counter[chat_id] = {}
|
328 |
+
users = len(await assistant.get_participants(chat_id))
|
329 |
+
if users == 1:
|
330 |
+
autoend[chat_id] = datetime.now() + timedelta(minutes=1)
|
331 |
+
|
332 |
+
async def change_stream(self, client, chat_id):
|
333 |
+
check = db.get(chat_id)
|
334 |
+
popped = None
|
335 |
+
loop = await get_loop(chat_id)
|
336 |
+
try:
|
337 |
+
if loop == 0:
|
338 |
+
popped = check.pop(0)
|
339 |
+
else:
|
340 |
+
loop = loop - 1
|
341 |
+
await set_loop(chat_id, loop)
|
342 |
+
await auto_clean(popped)
|
343 |
+
if not check:
|
344 |
+
await _clear_(chat_id)
|
345 |
+
return await client.leave_group_call(chat_id)
|
346 |
+
except:
|
347 |
+
try:
|
348 |
+
await _clear_(chat_id)
|
349 |
+
return await client.leave_group_call(chat_id)
|
350 |
+
except:
|
351 |
+
return
|
352 |
+
else:
|
353 |
+
queued = check[0]["file"]
|
354 |
+
language = await get_lang(chat_id)
|
355 |
+
_ = get_string(language)
|
356 |
+
title = (check[0]["title"]).title()
|
357 |
+
user = check[0]["by"]
|
358 |
+
original_chat_id = check[0]["chat_id"]
|
359 |
+
streamtype = check[0]["streamtype"]
|
360 |
+
videoid = check[0]["vidid"]
|
361 |
+
db[chat_id][0]["played"] = 0
|
362 |
+
exis = (check[0]).get("old_dur")
|
363 |
+
if exis:
|
364 |
+
db[chat_id][0]["dur"] = exis
|
365 |
+
db[chat_id][0]["seconds"] = check[0]["old_second"]
|
366 |
+
db[chat_id][0]["speed_path"] = None
|
367 |
+
db[chat_id][0]["speed"] = 1.0
|
368 |
+
video = True if str(streamtype) == "video" else False
|
369 |
+
if "live_" in queued:
|
370 |
+
n, link = await YouTube.video(videoid, True)
|
371 |
+
if n == 0:
|
372 |
+
return await app.send_message(
|
373 |
+
original_chat_id,
|
374 |
+
text=_["call_6"],
|
375 |
+
)
|
376 |
+
if video:
|
377 |
+
stream = AudioVideoPiped(
|
378 |
+
link,
|
379 |
+
audio_parameters=HighQualityAudio(),
|
380 |
+
video_parameters=MediumQualityVideo(),
|
381 |
+
)
|
382 |
+
else:
|
383 |
+
stream = AudioPiped(
|
384 |
+
link,
|
385 |
+
audio_parameters=HighQualityAudio(),
|
386 |
+
)
|
387 |
+
try:
|
388 |
+
await client.change_stream(chat_id, stream)
|
389 |
+
except Exception:
|
390 |
+
return await app.send_message(
|
391 |
+
original_chat_id,
|
392 |
+
text=_["call_6"],
|
393 |
+
)
|
394 |
+
img = await get_thumb(videoid)
|
395 |
+
button = stream_markup(_, chat_id)
|
396 |
+
run = await app.send_photo(
|
397 |
+
chat_id=original_chat_id,
|
398 |
+
photo=img,
|
399 |
+
caption=_["stream_1"].format(
|
400 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
401 |
+
title[:23],
|
402 |
+
check[0]["dur"],
|
403 |
+
user,
|
404 |
+
),
|
405 |
+
reply_markup=InlineKeyboardMarkup(button),
|
406 |
+
)
|
407 |
+
db[chat_id][0]["mystic"] = run
|
408 |
+
db[chat_id][0]["markup"] = "tg"
|
409 |
+
elif "vid_" in queued:
|
410 |
+
mystic = await app.send_message(original_chat_id, _["call_7"])
|
411 |
+
try:
|
412 |
+
file_path, direct = await YouTube.download(
|
413 |
+
videoid,
|
414 |
+
mystic,
|
415 |
+
videoid=True,
|
416 |
+
video=True if str(streamtype) == "video" else False,
|
417 |
+
)
|
418 |
+
except:
|
419 |
+
return await mystic.edit_text(
|
420 |
+
_["call_6"], disable_web_page_preview=True
|
421 |
+
)
|
422 |
+
if video:
|
423 |
+
stream = AudioVideoPiped(
|
424 |
+
file_path,
|
425 |
+
audio_parameters=HighQualityAudio(),
|
426 |
+
video_parameters=MediumQualityVideo(),
|
427 |
+
)
|
428 |
+
else:
|
429 |
+
stream = AudioPiped(
|
430 |
+
file_path,
|
431 |
+
audio_parameters=HighQualityAudio(),
|
432 |
+
)
|
433 |
+
try:
|
434 |
+
await client.change_stream(chat_id, stream)
|
435 |
+
except:
|
436 |
+
return await app.send_message(
|
437 |
+
original_chat_id,
|
438 |
+
text=_["call_6"],
|
439 |
+
)
|
440 |
+
img = await get_thumb(videoid)
|
441 |
+
button = stream_markup(_, chat_id)
|
442 |
+
await mystic.delete()
|
443 |
+
run = await app.send_photo(
|
444 |
+
chat_id=original_chat_id,
|
445 |
+
photo=img,
|
446 |
+
caption=_["stream_1"].format(
|
447 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
448 |
+
title[:23],
|
449 |
+
check[0]["dur"],
|
450 |
+
user,
|
451 |
+
),
|
452 |
+
reply_markup=InlineKeyboardMarkup(button),
|
453 |
+
)
|
454 |
+
db[chat_id][0]["mystic"] = run
|
455 |
+
db[chat_id][0]["markup"] = "stream"
|
456 |
+
elif "index_" in queued:
|
457 |
+
stream = (
|
458 |
+
AudioVideoPiped(
|
459 |
+
videoid,
|
460 |
+
audio_parameters=HighQualityAudio(),
|
461 |
+
video_parameters=MediumQualityVideo(),
|
462 |
+
)
|
463 |
+
if str(streamtype) == "video"
|
464 |
+
else AudioPiped(videoid, audio_parameters=HighQualityAudio())
|
465 |
+
)
|
466 |
+
try:
|
467 |
+
await client.change_stream(chat_id, stream)
|
468 |
+
except:
|
469 |
+
return await app.send_message(
|
470 |
+
original_chat_id,
|
471 |
+
text=_["call_6"],
|
472 |
+
)
|
473 |
+
button = stream_markup(_, chat_id)
|
474 |
+
run = await app.send_photo(
|
475 |
+
chat_id=original_chat_id,
|
476 |
+
photo=config.STREAM_IMG_URL,
|
477 |
+
caption=_["stream_2"].format(user),
|
478 |
+
reply_markup=InlineKeyboardMarkup(button),
|
479 |
+
)
|
480 |
+
db[chat_id][0]["mystic"] = run
|
481 |
+
db[chat_id][0]["markup"] = "tg"
|
482 |
+
else:
|
483 |
+
if video:
|
484 |
+
stream = AudioVideoPiped(
|
485 |
+
queued,
|
486 |
+
audio_parameters=HighQualityAudio(),
|
487 |
+
video_parameters=MediumQualityVideo(),
|
488 |
+
)
|
489 |
+
else:
|
490 |
+
stream = AudioPiped(
|
491 |
+
queued,
|
492 |
+
audio_parameters=HighQualityAudio(),
|
493 |
+
)
|
494 |
+
try:
|
495 |
+
await client.change_stream(chat_id, stream)
|
496 |
+
except:
|
497 |
+
return await app.send_message(
|
498 |
+
original_chat_id,
|
499 |
+
text=_["call_6"],
|
500 |
+
)
|
501 |
+
if videoid == "telegram":
|
502 |
+
button = stream_markup(_, chat_id)
|
503 |
+
run = await app.send_photo(
|
504 |
+
chat_id=original_chat_id,
|
505 |
+
photo=config.TELEGRAM_AUDIO_URL
|
506 |
+
if str(streamtype) == "audio"
|
507 |
+
else config.TELEGRAM_VIDEO_URL,
|
508 |
+
caption=_["stream_1"].format(
|
509 |
+
config.SUPPORT_CHAT, title[:23], check[0]["dur"], user
|
510 |
+
),
|
511 |
+
reply_markup=InlineKeyboardMarkup(button),
|
512 |
+
)
|
513 |
+
db[chat_id][0]["mystic"] = run
|
514 |
+
db[chat_id][0]["markup"] = "tg"
|
515 |
+
elif videoid == "soundcloud":
|
516 |
+
button = stream_markup(_, chat_id)
|
517 |
+
run = await app.send_photo(
|
518 |
+
chat_id=original_chat_id,
|
519 |
+
photo=config.SOUNCLOUD_IMG_URL,
|
520 |
+
caption=_["stream_1"].format(
|
521 |
+
config.SUPPORT_CHAT, title[:23], check[0]["dur"], user
|
522 |
+
),
|
523 |
+
reply_markup=InlineKeyboardMarkup(button),
|
524 |
+
)
|
525 |
+
db[chat_id][0]["mystic"] = run
|
526 |
+
db[chat_id][0]["markup"] = "tg"
|
527 |
+
else:
|
528 |
+
img = await get_thumb(videoid)
|
529 |
+
button = stream_markup(_, chat_id)
|
530 |
+
run = await app.send_photo(
|
531 |
+
chat_id=original_chat_id,
|
532 |
+
photo=img,
|
533 |
+
caption=_["stream_1"].format(
|
534 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
535 |
+
title[:23],
|
536 |
+
check[0]["dur"],
|
537 |
+
user,
|
538 |
+
),
|
539 |
+
reply_markup=InlineKeyboardMarkup(button),
|
540 |
+
)
|
541 |
+
db[chat_id][0]["mystic"] = run
|
542 |
+
db[chat_id][0]["markup"] = "stream"
|
543 |
+
|
544 |
+
async def ping(self):
|
545 |
+
pings = []
|
546 |
+
if config.STRING1:
|
547 |
+
pings.append(await self.one.ping)
|
548 |
+
if config.STRING2:
|
549 |
+
pings.append(await self.two.ping)
|
550 |
+
if config.STRING3:
|
551 |
+
pings.append(await self.three.ping)
|
552 |
+
if config.STRING4:
|
553 |
+
pings.append(await self.four.ping)
|
554 |
+
if config.STRING5:
|
555 |
+
pings.append(await self.five.ping)
|
556 |
+
return str(round(sum(pings) / len(pings), 3))
|
557 |
+
|
558 |
+
async def start(self):
|
559 |
+
LOGGER(__name__).info("Starting PyTgCalls Client...\n")
|
560 |
+
if config.STRING1:
|
561 |
+
await self.one.start()
|
562 |
+
if config.STRING2:
|
563 |
+
await self.two.start()
|
564 |
+
if config.STRING3:
|
565 |
+
await self.three.start()
|
566 |
+
if config.STRING4:
|
567 |
+
await self.four.start()
|
568 |
+
if config.STRING5:
|
569 |
+
await self.five.start()
|
570 |
+
|
571 |
+
async def decorators(self):
|
572 |
+
@self.one.on_kicked()
|
573 |
+
@self.two.on_kicked()
|
574 |
+
@self.three.on_kicked()
|
575 |
+
@self.four.on_kicked()
|
576 |
+
@self.five.on_kicked()
|
577 |
+
@self.one.on_closed_voice_chat()
|
578 |
+
@self.two.on_closed_voice_chat()
|
579 |
+
@self.three.on_closed_voice_chat()
|
580 |
+
@self.four.on_closed_voice_chat()
|
581 |
+
@self.five.on_closed_voice_chat()
|
582 |
+
@self.one.on_left()
|
583 |
+
@self.two.on_left()
|
584 |
+
@self.three.on_left()
|
585 |
+
@self.four.on_left()
|
586 |
+
@self.five.on_left()
|
587 |
+
async def stream_services_handler(_, chat_id: int):
|
588 |
+
await self.stop_stream(chat_id)
|
589 |
+
|
590 |
+
@self.one.on_stream_end()
|
591 |
+
@self.two.on_stream_end()
|
592 |
+
@self.three.on_stream_end()
|
593 |
+
@self.four.on_stream_end()
|
594 |
+
@self.five.on_stream_end()
|
595 |
+
async def stream_end_handler1(client, update: Update):
|
596 |
+
if not isinstance(update, StreamAudioEnded):
|
597 |
+
return
|
598 |
+
await self.change_stream(client, update.chat_id)
|
599 |
+
|
600 |
+
|
601 |
+
Anony = Call()
|
Devine/core/dir.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
from ..logging import LOGGER
|
4 |
+
|
5 |
+
|
6 |
+
def dirr():
|
7 |
+
for file in os.listdir():
|
8 |
+
if file.endswith(".jpg"):
|
9 |
+
os.remove(file)
|
10 |
+
elif file.endswith(".jpeg"):
|
11 |
+
os.remove(file)
|
12 |
+
elif file.endswith(".png"):
|
13 |
+
os.remove(file)
|
14 |
+
|
15 |
+
if "downloads" not in os.listdir():
|
16 |
+
os.mkdir("downloads")
|
17 |
+
if "cache" not in os.listdir():
|
18 |
+
os.mkdir("cache")
|
19 |
+
|
20 |
+
LOGGER(__name__).info("Directories Updated.")
|
Devine/core/git.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import shlex
|
3 |
+
from typing import Tuple
|
4 |
+
|
5 |
+
from git import Repo
|
6 |
+
from git.exc import GitCommandError, InvalidGitRepositoryError
|
7 |
+
|
8 |
+
import config
|
9 |
+
|
10 |
+
from ..logging import LOGGER
|
11 |
+
|
12 |
+
|
13 |
+
def install_req(cmd: str) -> Tuple[str, str, int, int]:
|
14 |
+
async def install_requirements():
|
15 |
+
args = shlex.split(cmd)
|
16 |
+
process = await asyncio.create_subprocess_exec(
|
17 |
+
*args,
|
18 |
+
stdout=asyncio.subprocess.PIPE,
|
19 |
+
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 |
+
return asyncio.get_event_loop().run_until_complete(install_requirements())
|
30 |
+
|
31 |
+
|
32 |
+
def hide_sensitive_info(message: str) -> str:
|
33 |
+
# Function to hide sensitive information in messages
|
34 |
+
return message.replace(config.UPSTREAM_REPO, "<hidden>")
|
35 |
+
|
36 |
+
|
37 |
+
def git():
|
38 |
+
REPO_LINK = config.UPSTREAM_REPO
|
39 |
+
if config.GIT_TOKEN:
|
40 |
+
GIT_USERNAME = REPO_LINK.split("com/")[1].split("/")[0]
|
41 |
+
TEMP_REPO = REPO_LINK.split("https://")[1]
|
42 |
+
UPSTREAM_REPO = f"https://{GIT_USERNAME}:{config.GIT_TOKEN}@{TEMP_REPO}"
|
43 |
+
else:
|
44 |
+
UPSTREAM_REPO = config.UPSTREAM_REPO
|
45 |
+
|
46 |
+
try:
|
47 |
+
repo = Repo()
|
48 |
+
LOGGER(__name__).info("Git Client Found [VPS DEPLOYER]")
|
49 |
+
except InvalidGitRepositoryError:
|
50 |
+
repo = Repo.init()
|
51 |
+
origin = repo.create_remote("origin", UPSTREAM_REPO)
|
52 |
+
origin.fetch()
|
53 |
+
repo.create_head(config.UPSTREAM_BRANCH, origin.refs[config.UPSTREAM_BRANCH])
|
54 |
+
repo.heads[config.UPSTREAM_BRANCH].set_tracking_branch(
|
55 |
+
origin.refs[config.UPSTREAM_BRANCH]
|
56 |
+
)
|
57 |
+
repo.heads[config.UPSTREAM_BRANCH].checkout()
|
58 |
+
except GitCommandError as e:
|
59 |
+
LOGGER(__name__).error(f"Invalid Git Command: {e}")
|
60 |
+
return
|
61 |
+
|
62 |
+
try:
|
63 |
+
origin = repo.remote("origin")
|
64 |
+
except ValueError:
|
65 |
+
origin = repo.create_remote("origin", UPSTREAM_REPO)
|
66 |
+
|
67 |
+
origin.fetch(config.UPSTREAM_BRANCH)
|
68 |
+
|
69 |
+
try:
|
70 |
+
origin.pull(config.UPSTREAM_BRANCH)
|
71 |
+
except GitCommandError as e:
|
72 |
+
repo.git.reset("--hard", "FETCH_HEAD")
|
73 |
+
LOGGER(__name__).error(f"Error pulling from upstream: {e}")
|
74 |
+
|
75 |
+
install_req("pip3 install --no-cache-dir -r requirements.txt")
|
76 |
+
LOGGER(__name__).info(f"Fetching updates from upstream repository: {hide_sensitive_info(UPSTREAM_REPO)}")
|
77 |
+
|
78 |
+
|
79 |
+
# Call the git function
|
80 |
+
git()
|
Devine/core/mongo.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from motor.motor_asyncio import AsyncIOMotorClient
|
2 |
+
|
3 |
+
from config import MONGO_DB_URI
|
4 |
+
|
5 |
+
from ..logging import LOGGER
|
6 |
+
|
7 |
+
LOGGER(__name__).info("Connecting to your Mongo Database...")
|
8 |
+
try:
|
9 |
+
_mongo_async_ = AsyncIOMotorClient(MONGO_DB_URI)
|
10 |
+
mongodb = _mongo_async_.Anon
|
11 |
+
LOGGER(__name__).info("Connected to your Mongo Database.")
|
12 |
+
except:
|
13 |
+
LOGGER(__name__).error("Failed to connect to your Mongo Database.")
|
14 |
+
exit()
|
Devine/core/userbot.py
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import Client
|
2 |
+
|
3 |
+
import config
|
4 |
+
|
5 |
+
from ..logging import LOGGER
|
6 |
+
|
7 |
+
assistants = []
|
8 |
+
assistantids = []
|
9 |
+
|
10 |
+
|
11 |
+
class Userbot(Client):
|
12 |
+
def __init__(self):
|
13 |
+
self.one = Client(
|
14 |
+
name="Devine1",
|
15 |
+
api_id=config.API_ID,
|
16 |
+
api_hash=config.API_HASH,
|
17 |
+
session_string=str(config.STRING1),
|
18 |
+
no_updates=True,
|
19 |
+
)
|
20 |
+
self.two = Client(
|
21 |
+
name="Devine2",
|
22 |
+
api_id=config.API_ID,
|
23 |
+
api_hash=config.API_HASH,
|
24 |
+
session_string=str(config.STRING2),
|
25 |
+
no_updates=True,
|
26 |
+
)
|
27 |
+
self.three = Client(
|
28 |
+
name="Devine3",
|
29 |
+
api_id=config.API_ID,
|
30 |
+
api_hash=config.API_HASH,
|
31 |
+
session_string=str(config.STRING3),
|
32 |
+
no_updates=True,
|
33 |
+
)
|
34 |
+
self.four = Client(
|
35 |
+
name="Devine4",
|
36 |
+
api_id=config.API_ID,
|
37 |
+
api_hash=config.API_HASH,
|
38 |
+
session_string=str(config.STRING4),
|
39 |
+
no_updates=True,
|
40 |
+
)
|
41 |
+
self.five = Client(
|
42 |
+
name="Devine5",
|
43 |
+
api_id=config.API_ID,
|
44 |
+
api_hash=config.API_HASH,
|
45 |
+
session_string=str(config.STRING5),
|
46 |
+
no_updates=True,
|
47 |
+
)
|
48 |
+
|
49 |
+
async def start(self):
|
50 |
+
LOGGER(__name__).info(f"Starting Assistants...")
|
51 |
+
if config.STRING1:
|
52 |
+
await self.one.start()
|
53 |
+
try:
|
54 |
+
await self.one.join_chat("Devine_Network")
|
55 |
+
await self.one.join_chat("Devine_Community")
|
56 |
+
except:
|
57 |
+
pass
|
58 |
+
assistants.append(1)
|
59 |
+
try:
|
60 |
+
await self.one.send_message(config.LOGGER_ID, "<b>ᴀssɪsᴛᴀɴᴛ 𝟷 sᴛᴀʀᴛᴇᴅ</b>")
|
61 |
+
except:
|
62 |
+
LOGGER(__name__).error(
|
63 |
+
"Assistant Account 1 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin!"
|
64 |
+
)
|
65 |
+
exit()
|
66 |
+
self.one.id = self.one.me.id
|
67 |
+
self.one.name = self.one.me.mention
|
68 |
+
self.one.username = self.one.me.username
|
69 |
+
assistantids.append(self.one.id)
|
70 |
+
LOGGER(__name__).info(f"Assistant Started as {self.one.name}")
|
71 |
+
|
72 |
+
if config.STRING2:
|
73 |
+
await self.two.start()
|
74 |
+
try:
|
75 |
+
await self.two.join_chat("Devine_Network")
|
76 |
+
await self.two.join_chat("Devine_community")
|
77 |
+
except:
|
78 |
+
pass
|
79 |
+
assistants.append(2)
|
80 |
+
try:
|
81 |
+
await self.two.send_message(config.LOGGER_ID, "<b>ᴀssɪsᴛᴀɴᴛ 𝟸 sᴛᴀʀᴛᴇᴅ</b>")
|
82 |
+
except:
|
83 |
+
LOGGER(__name__).error(
|
84 |
+
"Assistant Account 2 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin!"
|
85 |
+
)
|
86 |
+
exit()
|
87 |
+
self.two.id = self.two.me.id
|
88 |
+
self.two.name = self.two.me.mention
|
89 |
+
self.two.username = self.two.me.username
|
90 |
+
assistantids.append(self.two.id)
|
91 |
+
LOGGER(__name__).info(f"Assistant Two Started as {self.two.name}")
|
92 |
+
|
93 |
+
if config.STRING3:
|
94 |
+
await self.three.start()
|
95 |
+
try:
|
96 |
+
await self.three.join_chat("Devine_Network")
|
97 |
+
await self.three.join_chat("Devine_community")
|
98 |
+
except:
|
99 |
+
pass
|
100 |
+
assistants.append(3)
|
101 |
+
try:
|
102 |
+
await self.three.send_message(config.LOGGER_ID, "<b>ᴀssɪsᴛᴀɴᴛ 𝟹 sᴛᴀʀᴛᴇᴅ</b>")
|
103 |
+
except:
|
104 |
+
LOGGER(__name__).error(
|
105 |
+
"Assistant Account 3 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
106 |
+
)
|
107 |
+
exit()
|
108 |
+
self.three.id = self.three.me.id
|
109 |
+
self.three.name = self.three.me.mention
|
110 |
+
self.three.username = self.three.me.username
|
111 |
+
assistantids.append(self.three.id)
|
112 |
+
LOGGER(__name__).info(f"Assistant Three Started as {self.three.name}")
|
113 |
+
|
114 |
+
if config.STRING4:
|
115 |
+
await self.four.start()
|
116 |
+
try:
|
117 |
+
await self.four.join_chat("Devine_Network")
|
118 |
+
await self.four.join_chat("Devine_community")
|
119 |
+
except:
|
120 |
+
pass
|
121 |
+
assistants.append(4)
|
122 |
+
try:
|
123 |
+
await self.four.send_message(config.LOGGER_ID, "<b>ᴀssɪsᴛᴀɴᴛ 𝟺 sᴛᴀʀᴛᴇᴅ</b>")
|
124 |
+
except:
|
125 |
+
LOGGER(__name__).error(
|
126 |
+
"Assistant Account 4 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
127 |
+
)
|
128 |
+
exit()
|
129 |
+
self.four.id = self.four.me.id
|
130 |
+
self.four.name = self.four.me.mention
|
131 |
+
self.four.username = self.four.me.username
|
132 |
+
assistantids.append(self.four.id)
|
133 |
+
LOGGER(__name__).info(f"Assistant Four Started as {self.four.name}")
|
134 |
+
|
135 |
+
if config.STRING5:
|
136 |
+
await self.five.start()
|
137 |
+
try:
|
138 |
+
await self.five.join_chat("Devine_Network")
|
139 |
+
await self.five.join_chat("Devine_community")
|
140 |
+
except:
|
141 |
+
pass
|
142 |
+
assistants.append(5)
|
143 |
+
try:
|
144 |
+
await self.five.send_message(config.LOGGER_ID, "<b>ᴀssɪsᴛᴀɴᴛ 𝟻 sᴛᴀʀᴛᴇᴅ</b>")
|
145 |
+
except:
|
146 |
+
LOGGER(__name__).error(
|
147 |
+
"Assistant Account 5 has failed to access the log Group. Make sure that you have added your assistant to your log group and promoted as admin! "
|
148 |
+
)
|
149 |
+
exit()
|
150 |
+
self.five.id = self.five.me.id
|
151 |
+
self.five.name = self.five.me.mention
|
152 |
+
self.five.username = self.five.me.username
|
153 |
+
assistantids.append(self.five.id)
|
154 |
+
LOGGER(__name__).info(f"Assistant Five Started as {self.five.name}")
|
155 |
+
|
156 |
+
async def stop(self):
|
157 |
+
LOGGER(__name__).info(f"Stopping Assistants...")
|
158 |
+
try:
|
159 |
+
if config.STRING1:
|
160 |
+
await self.one.stop()
|
161 |
+
if config.STRING2:
|
162 |
+
await self.two.stop()
|
163 |
+
if config.STRING3:
|
164 |
+
await self.three.stop()
|
165 |
+
if config.STRING4:
|
166 |
+
await self.four.stop()
|
167 |
+
if config.STRING5:
|
168 |
+
await self.five.stop()
|
169 |
+
except:
|
170 |
+
pass
|
Devine/logging.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
|
3 |
+
logging.basicConfig(
|
4 |
+
level=logging.INFO,
|
5 |
+
format="[%(asctime)s - %(levelname)s] - %(name)s - %(message)s",
|
6 |
+
datefmt="%d-%b-%y %H:%M:%S",
|
7 |
+
handlers=[
|
8 |
+
logging.FileHandler("log.txt"),
|
9 |
+
logging.StreamHandler(),
|
10 |
+
],
|
11 |
+
)
|
12 |
+
|
13 |
+
logging.getLogger("httpx").setLevel(logging.ERROR)
|
14 |
+
logging.getLogger("pymongo").setLevel(logging.ERROR)
|
15 |
+
logging.getLogger("pyrogram").setLevel(logging.ERROR)
|
16 |
+
logging.getLogger("pytgcalls").setLevel(logging.ERROR)
|
17 |
+
|
18 |
+
def LOGGER(name: str) -> logging.Logger:
|
19 |
+
return logging.getLogger(name)
|
Devine/misc.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import socket
|
2 |
+
import time
|
3 |
+
|
4 |
+
import heroku3
|
5 |
+
from pyrogram import filters
|
6 |
+
|
7 |
+
import config
|
8 |
+
from Devine.core.mongo import mongodb
|
9 |
+
|
10 |
+
from .logging import LOGGER
|
11 |
+
|
12 |
+
SUDOERS = filters.user()
|
13 |
+
|
14 |
+
HAPP = None
|
15 |
+
_boot_ = time.time()
|
16 |
+
|
17 |
+
|
18 |
+
def is_heroku():
|
19 |
+
return "heroku" in socket.getfqdn()
|
20 |
+
|
21 |
+
# sec
|
22 |
+
XCB = [
|
23 |
+
"/",
|
24 |
+
"@",
|
25 |
+
".",
|
26 |
+
"com",
|
27 |
+
":",
|
28 |
+
"git",
|
29 |
+
"heroku",
|
30 |
+
"push",
|
31 |
+
str(config.HEROKU_API_KEY),
|
32 |
+
"https",
|
33 |
+
str(config.HEROKU_APP_NAME),
|
34 |
+
"HEAD",
|
35 |
+
"master",
|
36 |
+
]
|
37 |
+
|
38 |
+
|
39 |
+
def dbb():
|
40 |
+
global db
|
41 |
+
db = {}
|
42 |
+
LOGGER(__name__).info(f"Local Database Initialized.")
|
43 |
+
|
44 |
+
|
45 |
+
async def sudo():
|
46 |
+
global SUDOERS
|
47 |
+
SUDOERS.add(config.OWNER_ID)
|
48 |
+
sudoersdb = mongodb.sudoers
|
49 |
+
sudoers = await sudoersdb.find_one({"sudo": "sudo"})
|
50 |
+
sudoers = [] if not sudoers else sudoers["sudoers"]
|
51 |
+
if config.OWNER_ID not in sudoers:
|
52 |
+
sudoers.append(config.OWNER_ID)
|
53 |
+
await sudoersdb.update_one(
|
54 |
+
{"sudo": "sudo"},
|
55 |
+
{"$set": {"sudoers": sudoers}},
|
56 |
+
upsert=True,
|
57 |
+
)
|
58 |
+
if sudoers:
|
59 |
+
for user_id in sudoers:
|
60 |
+
SUDOERS.add(user_id)
|
61 |
+
LOGGER(__name__).info(f"Sudoers Loaded.")
|
62 |
+
|
63 |
+
|
64 |
+
def heroku():
|
65 |
+
global HAPP
|
66 |
+
if is_heroku:
|
67 |
+
if config.HEROKU_API_KEY and config.HEROKU_APP_NAME:
|
68 |
+
try:
|
69 |
+
Heroku = heroku3.from_key(config.HEROKU_API_KEY)
|
70 |
+
HAPP = Heroku.app(config.HEROKU_APP_NAME)
|
71 |
+
LOGGER(__name__).info(f"Heroku App Configured")
|
72 |
+
except BaseException:
|
73 |
+
LOGGER(__name__).warning(
|
74 |
+
f"Please make sure your Heroku API Key and Your App name are configured correctly in the heroku."
|
75 |
+
)
|
Devine/modules/fonts.py
ADDED
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
3 |
+
|
4 |
+
from AnonXMusic import app
|
5 |
+
from AnonXMusic.utils.fonts import Fonts
|
6 |
+
|
7 |
+
|
8 |
+
@app.on_message(filters.command(["font", "fonts"]))
|
9 |
+
async def style_buttons(c, m, cb=False):
|
10 |
+
buttons = [
|
11 |
+
[
|
12 |
+
InlineKeyboardButton("𝚃𝚢𝚙𝚎𝚠𝚛𝚒𝚝𝚎𝚛", callback_data="style+typewriter"),
|
13 |
+
InlineKeyboardButton("𝕆𝕦𝕥𝕝𝕚𝕟𝕖", callback_data="style+outline"),
|
14 |
+
InlineKeyboardButton("𝐒𝐞𝐫𝐢𝐟", callback_data="style+serif"),
|
15 |
+
],
|
16 |
+
[
|
17 |
+
InlineKeyboardButton("𝑺𝒆𝒓𝒊𝒇", callback_data="style+bold_cool"),
|
18 |
+
InlineKeyboardButton("𝑆𝑒𝑟𝑖𝑓", callback_data="style+cool"),
|
19 |
+
InlineKeyboardButton("Sᴍᴀʟʟ Cᴀᴘs", callback_data="style+small_cap"),
|
20 |
+
],
|
21 |
+
[
|
22 |
+
InlineKeyboardButton("𝓈𝒸𝓇𝒾𝓅𝓉", callback_data="style+script"),
|
23 |
+
InlineKeyboardButton("𝓼𝓬𝓻𝓲𝓹𝓽", callback_data="style+script_bolt"),
|
24 |
+
InlineKeyboardButton("ᵗⁱⁿʸ", callback_data="style+tiny"),
|
25 |
+
],
|
26 |
+
[
|
27 |
+
InlineKeyboardButton("ᑕOᗰIᑕ", callback_data="style+comic"),
|
28 |
+
InlineKeyboardButton("𝗦𝗮𝗻𝘀", callback_data="style+sans"),
|
29 |
+
InlineKeyboardButton("𝙎𝙖𝙣𝙨", callback_data="style+slant_sans"),
|
30 |
+
],
|
31 |
+
[
|
32 |
+
InlineKeyboardButton("𝘚𝘢𝘯𝘴", callback_data="style+slant"),
|
33 |
+
InlineKeyboardButton("𝖲𝖺𝗇𝗌", callback_data="style+sim"),
|
34 |
+
InlineKeyboardButton("Ⓒ︎Ⓘ︎Ⓡ︎Ⓒ︎Ⓛ︎Ⓔ︎Ⓢ︎", callback_data="style+circles"),
|
35 |
+
],
|
36 |
+
[
|
37 |
+
InlineKeyboardButton("🅒︎🅘︎🅡︎🅒︎🅛︎🅔︎🅢︎", callback_data="style+circle_dark"),
|
38 |
+
InlineKeyboardButton("𝔊𝔬𝔱𝔥𝔦𝔠", callback_data="style+gothic"),
|
39 |
+
InlineKeyboardButton("𝕲𝖔𝖙𝖍𝖎𝖈", callback_data="style+gothic_bolt"),
|
40 |
+
],
|
41 |
+
[
|
42 |
+
InlineKeyboardButton("C͜͡l͜͡o͜͡u͜͡d͜͡s͜͡", callback_data="style+cloud"),
|
43 |
+
InlineKeyboardButton("H̆̈ă̈p̆̈p̆̈y̆̈", callback_data="style+happy"),
|
44 |
+
InlineKeyboardButton("S̑̈ȃ̈d̑̈", callback_data="style+sad"),
|
45 |
+
],
|
46 |
+
[InlineKeyboardButton("ɴᴇxᴛ ➻", callback_data="nxt")],
|
47 |
+
]
|
48 |
+
if not cb:
|
49 |
+
await m.reply_text(
|
50 |
+
text=m.text.split(None, 1)[1],
|
51 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
52 |
+
quote=True,
|
53 |
+
)
|
54 |
+
else:
|
55 |
+
await m.answer()
|
56 |
+
await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons))
|
57 |
+
|
58 |
+
|
59 |
+
@pbot.on_callback_query(filters.regex("^nxt"))
|
60 |
+
async def nxt(c, m):
|
61 |
+
if m.data == "nxt":
|
62 |
+
buttons = [
|
63 |
+
[
|
64 |
+
InlineKeyboardButton("🇸 🇵 🇪 🇨 🇮 🇦 🇱 ", callback_data="style+special"),
|
65 |
+
InlineKeyboardButton("🅂🅀🅄🄰🅁🄴🅂", callback_data="style+squares"),
|
66 |
+
InlineKeyboardButton("🆂︎🆀︎🆄︎🅰︎🆁︎🅴︎🆂︎", callback_data="style+squares_bold"),
|
67 |
+
],
|
68 |
+
[
|
69 |
+
InlineKeyboardButton("ꪖꪀᦔꪖꪶꪊᥴ𝓲ꪖ", callback_data="style+andalucia"),
|
70 |
+
InlineKeyboardButton("爪卂几ᘜ卂", callback_data="style+manga"),
|
71 |
+
InlineKeyboardButton("S̾t̾i̾n̾k̾y̾", callback_data="style+stinky"),
|
72 |
+
],
|
73 |
+
[
|
74 |
+
InlineKeyboardButton("B̥ͦu̥ͦb̥ͦb̥ͦl̥ͦe̥ͦs̥ͦ", callback_data="style+bubbles"),
|
75 |
+
InlineKeyboardButton("U͟n͟d͟e͟r͟l͟i͟n͟e͟", callback_data="style+underline"),
|
76 |
+
InlineKeyboardButton("꒒ꍏꀷꌩꌃꀎꁅ", callback_data="style+ladybug"),
|
77 |
+
],
|
78 |
+
[
|
79 |
+
InlineKeyboardButton("R҉a҉y҉s҉", callback_data="style+rays"),
|
80 |
+
InlineKeyboardButton("B҈i҈r҈d҈s҈", callback_data="style+birds"),
|
81 |
+
InlineKeyboardButton("S̸l̸a̸s̸h̸", callback_data="style+slash"),
|
82 |
+
],
|
83 |
+
[
|
84 |
+
InlineKeyboardButton("s⃠t⃠o⃠p⃠", callback_data="style+stop"),
|
85 |
+
InlineKeyboardButton("S̺͆k̺͆y̺͆l̺͆i̺͆n̺͆e̺͆", callback_data="style+skyline"),
|
86 |
+
InlineKeyboardButton("A͎r͎r͎o͎w͎s͎", callback_data="style+arrows"),
|
87 |
+
],
|
88 |
+
[
|
89 |
+
InlineKeyboardButton("ዪሀክቿነ", callback_data="style+qvnes"),
|
90 |
+
InlineKeyboardButton("S̶t̶r̶i̶k̶e̶", callback_data="style+strike"),
|
91 |
+
InlineKeyboardButton("F༙r༙o༙z༙e༙n༙", callback_data="style+frozen"),
|
92 |
+
],
|
93 |
+
[InlineKeyboardButton("ʙᴀᴄᴋ", callback_data="nxt+0")],
|
94 |
+
]
|
95 |
+
await m.answer()
|
96 |
+
await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons))
|
97 |
+
else:
|
98 |
+
await style_buttons(c, m, cb=True)
|
99 |
+
|
100 |
+
|
101 |
+
@pbot.on_callback_query(filters.regex("^style"))
|
102 |
+
async def style(c, m):
|
103 |
+
await m.answer()
|
104 |
+
cmd, style = m.data.split("+")
|
105 |
+
|
106 |
+
if style == "typewriter":
|
107 |
+
cls = Fonts.typewriter
|
108 |
+
if style == "outline":
|
109 |
+
cls = Fonts.outline
|
110 |
+
if style == "serif":
|
111 |
+
cls = Fonts.serief
|
112 |
+
if style == "bold_cool":
|
113 |
+
cls = Fonts.bold_cool
|
114 |
+
if style == "cool":
|
115 |
+
cls = Fonts.cool
|
116 |
+
if style == "small_cap":
|
117 |
+
cls = Fonts.smallcap
|
118 |
+
if style == "script":
|
119 |
+
cls = Fonts.script
|
120 |
+
if style == "script_bolt":
|
121 |
+
cls = Fonts.bold_script
|
122 |
+
if style == "tiny":
|
123 |
+
cls = Fonts.tiny
|
124 |
+
if style == "comic":
|
125 |
+
cls = Fonts.comic
|
126 |
+
if style == "sans":
|
127 |
+
cls = Fonts.san
|
128 |
+
if style == "slant_sans":
|
129 |
+
cls = Fonts.slant_san
|
130 |
+
if style == "slant":
|
131 |
+
cls = Fonts.slant
|
132 |
+
if style == "sim":
|
133 |
+
cls = Fonts.sim
|
134 |
+
if style == "circles":
|
135 |
+
cls = Fonts.circles
|
136 |
+
if style == "circle_dark":
|
137 |
+
cls = Fonts.dark_circle
|
138 |
+
if style == "gothic":
|
139 |
+
cls = Fonts.gothic
|
140 |
+
if style == "gothic_bolt":
|
141 |
+
cls = Fonts.bold_gothic
|
142 |
+
if style == "cloud":
|
143 |
+
cls = Fonts.cloud
|
144 |
+
if style == "happy":
|
145 |
+
cls = Fonts.happy
|
146 |
+
if style == "sad":
|
147 |
+
cls = Fonts.sad
|
148 |
+
if style == "special":
|
149 |
+
cls = Fonts.special
|
150 |
+
if style == "squares":
|
151 |
+
cls = Fonts.square
|
152 |
+
if style == "squares_bold":
|
153 |
+
cls = Fonts.dark_square
|
154 |
+
if style == "andalucia":
|
155 |
+
cls = Fonts.andalucia
|
156 |
+
if style == "manga":
|
157 |
+
cls = Fonts.manga
|
158 |
+
if style == "stinky":
|
159 |
+
cls = Fonts.stinky
|
160 |
+
if style == "bubbles":
|
161 |
+
cls = Fonts.bubbles
|
162 |
+
if style == "underline":
|
163 |
+
cls = Fonts.underline
|
164 |
+
if style == "ladybug":
|
165 |
+
cls = Fonts.ladybug
|
166 |
+
if style == "rays":
|
167 |
+
cls = Fonts.rays
|
168 |
+
if style == "birds":
|
169 |
+
cls = Fonts.birds
|
170 |
+
if style == "slash":
|
171 |
+
cls = Fonts.slash
|
172 |
+
if style == "stop":
|
173 |
+
cls = Fonts.stop
|
174 |
+
if style == "skyline":
|
175 |
+
cls = Fonts.skyline
|
176 |
+
if style == "arrows":
|
177 |
+
cls = Fonts.arrows
|
178 |
+
if style == "qvnes":
|
179 |
+
cls = Fonts.rvnes
|
180 |
+
if style == "strike":
|
181 |
+
cls = Fonts.strike
|
182 |
+
if style == "frozen":
|
183 |
+
cls = Fonts.frozen
|
184 |
+
new_text = cls(m.message.reply_to_message.text.split(None, 1)[1])
|
185 |
+
try:
|
186 |
+
await m.message.edit_text(new_text, reply_markup=m.message.reply_markup)
|
187 |
+
except:
|
188 |
+
pass
|
Devine/mongo/afkdb.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from Devine.utils.mongo import db
|
2 |
+
|
3 |
+
afkdb = db.afk
|
4 |
+
|
5 |
+
|
6 |
+
async def is_afk(user_id: int) -> bool:
|
7 |
+
user = await afkdb.find_one({"user_id": user_id})
|
8 |
+
if not user:
|
9 |
+
return False, {}
|
10 |
+
return True, user["reason"]
|
11 |
+
|
12 |
+
|
13 |
+
async def add_afk(user_id: int, mode):
|
14 |
+
await afkdb.update_one(
|
15 |
+
{"user_id": user_id}, {"$set": {"reason": mode}}, upsert=True
|
16 |
+
)
|
17 |
+
|
18 |
+
|
19 |
+
async def remove_afk(user_id: int):
|
20 |
+
user = await afkdb.find_one({"user_id": user_id})
|
21 |
+
if user:
|
22 |
+
return await afkdb.delete_one({"user_id": user_id})
|
23 |
+
|
24 |
+
|
25 |
+
async def get_afk_users() -> list:
|
26 |
+
users = afkdb.find({"user_id": {"$gt": 0}})
|
27 |
+
if not users:
|
28 |
+
return []
|
29 |
+
users_list = []
|
30 |
+
for user in await users.to_list(length=1000000000):
|
31 |
+
users_list.append(user)
|
32 |
+
return users_list
|
Devine/mongo/readable_time.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def get_readable_time(seconds: int) -> str:
|
2 |
+
count = 0
|
3 |
+
readable_time = ""
|
4 |
+
time_list = []
|
5 |
+
time_suffix_list = ["s", "ᴍ", "ʜ", "ᴅᴀʏs"]
|
6 |
+
|
7 |
+
while count < 4:
|
8 |
+
count += 1
|
9 |
+
remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24)
|
10 |
+
if seconds == 0 and remainder == 0:
|
11 |
+
break
|
12 |
+
time_list.append(int(result))
|
13 |
+
seconds = int(remainder)
|
14 |
+
|
15 |
+
for x in range(len(time_list)):
|
16 |
+
time_list[x] = str(time_list[x]) + time_suffix_list[x]
|
17 |
+
if len(time_list) == 4:
|
18 |
+
readable_time += time_list.pop() + ", "
|
19 |
+
|
20 |
+
time_list.reverse()
|
21 |
+
readable_time += ":".join(time_list)
|
22 |
+
|
23 |
+
return readable_time
|
Devine/platforms/Apple.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
from typing import Union
|
3 |
+
|
4 |
+
import aiohttp
|
5 |
+
from bs4 import BeautifulSoup
|
6 |
+
from youtubesearchpython.__future__ import VideosSearch
|
7 |
+
|
8 |
+
|
9 |
+
class AppleAPI:
|
10 |
+
def __init__(self):
|
11 |
+
self.regex = r"^(https:\/\/music.apple.com\/)(.*)$"
|
12 |
+
self.base = "https://music.apple.com/in/playlist/"
|
13 |
+
|
14 |
+
async def valid(self, link: str):
|
15 |
+
if re.search(self.regex, link):
|
16 |
+
return True
|
17 |
+
else:
|
18 |
+
return False
|
19 |
+
|
20 |
+
async def track(self, url, playid: Union[bool, str] = None):
|
21 |
+
if playid:
|
22 |
+
url = self.base + url
|
23 |
+
async with aiohttp.ClientSession() as session:
|
24 |
+
async with session.get(url) as response:
|
25 |
+
if response.status != 200:
|
26 |
+
return False
|
27 |
+
html = await response.text()
|
28 |
+
soup = BeautifulSoup(html, "html.parser")
|
29 |
+
search = None
|
30 |
+
for tag in soup.find_all("meta"):
|
31 |
+
if tag.get("property", None) == "og:title":
|
32 |
+
search = tag.get("content", None)
|
33 |
+
if search is None:
|
34 |
+
return False
|
35 |
+
results = VideosSearch(search, limit=1)
|
36 |
+
for result in (await results.next())["result"]:
|
37 |
+
title = result["title"]
|
38 |
+
ytlink = result["link"]
|
39 |
+
vidid = result["id"]
|
40 |
+
duration_min = result["duration"]
|
41 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
42 |
+
track_details = {
|
43 |
+
"title": title,
|
44 |
+
"link": ytlink,
|
45 |
+
"vidid": vidid,
|
46 |
+
"duration_min": duration_min,
|
47 |
+
"thumb": thumbnail,
|
48 |
+
}
|
49 |
+
return track_details, vidid
|
50 |
+
|
51 |
+
async def playlist(self, url, playid: Union[bool, str] = None):
|
52 |
+
if playid:
|
53 |
+
url = self.base + url
|
54 |
+
playlist_id = url.split("playlist/")[1]
|
55 |
+
async with aiohttp.ClientSession() as session:
|
56 |
+
async with session.get(url) as response:
|
57 |
+
if response.status != 200:
|
58 |
+
return False
|
59 |
+
html = await response.text()
|
60 |
+
soup = BeautifulSoup(html, "html.parser")
|
61 |
+
applelinks = soup.find_all("meta", attrs={"property": "music:song"})
|
62 |
+
results = []
|
63 |
+
for item in applelinks:
|
64 |
+
try:
|
65 |
+
xx = (((item["content"]).split("album/")[1]).split("/")[0]).replace(
|
66 |
+
"-", " "
|
67 |
+
)
|
68 |
+
except:
|
69 |
+
xx = ((item["content"]).split("album/")[1]).split("/")[0]
|
70 |
+
results.append(xx)
|
71 |
+
return results, playlist_id
|
Devine/platforms/Carbon.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
from os.path import realpath
|
3 |
+
|
4 |
+
import aiohttp
|
5 |
+
from aiohttp import client_exceptions
|
6 |
+
|
7 |
+
|
8 |
+
class UnableToFetchCarbon(Exception):
|
9 |
+
pass
|
10 |
+
|
11 |
+
|
12 |
+
themes = [
|
13 |
+
"3024-night",
|
14 |
+
"a11y-dark",
|
15 |
+
"blackboard",
|
16 |
+
"base16-dark",
|
17 |
+
"base16-light",
|
18 |
+
"cobalt",
|
19 |
+
"duotone-dark",
|
20 |
+
"dracula-pro",
|
21 |
+
"hopscotch",
|
22 |
+
"lucario",
|
23 |
+
"material",
|
24 |
+
"monokai",
|
25 |
+
"nightowl",
|
26 |
+
"nord",
|
27 |
+
"oceanic-next",
|
28 |
+
"one-light",
|
29 |
+
"one-dark",
|
30 |
+
"panda-syntax",
|
31 |
+
"parasio-dark",
|
32 |
+
"seti",
|
33 |
+
"shades-of-purple",
|
34 |
+
"solarized+dark",
|
35 |
+
"solarized+light",
|
36 |
+
"synthwave-84",
|
37 |
+
"twilight",
|
38 |
+
"verminal",
|
39 |
+
"vscode",
|
40 |
+
"yeti",
|
41 |
+
"zenburn",
|
42 |
+
]
|
43 |
+
|
44 |
+
colour = [
|
45 |
+
"#FF0000",
|
46 |
+
"#FF5733",
|
47 |
+
"#FFFF00",
|
48 |
+
"#008000",
|
49 |
+
"#0000FF",
|
50 |
+
"#800080",
|
51 |
+
"#A52A2A",
|
52 |
+
"#FF00FF",
|
53 |
+
"#D2B48C",
|
54 |
+
"#00FFFF",
|
55 |
+
"#808000",
|
56 |
+
"#800000",
|
57 |
+
"#00FFFF",
|
58 |
+
"#30D5C8",
|
59 |
+
"#00FF00",
|
60 |
+
"#008080",
|
61 |
+
"#4B0082",
|
62 |
+
"#EE82EE",
|
63 |
+
"#FFC0CB",
|
64 |
+
"#000000",
|
65 |
+
"#FFFFFF",
|
66 |
+
"#808080",
|
67 |
+
]
|
68 |
+
|
69 |
+
|
70 |
+
class CarbonAPI:
|
71 |
+
def __init__(self):
|
72 |
+
self.language = "auto"
|
73 |
+
self.drop_shadow = True
|
74 |
+
self.drop_shadow_blur = "68px"
|
75 |
+
self.drop_shadow_offset = "20px"
|
76 |
+
self.font_family = "JetBrains Mono"
|
77 |
+
self.width_adjustment = True
|
78 |
+
self.watermark = False
|
79 |
+
|
80 |
+
async def generate(self, text: str, user_id):
|
81 |
+
async with aiohttp.ClientSession(
|
82 |
+
headers={"Content-Type": "application/json"},
|
83 |
+
) as ses:
|
84 |
+
params = {
|
85 |
+
"code": text,
|
86 |
+
}
|
87 |
+
params["backgroundColor"] = random.choice(colour)
|
88 |
+
params["theme"] = random.choice(themes)
|
89 |
+
params["dropShadow"] = self.drop_shadow
|
90 |
+
params["dropShadowOffsetY"] = self.drop_shadow_offset
|
91 |
+
params["dropShadowBlurRadius"] = self.drop_shadow_blur
|
92 |
+
params["fontFamily"] = self.font_family
|
93 |
+
params["language"] = self.language
|
94 |
+
params["watermark"] = self.watermark
|
95 |
+
params["widthAdjustment"] = self.width_adjustment
|
96 |
+
try:
|
97 |
+
request = await ses.post(
|
98 |
+
"https://carbonara.solopov.dev/api/cook",
|
99 |
+
json=params,
|
100 |
+
)
|
101 |
+
except client_exceptions.ClientConnectorError:
|
102 |
+
raise UnableToFetchCarbon("Can not reach the Host!")
|
103 |
+
resp = await request.read()
|
104 |
+
with open(f"cache/carbon{user_id}.jpg", "wb") as f:
|
105 |
+
f.write(resp)
|
106 |
+
return realpath(f.name)
|
Devine/platforms/Resso.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
from typing import Union
|
3 |
+
|
4 |
+
import aiohttp
|
5 |
+
from bs4 import BeautifulSoup
|
6 |
+
from youtubesearchpython.__future__ import VideosSearch
|
7 |
+
|
8 |
+
|
9 |
+
class RessoAPI:
|
10 |
+
def __init__(self):
|
11 |
+
self.regex = r"^(https:\/\/m.resso.com\/)(.*)$"
|
12 |
+
self.base = "https://m.resso.com/"
|
13 |
+
|
14 |
+
async def valid(self, link: str):
|
15 |
+
if re.search(self.regex, link):
|
16 |
+
return True
|
17 |
+
else:
|
18 |
+
return False
|
19 |
+
|
20 |
+
async def track(self, url, playid: Union[bool, str] = None):
|
21 |
+
if playid:
|
22 |
+
url = self.base + url
|
23 |
+
async with aiohttp.ClientSession() as session:
|
24 |
+
async with session.get(url) as response:
|
25 |
+
if response.status != 200:
|
26 |
+
return False
|
27 |
+
html = await response.text()
|
28 |
+
soup = BeautifulSoup(html, "html.parser")
|
29 |
+
for tag in soup.find_all("meta"):
|
30 |
+
if tag.get("property", None) == "og:title":
|
31 |
+
title = tag.get("content", None)
|
32 |
+
if tag.get("property", None) == "og:description":
|
33 |
+
des = tag.get("content", None)
|
34 |
+
try:
|
35 |
+
des = des.split("·")[0]
|
36 |
+
except:
|
37 |
+
pass
|
38 |
+
if des == "":
|
39 |
+
return
|
40 |
+
results = VideosSearch(title, limit=1)
|
41 |
+
for result in (await results.next())["result"]:
|
42 |
+
title = result["title"]
|
43 |
+
ytlink = result["link"]
|
44 |
+
vidid = result["id"]
|
45 |
+
duration_min = result["duration"]
|
46 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
47 |
+
track_details = {
|
48 |
+
"title": title,
|
49 |
+
"link": ytlink,
|
50 |
+
"vidid": vidid,
|
51 |
+
"duration_min": duration_min,
|
52 |
+
"thumb": thumbnail,
|
53 |
+
}
|
54 |
+
return track_details, vidid
|
Devine/platforms/Soundcloud.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from os import path
|
2 |
+
|
3 |
+
from yt_dlp import YoutubeDL
|
4 |
+
|
5 |
+
from Devine.utils.formatters import seconds_to_min
|
6 |
+
|
7 |
+
|
8 |
+
class SoundAPI:
|
9 |
+
def __init__(self):
|
10 |
+
self.opts = {
|
11 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
12 |
+
"format": "best",
|
13 |
+
"retries": 3,
|
14 |
+
"nooverwrites": False,
|
15 |
+
"continuedl": True,
|
16 |
+
}
|
17 |
+
|
18 |
+
async def valid(self, link: str):
|
19 |
+
if "soundcloud" in link:
|
20 |
+
return True
|
21 |
+
else:
|
22 |
+
return False
|
23 |
+
|
24 |
+
async def download(self, url):
|
25 |
+
d = YoutubeDL(self.opts)
|
26 |
+
try:
|
27 |
+
info = d.extract_info(url)
|
28 |
+
except:
|
29 |
+
return False
|
30 |
+
xyz = path.join("downloads", f"{info['id']}.{info['ext']}")
|
31 |
+
duration_min = seconds_to_min(info["duration"])
|
32 |
+
track_details = {
|
33 |
+
"title": info["title"],
|
34 |
+
"duration_sec": info["duration"],
|
35 |
+
"duration_min": duration_min,
|
36 |
+
"uploader": info["uploader"],
|
37 |
+
"filepath": xyz,
|
38 |
+
}
|
39 |
+
return track_details, xyz
|
Devine/platforms/Spotify.py
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
|
3 |
+
import spotipy
|
4 |
+
from spotipy.oauth2 import SpotifyClientCredentials
|
5 |
+
from youtubesearchpython.__future__ import VideosSearch
|
6 |
+
|
7 |
+
import config
|
8 |
+
|
9 |
+
|
10 |
+
class SpotifyAPI:
|
11 |
+
def __init__(self):
|
12 |
+
self.regex = r"^(https:\/\/open.spotify.com\/)(.*)$"
|
13 |
+
self.client_id = config.SPOTIFY_CLIENT_ID
|
14 |
+
self.client_secret = config.SPOTIFY_CLIENT_SECRET
|
15 |
+
if config.SPOTIFY_CLIENT_ID and config.SPOTIFY_CLIENT_SECRET:
|
16 |
+
self.client_credentials_manager = SpotifyClientCredentials(
|
17 |
+
self.client_id, self.client_secret
|
18 |
+
)
|
19 |
+
self.spotify = spotipy.Spotify(
|
20 |
+
client_credentials_manager=self.client_credentials_manager
|
21 |
+
)
|
22 |
+
else:
|
23 |
+
self.spotify = None
|
24 |
+
|
25 |
+
async def valid(self, link: str):
|
26 |
+
if re.search(self.regex, link):
|
27 |
+
return True
|
28 |
+
else:
|
29 |
+
return False
|
30 |
+
|
31 |
+
async def track(self, link: str):
|
32 |
+
track = self.spotify.track(link)
|
33 |
+
info = track["name"]
|
34 |
+
for artist in track["artists"]:
|
35 |
+
fetched = f' {artist["name"]}'
|
36 |
+
if "Various Artists" not in fetched:
|
37 |
+
info += fetched
|
38 |
+
results = VideosSearch(info, limit=1)
|
39 |
+
for result in (await results.next())["result"]:
|
40 |
+
ytlink = result["link"]
|
41 |
+
title = result["title"]
|
42 |
+
vidid = result["id"]
|
43 |
+
duration_min = result["duration"]
|
44 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
45 |
+
track_details = {
|
46 |
+
"title": title,
|
47 |
+
"link": ytlink,
|
48 |
+
"vidid": vidid,
|
49 |
+
"duration_min": duration_min,
|
50 |
+
"thumb": thumbnail,
|
51 |
+
}
|
52 |
+
return track_details, vidid
|
53 |
+
|
54 |
+
async def playlist(self, url):
|
55 |
+
playlist = self.spotify.playlist(url)
|
56 |
+
playlist_id = playlist["id"]
|
57 |
+
results = []
|
58 |
+
for item in playlist["tracks"]["items"]:
|
59 |
+
music_track = item["track"]
|
60 |
+
info = music_track["name"]
|
61 |
+
for artist in music_track["artists"]:
|
62 |
+
fetched = f' {artist["name"]}'
|
63 |
+
if "Various Artists" not in fetched:
|
64 |
+
info += fetched
|
65 |
+
results.append(info)
|
66 |
+
return results, playlist_id
|
67 |
+
|
68 |
+
async def album(self, url):
|
69 |
+
album = self.spotify.album(url)
|
70 |
+
album_id = album["id"]
|
71 |
+
results = []
|
72 |
+
for item in album["tracks"]["items"]:
|
73 |
+
info = item["name"]
|
74 |
+
for artist in item["artists"]:
|
75 |
+
fetched = f' {artist["name"]}'
|
76 |
+
if "Various Artists" not in fetched:
|
77 |
+
info += fetched
|
78 |
+
results.append(info)
|
79 |
+
|
80 |
+
return (
|
81 |
+
results,
|
82 |
+
album_id,
|
83 |
+
)
|
84 |
+
|
85 |
+
async def artist(self, url):
|
86 |
+
artistinfo = self.spotify.artist(url)
|
87 |
+
artist_id = artistinfo["id"]
|
88 |
+
results = []
|
89 |
+
artisttoptracks = self.spotify.artist_top_tracks(url)
|
90 |
+
for item in artisttoptracks["tracks"]:
|
91 |
+
info = item["name"]
|
92 |
+
for artist in item["artists"]:
|
93 |
+
fetched = f' {artist["name"]}'
|
94 |
+
if "Various Artists" not in fetched:
|
95 |
+
info += fetched
|
96 |
+
results.append(info)
|
97 |
+
|
98 |
+
return results, artist_id
|
Devine/platforms/Telegram.py
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import os
|
3 |
+
import time
|
4 |
+
from typing import Union
|
5 |
+
|
6 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Voice
|
7 |
+
|
8 |
+
import config
|
9 |
+
from Devine import app
|
10 |
+
from Devine.utils.formatters import (
|
11 |
+
check_duration,
|
12 |
+
convert_bytes,
|
13 |
+
get_readable_time,
|
14 |
+
seconds_to_min,
|
15 |
+
)
|
16 |
+
|
17 |
+
|
18 |
+
class TeleAPI:
|
19 |
+
def __init__(self):
|
20 |
+
self.chars_limit = 4096
|
21 |
+
self.sleep = 5
|
22 |
+
|
23 |
+
async def send_split_text(self, message, string):
|
24 |
+
n = self.chars_limit
|
25 |
+
out = [(string[i : i + n]) for i in range(0, len(string), n)]
|
26 |
+
j = 0
|
27 |
+
for x in out:
|
28 |
+
if j <= 2:
|
29 |
+
j += 1
|
30 |
+
await message.reply_text(x, disable_web_page_preview=True)
|
31 |
+
return True
|
32 |
+
|
33 |
+
async def get_link(self, message):
|
34 |
+
return message.link
|
35 |
+
|
36 |
+
async def get_filename(self, file, audio: Union[bool, str] = None):
|
37 |
+
try:
|
38 |
+
file_name = file.file_name
|
39 |
+
if file_name is None:
|
40 |
+
file_name = "ᴛᴇʟᴇɢʀᴀᴍ ᴀᴜᴅɪᴏ" if audio else "ᴛᴇʟᴇɢʀᴀᴍ ᴠɪᴅᴇᴏ"
|
41 |
+
except:
|
42 |
+
file_name = "ᴛᴇʟᴇɢʀᴀᴍ ᴀᴜᴅɪᴏ" if audio else "ᴛᴇʟᴇɢʀᴀᴍ ᴠɪᴅᴇᴏ"
|
43 |
+
return file_name
|
44 |
+
|
45 |
+
async def get_duration(self, file):
|
46 |
+
try:
|
47 |
+
dur = seconds_to_min(file.duration)
|
48 |
+
except:
|
49 |
+
dur = "Unknown"
|
50 |
+
return dur
|
51 |
+
|
52 |
+
async def get_duration(self, filex, file_path):
|
53 |
+
try:
|
54 |
+
dur = seconds_to_min(filex.duration)
|
55 |
+
except:
|
56 |
+
try:
|
57 |
+
dur = await asyncio.get_event_loop().run_in_executor(
|
58 |
+
None, check_duration, file_path
|
59 |
+
)
|
60 |
+
dur = seconds_to_min(dur)
|
61 |
+
except:
|
62 |
+
return "Unknown"
|
63 |
+
return dur
|
64 |
+
|
65 |
+
async def get_filepath(
|
66 |
+
self,
|
67 |
+
audio: Union[bool, str] = None,
|
68 |
+
video: Union[bool, str] = None,
|
69 |
+
):
|
70 |
+
if audio:
|
71 |
+
try:
|
72 |
+
file_name = (
|
73 |
+
audio.file_unique_id
|
74 |
+
+ "."
|
75 |
+
+ (
|
76 |
+
(audio.file_name.split(".")[-1])
|
77 |
+
if (not isinstance(audio, Voice))
|
78 |
+
else "ogg"
|
79 |
+
)
|
80 |
+
)
|
81 |
+
except:
|
82 |
+
file_name = audio.file_unique_id + "." + "ogg"
|
83 |
+
file_name = os.path.join(os.path.realpath("downloads"), file_name)
|
84 |
+
if video:
|
85 |
+
try:
|
86 |
+
file_name = (
|
87 |
+
video.file_unique_id + "." + (video.file_name.split(".")[-1])
|
88 |
+
)
|
89 |
+
except:
|
90 |
+
file_name = video.file_unique_id + "." + "mp4"
|
91 |
+
file_name = os.path.join(os.path.realpath("downloads"), file_name)
|
92 |
+
return file_name
|
93 |
+
|
94 |
+
async def download(self, _, message, mystic, fname):
|
95 |
+
lower = [0, 8, 17, 38, 64, 77, 96]
|
96 |
+
higher = [5, 10, 20, 40, 66, 80, 99]
|
97 |
+
checker = [5, 10, 20, 40, 66, 80, 99]
|
98 |
+
speed_counter = {}
|
99 |
+
if os.path.exists(fname):
|
100 |
+
return True
|
101 |
+
|
102 |
+
async def down_load():
|
103 |
+
async def progress(current, total):
|
104 |
+
if current == total:
|
105 |
+
return
|
106 |
+
current_time = time.time()
|
107 |
+
start_time = speed_counter.get(message.id)
|
108 |
+
check_time = current_time - start_time
|
109 |
+
upl = InlineKeyboardMarkup(
|
110 |
+
[
|
111 |
+
[
|
112 |
+
InlineKeyboardButton(
|
113 |
+
text="ᴄᴀɴᴄᴇʟ",
|
114 |
+
callback_data="stop_downloading",
|
115 |
+
),
|
116 |
+
]
|
117 |
+
]
|
118 |
+
)
|
119 |
+
percentage = current * 100 / total
|
120 |
+
percentage = str(round(percentage, 2))
|
121 |
+
speed = current / check_time
|
122 |
+
eta = int((total - current) / speed)
|
123 |
+
eta = get_readable_time(eta)
|
124 |
+
if not eta:
|
125 |
+
eta = "0 sᴇᴄᴏɴᴅs"
|
126 |
+
total_size = convert_bytes(total)
|
127 |
+
completed_size = convert_bytes(current)
|
128 |
+
speed = convert_bytes(speed)
|
129 |
+
percentage = int((percentage.split("."))[0])
|
130 |
+
for counter in range(7):
|
131 |
+
low = int(lower[counter])
|
132 |
+
high = int(higher[counter])
|
133 |
+
check = int(checker[counter])
|
134 |
+
if low < percentage <= high:
|
135 |
+
if high == check:
|
136 |
+
try:
|
137 |
+
await mystic.edit_text(
|
138 |
+
text=_["tg_1"].format(
|
139 |
+
app.mention,
|
140 |
+
total_size,
|
141 |
+
completed_size,
|
142 |
+
percentage[:5],
|
143 |
+
speed,
|
144 |
+
eta,
|
145 |
+
),
|
146 |
+
reply_markup=upl,
|
147 |
+
)
|
148 |
+
checker[counter] = 100
|
149 |
+
except:
|
150 |
+
pass
|
151 |
+
|
152 |
+
speed_counter[message.id] = time.time()
|
153 |
+
try:
|
154 |
+
await app.download_media(
|
155 |
+
message.reply_to_message,
|
156 |
+
file_name=fname,
|
157 |
+
progress=progress,
|
158 |
+
)
|
159 |
+
try:
|
160 |
+
elapsed = get_readable_time(
|
161 |
+
int(int(time.time()) - int(speed_counter[message.id]))
|
162 |
+
)
|
163 |
+
except:
|
164 |
+
elapsed = "0 sᴇᴄᴏɴᴅs"
|
165 |
+
await mystic.edit_text(_["tg_2"].format(elapsed))
|
166 |
+
except:
|
167 |
+
await mystic.edit_text(_["tg_3"])
|
168 |
+
|
169 |
+
task = asyncio.create_task(down_load())
|
170 |
+
config.lyrical[mystic.id] = task
|
171 |
+
await task
|
172 |
+
verify = config.lyrical.get(mystic.id)
|
173 |
+
if not verify:
|
174 |
+
return False
|
175 |
+
config.lyrical.pop(mystic.id)
|
176 |
+
return True
|
Devine/platforms/Youtube.py
ADDED
@@ -0,0 +1,407 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import glob
|
3 |
+
import os
|
4 |
+
import random
|
5 |
+
import re
|
6 |
+
from typing import Union
|
7 |
+
|
8 |
+
from pyrogram.enums import MessageEntityType
|
9 |
+
from pyrogram.types import Message
|
10 |
+
from youtubesearchpython.__future__ import VideosSearch
|
11 |
+
from yt_dlp import YoutubeDL
|
12 |
+
|
13 |
+
import config
|
14 |
+
from Devine.utils.database import is_on_off
|
15 |
+
from Devine.utils.formatters import time_to_seconds
|
16 |
+
|
17 |
+
def cookies():
|
18 |
+
folder_path = f"{os.getcwd()}/cookies"
|
19 |
+
txt_files = glob.glob(os.path.join(folder_path, "*.txt"))
|
20 |
+
if not txt_files:
|
21 |
+
raise FileNotFoundError("No .txt files found in the specified folder.")
|
22 |
+
cookie_txt_file = random.choice(txt_files)
|
23 |
+
return f"""cookies/{str(cookie_txt_file).split("/")[-1]}"""
|
24 |
+
|
25 |
+
|
26 |
+
def get_ytdl_options(ytdl_opts: Union[str, dict, list], commandline: bool = True) -> Union[str, dict, list]:
|
27 |
+
token_data = os.getenv("TOKEN_DATA")
|
28 |
+
|
29 |
+
if isinstance(ytdl_opts, list):
|
30 |
+
if token_data:
|
31 |
+
ytdl_opts += ["--username" if commandline else "username", "oauth2", "--password" if commandline else "password", "''"]
|
32 |
+
else:
|
33 |
+
ytdl_opts += ["--cookies" if commandline else "cookiefile", cookies()]
|
34 |
+
|
35 |
+
elif isinstance(ytdl_opts, str):
|
36 |
+
if token_data:
|
37 |
+
ytdl_opts += "--username oauth2 --password '' " if commandline else "username oauth2 password '' "
|
38 |
+
else:
|
39 |
+
ytdl_opts += f"--cookies {cookies()}" if commandline else f"cookiefile {cookies()}"
|
40 |
+
|
41 |
+
elif isinstance(ytdl_opts, dict):
|
42 |
+
if token_data:
|
43 |
+
ytdl_opts.update({"username": "oauth2", "password": ""})
|
44 |
+
else:
|
45 |
+
ytdl_opts["cookiefile"] = cookies()
|
46 |
+
|
47 |
+
return ytdl_opts
|
48 |
+
|
49 |
+
|
50 |
+
async def shell_cmd(cmd):
|
51 |
+
proc = await asyncio.create_subprocess_shell(
|
52 |
+
cmd,
|
53 |
+
stdout=asyncio.subprocess.PIPE,
|
54 |
+
stderr=asyncio.subprocess.PIPE,
|
55 |
+
)
|
56 |
+
out, errorz = await proc.communicate()
|
57 |
+
if errorz:
|
58 |
+
if "unavailable videos are hidden" in (errorz.decode("utf-8")).lower():
|
59 |
+
return out.decode("utf-8")
|
60 |
+
else:
|
61 |
+
return errorz.decode("utf-8")
|
62 |
+
return out.decode("utf-8")
|
63 |
+
|
64 |
+
|
65 |
+
class YouTubeAPI:
|
66 |
+
def __init__(self):
|
67 |
+
self.base = "https://www.youtube.com/watch?v="
|
68 |
+
self.regex = r"(?:youtube\.com|youtu\.be)"
|
69 |
+
self.status = "https://www.youtube.com/oembed?url="
|
70 |
+
self.listbase = "https://youtube.com/playlist?list="
|
71 |
+
self.reg = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
72 |
+
|
73 |
+
async def exists(self, link: str, videoid: Union[bool, str] = None):
|
74 |
+
if videoid:
|
75 |
+
link = self.base + link
|
76 |
+
if re.search(self.regex, link):
|
77 |
+
return True
|
78 |
+
else:
|
79 |
+
return False
|
80 |
+
|
81 |
+
async def url(self, message_1: Message) -> Union[str, None]:
|
82 |
+
messages = [message_1]
|
83 |
+
if message_1.reply_to_message:
|
84 |
+
messages.append(message_1.reply_to_message)
|
85 |
+
text = ""
|
86 |
+
offset = None
|
87 |
+
length = None
|
88 |
+
for message in messages:
|
89 |
+
if offset:
|
90 |
+
break
|
91 |
+
if message.entities:
|
92 |
+
for entity in message.entities:
|
93 |
+
if entity.type == MessageEntityType.URL:
|
94 |
+
text = message.text or message.caption
|
95 |
+
offset, length = entity.offset, entity.length
|
96 |
+
break
|
97 |
+
elif message.caption_entities:
|
98 |
+
for entity in message.caption_entities:
|
99 |
+
if entity.type == MessageEntityType.TEXT_LINK:
|
100 |
+
return entity.url
|
101 |
+
if offset in (None,):
|
102 |
+
return None
|
103 |
+
return text[offset : offset + length]
|
104 |
+
|
105 |
+
async def details(self, link: str, videoid: Union[bool, str] = None):
|
106 |
+
if videoid:
|
107 |
+
link = self.base + link
|
108 |
+
if "&" in link:
|
109 |
+
link = link.split("&")[0]
|
110 |
+
results = VideosSearch(link, limit=1)
|
111 |
+
for result in (await results.next())["result"]:
|
112 |
+
title = result["title"]
|
113 |
+
duration_min = result["duration"]
|
114 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
115 |
+
vidid = result["id"]
|
116 |
+
if str(duration_min) == "None":
|
117 |
+
duration_sec = 0
|
118 |
+
else:
|
119 |
+
duration_sec = int(time_to_seconds(duration_min))
|
120 |
+
return title, duration_min, duration_sec, thumbnail, vidid
|
121 |
+
|
122 |
+
async def title(self, link: str, videoid: Union[bool, str] = None):
|
123 |
+
if videoid:
|
124 |
+
link = self.base + link
|
125 |
+
if "&" in link:
|
126 |
+
link = link.split("&")[0]
|
127 |
+
results = VideosSearch(link, limit=1)
|
128 |
+
for result in (await results.next())["result"]:
|
129 |
+
title = result["title"]
|
130 |
+
return title
|
131 |
+
|
132 |
+
async def duration(self, link: str, videoid: Union[bool, str] = None):
|
133 |
+
if videoid:
|
134 |
+
link = self.base + link
|
135 |
+
if "&" in link:
|
136 |
+
link = link.split("&")[0]
|
137 |
+
results = VideosSearch(link, limit=1)
|
138 |
+
for result in (await results.next())["result"]:
|
139 |
+
duration = result["duration"]
|
140 |
+
return duration
|
141 |
+
|
142 |
+
async def thumbnail(self, link: str, videoid: Union[bool, str] = None):
|
143 |
+
if videoid:
|
144 |
+
link = self.base + link
|
145 |
+
if "&" in link:
|
146 |
+
link = link.split("&")[0]
|
147 |
+
results = VideosSearch(link, limit=1)
|
148 |
+
for result in (await results.next())["result"]:
|
149 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
150 |
+
return thumbnail
|
151 |
+
|
152 |
+
async def video(self, link: str, videoid: Union[bool, str] = None):
|
153 |
+
if videoid:
|
154 |
+
link = self.base + link
|
155 |
+
if "&" in link:
|
156 |
+
link = link.split("&")[0]
|
157 |
+
cmd = [
|
158 |
+
"yt-dlp",
|
159 |
+
"-g",
|
160 |
+
"-f",
|
161 |
+
"best[height<=?720][width<=?1280]",
|
162 |
+
f"{link}",
|
163 |
+
]
|
164 |
+
cmd = get_ytdl_options(cmd)
|
165 |
+
proc = await asyncio.create_subprocess_exec(
|
166 |
+
*cmd,
|
167 |
+
stdout=asyncio.subprocess.PIPE,
|
168 |
+
stderr=asyncio.subprocess.PIPE,
|
169 |
+
)
|
170 |
+
stdout, stderr = await proc.communicate()
|
171 |
+
if stdout:
|
172 |
+
return 1, stdout.decode().split("\n")[0]
|
173 |
+
else:
|
174 |
+
return 0, stderr.decode()
|
175 |
+
|
176 |
+
async def playlist(self, link, limit, user_id, videoid: Union[bool, str] = None):
|
177 |
+
if videoid:
|
178 |
+
link = self.listbase + link
|
179 |
+
if "&" in link:
|
180 |
+
link = link.split("&")[0]
|
181 |
+
|
182 |
+
cmd = get_ytdl_options(
|
183 |
+
f"yt-dlp -i --get-id --flat-playlist --playlist-end {limit} --skip-download {link}"
|
184 |
+
)
|
185 |
+
playlist = await shell_cmd(cmd)
|
186 |
+
try:
|
187 |
+
result = playlist.split("\n")
|
188 |
+
for key in result:
|
189 |
+
if key == "":
|
190 |
+
result.remove(key)
|
191 |
+
except:
|
192 |
+
result = []
|
193 |
+
return result
|
194 |
+
|
195 |
+
async def track(self, link: str, videoid: Union[bool, str] = None):
|
196 |
+
if videoid:
|
197 |
+
link = self.base + link
|
198 |
+
if "&" in link:
|
199 |
+
link = link.split("&")[0]
|
200 |
+
results = VideosSearch(link, limit=1)
|
201 |
+
for result in (await results.next())["result"]:
|
202 |
+
title = result["title"]
|
203 |
+
duration_min = result["duration"]
|
204 |
+
vidid = result["id"]
|
205 |
+
yturl = result["link"]
|
206 |
+
thumbnail = result["thumbnails"][0]["url"].split("?")[0]
|
207 |
+
track_details = {
|
208 |
+
"title": title,
|
209 |
+
"link": yturl,
|
210 |
+
"vidid": vidid,
|
211 |
+
"duration_min": duration_min,
|
212 |
+
"thumb": thumbnail,
|
213 |
+
}
|
214 |
+
return track_details, vidid
|
215 |
+
|
216 |
+
async def formats(self, link: str, videoid: Union[bool, str] = None):
|
217 |
+
if videoid:
|
218 |
+
link = self.base + link
|
219 |
+
if "&" in link:
|
220 |
+
link = link.split("&")[0]
|
221 |
+
|
222 |
+
ytdl_opts = {
|
223 |
+
"quiet": True,
|
224 |
+
}
|
225 |
+
ytdl_opts = get_ytdl_options(ytdl_opts, False)
|
226 |
+
|
227 |
+
ydl = YoutubeDL(ytdl_opts)
|
228 |
+
with ydl:
|
229 |
+
formats_available = []
|
230 |
+
r = ydl.extract_info(link, download=False)
|
231 |
+
for format in r["formats"]:
|
232 |
+
try:
|
233 |
+
str(format["format"])
|
234 |
+
except Exception:
|
235 |
+
continue
|
236 |
+
if "dash" not in str(format["format"]).lower():
|
237 |
+
try:
|
238 |
+
format["format"]
|
239 |
+
format["filesize"]
|
240 |
+
format["format_id"]
|
241 |
+
format["ext"]
|
242 |
+
format["format_note"]
|
243 |
+
except KeyError:
|
244 |
+
continue
|
245 |
+
formats_available.append(
|
246 |
+
{
|
247 |
+
"format": format["format"],
|
248 |
+
"filesize": format["filesize"],
|
249 |
+
"format_id": format["format_id"],
|
250 |
+
"ext": format["ext"],
|
251 |
+
"format_note": format["format_note"],
|
252 |
+
"yturl": link,
|
253 |
+
}
|
254 |
+
)
|
255 |
+
return formats_available, link
|
256 |
+
|
257 |
+
async def slider(
|
258 |
+
self,
|
259 |
+
link: str,
|
260 |
+
query_type: int,
|
261 |
+
videoid: Union[bool, str] = None,
|
262 |
+
):
|
263 |
+
if videoid:
|
264 |
+
link = self.base + link
|
265 |
+
if "&" in link:
|
266 |
+
link = link.split("&")[0]
|
267 |
+
a = VideosSearch(link, limit=10)
|
268 |
+
result = (await a.next()).get("result")
|
269 |
+
title = result[query_type]["title"]
|
270 |
+
duration_min = result[query_type]["duration"]
|
271 |
+
vidid = result[query_type]["id"]
|
272 |
+
thumbnail = result[query_type]["thumbnails"][0]["url"].split("?")[0]
|
273 |
+
return title, duration_min, thumbnail, vidid
|
274 |
+
|
275 |
+
async def download(
|
276 |
+
self,
|
277 |
+
link: str,
|
278 |
+
mystic,
|
279 |
+
video: Union[bool, str] = None,
|
280 |
+
videoid: Union[bool, str] = None,
|
281 |
+
songaudio: Union[bool, str] = None,
|
282 |
+
songvideo: Union[bool, str] = None,
|
283 |
+
format_id: Union[bool, str] = None,
|
284 |
+
title: Union[bool, str] = None,
|
285 |
+
) -> str:
|
286 |
+
if videoid:
|
287 |
+
link = self.base + link
|
288 |
+
loop = asyncio.get_running_loop()
|
289 |
+
|
290 |
+
def audio_dl():
|
291 |
+
ydl_optssx = {
|
292 |
+
"format": "bestaudio/best",
|
293 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
294 |
+
"geo_bypass": True,
|
295 |
+
"nocheckcertificate": True,
|
296 |
+
"quiet": True,
|
297 |
+
"no_warnings": True,
|
298 |
+
}
|
299 |
+
ydl_optssx = get_ytdl_options(ydl_optssx, False)
|
300 |
+
|
301 |
+
x = YoutubeDL(ydl_optssx)
|
302 |
+
info = x.extract_info(link, False)
|
303 |
+
xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}")
|
304 |
+
if os.path.exists(xyz):
|
305 |
+
return xyz
|
306 |
+
x.download([link])
|
307 |
+
return xyz
|
308 |
+
|
309 |
+
def video_dl():
|
310 |
+
ydl_optssx = {
|
311 |
+
"format": "(bestvideo[height<=?720][width<=?1280][ext=mp4])+(bestaudio[ext=m4a])",
|
312 |
+
"outtmpl": "downloads/%(id)s.%(ext)s",
|
313 |
+
"geo_bypass": True,
|
314 |
+
"nocheckcertificate": True,
|
315 |
+
"quiet": True,
|
316 |
+
"no_warnings": True,
|
317 |
+
}
|
318 |
+
ydl_optssx = get_ytdl_options(ydl_optssx, False)
|
319 |
+
|
320 |
+
x = YoutubeDL(ydl_optssx)
|
321 |
+
info = x.extract_info(link, False)
|
322 |
+
xyz = os.path.join("downloads", f"{info['id']}.{info['ext']}")
|
323 |
+
if os.path.exists(xyz):
|
324 |
+
return xyz
|
325 |
+
x.download([link])
|
326 |
+
return xyz
|
327 |
+
|
328 |
+
def song_video_dl():
|
329 |
+
formats = f"{format_id}+140"
|
330 |
+
fpath = f"downloads/{title}"
|
331 |
+
ydl_optssx = {
|
332 |
+
"format": formats,
|
333 |
+
"outtmpl": fpath,
|
334 |
+
"geo_bypass": True,
|
335 |
+
"nocheckcertificate": True,
|
336 |
+
"quiet": True,
|
337 |
+
"no_warnings": True,
|
338 |
+
"prefer_ffmpeg": True,
|
339 |
+
"merge_output_format": "mp4",
|
340 |
+
}
|
341 |
+
ydl_optssx = get_ytdl_options(ydl_optssx, False)
|
342 |
+
|
343 |
+
x = YoutubeDL(ydl_optssx)
|
344 |
+
x.download([link])
|
345 |
+
|
346 |
+
def song_audio_dl():
|
347 |
+
fpath = f"downloads/{title}.%(ext)s"
|
348 |
+
ydl_optssx = {
|
349 |
+
"format": format_id,
|
350 |
+
"outtmpl": fpath,
|
351 |
+
"geo_bypass": True,
|
352 |
+
"nocheckcertificate": True,
|
353 |
+
"quiet": True,
|
354 |
+
"no_warnings": True,
|
355 |
+
"prefer_ffmpeg": True,
|
356 |
+
"postprocessors": [
|
357 |
+
{
|
358 |
+
"key": "FFmpegExtractAudio",
|
359 |
+
"preferredcodec": "mp3",
|
360 |
+
"preferredquality": "192",
|
361 |
+
}
|
362 |
+
],
|
363 |
+
}
|
364 |
+
ydl_optssx = get_ytdl_options(ydl_optssx, False)
|
365 |
+
|
366 |
+
x = YoutubeDL(ydl_optssx)
|
367 |
+
x.download([link])
|
368 |
+
|
369 |
+
if songvideo:
|
370 |
+
await loop.run_in_executor(None, song_video_dl)
|
371 |
+
fpath = f"downloads/{title}.mp4"
|
372 |
+
return fpath
|
373 |
+
elif songaudio:
|
374 |
+
await loop.run_in_executor(None, song_audio_dl)
|
375 |
+
fpath = f"downloads/{title}.mp3"
|
376 |
+
return fpath
|
377 |
+
elif video:
|
378 |
+
if await is_on_off(config.YTDOWNLOADER):
|
379 |
+
direct = True
|
380 |
+
downloaded_file = await loop.run_in_executor(None, video_dl)
|
381 |
+
else:
|
382 |
+
command = [
|
383 |
+
"yt-dlp",
|
384 |
+
"-g",
|
385 |
+
"-f",
|
386 |
+
"best[height<=?720][width<=?1280]",
|
387 |
+
link,
|
388 |
+
]
|
389 |
+
command = get_ytdl_options(command)
|
390 |
+
|
391 |
+
proc = await asyncio.create_subprocess_exec(
|
392 |
+
*command,
|
393 |
+
stdout=asyncio.subprocess.PIPE,
|
394 |
+
stderr=asyncio.subprocess.PIPE,
|
395 |
+
)
|
396 |
+
stdout, stderr = await proc.communicate()
|
397 |
+
|
398 |
+
if stdout:
|
399 |
+
downloaded_file = stdout.decode().split("\n")[0]
|
400 |
+
direct = None
|
401 |
+
else:
|
402 |
+
return
|
403 |
+
else:
|
404 |
+
direct = True
|
405 |
+
downloaded_file = await loop.run_in_executor(None, audio_dl)
|
406 |
+
|
407 |
+
return downloaded_file, direct
|
Devine/platforms/__init__.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .Apple import AppleAPI
|
2 |
+
from .Carbon import CarbonAPI
|
3 |
+
from .Resso import RessoAPI
|
4 |
+
from .Soundcloud import SoundAPI
|
5 |
+
from .Spotify import SpotifyAPI
|
6 |
+
from .Telegram import TeleAPI
|
7 |
+
from .Youtube import YouTubeAPI
|
Devine/plugins/Dev/fonts.py
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
3 |
+
|
4 |
+
from Devine.utils.fonts import Fonts
|
5 |
+
from Devine import app
|
6 |
+
|
7 |
+
@app.on_message(filters.command(["font", "fonts"]))
|
8 |
+
async def style_buttons(c, m, cb=False):
|
9 |
+
text = m.text.split(' ',1)[1]
|
10 |
+
buttons = [
|
11 |
+
[
|
12 |
+
InlineKeyboardButton("𝗦𝗮𝗻𝘀", callback_data="style+sans"),
|
13 |
+
InlineKeyboardButton("𝙎𝙖𝙣𝙨", callback_data="style+slant_sans"),
|
14 |
+
InlineKeyboardButton("𝖲𝖺𝗇𝗌", callback_data="style+sim"),
|
15 |
+
],
|
16 |
+
[
|
17 |
+
InlineKeyboardButton("𝘚𝘢𝘯𝘴", callback_data="style+slant"),
|
18 |
+
InlineKeyboardButton("𝐒𝐞𝐫𝐢𝐟", callback_data="style+serif"),
|
19 |
+
InlineKeyboardButton("𝑺𝒆𝒓𝒊𝒇", callback_data="style+bold_cool"),
|
20 |
+
],
|
21 |
+
[
|
22 |
+
InlineKeyboardButton("𝑆𝑒𝑟𝑖𝑓", callback_data="style+cool"),
|
23 |
+
InlineKeyboardButton("𝓈𝒸𝓇𝒾𝓅𝓉", callback_data="style+script"),
|
24 |
+
InlineKeyboardButton("𝓼𝓬𝓻𝓲𝓹𝓽", callback_data="style+script_bolt"),
|
25 |
+
],
|
26 |
+
[
|
27 |
+
InlineKeyboardButton("Sᴍᴀʟʟ Cᴀᴘs", callback_data="style+small_cap"),
|
28 |
+
InlineKeyboardButton("🅒︎🅘︎🅡︎🅒︎🅛︎🅔︎🅢︎", callback_data="style+circle_dark"),
|
29 |
+
InlineKeyboardButton("Ⓒ︎Ⓘ︎Ⓡ︎Ⓒ︎Ⓛ︎Ⓔ︎Ⓢ︎", callback_data="style+circles"),
|
30 |
+
],
|
31 |
+
[
|
32 |
+
InlineKeyboardButton("𝕲𝖔𝖙𝖍𝖎𝖈", callback_data="style+gothic_bolt"),
|
33 |
+
InlineKeyboardButton("𝔊𝔬𝔱𝔥𝔦𝔠", callback_data="style+gothic"),
|
34 |
+
InlineKeyboardButton("ᵗⁱⁿʸ", callback_data="style+tiny"),
|
35 |
+
],
|
36 |
+
[
|
37 |
+
InlineKeyboardButton("𝚃𝚢𝚙𝚎𝚠𝚛𝚒𝚝𝚎𝚛", callback_data="style+typewriter"),
|
38 |
+
InlineKeyboardButton("𝕆𝕦𝕥𝕝𝕚𝕟𝕖", callback_data="style+outline"),
|
39 |
+
InlineKeyboardButton("ᑕOᗰIᑕ", callback_data="style+comic"),
|
40 |
+
],
|
41 |
+
[
|
42 |
+
InlineKeyboardButton("C͜͡l͜͡o͜͡u͜͡d͜͡s͜͡", callback_data="style+cloud"),
|
43 |
+
InlineKeyboardButton("H̆̈ă̈p̆̈p̆̈y̆̈", callback_data="style+happy"),
|
44 |
+
InlineKeyboardButton("S̑̈ȃ̈d̑̈", callback_data="style+sad"),
|
45 |
+
],
|
46 |
+
[
|
47 |
+
InlineKeyboardButton ("ᴄʟᴏsᴇ",callback_data="close_reply"),InlineKeyboardButton ("ɴᴇxᴛ", callback_data="nxt")],
|
48 |
+
]
|
49 |
+
if not cb:
|
50 |
+
await m.reply_text(
|
51 |
+
f"{text}", reply_markup=InlineKeyboardMarkup(buttons), quote=True
|
52 |
+
)
|
53 |
+
else:
|
54 |
+
await m.answer()
|
55 |
+
await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons))
|
56 |
+
|
57 |
+
|
58 |
+
@app.on_callback_query(filters.regex("^nxt"))
|
59 |
+
async def nxt(c, m):
|
60 |
+
if m.data == "nxt":
|
61 |
+
buttons = [
|
62 |
+
[
|
63 |
+
InlineKeyboardButton("🇸 🇵 🇪 🇨 🇮 🇦 🇱 ", callback_data="style+special"),
|
64 |
+
InlineKeyboardButton("🅂🅀🅄🄰🅁🄴🅂", callback_data="style+squares"),
|
65 |
+
InlineKeyboardButton(
|
66 |
+
"🆂︎🆀︎🆄︎🅰︎🆁︎🅴︎🆂︎", callback_data="style+squares_bold"
|
67 |
+
),
|
68 |
+
],
|
69 |
+
[
|
70 |
+
InlineKeyboardButton("ꪖꪀᦔꪖꪶꪊᥴ𝓲ꪖ", callback_data="style+andalucia"),
|
71 |
+
InlineKeyboardButton("爪卂几ᘜ卂", callback_data="style+manga"),
|
72 |
+
InlineKeyboardButton("S̾t̾i̾n̾k̾y̾", callback_data="style+stinky"),
|
73 |
+
],
|
74 |
+
[
|
75 |
+
InlineKeyboardButton(
|
76 |
+
"B̥ͦu̥ͦb̥ͦb̥ͦl̥ͦe̥ͦs̥ͦ", callback_data="style+bubbles"
|
77 |
+
),
|
78 |
+
InlineKeyboardButton(
|
79 |
+
"U͟n͟d͟e͟r͟l͟i͟n͟e͟", callback_data="style+underline"
|
80 |
+
),
|
81 |
+
InlineKeyboardButton("꒒ꍏꀷꌩꌃꀎꁅ", callback_data="style+ladybug"),
|
82 |
+
],
|
83 |
+
[
|
84 |
+
InlineKeyboardButton("R҉a҉y҉s҉", callback_data="style+rays"),
|
85 |
+
InlineKeyboardButton("B҈i҈r҈d҈s҈", callback_data="style+birds"),
|
86 |
+
InlineKeyboardButton("S̸l̸a̸s̸h̸", callback_data="style+slash"),
|
87 |
+
],
|
88 |
+
[
|
89 |
+
InlineKeyboardButton("s⃠t⃠o⃠p⃠", callback_data="style+stop"),
|
90 |
+
InlineKeyboardButton(
|
91 |
+
"S̺͆k̺͆y̺͆l̺͆i̺͆n̺͆e̺͆", callback_data="style+skyline"
|
92 |
+
),
|
93 |
+
InlineKeyboardButton("A͎r͎r͎o͎w͎s͎", callback_data="style+arrows"),
|
94 |
+
],
|
95 |
+
[
|
96 |
+
InlineKeyboardButton("ዪሀክቿነ", callback_data="style+qvnes"),
|
97 |
+
InlineKeyboardButton("S̶t̶r̶i̶k̶e̶", callback_data="style+strike"),
|
98 |
+
InlineKeyboardButton("F༙r༙o༙z༙e༙n༙", callback_data="style+frozen"),
|
99 |
+
],
|
100 |
+
[
|
101 |
+
InlineKeyboardButton ("ᴄʟᴏsᴇ",callback_data="close_reply"),InlineKeyboardButton ("ʙᴀᴄᴋ", callback_data="nxt+0")],
|
102 |
+
]
|
103 |
+
await m.answer()
|
104 |
+
await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons))
|
105 |
+
else:
|
106 |
+
await style_buttons(c, m, cb=True)
|
107 |
+
|
108 |
+
|
109 |
+
@app.on_callback_query(filters.regex("^style"))
|
110 |
+
async def style(c, m):
|
111 |
+
await m.answer()
|
112 |
+
cmd,style = m.data.split('+')
|
113 |
+
if style == "typewriter":
|
114 |
+
cls = Fonts.typewriter
|
115 |
+
if style == "outline":
|
116 |
+
cls = Fonts.outline
|
117 |
+
if style == "serif":
|
118 |
+
cls = Fonts.serief
|
119 |
+
if style == "bold_cool":
|
120 |
+
cls = Fonts.bold_cool
|
121 |
+
if style == "cool":
|
122 |
+
cls = Fonts.cool
|
123 |
+
if style == "small_cap":
|
124 |
+
cls = Fonts.smallcap
|
125 |
+
if style == "script":
|
126 |
+
cls = Fonts.script
|
127 |
+
if style == "script_bolt":
|
128 |
+
cls = Fonts.bold_script
|
129 |
+
if style == "tiny":
|
130 |
+
cls = Fonts.tiny
|
131 |
+
if style == "comic":
|
132 |
+
cls = Fonts.comic
|
133 |
+
if style == "sans":
|
134 |
+
cls = Fonts.san
|
135 |
+
if style == "slant_sans":
|
136 |
+
cls = Fonts.slant_san
|
137 |
+
if style == "slant":
|
138 |
+
cls = Fonts.slant
|
139 |
+
if style == "sim":
|
140 |
+
cls = Fonts.sim
|
141 |
+
if style == "circles":
|
142 |
+
cls = Fonts.circles
|
143 |
+
if style == "circle_dark":
|
144 |
+
cls = Fonts.dark_circle
|
145 |
+
if style == "gothic":
|
146 |
+
cls = Fonts.gothic
|
147 |
+
if style == "gothic_bolt":
|
148 |
+
cls = Fonts.bold_gothic
|
149 |
+
if style == "cloud":
|
150 |
+
cls = Fonts.cloud
|
151 |
+
if style == "happy":
|
152 |
+
cls = Fonts.happy
|
153 |
+
if style == "sad":
|
154 |
+
cls = Fonts.sad
|
155 |
+
if style == "special":
|
156 |
+
cls = Fonts.special
|
157 |
+
if style == "squares":
|
158 |
+
cls = Fonts.square
|
159 |
+
if style == "squares_bold":
|
160 |
+
cls = Fonts.dark_square
|
161 |
+
if style == "andalucia":
|
162 |
+
cls = Fonts.andalucia
|
163 |
+
if style == "manga":
|
164 |
+
cls = Fonts.manga
|
165 |
+
if style == "stinky":
|
166 |
+
cls = Fonts.stinky
|
167 |
+
if style == "bubbles":
|
168 |
+
cls = Fonts.bubbles
|
169 |
+
if style == "underline":
|
170 |
+
cls = Fonts.underline
|
171 |
+
if style == "ladybug":
|
172 |
+
cls = Fonts.ladybug
|
173 |
+
if style == "rays":
|
174 |
+
cls = Fonts.rays
|
175 |
+
if style == "birds":
|
176 |
+
cls = Fonts.birds
|
177 |
+
if style == "slash":
|
178 |
+
cls = Fonts.slash
|
179 |
+
if style == "stop":
|
180 |
+
cls = Fonts.stop
|
181 |
+
if style == "skyline":
|
182 |
+
cls = Fonts.skyline
|
183 |
+
if style == "arrows":
|
184 |
+
cls = Fonts.arrows
|
185 |
+
if style == "qvnes":
|
186 |
+
cls = Fonts.rvnes
|
187 |
+
if style == "strike":
|
188 |
+
cls = Fonts.strike
|
189 |
+
if style == "frozen":
|
190 |
+
cls = Fonts.frozen
|
191 |
+
#text = m.text.split(' ',1)[1]
|
192 |
+
new_text = cls(m.message.reply_to_message.text.split(" ",1)[1])
|
193 |
+
try:
|
194 |
+
await m.message.edit_text(new_text, reply_markup=m.message.reply_markup)
|
195 |
+
except:
|
196 |
+
pass
|
Devine/plugins/Dev/groupdata.py
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import time
|
3 |
+
from asyncio import sleep
|
4 |
+
from pyrogram import Client, filters
|
5 |
+
from pyrogram import enums, filters
|
6 |
+
from config import OWNER_ID, SPECIAL_USER_ID
|
7 |
+
from Devine import app
|
8 |
+
|
9 |
+
@app.on_message(~filters.private & filters.command(["groupdata"]), group=2)
|
10 |
+
async def instatus(app, message):
|
11 |
+
start_time = time.perf_counter()
|
12 |
+
user = await app.get_chat_member(message.chat.id, message.from_user.id)
|
13 |
+
count = await app.get_chat_members_count(message.chat.id)
|
14 |
+
|
15 |
+
if user.status in (
|
16 |
+
enums.ChatMemberStatus.ADMINISTRATOR,
|
17 |
+
enums.ChatMemberStatus.OWNER,
|
18 |
+
) or message.from_user.id in {OWNER_ID, SPECIAL_USER_ID}:
|
19 |
+
sent_message = await message.reply_text("ɢᴇᴛᴛɪɴɢ ɪɴғᴏʀᴍᴀᴛɪᴏɴ...")
|
20 |
+
deleted_acc = 0
|
21 |
+
premium_acc = 0
|
22 |
+
banned = 0
|
23 |
+
bot = 0
|
24 |
+
uncached = 0
|
25 |
+
|
26 |
+
async for ban in app.get_chat_members(message.chat.id, filter=enums.ChatMembersFilter.BANNED):
|
27 |
+
banned += 1
|
28 |
+
|
29 |
+
async for member in app.get_chat_members(message.chat.id):
|
30 |
+
user = member.user
|
31 |
+
if user.is_deleted:
|
32 |
+
deleted_acc += 1
|
33 |
+
elif user.is_bot:
|
34 |
+
bot += 1
|
35 |
+
elif user.is_premium:
|
36 |
+
premium_acc += 1
|
37 |
+
else:
|
38 |
+
uncached += 1
|
39 |
+
|
40 |
+
end_time = time.perf_counter()
|
41 |
+
timelog = "{:.2f}".format(end_time - start_time)
|
42 |
+
await sent_message.edit(f"""
|
43 |
+
<b>• ɴᴀᴍᴇ : {message.chat.title}</b>
|
44 |
+
<b>• ᴍᴇᴍʙᴇʀs : {count}</b>
|
45 |
+
<b>• ʙᴏᴛs : {bot}</b>
|
46 |
+
<b>• ᴢᴏᴍʙɪᴇs : {deleted_acc}</b>
|
47 |
+
<b>• ʙᴀɴɴᴇᴅ ᴜsᴇʀs : {banned}</b>
|
48 |
+
<b>• ᴘʀᴇᴍɪᴜᴍ ᴜsᴇʀs : {premium_acc}</b>\n
|
49 |
+
<b>↬ ᴛɪᴍᴇ ᴛᴀᴋᴇɴ : {timelog}s</b>""")
|
50 |
+
else:
|
51 |
+
sent_message = await message.reply_text("ᴏɴʟʏ ᴀᴅᴍɪɴ ᴄᴀɴ ᴇxᴇᴄᴜᴛᴇ ᴛʜᴇ ᴄᴏᴍᴍᴀɴᴅ !")
|
52 |
+
await sleep(5)
|
53 |
+
await sent_message.delete()
|
Devine/plugins/Dev/groupinfo.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import Client, filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
from Devine import app
|
4 |
+
|
5 |
+
@app.on_message(filters.command("groupinfo", prefixes="/"))
|
6 |
+
async def get_group_status(_, message: Message):
|
7 |
+
if len(message.command) != 2:
|
8 |
+
await message.reply("ᴘʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ ɢʀᴏᴜᴘ ᴜsᴇʀɴᴀᴍᴇ. ᴇxᴀᴍᴘʟᴇ: `/groupinfo YourGroupUsername`")
|
9 |
+
return
|
10 |
+
|
11 |
+
group_username = message.command[1]
|
12 |
+
|
13 |
+
try:
|
14 |
+
group = await app.get_chat(group_username)
|
15 |
+
except Exception as e:
|
16 |
+
await message.reply(f"ᴇʀʀᴏʀ: {e}")
|
17 |
+
return
|
18 |
+
|
19 |
+
total_members = await app.get_chat_members_count(group.id)
|
20 |
+
group_description = group.description
|
21 |
+
premium_acc = banned = deleted_acc = bot = 0 # Replace with actual counts.
|
22 |
+
|
23 |
+
# Close the parenthesis here
|
24 |
+
response_text = (
|
25 |
+
f"➲ ɢʀᴏᴜᴘ ɴᴀᴍᴇ : {group.title}\n"
|
26 |
+
f"➲ ɢʀᴏᴜᴘ ɪᴅ : <code>{group.id}</code>\n"
|
27 |
+
f"➲ ᴛᴏᴛᴀʟ ᴍᴇᴍʙᴇʀs : {total_members}\n"
|
28 |
+
f"➲ ᴅᴇsᴄʀɪᴘᴛɪᴏɴ : {group_description or 'N/A'}\n"
|
29 |
+
f"➲ ᴜsᴇʀɴᴀᴍᴇ : {group_username}.t.me\n"
|
30 |
+
) # <-- This closes the string
|
31 |
+
|
32 |
+
await message.reply(response_text)
|
33 |
+
|
34 |
+
|
35 |
+
# Command handler to get group status
|
36 |
+
@app.on_message(filters.command("cstatus") & filters.group)
|
37 |
+
def group_status(client, message):
|
38 |
+
chat = message.chat # Chat where the command was sent
|
39 |
+
status_text = (
|
40 |
+
f"ɢʀᴏᴜᴘ ɪᴅ: {chat.id}\n"
|
41 |
+
f"ᴛɪᴛʟᴇ: <code>{chat.title}</code>\n"
|
42 |
+
f"ᴛʏᴘᴇ: {chat.type}\n"
|
43 |
+
)
|
44 |
+
|
45 |
+
if chat.username: # Not all groups have a username
|
46 |
+
status_text += f"ᴜsᴇʀɴᴀᴍᴇ: {chat.username}.t.me"
|
47 |
+
else:
|
48 |
+
status_text += "ᴜsᴇʀɴᴀᴍᴇ: None"
|
49 |
+
|
50 |
+
message.reply_text(status_text)
|
Devine/plugins/Dev/password.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import string
|
3 |
+
from pyrogram import Client, filters, enums
|
4 |
+
from Devine import app
|
5 |
+
|
6 |
+
def generate_strong_password(length):
|
7 |
+
# Define character sets
|
8 |
+
lowercase = string.ascii_lowercase
|
9 |
+
uppercase = string.ascii_uppercase
|
10 |
+
digits = string.digits
|
11 |
+
special_chars = "!@#$%^&*()_+"
|
12 |
+
|
13 |
+
# Ensure the password has at least one character from each set
|
14 |
+
password = [
|
15 |
+
random.choice(lowercase),
|
16 |
+
random.choice(uppercase),
|
17 |
+
random.choice(digits),
|
18 |
+
random.choice(special_chars),
|
19 |
+
]
|
20 |
+
|
21 |
+
# Fill the rest of the password length with random choices from all sets
|
22 |
+
all_chars = lowercase + uppercase + digits + special_chars
|
23 |
+
password += random.choices(all_chars, k=length - len(password))
|
24 |
+
|
25 |
+
# Shuffle to prevent predictable patterns
|
26 |
+
random.shuffle(password)
|
27 |
+
|
28 |
+
# Join the list into a string
|
29 |
+
return ''.join(password)
|
30 |
+
|
31 |
+
@app.on_message(filters.command(["genpass", 'genpw', "genpassword"]))
|
32 |
+
async def password(bot, update):
|
33 |
+
message = await update.reply_text(text="ᴘʀᴏᴄᴇꜱꜱɪɴɢ...")
|
34 |
+
|
35 |
+
if len(update.command) > 1:
|
36 |
+
qw = update.text.split(" ", 1)[1]
|
37 |
+
else:
|
38 |
+
ST = ["12", "14", "16", "18", "20"] # Stronger password length
|
39 |
+
qw = random.choice(ST)
|
40 |
+
|
41 |
+
limit = int(qw)
|
42 |
+
random_value = generate_strong_password(limit)
|
43 |
+
|
44 |
+
txt = f"<b>ʟɪᴍɪᴛ :</b> {str(limit)} \n<b> ᴘᴀꜱꜱᴡᴏʀᴅ: <code>{random_value}</code>"
|
45 |
+
|
46 |
+
await message.edit_text(text=txt, parse_mode=enums.ParseMode.HTML)
|
Devine/plugins/Dev/sangmeta.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import random
|
3 |
+
from pyrogram import Client, filters
|
4 |
+
from pyrogram.types import Message
|
5 |
+
from pyrogram.raw.functions.messages import DeleteHistory
|
6 |
+
from Devine import userbot as us, app
|
7 |
+
from Devine.core.userbot import assistants
|
8 |
+
|
9 |
+
|
10 |
+
@app.on_message(filters.command(["sg", "sang", "sangmeta"]))
|
11 |
+
async def sg(client: Client, message: Message):
|
12 |
+
if len(message.command) < 2 and not message.reply_to_message:
|
13 |
+
return await message.reply("<b>ᴘʀᴏᴠɪᴅᴇ ᴀ ᴜsᴇʀɴᴀᴍᴇ, ᴜsᴇʀ ɪᴅ, ᴏʀ ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴜsᴇʀ's ᴍᴇssᴀɢᴇ.</b>")
|
14 |
+
|
15 |
+
if message.reply_to_message:
|
16 |
+
args = message.reply_to_message.from_user.id
|
17 |
+
else:
|
18 |
+
args = message.text.split()[1]
|
19 |
+
|
20 |
+
lol = await message.reply("<b>ᴘʀᴏᴄᴇssɪɴɢ...</b>")
|
21 |
+
|
22 |
+
try:
|
23 |
+
user = await client.get_users(f"{args}")
|
24 |
+
except Exception:
|
25 |
+
return await lol.edit("<b>sᴘᴇᴄɪғʏ ᴀ ᴠᴀʟɪᴅ ᴜsᴇʀ !</b>")
|
26 |
+
|
27 |
+
bo = ["sangmata_bot", "sangmata_beta_bot"]
|
28 |
+
sg = random.choice(bo)
|
29 |
+
|
30 |
+
if 1 in assistants:
|
31 |
+
ubot = us.one
|
32 |
+
|
33 |
+
try:
|
34 |
+
a = await ubot.send_message(sg, f"{user.id}")
|
35 |
+
await a.delete()
|
36 |
+
except Exception as e:
|
37 |
+
return await lol.edit(f"Error: {e}")
|
38 |
+
|
39 |
+
await asyncio.sleep(1)
|
40 |
+
|
41 |
+
async for stalk in ubot.search_messages(a.chat.id):
|
42 |
+
if stalk.text is None:
|
43 |
+
continue
|
44 |
+
if not stalk:
|
45 |
+
await message.reply("<b>ᴛʜᴇ ʙᴏᴛ ɪs ᴜɴʀᴇsᴘᴏɴsɪᴠᴇ.</b>")
|
46 |
+
elif stalk:
|
47 |
+
await message.reply(f"{stalk.text}")
|
48 |
+
break # Exit the loop after displaying one message
|
49 |
+
|
50 |
+
try:
|
51 |
+
user_info = await ubot.resolve_peer(sg)
|
52 |
+
await ubot.send(DeleteHistory(peer=user_info, max_id=0, revoke=True))
|
53 |
+
except Exception:
|
54 |
+
pass
|
55 |
+
|
56 |
+
await lol.delete()
|
Devine/plugins/Dev/truth_and_dare.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from pyrogram import Client, filters
|
3 |
+
from pyrogram.types import Message
|
4 |
+
|
5 |
+
from Devine import app
|
6 |
+
|
7 |
+
@app.on_message(filters.command("truth"))
|
8 |
+
async def truth(client: Client, message: Message):
|
9 |
+
truth = requests.get("https://api.truthordarebot.xyz/v1/truth").json()["question"]
|
10 |
+
await message.reply_text(truth)
|
11 |
+
|
12 |
+
|
13 |
+
@app.on_message(filters.command("dare"))
|
14 |
+
async def dare(client: Client, message: Message):
|
15 |
+
dare = requests.get("https://api.truthordarebot.xyz/v1/dare").json()["question"]
|
16 |
+
await message.reply_text(dare)
|
17 |
+
|
Devine/plugins/Dev/upload.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
from pyrogram import Client, filters
|
3 |
+
from Devine import app as Devine
|
4 |
+
import time
|
5 |
+
import asyncio
|
6 |
+
from config import OWNER_ID
|
7 |
+
|
8 |
+
CLOUDINARY_UPLOAD_URL = "https://api.cloudinary.com/v1_1/your_cloud_name/upload"
|
9 |
+
CLOUD_NAME = "Untitled"
|
10 |
+
API_KEY = "769593722143466"
|
11 |
+
API_SECRET = "DztGFORQqYfBoxCdawh0g5jBRCg"
|
12 |
+
MAX_FILE_SIZE_MB = 32
|
13 |
+
USER_UPLOAD_LIMIT = {}
|
14 |
+
|
15 |
+
async def send_temp_message(message, text):
|
16 |
+
reply = await message.reply(text)
|
17 |
+
|
18 |
+
for i in range(3):
|
19 |
+
await asyncio.sleep(0.3)
|
20 |
+
updated_text = text + '.' * (i + 1)
|
21 |
+
await reply.edit(updated_text)
|
22 |
+
|
23 |
+
return reply
|
24 |
+
|
25 |
+
async def upload_file(client, message, file_path):
|
26 |
+
waiting_message = await send_temp_message(message, "ᴡᴀɪᴛ")
|
27 |
+
|
28 |
+
start_time = time.time()
|
29 |
+
|
30 |
+
with open(file_path, 'rb') as file:
|
31 |
+
files = {
|
32 |
+
"file": file,
|
33 |
+
"api_key": API_KEY,
|
34 |
+
"timestamp": int(time.time()),
|
35 |
+
"signature": API_SECRET
|
36 |
+
|
37 |
+
response = requests.post(CLOUDINARY_UPLOAD_URL, data=files)
|
38 |
+
|
39 |
+
upload_time = round(time.time() - start_time, 2)
|
40 |
+
|
41 |
+
if response.status_code == 200:
|
42 |
+
response_data = response.json()
|
43 |
+
file_url = response_data["secure_url"]
|
44 |
+
|
45 |
+
await waiting_message.edit(f"<b>ᴜᴘʟᴏᴀᴅᴇᴅ ᴛᴏ <a href='{file_url}' target='_blank'>Cloudinary</a> ɪɴ {upload_time} sᴇᴄᴏɴᴅs.</b>\n\n"
|
46 |
+
f"<b>ᴄᴏᴘʏ ʟɪɴᴋ : <code>{file_url}</code></b> ")
|
47 |
+
else:
|
48 |
+
await waiting_message.edit("<b>ғᴀɪʟᴇᴅ ᴛᴏ ᴜᴘʟᴏᴀᴅ ᴛʜᴇ ғɪʟᴇ.</b>")
|
49 |
+
|
50 |
+
async def handle_upload(client, message, target_message):
|
51 |
+
user_id = message.from_user.id
|
52 |
+
current_time = time.time()
|
53 |
+
last_upload_time = USER_UPLOAD_LIMIT.get(user_id, 0)
|
54 |
+
|
55 |
+
if current_time - last_upload_time < 10:
|
56 |
+
await message.reply("<b>ʏᴏᴜ ᴀʀᴇ ʙᴇɪɴɢ ʀᴀᴛᴇ-ʟɪᴍɪᴛᴇᴅ. ᴛʀʏ ᴀɢᴀɪɴ ᴀғᴛᴇʀ 10 sᴇᴄᴏɴᴅs.</b>")
|
57 |
+
return
|
58 |
+
|
59 |
+
USER_UPLOAD_LIMIT[user_id] = current_time
|
60 |
+
|
61 |
+
file_size = (target_message.photo or target_message.video).file_size / (1024 * 1024)
|
62 |
+
if file_size > MAX_FILE_SIZE_MB:
|
63 |
+
await message.reply("<b>ғɪʟᴇ sɪᴢᴇ ᴇxᴄᴇᴇᴅs 32 ᴍʙ ʟɪᴍɪᴛ.</b>")
|
64 |
+
else:
|
65 |
+
file_path = await target_message.download()
|
66 |
+
await upload_file(client, message, file_path)
|
67 |
+
|
68 |
+
@Devine.on_message(filters.command("xtgm"))
|
69 |
+
async def upload_command(client, message):
|
70 |
+
if message.from_user.is_bot:
|
71 |
+
return
|
72 |
+
|
73 |
+
target_message = message.reply_to_message if message.reply_to_message else message
|
74 |
+
media = target_message.photo or target_message.video
|
75 |
+
|
76 |
+
if media:
|
77 |
+
await handle_upload(client, message, target_message)
|
78 |
+
else:
|
79 |
+
await message.reply("<b>sᴇɴᴅ ᴏʀ ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴘʜᴏᴛᴏ ᴏʀ ᴠɪᴅᴇᴏ ғᴏʀ ᴜᴘʟᴏᴀᴅ.</b>")
|
Devine/plugins/Dev/write.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram import *
|
3 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
|
4 |
+
from datetime import datetime
|
5 |
+
from Devine import app as app
|
6 |
+
import requests
|
7 |
+
|
8 |
+
@app.on_message(filters.command("write"))
|
9 |
+
async def handwrite(_, message: Message):
|
10 |
+
if message.reply_to_message:
|
11 |
+
text = message.reply_to_message.text
|
12 |
+
else:
|
13 |
+
text =message.text.split(None, 1)[1]
|
14 |
+
m =await message.reply_text( "<b>ʜᴏʟᴅ ᴏɴ,\nᴡʀɪᴛɪɴɢ ʏᴏᴜʀ ᴛᴇxᴛ...</b>")
|
15 |
+
write = requests.get(f"https://apis.xditya.me/write?text={text}").url
|
16 |
+
|
17 |
+
caption = f"""
|
18 |
+
<b>sᴜᴄᴇssғᴜʟʟʏ ᴛᴇxᴛ ᴡʀɪᴛᴛᴇɴ, ✨</b>
|
19 |
+
|
20 |
+
<b>• ᴡʀɪᴛᴛᴇɴ ʙʏ : </b>{app.mention}
|
21 |
+
<b>• ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ : </b>{message.from_user.mention}
|
22 |
+
"""
|
23 |
+
await m.delete()
|
24 |
+
await message.reply_photo(photo=write,caption=caption)
|
Devine/plugins/__init__.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import glob
|
2 |
+
from os.path import dirname, isfile
|
3 |
+
|
4 |
+
|
5 |
+
def __list_all_modules():
|
6 |
+
work_dir = dirname(__file__)
|
7 |
+
mod_paths = glob.glob(work_dir + "/*/*.py")
|
8 |
+
|
9 |
+
all_modules = [
|
10 |
+
(((f.replace(work_dir, "")).replace("/", "."))[:-3])
|
11 |
+
for f in mod_paths
|
12 |
+
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
|
13 |
+
]
|
14 |
+
|
15 |
+
return all_modules
|
16 |
+
|
17 |
+
|
18 |
+
ALL_MODULES = sorted(__list_all_modules())
|
19 |
+
__all__ = ALL_MODULES + ["ALL_MODULES"]
|
Devine/plugins/admins/auth.py
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.utils import extract_user, int_to_alpha
|
6 |
+
from Devine.utils.database import (
|
7 |
+
delete_authuser,
|
8 |
+
get_authuser,
|
9 |
+
get_authuser_names,
|
10 |
+
save_authuser,
|
11 |
+
)
|
12 |
+
from Devine.utils.decorators import AdminActual, language
|
13 |
+
from Devine.utils.inline import close_markup
|
14 |
+
from config import BANNED_USERS, adminlist
|
15 |
+
|
16 |
+
|
17 |
+
@app.on_message(filters.command("auth") & filters.group & ~BANNED_USERS)
|
18 |
+
@AdminActual
|
19 |
+
async def auth(client, message: Message, _):
|
20 |
+
if not message.reply_to_message:
|
21 |
+
if len(message.command) != 2:
|
22 |
+
return await message.reply_text(_["general_1"])
|
23 |
+
user = await extract_user(message)
|
24 |
+
token = await int_to_alpha(user.id)
|
25 |
+
_check = await get_authuser_names(message.chat.id)
|
26 |
+
count = len(_check)
|
27 |
+
if int(count) == 25:
|
28 |
+
return await message.reply_text(_["auth_1"])
|
29 |
+
if token not in _check:
|
30 |
+
assis = {
|
31 |
+
"auth_user_id": user.id,
|
32 |
+
"auth_name": user.first_name,
|
33 |
+
"admin_id": message.from_user.id,
|
34 |
+
"admin_name": message.from_user.first_name,
|
35 |
+
}
|
36 |
+
get = adminlist.get(message.chat.id)
|
37 |
+
if get:
|
38 |
+
if user.id not in get:
|
39 |
+
get.append(user.id)
|
40 |
+
await save_authuser(message.chat.id, token, assis)
|
41 |
+
return await message.reply_text(_["auth_2"].format(user.mention))
|
42 |
+
else:
|
43 |
+
return await message.reply_text(_["auth_3"].format(user.mention))
|
44 |
+
|
45 |
+
|
46 |
+
@app.on_message(filters.command("unauth") & filters.group & ~BANNED_USERS)
|
47 |
+
@AdminActual
|
48 |
+
async def unauthusers(client, message: Message, _):
|
49 |
+
if not message.reply_to_message:
|
50 |
+
if len(message.command) != 2:
|
51 |
+
return await message.reply_text(_["general_1"])
|
52 |
+
user = await extract_user(message)
|
53 |
+
token = await int_to_alpha(user.id)
|
54 |
+
deleted = await delete_authuser(message.chat.id, token)
|
55 |
+
get = adminlist.get(message.chat.id)
|
56 |
+
if get:
|
57 |
+
if user.id in get:
|
58 |
+
get.remove(user.id)
|
59 |
+
if deleted:
|
60 |
+
return await message.reply_text(_["auth_4"].format(user.mention))
|
61 |
+
else:
|
62 |
+
return await message.reply_text(_["auth_5"].format(user.mention))
|
63 |
+
|
64 |
+
|
65 |
+
@app.on_message(
|
66 |
+
filters.command(["authlist", "authusers"]) & filters.group & ~BANNED_USERS
|
67 |
+
)
|
68 |
+
@language
|
69 |
+
async def authusers(client, message: Message, _):
|
70 |
+
_wtf = await get_authuser_names(message.chat.id)
|
71 |
+
if not _wtf:
|
72 |
+
return await message.reply_text(_["setting_4"])
|
73 |
+
else:
|
74 |
+
j = 0
|
75 |
+
mystic = await message.reply_text(_["auth_6"])
|
76 |
+
text = _["auth_7"].format(message.chat.title)
|
77 |
+
for umm in _wtf:
|
78 |
+
_umm = await get_authuser(message.chat.id, umm)
|
79 |
+
user_id = _umm["auth_user_id"]
|
80 |
+
admin_id = _umm["admin_id"]
|
81 |
+
admin_name = _umm["admin_name"]
|
82 |
+
try:
|
83 |
+
user = (await app.get_users(user_id)).first_name
|
84 |
+
j += 1
|
85 |
+
except:
|
86 |
+
continue
|
87 |
+
text += f"{j}» {user}[<code>{user_id}</code>]\n"
|
88 |
+
text += f" {_['auth_8']} {admin_name}[<code>{admin_id}</code>]\n\n"
|
89 |
+
await mystic.edit_text(text, reply_markup=close_markup(_))
|
Devine/plugins/admins/callback.py
ADDED
@@ -0,0 +1,397 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
5 |
+
|
6 |
+
from Devine import YouTube, app
|
7 |
+
from Devine.core.call import Anony
|
8 |
+
from Devine.misc import SUDOERS, db
|
9 |
+
from Devine.utils.database import (
|
10 |
+
get_active_chats,
|
11 |
+
get_lang,
|
12 |
+
get_upvote_count,
|
13 |
+
is_active_chat,
|
14 |
+
is_music_playing,
|
15 |
+
is_nonadmin_chat,
|
16 |
+
music_off,
|
17 |
+
music_on,
|
18 |
+
set_loop,
|
19 |
+
)
|
20 |
+
from Devine.utils.decorators.language import languageCB
|
21 |
+
from Devine.utils.formatters import seconds_to_min
|
22 |
+
from Devine.utils.inline import close_markup, stream_markup, stream_markup_timer
|
23 |
+
from Devine.utils.stream.autoclear import auto_clean
|
24 |
+
from Devine.utils.thumbnails import get_thumb
|
25 |
+
from config import (
|
26 |
+
BANNED_USERS,
|
27 |
+
SUPPORT_CHAT,
|
28 |
+
SOUNCLOUD_IMG_URL,
|
29 |
+
STREAM_IMG_URL,
|
30 |
+
TELEGRAM_AUDIO_URL,
|
31 |
+
TELEGRAM_VIDEO_URL,
|
32 |
+
adminlist,
|
33 |
+
confirmer,
|
34 |
+
votemode,
|
35 |
+
)
|
36 |
+
from strings import get_string
|
37 |
+
|
38 |
+
checker = {}
|
39 |
+
upvoters = {}
|
40 |
+
|
41 |
+
|
42 |
+
@app.on_callback_query(filters.regex("ADMIN") & ~BANNED_USERS)
|
43 |
+
@languageCB
|
44 |
+
async def del_back_playlist(client, CallbackQuery, _):
|
45 |
+
callback_data = CallbackQuery.data.strip()
|
46 |
+
callback_request = callback_data.split(None, 1)[1]
|
47 |
+
command, chat = callback_request.split("|")
|
48 |
+
if "_" in str(chat):
|
49 |
+
bet = chat.split("_")
|
50 |
+
chat = bet[0]
|
51 |
+
counter = bet[1]
|
52 |
+
chat_id = int(chat)
|
53 |
+
if not await is_active_chat(chat_id):
|
54 |
+
return await CallbackQuery.answer(_["general_5"], show_alert=True)
|
55 |
+
mention = CallbackQuery.from_user.mention
|
56 |
+
if command == "UpVote":
|
57 |
+
if chat_id not in votemode:
|
58 |
+
votemode[chat_id] = {}
|
59 |
+
if chat_id not in upvoters:
|
60 |
+
upvoters[chat_id] = {}
|
61 |
+
|
62 |
+
voters = (upvoters[chat_id]).get(CallbackQuery.message.id)
|
63 |
+
if not voters:
|
64 |
+
upvoters[chat_id][CallbackQuery.message.id] = []
|
65 |
+
|
66 |
+
vote = (votemode[chat_id]).get(CallbackQuery.message.id)
|
67 |
+
if not vote:
|
68 |
+
votemode[chat_id][CallbackQuery.message.id] = 0
|
69 |
+
|
70 |
+
if CallbackQuery.from_user.id in upvoters[chat_id][CallbackQuery.message.id]:
|
71 |
+
(upvoters[chat_id][CallbackQuery.message.id]).remove(
|
72 |
+
CallbackQuery.from_user.id
|
73 |
+
)
|
74 |
+
votemode[chat_id][CallbackQuery.message.id] -= 1
|
75 |
+
else:
|
76 |
+
(upvoters[chat_id][CallbackQuery.message.id]).append(
|
77 |
+
CallbackQuery.from_user.id
|
78 |
+
)
|
79 |
+
votemode[chat_id][CallbackQuery.message.id] += 1
|
80 |
+
upvote = await get_upvote_count(chat_id)
|
81 |
+
get_upvotes = int(votemode[chat_id][CallbackQuery.message.id])
|
82 |
+
if get_upvotes >= upvote:
|
83 |
+
votemode[chat_id][CallbackQuery.message.id] = upvote
|
84 |
+
try:
|
85 |
+
exists = confirmer[chat_id][CallbackQuery.message.id]
|
86 |
+
current = db[chat_id][0]
|
87 |
+
except:
|
88 |
+
return await CallbackQuery.edit_message_text(f"ғᴀɪʟᴇᴅ.")
|
89 |
+
try:
|
90 |
+
if current["vidid"] != exists["vidid"]:
|
91 |
+
return await CallbackQuery.edit_message.text(_["admin_35"])
|
92 |
+
if current["file"] != exists["file"]:
|
93 |
+
return await CallbackQuery.edit_message.text(_["admin_35"])
|
94 |
+
except:
|
95 |
+
return await CallbackQuery.edit_message_text(_["admin_36"])
|
96 |
+
try:
|
97 |
+
await CallbackQuery.edit_message_text(_["admin_37"].format(upvote))
|
98 |
+
except:
|
99 |
+
pass
|
100 |
+
command = counter
|
101 |
+
mention = "ᴜᴘᴠᴏᴛᴇs"
|
102 |
+
else:
|
103 |
+
if (
|
104 |
+
CallbackQuery.from_user.id
|
105 |
+
in upvoters[chat_id][CallbackQuery.message.id]
|
106 |
+
):
|
107 |
+
await CallbackQuery.answer(_["admin_38"], show_alert=True)
|
108 |
+
else:
|
109 |
+
await CallbackQuery.answer(_["admin_39"], show_alert=True)
|
110 |
+
upl = InlineKeyboardMarkup(
|
111 |
+
[
|
112 |
+
[
|
113 |
+
InlineKeyboardButton(
|
114 |
+
text=f"👍 {get_upvotes}",
|
115 |
+
callback_data=f"ADMIN UpVote|{chat_id}_{counter}",
|
116 |
+
)
|
117 |
+
]
|
118 |
+
]
|
119 |
+
)
|
120 |
+
await CallbackQuery.answer(_["admin_40"], show_alert=True)
|
121 |
+
return await CallbackQuery.edit_message_reply_markup(reply_markup=upl)
|
122 |
+
else:
|
123 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
124 |
+
if not is_non_admin:
|
125 |
+
if CallbackQuery.from_user.id not in SUDOERS:
|
126 |
+
admins = adminlist.get(CallbackQuery.message.chat.id)
|
127 |
+
if not admins:
|
128 |
+
return await CallbackQuery.answer(_["admin_13"], show_alert=True)
|
129 |
+
else:
|
130 |
+
if CallbackQuery.from_user.id not in admins:
|
131 |
+
return await CallbackQuery.answer(
|
132 |
+
_["admin_14"], show_alert=True
|
133 |
+
)
|
134 |
+
if command == "Pause":
|
135 |
+
if not await is_music_playing(chat_id):
|
136 |
+
return await CallbackQuery.answer(_["admin_1"], show_alert=True)
|
137 |
+
await CallbackQuery.answer()
|
138 |
+
await music_off(chat_id)
|
139 |
+
await Anony.pause_stream(chat_id)
|
140 |
+
await CallbackQuery.message.reply_text(
|
141 |
+
_["admin_2"].format(mention), reply_markup=close_markup(_)
|
142 |
+
)
|
143 |
+
elif command == "Resume":
|
144 |
+
if await is_music_playing(chat_id):
|
145 |
+
return await CallbackQuery.answer(_["admin_3"], show_alert=True)
|
146 |
+
await CallbackQuery.answer()
|
147 |
+
await music_on(chat_id)
|
148 |
+
await Anony.resume_stream(chat_id)
|
149 |
+
await CallbackQuery.message.reply_text(
|
150 |
+
_["admin_4"].format(mention), reply_markup=close_markup(_)
|
151 |
+
)
|
152 |
+
elif command == "Stop" or command == "End":
|
153 |
+
await CallbackQuery.answer()
|
154 |
+
await Anony.stop_stream(chat_id)
|
155 |
+
await set_loop(chat_id, 0)
|
156 |
+
await CallbackQuery.message.reply_text(
|
157 |
+
_["admin_5"].format(mention), reply_markup=close_markup(_)
|
158 |
+
)
|
159 |
+
await CallbackQuery.message.delete()
|
160 |
+
elif command == "Skip" or command == "Replay":
|
161 |
+
check = db.get(chat_id)
|
162 |
+
if command == "Skip":
|
163 |
+
txt = f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀"
|
164 |
+
popped = None
|
165 |
+
try:
|
166 |
+
popped = check.pop(0)
|
167 |
+
if popped:
|
168 |
+
await auto_clean(popped)
|
169 |
+
if not check:
|
170 |
+
await CallbackQuery.edit_message_text(
|
171 |
+
f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀"
|
172 |
+
)
|
173 |
+
await CallbackQuery.message.reply_text(
|
174 |
+
text=_["admin_6"].format(
|
175 |
+
mention, CallbackQuery.message.chat.title
|
176 |
+
),
|
177 |
+
reply_markup=close_markup(_),
|
178 |
+
)
|
179 |
+
try:
|
180 |
+
return await Anony.stop_stream(chat_id)
|
181 |
+
except:
|
182 |
+
return
|
183 |
+
except:
|
184 |
+
try:
|
185 |
+
await CallbackQuery.edit_message_text(
|
186 |
+
f"➻ sᴛʀᴇᴀᴍ sᴋɪᴩᴩᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀"
|
187 |
+
)
|
188 |
+
await CallbackQuery.message.reply_text(
|
189 |
+
text=_["admin_6"].format(
|
190 |
+
mention, CallbackQuery.message.chat.title
|
191 |
+
),
|
192 |
+
reply_markup=close_markup(_),
|
193 |
+
)
|
194 |
+
return await Anony.stop_stream(chat_id)
|
195 |
+
except:
|
196 |
+
return
|
197 |
+
else:
|
198 |
+
txt = f"➻ sᴛʀᴇᴀᴍ ʀᴇ-ᴘʟᴀʏᴇᴅ 🎄\n│ \n└ʙʏ : {mention} 🥀"
|
199 |
+
await CallbackQuery.answer()
|
200 |
+
queued = check[0]["file"]
|
201 |
+
title = (check[0]["title"]).title()
|
202 |
+
user = check[0]["by"]
|
203 |
+
duration = check[0]["dur"]
|
204 |
+
streamtype = check[0]["streamtype"]
|
205 |
+
videoid = check[0]["vidid"]
|
206 |
+
status = True if str(streamtype) == "video" else None
|
207 |
+
db[chat_id][0]["played"] = 0
|
208 |
+
exis = (check[0]).get("old_dur")
|
209 |
+
if exis:
|
210 |
+
db[chat_id][0]["dur"] = exis
|
211 |
+
db[chat_id][0]["seconds"] = check[0]["old_second"]
|
212 |
+
db[chat_id][0]["speed_path"] = None
|
213 |
+
db[chat_id][0]["speed"] = 1.0
|
214 |
+
if "live_" in queued:
|
215 |
+
n, link = await YouTube.video(videoid, True)
|
216 |
+
if n == 0:
|
217 |
+
return await CallbackQuery.message.reply_text(
|
218 |
+
text=_["admin_7"].format(title),
|
219 |
+
reply_markup=close_markup(_),
|
220 |
+
)
|
221 |
+
try:
|
222 |
+
image = await YouTube.thumbnail(videoid, True)
|
223 |
+
except:
|
224 |
+
image = None
|
225 |
+
try:
|
226 |
+
await Anony.skip_stream(chat_id, link, video=status, image=image)
|
227 |
+
except:
|
228 |
+
return await CallbackQuery.message.reply_text(_["call_6"])
|
229 |
+
button = stream_markup(_, chat_id)
|
230 |
+
img = await get_thumb(videoid)
|
231 |
+
run = await CallbackQuery.message.reply_photo(
|
232 |
+
photo=img,
|
233 |
+
caption=_["stream_1"].format(
|
234 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
235 |
+
title[:23],
|
236 |
+
duration,
|
237 |
+
user,
|
238 |
+
),
|
239 |
+
reply_markup=InlineKeyboardMarkup(button),
|
240 |
+
)
|
241 |
+
db[chat_id][0]["mystic"] = run
|
242 |
+
db[chat_id][0]["markup"] = "tg"
|
243 |
+
await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_))
|
244 |
+
elif "vid_" in queued:
|
245 |
+
mystic = await CallbackQuery.message.reply_text(
|
246 |
+
_["call_7"], disable_web_page_preview=True
|
247 |
+
)
|
248 |
+
try:
|
249 |
+
file_path, direct = await YouTube.download(
|
250 |
+
videoid,
|
251 |
+
mystic,
|
252 |
+
videoid=True,
|
253 |
+
video=status,
|
254 |
+
)
|
255 |
+
except:
|
256 |
+
return await mystic.edit_text(_["call_6"])
|
257 |
+
try:
|
258 |
+
image = await YouTube.thumbnail(videoid, True)
|
259 |
+
except:
|
260 |
+
image = None
|
261 |
+
try:
|
262 |
+
await Anony.skip_stream(chat_id, file_path, video=status, image=image)
|
263 |
+
except:
|
264 |
+
return await mystic.edit_text(_["call_6"])
|
265 |
+
button = stream_markup(_, chat_id)
|
266 |
+
img = await get_thumb(videoid)
|
267 |
+
run = await CallbackQuery.message.reply_photo(
|
268 |
+
photo=img,
|
269 |
+
caption=_["stream_1"].format(
|
270 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
271 |
+
title[:23],
|
272 |
+
duration,
|
273 |
+
user,
|
274 |
+
),
|
275 |
+
reply_markup=InlineKeyboardMarkup(button),
|
276 |
+
)
|
277 |
+
db[chat_id][0]["mystic"] = run
|
278 |
+
db[chat_id][0]["markup"] = "stream"
|
279 |
+
await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_))
|
280 |
+
await mystic.delete()
|
281 |
+
elif "index_" in queued:
|
282 |
+
try:
|
283 |
+
await Anony.skip_stream(chat_id, videoid, video=status)
|
284 |
+
except:
|
285 |
+
return await CallbackQuery.message.reply_text(_["call_6"])
|
286 |
+
button = stream_markup(_, chat_id)
|
287 |
+
run = await CallbackQuery.message.reply_photo(
|
288 |
+
photo=STREAM_IMG_URL,
|
289 |
+
caption=_["stream_2"].format(user),
|
290 |
+
reply_markup=InlineKeyboardMarkup(button),
|
291 |
+
)
|
292 |
+
db[chat_id][0]["mystic"] = run
|
293 |
+
db[chat_id][0]["markup"] = "tg"
|
294 |
+
await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_))
|
295 |
+
else:
|
296 |
+
if videoid == "telegram":
|
297 |
+
image = None
|
298 |
+
elif videoid == "soundcloud":
|
299 |
+
image = None
|
300 |
+
else:
|
301 |
+
try:
|
302 |
+
image = await YouTube.thumbnail(videoid, True)
|
303 |
+
except:
|
304 |
+
image = None
|
305 |
+
try:
|
306 |
+
await Anony.skip_stream(chat_id, queued, video=status, image=image)
|
307 |
+
except:
|
308 |
+
return await CallbackQuery.message.reply_text(_["call_6"])
|
309 |
+
if videoid == "telegram":
|
310 |
+
button = stream_markup(_, chat_id)
|
311 |
+
run = await CallbackQuery.message.reply_photo(
|
312 |
+
photo=TELEGRAM_AUDIO_URL
|
313 |
+
if str(streamtype) == "audio"
|
314 |
+
else TELEGRAM_VIDEO_URL,
|
315 |
+
caption=_["stream_1"].format(
|
316 |
+
SUPPORT_CHAT, title[:23], duration, user
|
317 |
+
),
|
318 |
+
reply_markup=InlineKeyboardMarkup(button),
|
319 |
+
)
|
320 |
+
db[chat_id][0]["mystic"] = run
|
321 |
+
db[chat_id][0]["markup"] = "tg"
|
322 |
+
elif videoid == "soundcloud":
|
323 |
+
button = stream_markup(_, chat_id)
|
324 |
+
run = await CallbackQuery.message.reply_photo(
|
325 |
+
photo=SOUNCLOUD_IMG_URL
|
326 |
+
if str(streamtype) == "audio"
|
327 |
+
else TELEGRAM_VIDEO_URL,
|
328 |
+
caption=_["stream_1"].format(
|
329 |
+
SUPPORT_CHAT, title[:23], duration, user
|
330 |
+
),
|
331 |
+
reply_markup=InlineKeyboardMarkup(button),
|
332 |
+
)
|
333 |
+
db[chat_id][0]["mystic"] = run
|
334 |
+
db[chat_id][0]["markup"] = "tg"
|
335 |
+
else:
|
336 |
+
button = stream_markup(_, chat_id)
|
337 |
+
img = await get_thumb(videoid)
|
338 |
+
run = await CallbackQuery.message.reply_photo(
|
339 |
+
photo=img,
|
340 |
+
caption=_["stream_1"].format(
|
341 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
342 |
+
title[:23],
|
343 |
+
duration,
|
344 |
+
user,
|
345 |
+
),
|
346 |
+
reply_markup=InlineKeyboardMarkup(button),
|
347 |
+
)
|
348 |
+
db[chat_id][0]["mystic"] = run
|
349 |
+
db[chat_id][0]["markup"] = "stream"
|
350 |
+
await CallbackQuery.edit_message_text(txt, reply_markup=close_markup(_))
|
351 |
+
|
352 |
+
|
353 |
+
async def markup_timer():
|
354 |
+
while not await asyncio.sleep(7):
|
355 |
+
active_chats = await get_active_chats()
|
356 |
+
for chat_id in active_chats:
|
357 |
+
try:
|
358 |
+
if not await is_music_playing(chat_id):
|
359 |
+
continue
|
360 |
+
playing = db.get(chat_id)
|
361 |
+
if not playing:
|
362 |
+
continue
|
363 |
+
duration_seconds = int(playing[0]["seconds"])
|
364 |
+
if duration_seconds == 0:
|
365 |
+
continue
|
366 |
+
try:
|
367 |
+
mystic = playing[0]["mystic"]
|
368 |
+
except:
|
369 |
+
continue
|
370 |
+
try:
|
371 |
+
check = checker[chat_id][mystic.id]
|
372 |
+
if check is False:
|
373 |
+
continue
|
374 |
+
except:
|
375 |
+
pass
|
376 |
+
try:
|
377 |
+
language = await get_lang(chat_id)
|
378 |
+
_ = get_string(language)
|
379 |
+
except:
|
380 |
+
_ = get_string("en")
|
381 |
+
try:
|
382 |
+
buttons = stream_markup_timer(
|
383 |
+
_,
|
384 |
+
chat_id,
|
385 |
+
seconds_to_min(playing[0]["played"]),
|
386 |
+
playing[0]["dur"],
|
387 |
+
)
|
388 |
+
await mystic.edit_reply_markup(
|
389 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
390 |
+
)
|
391 |
+
except:
|
392 |
+
continue
|
393 |
+
except:
|
394 |
+
continue
|
395 |
+
|
396 |
+
|
397 |
+
asyncio.create_task(markup_timer())
|
Devine/plugins/admins/loop.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.utils.database import get_loop, set_loop
|
6 |
+
from Devine.utils.decorators import AdminRightsCheck
|
7 |
+
from Devine.utils.inline import close_markup
|
8 |
+
from config import BANNED_USERS
|
9 |
+
|
10 |
+
|
11 |
+
@app.on_message(filters.command(["loop", "cloop"]) & filters.group & ~BANNED_USERS)
|
12 |
+
@AdminRightsCheck
|
13 |
+
async def admins(cli, message: Message, _, chat_id):
|
14 |
+
usage = _["admin_17"]
|
15 |
+
if len(message.command) != 2:
|
16 |
+
return await message.reply_text(usage)
|
17 |
+
state = message.text.split(None, 1)[1].strip()
|
18 |
+
if state.isnumeric():
|
19 |
+
state = int(state)
|
20 |
+
if 1 <= state <= 10:
|
21 |
+
got = await get_loop(chat_id)
|
22 |
+
if got != 0:
|
23 |
+
state = got + state
|
24 |
+
if int(state) > 10:
|
25 |
+
state = 10
|
26 |
+
await set_loop(chat_id, state)
|
27 |
+
return await message.reply_text(
|
28 |
+
text=_["admin_18"].format(state, message.from_user.mention),
|
29 |
+
reply_markup=close_markup(_),
|
30 |
+
)
|
31 |
+
else:
|
32 |
+
return await message.reply_text(_["admin_17"])
|
33 |
+
elif state.lower() == "enable":
|
34 |
+
await set_loop(chat_id, 10)
|
35 |
+
return await message.reply_text(
|
36 |
+
text=_["admin_18"].format(state, message.from_user.mention),
|
37 |
+
reply_markup=close_markup(_),
|
38 |
+
)
|
39 |
+
elif state.lower() == "disable":
|
40 |
+
await set_loop(chat_id, 0)
|
41 |
+
return await message.reply_text(
|
42 |
+
_["admin_19"].format(message.from_user.mention),
|
43 |
+
reply_markup=close_markup(_),
|
44 |
+
)
|
45 |
+
else:
|
46 |
+
return await message.reply_text(usage)
|
Devine/plugins/admins/pause.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.core.call import Anony
|
6 |
+
from Devine.utils.database import is_music_playing, music_off
|
7 |
+
from Devine.utils.decorators import AdminRightsCheck
|
8 |
+
from Devine.utils.inline import close_markup
|
9 |
+
from config import BANNED_USERS
|
10 |
+
|
11 |
+
|
12 |
+
@app.on_message(filters.command(["pause", "cpause"]) & filters.group & ~BANNED_USERS)
|
13 |
+
@AdminRightsCheck
|
14 |
+
async def pause_admin(cli, message: Message, _, chat_id):
|
15 |
+
if not await is_music_playing(chat_id):
|
16 |
+
return await message.reply_text(_["admin_1"])
|
17 |
+
await music_off(chat_id)
|
18 |
+
await Anony.pause_stream(chat_id)
|
19 |
+
await message.reply_text(
|
20 |
+
_["admin_2"].format(message.from_user.mention), reply_markup=close_markup(_)
|
21 |
+
)
|
Devine/plugins/admins/resume.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.core.call import Anony
|
6 |
+
from Devine.utils.database import is_music_playing, music_on
|
7 |
+
from Devine.utils.decorators import AdminRightsCheck
|
8 |
+
from Devine.utils.inline import close_markup
|
9 |
+
from config import BANNED_USERS
|
10 |
+
|
11 |
+
|
12 |
+
@app.on_message(filters.command(["resume", "cresume"]) & filters.group & ~BANNED_USERS)
|
13 |
+
@AdminRightsCheck
|
14 |
+
async def resume_com(cli, message: Message, _, chat_id):
|
15 |
+
if await is_music_playing(chat_id):
|
16 |
+
return await message.reply_text(_["admin_3"])
|
17 |
+
await music_on(chat_id)
|
18 |
+
await Anony.resume_stream(chat_id)
|
19 |
+
await message.reply_text(
|
20 |
+
_["admin_4"].format(message.from_user.mention), reply_markup=close_markup(_)
|
21 |
+
)
|
Devine/plugins/admins/seek.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import YouTube, app
|
5 |
+
from Devine.core.call import Anony
|
6 |
+
from Devine.misc import db
|
7 |
+
from Devine.utils import AdminRightsCheck, seconds_to_min
|
8 |
+
from Devine.utils.inline import close_markup
|
9 |
+
from config import BANNED_USERS
|
10 |
+
|
11 |
+
|
12 |
+
@app.on_message(
|
13 |
+
filters.command(["seek", "cseek", "seekback", "cseekback"])
|
14 |
+
& filters.group
|
15 |
+
& ~BANNED_USERS
|
16 |
+
)
|
17 |
+
@AdminRightsCheck
|
18 |
+
async def seek_comm(cli, message: Message, _, chat_id):
|
19 |
+
if len(message.command) == 1:
|
20 |
+
return await message.reply_text(_["admin_20"])
|
21 |
+
query = message.text.split(None, 1)[1].strip()
|
22 |
+
if not query.isnumeric():
|
23 |
+
return await message.reply_text(_["admin_21"])
|
24 |
+
playing = db.get(chat_id)
|
25 |
+
if not playing:
|
26 |
+
return await message.reply_text(_["queue_2"])
|
27 |
+
duration_seconds = int(playing[0]["seconds"])
|
28 |
+
if duration_seconds == 0:
|
29 |
+
return await message.reply_text(_["admin_22"])
|
30 |
+
file_path = playing[0]["file"]
|
31 |
+
duration_played = int(playing[0]["played"])
|
32 |
+
duration_to_skip = int(query)
|
33 |
+
duration = playing[0]["dur"]
|
34 |
+
if message.command[0][-2] == "c":
|
35 |
+
if (duration_played - duration_to_skip) <= 10:
|
36 |
+
return await message.reply_text(
|
37 |
+
text=_["admin_23"].format(seconds_to_min(duration_played), duration),
|
38 |
+
reply_markup=close_markup(_),
|
39 |
+
)
|
40 |
+
to_seek = duration_played - duration_to_skip + 1
|
41 |
+
else:
|
42 |
+
if (duration_seconds - (duration_played + duration_to_skip)) <= 10:
|
43 |
+
return await message.reply_text(
|
44 |
+
text=_["admin_23"].format(seconds_to_min(duration_played), duration),
|
45 |
+
reply_markup=close_markup(_),
|
46 |
+
)
|
47 |
+
to_seek = duration_played + duration_to_skip + 1
|
48 |
+
mystic = await message.reply_text(_["admin_24"])
|
49 |
+
if "vid_" in file_path:
|
50 |
+
n, file_path = await YouTube.video(playing[0]["vidid"], True)
|
51 |
+
if n == 0:
|
52 |
+
return await message.reply_text(_["admin_22"])
|
53 |
+
check = (playing[0]).get("speed_path")
|
54 |
+
if check:
|
55 |
+
file_path = check
|
56 |
+
if "index_" in file_path:
|
57 |
+
file_path = playing[0]["vidid"]
|
58 |
+
try:
|
59 |
+
await Anony.seek_stream(
|
60 |
+
chat_id,
|
61 |
+
file_path,
|
62 |
+
seconds_to_min(to_seek),
|
63 |
+
duration,
|
64 |
+
playing[0]["streamtype"],
|
65 |
+
)
|
66 |
+
except:
|
67 |
+
return await mystic.edit_text(_["admin_26"], reply_markup=close_markup(_))
|
68 |
+
if message.command[0][-2] == "c":
|
69 |
+
db[chat_id][0]["played"] -= duration_to_skip
|
70 |
+
else:
|
71 |
+
db[chat_id][0]["played"] += duration_to_skip
|
72 |
+
await mystic.edit_text(
|
73 |
+
text=_["admin_25"].format(seconds_to_min(to_seek), message.from_user.mention),
|
74 |
+
reply_markup=close_markup(_),
|
75 |
+
)
|
Devine/plugins/admins/shuffle.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.types import Message
|
5 |
+
|
6 |
+
from Devine import app
|
7 |
+
from Devine.misc import db
|
8 |
+
from Devine.utils.decorators import AdminRightsCheck
|
9 |
+
from Devine.utils.inline import close_markup
|
10 |
+
from config import BANNED_USERS
|
11 |
+
|
12 |
+
|
13 |
+
@app.on_message(
|
14 |
+
filters.command(["shuffle", "cshuffle"]) & filters.group & ~BANNED_USERS
|
15 |
+
)
|
16 |
+
@AdminRightsCheck
|
17 |
+
async def admins(Client, message: Message, _, chat_id):
|
18 |
+
check = db.get(chat_id)
|
19 |
+
if not check:
|
20 |
+
return await message.reply_text(_["queue_2"])
|
21 |
+
try:
|
22 |
+
popped = check.pop(0)
|
23 |
+
except:
|
24 |
+
return await message.reply_text(_["admin_15"], reply_markup=close_markup(_))
|
25 |
+
check = db.get(chat_id)
|
26 |
+
if not check:
|
27 |
+
check.insert(0, popped)
|
28 |
+
return await message.reply_text(_["admin_15"], reply_markup=close_markup(_))
|
29 |
+
random.shuffle(check)
|
30 |
+
check.insert(0, popped)
|
31 |
+
await message.reply_text(
|
32 |
+
_["admin_16"].format(message.from_user.mention), reply_markup=close_markup(_)
|
33 |
+
)
|
Devine/plugins/admins/skip.py
ADDED
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import InlineKeyboardMarkup, Message
|
3 |
+
|
4 |
+
import config
|
5 |
+
from Devine import YouTube, app
|
6 |
+
from Devine.core.call import Anony
|
7 |
+
from Devine.misc import db
|
8 |
+
from Devine.utils.database import get_loop
|
9 |
+
from Devine.utils.decorators import AdminRightsCheck
|
10 |
+
from Devine.utils.inline import close_markup, stream_markup
|
11 |
+
from Devine.utils.stream.autoclear import auto_clean
|
12 |
+
from Devine.utils.thumbnails import get_thumb
|
13 |
+
from config import BANNED_USERS
|
14 |
+
|
15 |
+
|
16 |
+
@app.on_message(
|
17 |
+
filters.command(["skip", "cskip", "next", "cnext"]) & filters.group & ~BANNED_USERS
|
18 |
+
)
|
19 |
+
@AdminRightsCheck
|
20 |
+
async def skip(cli, message: Message, _, chat_id):
|
21 |
+
if not len(message.command) < 2:
|
22 |
+
loop = await get_loop(chat_id)
|
23 |
+
if loop != 0:
|
24 |
+
return await message.reply_text(_["admin_8"])
|
25 |
+
state = message.text.split(None, 1)[1].strip()
|
26 |
+
if state.isnumeric():
|
27 |
+
state = int(state)
|
28 |
+
check = db.get(chat_id)
|
29 |
+
if check:
|
30 |
+
count = len(check)
|
31 |
+
if count > 2:
|
32 |
+
count = int(count - 1)
|
33 |
+
if 1 <= state <= count:
|
34 |
+
for x in range(state):
|
35 |
+
popped = None
|
36 |
+
try:
|
37 |
+
popped = check.pop(0)
|
38 |
+
except:
|
39 |
+
return await message.reply_text(_["admin_12"])
|
40 |
+
if popped:
|
41 |
+
await auto_clean(popped)
|
42 |
+
if not check:
|
43 |
+
try:
|
44 |
+
await message.reply_text(
|
45 |
+
text=_["admin_6"].format(
|
46 |
+
message.from_user.mention,
|
47 |
+
message.chat.title,
|
48 |
+
),
|
49 |
+
reply_markup=close_markup(_),
|
50 |
+
)
|
51 |
+
await Anony.stop_stream(chat_id)
|
52 |
+
except:
|
53 |
+
return
|
54 |
+
break
|
55 |
+
else:
|
56 |
+
return await message.reply_text(_["admin_11"].format(count))
|
57 |
+
else:
|
58 |
+
return await message.reply_text(_["admin_10"])
|
59 |
+
else:
|
60 |
+
return await message.reply_text(_["queue_2"])
|
61 |
+
else:
|
62 |
+
return await message.reply_text(_["admin_9"])
|
63 |
+
else:
|
64 |
+
check = db.get(chat_id)
|
65 |
+
popped = None
|
66 |
+
try:
|
67 |
+
popped = check.pop(0)
|
68 |
+
if popped:
|
69 |
+
await auto_clean(popped)
|
70 |
+
if not check:
|
71 |
+
await message.reply_text(
|
72 |
+
text=_["admin_6"].format(
|
73 |
+
message.from_user.mention, message.chat.title
|
74 |
+
),
|
75 |
+
reply_markup=close_markup(_),
|
76 |
+
)
|
77 |
+
try:
|
78 |
+
return await Anony.stop_stream(chat_id)
|
79 |
+
except:
|
80 |
+
return
|
81 |
+
except:
|
82 |
+
try:
|
83 |
+
await message.reply_text(
|
84 |
+
text=_["admin_6"].format(
|
85 |
+
message.from_user.mention, message.chat.title
|
86 |
+
),
|
87 |
+
reply_markup=close_markup(_),
|
88 |
+
)
|
89 |
+
return await Anony.stop_stream(chat_id)
|
90 |
+
except:
|
91 |
+
return
|
92 |
+
queued = check[0]["file"]
|
93 |
+
title = (check[0]["title"]).title()
|
94 |
+
user = check[0]["by"]
|
95 |
+
streamtype = check[0]["streamtype"]
|
96 |
+
videoid = check[0]["vidid"]
|
97 |
+
status = True if str(streamtype) == "video" else None
|
98 |
+
db[chat_id][0]["played"] = 0
|
99 |
+
exis = (check[0]).get("old_dur")
|
100 |
+
if exis:
|
101 |
+
db[chat_id][0]["dur"] = exis
|
102 |
+
db[chat_id][0]["seconds"] = check[0]["old_second"]
|
103 |
+
db[chat_id][0]["speed_path"] = None
|
104 |
+
db[chat_id][0]["speed"] = 1.0
|
105 |
+
if "live_" in queued:
|
106 |
+
n, link = await YouTube.video(videoid, True)
|
107 |
+
if n == 0:
|
108 |
+
return await message.reply_text(_["admin_7"].format(title))
|
109 |
+
try:
|
110 |
+
image = await YouTube.thumbnail(videoid, True)
|
111 |
+
except:
|
112 |
+
image = None
|
113 |
+
try:
|
114 |
+
await Anony.skip_stream(chat_id, link, video=status, image=image)
|
115 |
+
except:
|
116 |
+
return await message.reply_text(_["call_6"])
|
117 |
+
button = stream_markup(_, chat_id)
|
118 |
+
img = await get_thumb(videoid)
|
119 |
+
run = await message.reply_photo(
|
120 |
+
photo=img,
|
121 |
+
caption=_["stream_1"].format(
|
122 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
123 |
+
title[:23],
|
124 |
+
check[0]["dur"],
|
125 |
+
user,
|
126 |
+
),
|
127 |
+
reply_markup=InlineKeyboardMarkup(button),
|
128 |
+
)
|
129 |
+
db[chat_id][0]["mystic"] = run
|
130 |
+
db[chat_id][0]["markup"] = "tg"
|
131 |
+
elif "vid_" in queued:
|
132 |
+
mystic = await message.reply_text(_["call_7"], disable_web_page_preview=True)
|
133 |
+
try:
|
134 |
+
file_path, direct = await YouTube.download(
|
135 |
+
videoid,
|
136 |
+
mystic,
|
137 |
+
videoid=True,
|
138 |
+
video=status,
|
139 |
+
)
|
140 |
+
except:
|
141 |
+
return await mystic.edit_text(_["call_6"])
|
142 |
+
try:
|
143 |
+
image = await YouTube.thumbnail(videoid, True)
|
144 |
+
except:
|
145 |
+
image = None
|
146 |
+
try:
|
147 |
+
await Anony.skip_stream(chat_id, file_path, video=status, image=image)
|
148 |
+
except:
|
149 |
+
return await mystic.edit_text(_["call_6"])
|
150 |
+
button = stream_markup(_, chat_id)
|
151 |
+
img = await get_thumb(videoid)
|
152 |
+
run = await message.reply_photo(
|
153 |
+
photo=img,
|
154 |
+
caption=_["stream_1"].format(
|
155 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
156 |
+
title[:23],
|
157 |
+
check[0]["dur"],
|
158 |
+
user,
|
159 |
+
),
|
160 |
+
reply_markup=InlineKeyboardMarkup(button),
|
161 |
+
)
|
162 |
+
db[chat_id][0]["mystic"] = run
|
163 |
+
db[chat_id][0]["markup"] = "stream"
|
164 |
+
await mystic.delete()
|
165 |
+
elif "index_" in queued:
|
166 |
+
try:
|
167 |
+
await Anony.skip_stream(chat_id, videoid, video=status)
|
168 |
+
except:
|
169 |
+
return await message.reply_text(_["call_6"])
|
170 |
+
button = stream_markup(_, chat_id)
|
171 |
+
run = await message.reply_photo(
|
172 |
+
photo=config.STREAM_IMG_URL,
|
173 |
+
caption=_["stream_2"].format(user),
|
174 |
+
reply_markup=InlineKeyboardMarkup(button),
|
175 |
+
)
|
176 |
+
db[chat_id][0]["mystic"] = run
|
177 |
+
db[chat_id][0]["markup"] = "tg"
|
178 |
+
else:
|
179 |
+
if videoid == "telegram":
|
180 |
+
image = None
|
181 |
+
elif videoid == "soundcloud":
|
182 |
+
image = None
|
183 |
+
else:
|
184 |
+
try:
|
185 |
+
image = await YouTube.thumbnail(videoid, True)
|
186 |
+
except:
|
187 |
+
image = None
|
188 |
+
try:
|
189 |
+
await Anony.skip_stream(chat_id, queued, video=status, image=image)
|
190 |
+
except:
|
191 |
+
return await message.reply_text(_["call_6"])
|
192 |
+
if videoid == "telegram":
|
193 |
+
button = stream_markup(_, chat_id)
|
194 |
+
run = await message.reply_photo(
|
195 |
+
photo=config.TELEGRAM_AUDIO_URL
|
196 |
+
if str(streamtype) == "audio"
|
197 |
+
else config.TELEGRAM_VIDEO_URL,
|
198 |
+
caption=_["stream_1"].format(
|
199 |
+
config.SUPPORT_CHAT, title[:23], check[0]["dur"], user
|
200 |
+
),
|
201 |
+
reply_markup=InlineKeyboardMarkup(button),
|
202 |
+
)
|
203 |
+
db[chat_id][0]["mystic"] = run
|
204 |
+
db[chat_id][0]["markup"] = "tg"
|
205 |
+
elif videoid == "soundcloud":
|
206 |
+
button = stream_markup(_, chat_id)
|
207 |
+
run = await message.reply_photo(
|
208 |
+
photo=config.SOUNCLOUD_IMG_URL
|
209 |
+
if str(streamtype) == "audio"
|
210 |
+
else config.TELEGRAM_VIDEO_URL,
|
211 |
+
caption=_["stream_1"].format(
|
212 |
+
config.SUPPORT_CHAT, title[:23], check[0]["dur"], user
|
213 |
+
),
|
214 |
+
reply_markup=InlineKeyboardMarkup(button),
|
215 |
+
)
|
216 |
+
db[chat_id][0]["mystic"] = run
|
217 |
+
db[chat_id][0]["markup"] = "tg"
|
218 |
+
else:
|
219 |
+
button = stream_markup(_, chat_id)
|
220 |
+
img = await get_thumb(videoid)
|
221 |
+
run = await message.reply_photo(
|
222 |
+
photo=img,
|
223 |
+
caption=_["stream_1"].format(
|
224 |
+
f"https://t.me/{app.username}?start=info_{videoid}",
|
225 |
+
title[:23],
|
226 |
+
check[0]["dur"],
|
227 |
+
user,
|
228 |
+
),
|
229 |
+
reply_markup=InlineKeyboardMarkup(button),
|
230 |
+
)
|
231 |
+
db[chat_id][0]["mystic"] = run
|
232 |
+
db[chat_id][0]["markup"] = "stream"
|
Devine/plugins/admins/speed.py
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.core.call import Anony
|
6 |
+
from Devine.misc import SUDOERS, db
|
7 |
+
from Devine.utils import AdminRightsCheck
|
8 |
+
from Devine.utils.database import is_active_chat, is_nonadmin_chat
|
9 |
+
from Devine.utils.decorators.language import languageCB
|
10 |
+
from Devine.utils.inline import close_markup, speed_markup
|
11 |
+
from config import BANNED_USERS, adminlist
|
12 |
+
|
13 |
+
checker = []
|
14 |
+
|
15 |
+
|
16 |
+
@app.on_message(
|
17 |
+
filters.command(["cspeed", "speed", "cslow", "slow", "playback", "cplayback"])
|
18 |
+
& filters.group
|
19 |
+
& ~BANNED_USERS
|
20 |
+
)
|
21 |
+
@AdminRightsCheck
|
22 |
+
async def playback(cli, message: Message, _, chat_id):
|
23 |
+
playing = db.get(chat_id)
|
24 |
+
if not playing:
|
25 |
+
return await message.reply_text(_["queue_2"])
|
26 |
+
duration_seconds = int(playing[0]["seconds"])
|
27 |
+
if duration_seconds == 0:
|
28 |
+
return await message.reply_text(_["admin_27"])
|
29 |
+
file_path = playing[0]["file"]
|
30 |
+
if "downloads" not in file_path:
|
31 |
+
return await message.reply_text(_["admin_27"])
|
32 |
+
upl = speed_markup(_, chat_id)
|
33 |
+
return await message.reply_text(
|
34 |
+
text=_["admin_28"].format(app.mention),
|
35 |
+
reply_markup=upl,
|
36 |
+
)
|
37 |
+
|
38 |
+
|
39 |
+
@app.on_callback_query(filters.regex("SpeedUP") & ~BANNED_USERS)
|
40 |
+
@languageCB
|
41 |
+
async def del_back_playlist(client, CallbackQuery, _):
|
42 |
+
callback_data = CallbackQuery.data.strip()
|
43 |
+
callback_request = callback_data.split(None, 1)[1]
|
44 |
+
chat, speed = callback_request.split("|")
|
45 |
+
chat_id = int(chat)
|
46 |
+
if not await is_active_chat(chat_id):
|
47 |
+
return await CallbackQuery.answer(_["general_5"], show_alert=True)
|
48 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
49 |
+
if not is_non_admin:
|
50 |
+
if CallbackQuery.from_user.id not in SUDOERS:
|
51 |
+
admins = adminlist.get(CallbackQuery.message.chat.id)
|
52 |
+
if not admins:
|
53 |
+
return await CallbackQuery.answer(_["admin_13"], show_alert=True)
|
54 |
+
else:
|
55 |
+
if CallbackQuery.from_user.id not in admins:
|
56 |
+
return await CallbackQuery.answer(_["admin_14"], show_alert=True)
|
57 |
+
playing = db.get(chat_id)
|
58 |
+
if not playing:
|
59 |
+
return await CallbackQuery.answer(_["queue_2"], show_alert=True)
|
60 |
+
duration_seconds = int(playing[0]["seconds"])
|
61 |
+
if duration_seconds == 0:
|
62 |
+
return await CallbackQuery.answer(_["admin_27"], show_alert=True)
|
63 |
+
file_path = playing[0]["file"]
|
64 |
+
if "downloads" not in file_path:
|
65 |
+
return await CallbackQuery.answer(_["admin_27"], show_alert=True)
|
66 |
+
checkspeed = (playing[0]).get("speed")
|
67 |
+
if checkspeed:
|
68 |
+
if str(checkspeed) == str(speed):
|
69 |
+
if str(speed) == str("1.0"):
|
70 |
+
return await CallbackQuery.answer(
|
71 |
+
_["admin_29"],
|
72 |
+
show_alert=True,
|
73 |
+
)
|
74 |
+
else:
|
75 |
+
if str(speed) == str("1.0"):
|
76 |
+
return await CallbackQuery.answer(
|
77 |
+
_["admin_29"],
|
78 |
+
show_alert=True,
|
79 |
+
)
|
80 |
+
if chat_id in checker:
|
81 |
+
return await CallbackQuery.answer(
|
82 |
+
_["admin_30"],
|
83 |
+
show_alert=True,
|
84 |
+
)
|
85 |
+
else:
|
86 |
+
checker.append(chat_id)
|
87 |
+
try:
|
88 |
+
await CallbackQuery.answer(
|
89 |
+
_["admin_31"],
|
90 |
+
)
|
91 |
+
except:
|
92 |
+
pass
|
93 |
+
mystic = await CallbackQuery.edit_message_text(
|
94 |
+
text=_["admin_32"].format(CallbackQuery.from_user.mention),
|
95 |
+
)
|
96 |
+
try:
|
97 |
+
await Anony.speedup_stream(
|
98 |
+
chat_id,
|
99 |
+
file_path,
|
100 |
+
speed,
|
101 |
+
playing,
|
102 |
+
)
|
103 |
+
except:
|
104 |
+
if chat_id in checker:
|
105 |
+
checker.remove(chat_id)
|
106 |
+
return await mystic.edit_text(_["admin_33"], reply_markup=close_markup(_))
|
107 |
+
if chat_id in checker:
|
108 |
+
checker.remove(chat_id)
|
109 |
+
await mystic.edit_text(
|
110 |
+
text=_["admin_34"].format(speed, CallbackQuery.from_user.mention),
|
111 |
+
reply_markup=close_markup(_),
|
112 |
+
)
|
Devine/plugins/admins/stop.py
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Devine import app
|
5 |
+
from Devine.core.call import Anony
|
6 |
+
from Devine.utils.database import set_loop
|
7 |
+
from Devine.utils.decorators import AdminRightsCheck
|
8 |
+
from Devine.utils.inline import close_markup
|
9 |
+
from config import BANNED_USERS
|
10 |
+
|
11 |
+
|
12 |
+
@app.on_message(
|
13 |
+
filters.command(["end", "stop", "cend", "cstop"]) & filters.group & ~BANNED_USERS
|
14 |
+
)
|
15 |
+
@AdminRightsCheck
|
16 |
+
async def stop_music(cli, message: Message, _, chat_id):
|
17 |
+
if not len(message.command) == 1:
|
18 |
+
return
|
19 |
+
await Anony.stop_stream(chat_id)
|
20 |
+
await set_loop(chat_id, 0)
|
21 |
+
await message.reply_text(
|
22 |
+
_["admin_5"].format(message.from_user.mention), reply_markup=close_markup(_)
|
23 |
+
)
|
Devine/plugins/bot/help.py
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Union
|
2 |
+
|
3 |
+
from pyrogram import filters, types
|
4 |
+
from pyrogram.types import InlineKeyboardMarkup, Message
|
5 |
+
|
6 |
+
from Devine import app
|
7 |
+
from Devine.utils import help_pannel
|
8 |
+
from Devine.utils.database import get_lang
|
9 |
+
from Devine.utils.decorators.language import LanguageStart, languageCB
|
10 |
+
from Devine.utils.inline.help import help_back_markup, private_help_panel
|
11 |
+
from config import BANNED_USERS, START_IMG_URL, SUPPORT_CHAT
|
12 |
+
from strings import get_string, helpers
|
13 |
+
|
14 |
+
|
15 |
+
@app.on_message(filters.command(["musichelp"]) & filters.private & ~BANNED_USERS)
|
16 |
+
@app.on_callback_query(filters.regex("settings_back_helper") & ~BANNED_USERS)
|
17 |
+
async def helper_private(
|
18 |
+
client: app, update: Union[types.Message, types.CallbackQuery]
|
19 |
+
):
|
20 |
+
is_callback = isinstance(update, types.CallbackQuery)
|
21 |
+
if is_callback:
|
22 |
+
try:
|
23 |
+
await update.answer()
|
24 |
+
except:
|
25 |
+
pass
|
26 |
+
chat_id = update.message.chat.id
|
27 |
+
language = await get_lang(chat_id)
|
28 |
+
_ = get_string(language)
|
29 |
+
keyboard = help_pannel(_, True)
|
30 |
+
await update.edit_message_text(
|
31 |
+
_["help_1"].format(SUPPORT_CHAT), reply_markup=keyboard
|
32 |
+
)
|
33 |
+
else:
|
34 |
+
try:
|
35 |
+
await update.delete()
|
36 |
+
except:
|
37 |
+
pass
|
38 |
+
language = await get_lang(update.chat.id)
|
39 |
+
_ = get_string(language)
|
40 |
+
keyboard = help_pannel(_)
|
41 |
+
await update.reply_photo(
|
42 |
+
photo=START_IMG_URL,
|
43 |
+
caption=_["help_1"].format(SUPPORT_CHAT),
|
44 |
+
reply_markup=keyboard,
|
45 |
+
)
|
46 |
+
|
47 |
+
|
48 |
+
@app.on_message(filters.command(["musichelp"]) & filters.group & ~BANNED_USERS)
|
49 |
+
@LanguageStart
|
50 |
+
async def help_com_group(client, message: Message, _):
|
51 |
+
keyboard = private_help_panel(_)
|
52 |
+
await message.reply_text(_["help_2"], reply_markup=InlineKeyboardMarkup(keyboard))
|
53 |
+
|
54 |
+
|
55 |
+
@app.on_callback_query(filters.regex("help_callback") & ~BANNED_USERS)
|
56 |
+
@languageCB
|
57 |
+
async def helper_cb(client, CallbackQuery, _):
|
58 |
+
callback_data = CallbackQuery.data.strip()
|
59 |
+
cb = callback_data.split(None, 1)[1]
|
60 |
+
keyboard = help_back_markup(_)
|
61 |
+
if cb == "hb1":
|
62 |
+
await CallbackQuery.edit_message_text(helpers.HELP_1, reply_markup=keyboard)
|
63 |
+
elif cb == "hb2":
|
64 |
+
await CallbackQuery.edit_message_text(helpers.HELP_2, reply_markup=keyboard)
|
65 |
+
elif cb == "hb3":
|
66 |
+
await CallbackQuery.edit_message_text(helpers.HELP_3, reply_markup=keyboard)
|
67 |
+
elif cb == "hb4":
|
68 |
+
await CallbackQuery.edit_message_text(helpers.HELP_4, reply_markup=keyboard)
|
69 |
+
elif cb == "hb5":
|
70 |
+
await CallbackQuery.edit_message_text(helpers.HELP_5, reply_markup=keyboard)
|
71 |
+
elif cb == "hb6":
|
72 |
+
await CallbackQuery.edit_message_text(helpers.HELP_6, reply_markup=keyboard)
|
73 |
+
elif cb == "hb7":
|
74 |
+
await CallbackQuery.edit_message_text(helpers.HELP_7, reply_markup=keyboard)
|
75 |
+
elif cb == "hb8":
|
76 |
+
await CallbackQuery.edit_message_text(helpers.HELP_8, reply_markup=keyboard)
|
77 |
+
elif cb == "hb9":
|
78 |
+
await CallbackQuery.edit_message_text(helpers.HELP_9, reply_markup=keyboard)
|
79 |
+
elif cb == "hb10":
|
80 |
+
await CallbackQuery.edit_message_text(helpers.HELP_10, reply_markup=keyboard)
|
81 |
+
elif cb == "hb11":
|
82 |
+
await CallbackQuery.edit_message_text(helpers.HELP_11, reply_markup=keyboard)
|
83 |
+
elif cb == "hb12":
|
84 |
+
await CallbackQuery.edit_message_text(helpers.HELP_12, reply_markup=keyboard)
|
85 |
+
elif cb == "hb13":
|
86 |
+
await CallbackQuery.edit_message_text(helpers.HELP_13, reply_markup=keyboard)
|
87 |
+
elif cb == "hb14":
|
88 |
+
await CallbackQuery.edit_message_text(helpers.HELP_14, reply_markup=keyboard)
|
89 |
+
elif cb == "hb15":
|
90 |
+
await CallbackQuery.edit_message_text(helpers.HELP_15, reply_markup=keyboard)
|
Devine/plugins/bot/inline.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram.types import (
|
2 |
+
InlineKeyboardButton,
|
3 |
+
InlineKeyboardMarkup,
|
4 |
+
InlineQueryResultPhoto,
|
5 |
+
)
|
6 |
+
from youtubesearchpython.__future__ import VideosSearch
|
7 |
+
|
8 |
+
from Devine import app
|
9 |
+
from Devine.utils.inlinequery import answer
|
10 |
+
from config import BANNED_USERS
|
11 |
+
|
12 |
+
|
13 |
+
@app.on_inline_query(~BANNED_USERS)
|
14 |
+
async def inline_query_handler(client, query):
|
15 |
+
text = query.query.strip().lower()
|
16 |
+
answers = []
|
17 |
+
if text.strip() == "":
|
18 |
+
try:
|
19 |
+
await client.answer_inline_query(query.id, results=answer, cache_time=10)
|
20 |
+
except:
|
21 |
+
return
|
22 |
+
else:
|
23 |
+
a = VideosSearch(text, limit=20)
|
24 |
+
result = (await a.next()).get("result")
|
25 |
+
for x in range(15):
|
26 |
+
title = (result[x]["title"]).title()
|
27 |
+
duration = result[x]["duration"]
|
28 |
+
views = result[x]["viewCount"]["short"]
|
29 |
+
thumbnail = result[x]["thumbnails"][0]["url"].split("?")[0]
|
30 |
+
channellink = result[x]["channel"]["link"]
|
31 |
+
channel = result[x]["channel"]["name"]
|
32 |
+
link = result[x]["link"]
|
33 |
+
published = result[x]["publishedTime"]
|
34 |
+
description = f"{views} | {duration} ᴍɪɴᴜᴛᴇs | {channel} | {published}"
|
35 |
+
buttons = InlineKeyboardMarkup(
|
36 |
+
[
|
37 |
+
[
|
38 |
+
InlineKeyboardButton(
|
39 |
+
text="ʏᴏᴜᴛᴜʙᴇ",
|
40 |
+
url=link,
|
41 |
+
)
|
42 |
+
],
|
43 |
+
]
|
44 |
+
)
|
45 |
+
searched_text = f"""
|
46 |
+
<b>‣ ᴛɪᴛʟᴇ :</b> <a href={link}>{title}</a>
|
47 |
+
|
48 |
+
<b>ᴅᴜʀᴀᴛɪᴏɴ :</b> {duration} ᴍɪɴᴜᴛᴇs
|
49 |
+
<b>ᴠɪᴇᴡs :</b> <code>{views}</code>
|
50 |
+
<b>ᴄʜᴀɴɴᴇʟ :</b> <a href={channellink}>{channel}</a>
|
51 |
+
<b>ᴘᴜʙʟɪsʜᴇᴅ ᴏɴ :</b> {published}
|
52 |
+
|
53 |
+
|
54 |
+
<u><b>‣ ɪɴʟɪɴᴇ sᴇᴀʀᴄʜ ᴍᴏᴅᴇ ʙʏ {app.name}</b></u>"""
|
55 |
+
answers.append(
|
56 |
+
InlineQueryResultPhoto(
|
57 |
+
photo_url=thumbnail,
|
58 |
+
title=title,
|
59 |
+
thumb_url=thumbnail,
|
60 |
+
description=description,
|
61 |
+
caption=searched_text,
|
62 |
+
reply_markup=buttons,
|
63 |
+
)
|
64 |
+
)
|
65 |
+
try:
|
66 |
+
return await client.answer_inline_query(query.id, results=answers)
|
67 |
+
except:
|
68 |
+
return
|
Devine/plugins/bot/settings.py
ADDED
@@ -0,0 +1,391 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.enums import ChatType
|
3 |
+
from pyrogram.errors import MessageNotModified
|
4 |
+
from pyrogram.types import (
|
5 |
+
CallbackQuery,
|
6 |
+
InlineKeyboardButton,
|
7 |
+
InlineKeyboardMarkup,
|
8 |
+
Message,
|
9 |
+
)
|
10 |
+
|
11 |
+
from Devine import app
|
12 |
+
from Devine.utils.database import (
|
13 |
+
add_nonadmin_chat,
|
14 |
+
get_authuser,
|
15 |
+
get_authuser_names,
|
16 |
+
get_playmode,
|
17 |
+
get_playtype,
|
18 |
+
get_upvote_count,
|
19 |
+
is_nonadmin_chat,
|
20 |
+
is_skipmode,
|
21 |
+
remove_nonadmin_chat,
|
22 |
+
set_playmode,
|
23 |
+
set_playtype,
|
24 |
+
set_upvotes,
|
25 |
+
skip_off,
|
26 |
+
skip_on,
|
27 |
+
)
|
28 |
+
from Devine.utils.decorators.admins import ActualAdminCB
|
29 |
+
from Devine.utils.decorators.language import language, languageCB
|
30 |
+
from Devine.utils.inline.settings import (
|
31 |
+
auth_users_markup,
|
32 |
+
playmode_users_markup,
|
33 |
+
setting_markup,
|
34 |
+
vote_mode_markup,
|
35 |
+
)
|
36 |
+
from Devine.utils.inline.start import private_panel
|
37 |
+
from config import BANNED_USERS, OWNER_ID
|
38 |
+
|
39 |
+
|
40 |
+
@app.on_message(
|
41 |
+
filters.command(["musucsettings", "musicsetting"]) & filters.group & ~BANNED_USERS
|
42 |
+
)
|
43 |
+
@language
|
44 |
+
async def settings_mar(client, message: Message, _):
|
45 |
+
buttons = setting_markup(_)
|
46 |
+
await message.reply_text(
|
47 |
+
_["setting_1"].format(app.mention, message.chat.id, message.chat.title),
|
48 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
49 |
+
)
|
50 |
+
|
51 |
+
|
52 |
+
@app.on_callback_query(filters.regex("settings_helper") & ~BANNED_USERS)
|
53 |
+
@languageCB
|
54 |
+
async def settings_cb(client, CallbackQuery, _):
|
55 |
+
try:
|
56 |
+
await CallbackQuery.answer(_["set_cb_5"])
|
57 |
+
except:
|
58 |
+
pass
|
59 |
+
buttons = setting_markup(_)
|
60 |
+
return await CallbackQuery.edit_message_text(
|
61 |
+
_["setting_1"].format(
|
62 |
+
app.mention,
|
63 |
+
CallbackQuery.message.chat.id,
|
64 |
+
CallbackQuery.message.chat.title,
|
65 |
+
),
|
66 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
67 |
+
)
|
68 |
+
|
69 |
+
|
70 |
+
@app.on_callback_query(filters.regex("settingsback_helper") & ~BANNED_USERS)
|
71 |
+
@languageCB
|
72 |
+
async def settings_back_markup(client, CallbackQuery: CallbackQuery, _):
|
73 |
+
try:
|
74 |
+
await CallbackQuery.answer()
|
75 |
+
except:
|
76 |
+
pass
|
77 |
+
if CallbackQuery.message.chat.type == ChatType.PRIVATE:
|
78 |
+
await app.resolve_peer(OWNER_ID)
|
79 |
+
OWNER = OWNER_ID
|
80 |
+
buttons = private_panel(_)
|
81 |
+
return await CallbackQuery.edit_message_text(
|
82 |
+
_["start_2"].format(CallbackQuery.from_user.mention, app.mention),
|
83 |
+
reply_markup=InlineKeyboardMarkup(buttons),
|
84 |
+
)
|
85 |
+
else:
|
86 |
+
buttons = setting_markup(_)
|
87 |
+
return await CallbackQuery.edit_message_reply_markup(
|
88 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
89 |
+
)
|
90 |
+
|
91 |
+
|
92 |
+
@app.on_callback_query(
|
93 |
+
filters.regex(
|
94 |
+
pattern=r"^(SEARCHANSWER|PLAYMODEANSWER|PLAYTYPEANSWER|AUTHANSWER|ANSWERVOMODE|VOTEANSWER|PM|AU|VM)$"
|
95 |
+
)
|
96 |
+
& ~BANNED_USERS
|
97 |
+
)
|
98 |
+
@languageCB
|
99 |
+
async def without_Admin_rights(client, CallbackQuery, _):
|
100 |
+
command = CallbackQuery.matches[0].group(1)
|
101 |
+
if command == "SEARCHANSWER":
|
102 |
+
try:
|
103 |
+
return await CallbackQuery.answer(_["setting_2"], show_alert=True)
|
104 |
+
except:
|
105 |
+
return
|
106 |
+
if command == "PLAYMODEANSWER":
|
107 |
+
try:
|
108 |
+
return await CallbackQuery.answer(_["setting_5"], show_alert=True)
|
109 |
+
except:
|
110 |
+
return
|
111 |
+
if command == "PLAYTYPEANSWER":
|
112 |
+
try:
|
113 |
+
return await CallbackQuery.answer(_["setting_6"], show_alert=True)
|
114 |
+
except:
|
115 |
+
return
|
116 |
+
if command == "AUTHANSWER":
|
117 |
+
try:
|
118 |
+
return await CallbackQuery.answer(_["setting_3"], show_alert=True)
|
119 |
+
except:
|
120 |
+
return
|
121 |
+
if command == "VOTEANSWER":
|
122 |
+
try:
|
123 |
+
return await CallbackQuery.answer(
|
124 |
+
_["setting_8"],
|
125 |
+
show_alert=True,
|
126 |
+
)
|
127 |
+
except:
|
128 |
+
return
|
129 |
+
if command == "ANSWERVOMODE":
|
130 |
+
current = await get_upvote_count(CallbackQuery.message.chat.id)
|
131 |
+
try:
|
132 |
+
return await CallbackQuery.answer(
|
133 |
+
_["setting_9"].format(current),
|
134 |
+
show_alert=True,
|
135 |
+
)
|
136 |
+
except:
|
137 |
+
return
|
138 |
+
if command == "PM":
|
139 |
+
try:
|
140 |
+
await CallbackQuery.answer(_["set_cb_2"], show_alert=True)
|
141 |
+
except:
|
142 |
+
pass
|
143 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
144 |
+
if playmode == "Direct":
|
145 |
+
Direct = True
|
146 |
+
else:
|
147 |
+
Direct = None
|
148 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
149 |
+
if not is_non_admin:
|
150 |
+
Group = True
|
151 |
+
else:
|
152 |
+
Group = None
|
153 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
154 |
+
if playty == "Everyone":
|
155 |
+
Playtype = None
|
156 |
+
else:
|
157 |
+
Playtype = True
|
158 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
159 |
+
if command == "AU":
|
160 |
+
try:
|
161 |
+
await CallbackQuery.answer(_["set_cb_1"], show_alert=True)
|
162 |
+
except:
|
163 |
+
pass
|
164 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
165 |
+
if not is_non_admin:
|
166 |
+
buttons = auth_users_markup(_, True)
|
167 |
+
else:
|
168 |
+
buttons = auth_users_markup(_)
|
169 |
+
if command == "VM":
|
170 |
+
mode = await is_skipmode(CallbackQuery.message.chat.id)
|
171 |
+
current = await get_upvote_count(CallbackQuery.message.chat.id)
|
172 |
+
buttons = vote_mode_markup(_, current, mode)
|
173 |
+
try:
|
174 |
+
return await CallbackQuery.edit_message_reply_markup(
|
175 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
176 |
+
)
|
177 |
+
except MessageNotModified:
|
178 |
+
return
|
179 |
+
|
180 |
+
|
181 |
+
@app.on_callback_query(filters.regex("FERRARIUDTI") & ~BANNED_USERS)
|
182 |
+
@ActualAdminCB
|
183 |
+
async def addition(client, CallbackQuery, _):
|
184 |
+
callback_data = CallbackQuery.data.strip()
|
185 |
+
mode = callback_data.split(None, 1)[1]
|
186 |
+
if not await is_skipmode(CallbackQuery.message.chat.id):
|
187 |
+
return await CallbackQuery.answer(_["setting_10"], show_alert=True)
|
188 |
+
current = await get_upvote_count(CallbackQuery.message.chat.id)
|
189 |
+
if mode == "M":
|
190 |
+
final = current - 2
|
191 |
+
print(final)
|
192 |
+
if final == 0:
|
193 |
+
return await CallbackQuery.answer(
|
194 |
+
_["setting_11"],
|
195 |
+
show_alert=True,
|
196 |
+
)
|
197 |
+
if final <= 2:
|
198 |
+
final = 2
|
199 |
+
await set_upvotes(CallbackQuery.message.chat.id, final)
|
200 |
+
else:
|
201 |
+
final = current + 2
|
202 |
+
print(final)
|
203 |
+
if final == 17:
|
204 |
+
return await CallbackQuery.answer(
|
205 |
+
_["setting_12"],
|
206 |
+
show_alert=True,
|
207 |
+
)
|
208 |
+
if final >= 15:
|
209 |
+
final = 15
|
210 |
+
await set_upvotes(CallbackQuery.message.chat.id, final)
|
211 |
+
buttons = vote_mode_markup(_, final, True)
|
212 |
+
try:
|
213 |
+
return await CallbackQuery.edit_message_reply_markup(
|
214 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
215 |
+
)
|
216 |
+
except MessageNotModified:
|
217 |
+
return
|
218 |
+
|
219 |
+
|
220 |
+
@app.on_callback_query(
|
221 |
+
filters.regex(pattern=r"^(MODECHANGE|CHANNELMODECHANGE|PLAYTYPECHANGE)$")
|
222 |
+
& ~BANNED_USERS
|
223 |
+
)
|
224 |
+
@ActualAdminCB
|
225 |
+
async def playmode_ans(client, CallbackQuery, _):
|
226 |
+
command = CallbackQuery.matches[0].group(1)
|
227 |
+
if command == "CHANNELMODECHANGE":
|
228 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
229 |
+
if not is_non_admin:
|
230 |
+
await add_nonadmin_chat(CallbackQuery.message.chat.id)
|
231 |
+
Group = None
|
232 |
+
else:
|
233 |
+
await remove_nonadmin_chat(CallbackQuery.message.chat.id)
|
234 |
+
Group = True
|
235 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
236 |
+
if playmode == "Direct":
|
237 |
+
Direct = True
|
238 |
+
else:
|
239 |
+
Direct = None
|
240 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
241 |
+
if playty == "Everyone":
|
242 |
+
Playtype = None
|
243 |
+
else:
|
244 |
+
Playtype = True
|
245 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
246 |
+
if command == "MODECHANGE":
|
247 |
+
try:
|
248 |
+
await CallbackQuery.answer(_["set_cb_3"], show_alert=True)
|
249 |
+
except:
|
250 |
+
pass
|
251 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
252 |
+
if playmode == "Direct":
|
253 |
+
await set_playmode(CallbackQuery.message.chat.id, "Inline")
|
254 |
+
Direct = None
|
255 |
+
else:
|
256 |
+
await set_playmode(CallbackQuery.message.chat.id, "Direct")
|
257 |
+
Direct = True
|
258 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
259 |
+
if not is_non_admin:
|
260 |
+
Group = True
|
261 |
+
else:
|
262 |
+
Group = None
|
263 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
264 |
+
if playty == "Everyone":
|
265 |
+
Playtype = False
|
266 |
+
else:
|
267 |
+
Playtype = True
|
268 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
269 |
+
if command == "PLAYTYPECHANGE":
|
270 |
+
try:
|
271 |
+
await CallbackQuery.answer(_["set_cb_3"], show_alert=True)
|
272 |
+
except:
|
273 |
+
pass
|
274 |
+
playty = await get_playtype(CallbackQuery.message.chat.id)
|
275 |
+
if playty == "Everyone":
|
276 |
+
await set_playtype(CallbackQuery.message.chat.id, "Admin")
|
277 |
+
Playtype = False
|
278 |
+
else:
|
279 |
+
await set_playtype(CallbackQuery.message.chat.id, "Everyone")
|
280 |
+
Playtype = True
|
281 |
+
playmode = await get_playmode(CallbackQuery.message.chat.id)
|
282 |
+
if playmode == "Direct":
|
283 |
+
Direct = True
|
284 |
+
else:
|
285 |
+
Direct = None
|
286 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
287 |
+
if not is_non_admin:
|
288 |
+
Group = True
|
289 |
+
else:
|
290 |
+
Group = None
|
291 |
+
buttons = playmode_users_markup(_, Direct, Group, Playtype)
|
292 |
+
try:
|
293 |
+
return await CallbackQuery.edit_message_reply_markup(
|
294 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
295 |
+
)
|
296 |
+
except MessageNotModified:
|
297 |
+
return
|
298 |
+
|
299 |
+
|
300 |
+
@app.on_callback_query(filters.regex(pattern=r"^(AUTH|AUTHLIST)$") & ~BANNED_USERS)
|
301 |
+
@ActualAdminCB
|
302 |
+
async def authusers_mar(client, CallbackQuery, _):
|
303 |
+
command = CallbackQuery.matches[0].group(1)
|
304 |
+
if command == "AUTHLIST":
|
305 |
+
_authusers = await get_authuser_names(CallbackQuery.message.chat.id)
|
306 |
+
if not _authusers:
|
307 |
+
try:
|
308 |
+
return await CallbackQuery.answer(_["setting_4"], show_alert=True)
|
309 |
+
except:
|
310 |
+
return
|
311 |
+
else:
|
312 |
+
try:
|
313 |
+
await CallbackQuery.answer(_["set_cb_4"], show_alert=True)
|
314 |
+
except:
|
315 |
+
pass
|
316 |
+
j = 0
|
317 |
+
await CallbackQuery.edit_message_text(_["auth_6"])
|
318 |
+
msg = _["auth_7"].format(CallbackQuery.message.chat.title)
|
319 |
+
for note in _authusers:
|
320 |
+
_note = await get_authuser(CallbackQuery.message.chat.id, note)
|
321 |
+
user_id = _note["auth_user_id"]
|
322 |
+
admin_id = _note["admin_id"]
|
323 |
+
admin_name = _note["admin_name"]
|
324 |
+
try:
|
325 |
+
user = await app.get_users(user_id)
|
326 |
+
user = user.first_name
|
327 |
+
j += 1
|
328 |
+
except:
|
329 |
+
continue
|
330 |
+
msg += f"{j}➤ {user}[<code>{user_id}</code>]\n"
|
331 |
+
msg += f" {_['auth_8']} {admin_name}[<code>{admin_id}</code>]\n\n"
|
332 |
+
upl = InlineKeyboardMarkup(
|
333 |
+
[
|
334 |
+
[
|
335 |
+
InlineKeyboardButton(
|
336 |
+
text=_["BACK_BUTTON"], callback_data=f"AU"
|
337 |
+
),
|
338 |
+
InlineKeyboardButton(
|
339 |
+
text=_["CLOSE_BUTTON"],
|
340 |
+
callback_data=f"close",
|
341 |
+
),
|
342 |
+
]
|
343 |
+
]
|
344 |
+
)
|
345 |
+
try:
|
346 |
+
return await CallbackQuery.edit_message_text(msg, reply_markup=upl)
|
347 |
+
except MessageNotModified:
|
348 |
+
return
|
349 |
+
try:
|
350 |
+
await CallbackQuery.answer(_["set_cb_3"], show_alert=True)
|
351 |
+
except:
|
352 |
+
pass
|
353 |
+
if command == "AUTH":
|
354 |
+
is_non_admin = await is_nonadmin_chat(CallbackQuery.message.chat.id)
|
355 |
+
if not is_non_admin:
|
356 |
+
await add_nonadmin_chat(CallbackQuery.message.chat.id)
|
357 |
+
buttons = auth_users_markup(_)
|
358 |
+
else:
|
359 |
+
await remove_nonadmin_chat(CallbackQuery.message.chat.id)
|
360 |
+
buttons = auth_users_markup(_, True)
|
361 |
+
try:
|
362 |
+
return await CallbackQuery.edit_message_reply_markup(
|
363 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
364 |
+
)
|
365 |
+
except MessageNotModified:
|
366 |
+
return
|
367 |
+
|
368 |
+
|
369 |
+
@app.on_callback_query(filters.regex("VOMODECHANGE") & ~BANNED_USERS)
|
370 |
+
@ActualAdminCB
|
371 |
+
async def vote_change(client, CallbackQuery, _):
|
372 |
+
command = CallbackQuery.matches[0].group(1)
|
373 |
+
try:
|
374 |
+
await CallbackQuery.answer(_["set_cb_3"], show_alert=True)
|
375 |
+
except:
|
376 |
+
pass
|
377 |
+
mod = None
|
378 |
+
if await is_skipmode(CallbackQuery.message.chat.id):
|
379 |
+
await skip_off(CallbackQuery.message.chat.id)
|
380 |
+
else:
|
381 |
+
mod = True
|
382 |
+
await skip_on(CallbackQuery.message.chat.id)
|
383 |
+
current = await get_upvote_count(CallbackQuery.message.chat.id)
|
384 |
+
buttons = vote_mode_markup(_, current, mod)
|
385 |
+
|
386 |
+
try:
|
387 |
+
return await CallbackQuery.edit_message_reply_markup(
|
388 |
+
reply_markup=InlineKeyboardMarkup(buttons)
|
389 |
+
)
|
390 |
+
except MessageNotModified:
|
391 |
+
return
|