taslim19 commited on
Commit
80287e2
·
1 Parent(s): f5c5d5b

Initial commit

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +10 -0
  2. .github/readme.md +1 -0
  3. .github/workflows/build.yml +11 -0
  4. .github/workflows/main.yml +47 -0
  5. .github/workflows/youtube_download.yml +27 -0
  6. .gitignore +11 -0
  7. .nixpacks.yml +4 -0
  8. Devine/__init__.py +24 -0
  9. Devine/__main__.py +74 -0
  10. Devine/core/bot.py +57 -0
  11. Devine/core/call.py +601 -0
  12. Devine/core/dir.py +20 -0
  13. Devine/core/git.py +80 -0
  14. Devine/core/mongo.py +14 -0
  15. Devine/core/userbot.py +170 -0
  16. Devine/logging.py +19 -0
  17. Devine/misc.py +75 -0
  18. Devine/modules/fonts.py +188 -0
  19. Devine/mongo/afkdb.py +32 -0
  20. Devine/mongo/readable_time.py +23 -0
  21. Devine/platforms/Apple.py +71 -0
  22. Devine/platforms/Carbon.py +106 -0
  23. Devine/platforms/Resso.py +54 -0
  24. Devine/platforms/Soundcloud.py +39 -0
  25. Devine/platforms/Spotify.py +98 -0
  26. Devine/platforms/Telegram.py +176 -0
  27. Devine/platforms/Youtube.py +407 -0
  28. Devine/platforms/__init__.py +7 -0
  29. Devine/plugins/Dev/fonts.py +196 -0
  30. Devine/plugins/Dev/groupdata.py +53 -0
  31. Devine/plugins/Dev/groupinfo.py +50 -0
  32. Devine/plugins/Dev/password.py +46 -0
  33. Devine/plugins/Dev/sangmeta.py +56 -0
  34. Devine/plugins/Dev/truth_and_dare.py +17 -0
  35. Devine/plugins/Dev/upload.py +79 -0
  36. Devine/plugins/Dev/write.py +24 -0
  37. Devine/plugins/__init__.py +19 -0
  38. Devine/plugins/admins/auth.py +89 -0
  39. Devine/plugins/admins/callback.py +397 -0
  40. Devine/plugins/admins/loop.py +46 -0
  41. Devine/plugins/admins/pause.py +21 -0
  42. Devine/plugins/admins/resume.py +21 -0
  43. Devine/plugins/admins/seek.py +75 -0
  44. Devine/plugins/admins/shuffle.py +33 -0
  45. Devine/plugins/admins/skip.py +232 -0
  46. Devine/plugins/admins/speed.py +112 -0
  47. Devine/plugins/admins/stop.py +23 -0
  48. Devine/plugins/bot/help.py +90 -0
  49. Devine/plugins/bot/inline.py +68 -0
  50. 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