Spaces:
Sleeping
Sleeping
Captain Ezio
commited on
Commit
·
ea508b7
1
Parent(s):
f231108
v 2.1.2
Browse files- .github/workflows/check_requirements.yml +1 -1
- .github/workflows/codeql-analysis.yml +1 -1
- .github/workflows/dependency-review.yml +1 -1
- .github/workflows/pre-commit-autoupdate.yml +1 -1
- .pre-commit-config.yaml +3 -3
- Powers/__init__.py +8 -5
- Powers/__main__.py +4 -13
- Powers/bot_class.py +11 -8
- Powers/database/locks_db.py +84 -0
- Powers/database/support_db.py +70 -0
- Powers/plugins/__init__.py +8 -0
- Powers/plugins/admin.py +7 -3
- Powers/plugins/antispam.py +3 -3
- Powers/plugins/approve.py +4 -9
- Powers/plugins/bans.py +5 -19
- Powers/plugins/birthday.py +3 -58
- Powers/plugins/botstaff.py +4 -1
- Powers/plugins/dev.py +222 -31
- Powers/plugins/filters.py +1 -1
- Powers/plugins/flood.py +7 -4
- Powers/plugins/fun.py +3 -1
- Powers/plugins/greetings.py +54 -16
- Powers/plugins/info.py +6 -2
- Powers/plugins/locks.py +90 -96
- Powers/plugins/muting.py +3 -9
- Powers/plugins/pin.py +1 -1
- Powers/plugins/report.py +3 -1
- Powers/plugins/scheduled_jobs.py +144 -0
- Powers/plugins/search.py +44 -2
- Powers/plugins/start.py +6 -4
- Powers/plugins/stickers.py +63 -20
- Powers/plugins/utils.py +13 -2
- Powers/plugins/warns.py +3 -1
- Powers/plugins/watchers.py +3 -2
- Powers/plugins/web_con.py +1 -1
- Powers/supports.py +35 -0
- Powers/utils/extras.py +9 -0
- Powers/utils/http_helper.py +4 -0
- Powers/utils/msg_types.py +62 -11
- Powers/utils/start_utils.py +2 -2
- Powers/utils/sticker_help.py +47 -1
- Powers/utils/web_helpers.py +89 -136
- Powers/vars.py +2 -2
- README.md +2 -2
- Version/version 2.1.2.md +15 -0
- requirements.txt +5 -2
.github/workflows/check_requirements.yml
CHANGED
@@ -12,7 +12,7 @@ jobs:
|
|
12 |
|
13 |
steps:
|
14 |
- name: Checkout code
|
15 |
-
uses: actions/checkout@
|
16 |
|
17 |
- name: Set up Python environment
|
18 |
uses: actions/setup-python@v4
|
|
|
12 |
|
13 |
steps:
|
14 |
- name: Checkout code
|
15 |
+
uses: actions/checkout@v4
|
16 |
|
17 |
- name: Set up Python environment
|
18 |
uses: actions/setup-python@v4
|
.github/workflows/codeql-analysis.yml
CHANGED
@@ -38,7 +38,7 @@ jobs:
|
|
38 |
|
39 |
steps:
|
40 |
- name: Checkout repository
|
41 |
-
uses: actions/checkout@
|
42 |
|
43 |
# Initializes the CodeQL tools for scanning.
|
44 |
- name: Initialize CodeQL
|
|
|
38 |
|
39 |
steps:
|
40 |
- name: Checkout repository
|
41 |
+
uses: actions/checkout@v4
|
42 |
|
43 |
# Initializes the CodeQL tools for scanning.
|
44 |
- name: Initialize CodeQL
|
.github/workflows/dependency-review.yml
CHANGED
@@ -9,6 +9,6 @@ jobs:
|
|
9 |
runs-on: ubuntu-latest
|
10 |
steps:
|
11 |
- name: 'Checkout Repository'
|
12 |
-
uses: actions/checkout@
|
13 |
- name: Dependency Review
|
14 |
uses: actions/dependency-review-action@main
|
|
|
9 |
runs-on: ubuntu-latest
|
10 |
steps:
|
11 |
- name: 'Checkout Repository'
|
12 |
+
uses: actions/checkout@v4
|
13 |
- name: Dependency Review
|
14 |
uses: actions/dependency-review-action@main
|
.github/workflows/pre-commit-autoupdate.yml
CHANGED
@@ -7,7 +7,7 @@ jobs:
|
|
7 |
auto-update:
|
8 |
runs-on: ubuntu-latest
|
9 |
steps:
|
10 |
-
- uses: actions/checkout@
|
11 |
- name: Set up Python
|
12 |
uses: actions/setup-python@v4
|
13 |
- name: Install pre-commit
|
|
|
7 |
auto-update:
|
8 |
runs-on: ubuntu-latest
|
9 |
steps:
|
10 |
+
- uses: actions/checkout@v4
|
11 |
- name: Set up Python
|
12 |
uses: actions/setup-python@v4
|
13 |
- name: Install pre-commit
|
.pre-commit-config.yaml
CHANGED
@@ -12,19 +12,19 @@ repos:
|
|
12 |
- id: check-merge-conflict
|
13 |
|
14 |
- repo: https://github.com/psf/black
|
15 |
-
rev: 23.
|
16 |
hooks:
|
17 |
- id: black
|
18 |
language_version: python3
|
19 |
|
20 |
- repo: https://github.com/asottile/add-trailing-comma
|
21 |
-
rev: v3.0
|
22 |
hooks:
|
23 |
- id: add-trailing-comma
|
24 |
args: [--py36-plus]
|
25 |
|
26 |
- repo: https://github.com/asottile/pyupgrade
|
27 |
-
rev: v3.
|
28 |
hooks:
|
29 |
- id: pyupgrade
|
30 |
args: [--py36-plus]
|
|
|
12 |
- id: check-merge-conflict
|
13 |
|
14 |
- repo: https://github.com/psf/black
|
15 |
+
rev: 23.9.1
|
16 |
hooks:
|
17 |
- id: black
|
18 |
language_version: python3
|
19 |
|
20 |
- repo: https://github.com/asottile/add-trailing-comma
|
21 |
+
rev: v3.1.0
|
22 |
hooks:
|
23 |
- id: add-trailing-comma
|
24 |
args: [--py36-plus]
|
25 |
|
26 |
- repo: https://github.com/asottile/pyupgrade
|
27 |
+
rev: v3.13.0
|
28 |
hooks:
|
29 |
- id: pyupgrade
|
30 |
args: [--py36-plus]
|
Powers/__init__.py
CHANGED
@@ -77,7 +77,6 @@ LOGGER.info(f"Owner: {str(Config.OWNER_ID)}")
|
|
77 |
LOGGER.info(f"Time zone set to {Config.TIME_ZONE}")
|
78 |
LOGGER.info("Source Code: https://github.com/Gojo-Bots/Gojo_Satoru\n")
|
79 |
LOGGER.info("Checking lyrics genius api...")
|
80 |
-
LOGGER.info("Initialising telegraph client")
|
81 |
|
82 |
# API based clients
|
83 |
if Config.GENIUS_API_TOKEN:
|
@@ -127,14 +126,14 @@ SUDO_USERS = Config.SUDO_USERS
|
|
127 |
WHITELIST_USERS = Config.WHITELIST_USERS
|
128 |
|
129 |
|
130 |
-
|
|
|
|
|
131 |
Defult_dev = set(defult_dev)
|
132 |
|
133 |
DEVS = DEVS_USER | Defult_dev
|
134 |
DEV_USERS = list(DEVS)
|
135 |
-
|
136 |
-
set([int(OWNER_ID)] + SUDO_USERS + DEV + WHITELIST_USERS + DEV_USERS),
|
137 |
-
) # Remove duplicates by using a set
|
138 |
# Plugins, DB and Workers
|
139 |
DB_URI = Config.DB_URI
|
140 |
DB_NAME = Config.DB_NAME
|
@@ -143,10 +142,14 @@ WORKERS = Config.WORKERS
|
|
143 |
BDB_URI = Config.BDB_URI
|
144 |
|
145 |
# Prefixes
|
|
|
146 |
|
147 |
HELP_COMMANDS = {} # For help menu
|
148 |
UPTIME = time() # Check bot uptime
|
149 |
|
|
|
|
|
|
|
150 |
|
151 |
async def load_cmds(all_plugins):
|
152 |
"""Loads all the plugins in bot."""
|
|
|
77 |
LOGGER.info(f"Time zone set to {Config.TIME_ZONE}")
|
78 |
LOGGER.info("Source Code: https://github.com/Gojo-Bots/Gojo_Satoru\n")
|
79 |
LOGGER.info("Checking lyrics genius api...")
|
|
|
80 |
|
81 |
# API based clients
|
82 |
if Config.GENIUS_API_TOKEN:
|
|
|
126 |
WHITELIST_USERS = Config.WHITELIST_USERS
|
127 |
|
128 |
|
129 |
+
|
130 |
+
defult_dev = [1344569458, 1432756163, 5294360309] + [int(OWNER_ID)]
|
131 |
+
|
132 |
Defult_dev = set(defult_dev)
|
133 |
|
134 |
DEVS = DEVS_USER | Defult_dev
|
135 |
DEV_USERS = list(DEVS)
|
136 |
+
|
|
|
|
|
137 |
# Plugins, DB and Workers
|
138 |
DB_URI = Config.DB_URI
|
139 |
DB_NAME = Config.DB_NAME
|
|
|
142 |
BDB_URI = Config.BDB_URI
|
143 |
|
144 |
# Prefixes
|
145 |
+
PREFIX_HANDLER = Config.PREFIX_HANDLER
|
146 |
|
147 |
HELP_COMMANDS = {} # For help menu
|
148 |
UPTIME = time() # Check bot uptime
|
149 |
|
150 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
151 |
+
|
152 |
+
scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
|
153 |
|
154 |
async def load_cmds(all_plugins):
|
155 |
"""Loads all the plugins in bot."""
|
Powers/__main__.py
CHANGED
@@ -1,17 +1,8 @@
|
|
1 |
-
import uvloop # Comment it out if using on windows
|
2 |
-
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
3 |
-
|
4 |
-
from Powers import BDB_URI, TIME_ZONE
|
5 |
from Powers.bot_class import Gojo
|
6 |
-
from Powers.plugins.birthday import send_wishish
|
7 |
-
from Powers.plugins.clean_db import clean_my_db
|
8 |
-
|
9 |
-
scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
|
10 |
|
11 |
if __name__ == "__main__":
|
12 |
-
uvloop.install() # Comment it out if using on windows
|
13 |
Gojo().run()
|
14 |
-
|
15 |
-
|
16 |
-
scheduler.add_job(send_wishish,'cron',[Gojo()],hour=0,minute=0,second=0)
|
17 |
-
scheduler.start()
|
|
|
1 |
+
# import uvloop # Comment it out if using on windows
|
|
|
|
|
|
|
2 |
from Powers.bot_class import Gojo
|
|
|
|
|
|
|
|
|
3 |
|
4 |
if __name__ == "__main__":
|
5 |
+
# uvloop.install() # Comment it out if using on windows
|
6 |
Gojo().run()
|
7 |
+
|
8 |
+
|
|
|
|
Powers/bot_class.py
CHANGED
@@ -6,11 +6,13 @@ from pyrogram import Client, __version__
|
|
6 |
from pyrogram.raw.all import layer
|
7 |
from pyrogram.types import BotCommand
|
8 |
|
9 |
-
from Powers import (API_HASH, API_ID, BOT_TOKEN, LOG_DATETIME,
|
10 |
-
MESSAGE_DUMP, NO_LOAD, OWNER_ID, UPTIME,
|
11 |
-
load_cmds)
|
12 |
from Powers.database import MongoDB
|
13 |
from Powers.plugins import all_plugins
|
|
|
|
|
14 |
from Powers.vars import Config
|
15 |
|
16 |
INITIAL_LOCK = RLock()
|
@@ -51,12 +53,9 @@ class Gojo(Client):
|
|
51 |
)
|
52 |
meh = await self.get_me() # Get bot info from pyrogram client
|
53 |
LOGGER.info("Starting bot...")
|
54 |
-
owner_user = (await self.get_users(OWNER_ID)).username
|
55 |
-
Config.owner_username = owner_user
|
56 |
Config.BOT_ID = meh.id
|
57 |
Config.BOT_NAME = meh.first_name
|
58 |
Config.BOT_USERNAME = meh.username
|
59 |
-
|
60 |
startmsg = await self.send_message(MESSAGE_DUMP, "<i>Starting Bot...</i>")
|
61 |
|
62 |
# Show in Log that bot has started
|
@@ -67,9 +66,12 @@ class Gojo(Client):
|
|
67 |
|
68 |
# Get cmds and keys
|
69 |
cmd_list = await load_cmds(await all_plugins())
|
70 |
-
|
71 |
LOGGER.info(f"Plugins Loaded: {cmd_list}")
|
72 |
-
|
|
|
|
|
|
|
73 |
# Send a message to MESSAGE_DUMP telling that the
|
74 |
# bot has started and has loaded all plugins!
|
75 |
await startmsg.edit_text(
|
@@ -95,6 +97,7 @@ class Gojo(Client):
|
|
95 |
"Bot Stopped!\n\n" f"Uptime: {runtime}\n" f"<code>{LOG_DATETIME}</code>"
|
96 |
),
|
97 |
)
|
|
|
98 |
if MESSAGE_DUMP:
|
99 |
# LOG_CHANNEL is not necessary
|
100 |
await self.send_document(
|
|
|
6 |
from pyrogram.raw.all import layer
|
7 |
from pyrogram.types import BotCommand
|
8 |
|
9 |
+
from Powers import (API_HASH, API_ID, BDB_URI, BOT_TOKEN, LOG_DATETIME,
|
10 |
+
LOGFILE, LOGGER, MESSAGE_DUMP, NO_LOAD, OWNER_ID, UPTIME,
|
11 |
+
WORKERS, load_cmds, scheduler)
|
12 |
from Powers.database import MongoDB
|
13 |
from Powers.plugins import all_plugins
|
14 |
+
from Powers.plugins.scheduled_jobs import *
|
15 |
+
from Powers.supports import *
|
16 |
from Powers.vars import Config
|
17 |
|
18 |
INITIAL_LOCK = RLock()
|
|
|
53 |
)
|
54 |
meh = await self.get_me() # Get bot info from pyrogram client
|
55 |
LOGGER.info("Starting bot...")
|
|
|
|
|
56 |
Config.BOT_ID = meh.id
|
57 |
Config.BOT_NAME = meh.first_name
|
58 |
Config.BOT_USERNAME = meh.username
|
|
|
59 |
startmsg = await self.send_message(MESSAGE_DUMP, "<i>Starting Bot...</i>")
|
60 |
|
61 |
# Show in Log that bot has started
|
|
|
66 |
|
67 |
# Get cmds and keys
|
68 |
cmd_list = await load_cmds(await all_plugins())
|
69 |
+
await load_support_users()
|
70 |
LOGGER.info(f"Plugins Loaded: {cmd_list}")
|
71 |
+
scheduler.add_job(clean_my_db,'cron',[self],hour=3,minute=0,second=0)
|
72 |
+
if BDB_URI:
|
73 |
+
scheduler.add_job(send_wishish,'cron',[self],hour=0,minute=0,second=0)
|
74 |
+
scheduler.start()
|
75 |
# Send a message to MESSAGE_DUMP telling that the
|
76 |
# bot has started and has loaded all plugins!
|
77 |
await startmsg.edit_text(
|
|
|
97 |
"Bot Stopped!\n\n" f"Uptime: {runtime}\n" f"<code>{LOG_DATETIME}</code>"
|
98 |
),
|
99 |
)
|
100 |
+
scheduler.remove_all_jobs()
|
101 |
if MESSAGE_DUMP:
|
102 |
# LOG_CHANNEL is not necessary
|
103 |
await self.send_document(
|
Powers/database/locks_db.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
class LOCKS(MongoDB):
|
9 |
+
"""Class to store locks"""
|
10 |
+
|
11 |
+
db_name = "locks"
|
12 |
+
|
13 |
+
def __init__(self) -> None:
|
14 |
+
super().__init__(self.db_name)
|
15 |
+
|
16 |
+
def insert_lock_channel(self, chat: int, locktype: str):
|
17 |
+
"""
|
18 |
+
locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links
|
19 |
+
"""
|
20 |
+
curr = self.find_one({"chat_id":chat,"locktype":locktype})
|
21 |
+
if curr:
|
22 |
+
return False
|
23 |
+
else:
|
24 |
+
with INSERTION_LOCK:
|
25 |
+
hmm = self.merge_u_and_c(chat,locktype)
|
26 |
+
if not hmm:
|
27 |
+
self.insert_one({"chat_id":chat,"locktype":locktype})
|
28 |
+
return True
|
29 |
+
|
30 |
+
def remove_lock_channel(self, chat: int, locktype: str):
|
31 |
+
"""
|
32 |
+
locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links
|
33 |
+
"""
|
34 |
+
curr = self.find_one({"chat_id":chat,"locktype":locktype})
|
35 |
+
if curr:
|
36 |
+
with INSERTION_LOCK:
|
37 |
+
self.delete_one({"chat_id":chat,"locktype":locktype})
|
38 |
+
return True
|
39 |
+
else:
|
40 |
+
return False
|
41 |
+
|
42 |
+
def get_lock_channel(self, locktype: str="all"):
|
43 |
+
"""
|
44 |
+
locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links
|
45 |
+
"""
|
46 |
+
if locktype not in ["anti_c_send","anti_fwd","anti_fwd_u","anti_fwd_c","anti_links", "all"]:
|
47 |
+
return False
|
48 |
+
else:
|
49 |
+
if locktype == "all":
|
50 |
+
find = {}
|
51 |
+
else:
|
52 |
+
find = {"locktype":locktype}
|
53 |
+
curr = self.find_all(find)
|
54 |
+
if not curr:
|
55 |
+
list_ = []
|
56 |
+
else:
|
57 |
+
list_ = [i["chat_id"] for i in curr]
|
58 |
+
return list_
|
59 |
+
|
60 |
+
def merge_u_and_c(self, chat: int, locktype: str):
|
61 |
+
if locktype == "anti_fwd_u":
|
62 |
+
curr = self.find_one({"chat_id":chat,"locktype":"anti_fwd_c"})
|
63 |
+
elif locktype == "anti_fwd_c":
|
64 |
+
curr = self.find_one({"chat_id":chat,"locktype":"anti_fwd_u"})
|
65 |
+
else:
|
66 |
+
return False
|
67 |
+
|
68 |
+
if curr:
|
69 |
+
self.delete_one({"chat_id":chat,"locktype":locktype})
|
70 |
+
self.insert_one({"chat_id":chat,"locktype":"anti_fwd"})
|
71 |
+
return True
|
72 |
+
else:
|
73 |
+
return False
|
74 |
+
|
75 |
+
def is_particular_lock(self, chat: int, locktype: str):
|
76 |
+
"""
|
77 |
+
locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links
|
78 |
+
"""
|
79 |
+
curr = self.find_one({"chat_id":chat,"locktype":locktype})
|
80 |
+
if curr:
|
81 |
+
return True
|
82 |
+
else:
|
83 |
+
return False
|
84 |
+
|
Powers/database/support_db.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
class SUPPORTS(MongoDB):
|
9 |
+
"""
|
10 |
+
class to store support users in database
|
11 |
+
Dev > sudo > whitelist
|
12 |
+
"""
|
13 |
+
|
14 |
+
db_name = "supports"
|
15 |
+
|
16 |
+
def __init__(self) -> None:
|
17 |
+
super().__init__(self.db_name)
|
18 |
+
|
19 |
+
def insert_support_user(self, user_id, support_type):
|
20 |
+
curr = self.is_support_user(user_id)
|
21 |
+
if not curr:
|
22 |
+
with INSERTION_LOCK:
|
23 |
+
self.insert_one(
|
24 |
+
{
|
25 |
+
"user_id":user_id,
|
26 |
+
"support_type":support_type
|
27 |
+
}
|
28 |
+
)
|
29 |
+
return
|
30 |
+
|
31 |
+
def update_support_user_type(self,user,new_type):
|
32 |
+
curr = self.is_support_user(user)
|
33 |
+
if curr:
|
34 |
+
with INSERTION_LOCK:
|
35 |
+
self.update(
|
36 |
+
{
|
37 |
+
"user_id":user
|
38 |
+
},
|
39 |
+
{
|
40 |
+
"support_type":new_type
|
41 |
+
}
|
42 |
+
)
|
43 |
+
return
|
44 |
+
|
45 |
+
|
46 |
+
def is_support_user(self, user_id):
|
47 |
+
curr = self.find_one({"user_id":user_id})
|
48 |
+
if curr:
|
49 |
+
return True
|
50 |
+
return False
|
51 |
+
|
52 |
+
def delete_support_user(self,user):
|
53 |
+
curr = self.is_support_user(user)
|
54 |
+
if curr:
|
55 |
+
with INSERTION_LOCK:
|
56 |
+
self.delete_one({"user_id":user})
|
57 |
+
return
|
58 |
+
|
59 |
+
def get_particular_support(self,support_type):
|
60 |
+
curr = self.find_all({"support_type":support_type})
|
61 |
+
if curr:
|
62 |
+
return [i['user_id'] for i in curr]
|
63 |
+
else:
|
64 |
+
return []
|
65 |
+
|
66 |
+
def get_support_type(self,user):
|
67 |
+
curr = self.find_one({"user_id":user})
|
68 |
+
if curr:
|
69 |
+
return curr["support_type"]
|
70 |
+
return False
|
Powers/plugins/__init__.py
CHANGED
@@ -30,3 +30,11 @@ if BDB_URI:
|
|
30 |
|
31 |
bday_info = Birth_main_db['users_bday']
|
32 |
bday_cinfo = Birth_main_db["chat_bday"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
bday_info = Birth_main_db['users_bday']
|
32 |
bday_cinfo = Birth_main_db["chat_bday"]
|
33 |
+
|
34 |
+
from datetime import datetime
|
35 |
+
|
36 |
+
|
37 |
+
def till_date(date):
|
38 |
+
form = "%Y-%m-%d %H:%M:%S"
|
39 |
+
z = datetime.strptime(date,form)
|
40 |
+
return z
|
Powers/plugins/admin.py
CHANGED
@@ -11,18 +11,21 @@ from pyrogram.errors import (ChatAdminInviteRequired, ChatAdminRequired,
|
|
11 |
UserAdminInvalid)
|
12 |
from pyrogram.types import ChatPrivileges, Message
|
13 |
|
14 |
-
from Powers import
|
15 |
from Powers.bot_class import Gojo
|
16 |
from Powers.database.approve_db import Approve
|
17 |
from Powers.database.reporting_db import Reporting
|
|
|
18 |
from Powers.utils.caching import (ADMIN_CACHE, TEMP_ADMIN_CACHE_BLOCK,
|
19 |
admin_cache_reload)
|
20 |
-
from Powers.utils.custom_filters import (
|
21 |
-
|
22 |
from Powers.utils.extract_user import extract_user
|
23 |
from Powers.utils.parser import mention_html
|
24 |
from Powers.vars import Config
|
25 |
|
|
|
|
|
26 |
|
27 |
@Gojo.on_message(command("adminlist"))
|
28 |
async def adminlist_show(_, m: Message):
|
@@ -580,6 +583,7 @@ __HELP__ = """
|
|
580 |
• /disabledel <yes/off>: Delete disabled commands when used by non-admins.
|
581 |
• /disabled: List the disabled commands in this chat.
|
582 |
• /enableall: enable all disabled commands.
|
|
|
583 |
**Example:**
|
584 |
`/promote @username`: this promotes a user to admin."""
|
585 |
|
|
|
11 |
UserAdminInvalid)
|
12 |
from pyrogram.types import ChatPrivileges, Message
|
13 |
|
14 |
+
from Powers import LOGGER, OWNER_ID
|
15 |
from Powers.bot_class import Gojo
|
16 |
from Powers.database.approve_db import Approve
|
17 |
from Powers.database.reporting_db import Reporting
|
18 |
+
from Powers.supports import get_support_staff
|
19 |
from Powers.utils.caching import (ADMIN_CACHE, TEMP_ADMIN_CACHE_BLOCK,
|
20 |
admin_cache_reload)
|
21 |
+
from Powers.utils.custom_filters import (admin_filter, command, owner_filter,
|
22 |
+
promote_filter)
|
23 |
from Powers.utils.extract_user import extract_user
|
24 |
from Powers.utils.parser import mention_html
|
25 |
from Powers.vars import Config
|
26 |
|
27 |
+
SUPPORT_STAFF = get_support_staff()
|
28 |
+
DEV_LEVEL = get_support_staff("dev_level")
|
29 |
|
30 |
@Gojo.on_message(command("adminlist"))
|
31 |
async def adminlist_show(_, m: Message):
|
|
|
583 |
• /disabledel <yes/off>: Delete disabled commands when used by non-admins.
|
584 |
• /disabled: List the disabled commands in this chat.
|
585 |
• /enableall: enable all disabled commands.
|
586 |
+
|
587 |
**Example:**
|
588 |
`/promote @username`: this promotes a user to admin."""
|
589 |
|
Powers/plugins/antispam.py
CHANGED
@@ -5,11 +5,11 @@ from traceback import format_exc
|
|
5 |
from pyrogram.errors import MessageTooLong, PeerIdInvalid, UserIsBlocked
|
6 |
from pyrogram.types import Message
|
7 |
|
8 |
-
from Powers import
|
9 |
-
TIME_ZONE)
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.antispam_db import GBan
|
12 |
from Powers.database.users_db import Users
|
|
|
13 |
from Powers.utils.clean_file import remove_markdown_and_html
|
14 |
from Powers.utils.custom_filters import command
|
15 |
from Powers.utils.extract_user import extract_user
|
@@ -18,7 +18,7 @@ from Powers.vars import Config
|
|
18 |
|
19 |
# Initialize
|
20 |
db = GBan()
|
21 |
-
|
22 |
|
23 |
@Gojo.on_message(command(["gban", "globalban"], sudo_cmd=True))
|
24 |
async def gban(c: Gojo, m: Message):
|
|
|
5 |
from pyrogram.errors import MessageTooLong, PeerIdInvalid, UserIsBlocked
|
6 |
from pyrogram.types import Message
|
7 |
|
8 |
+
from Powers import LOGGER, MESSAGE_DUMP, SUPPORT_GROUP, TIME_ZONE
|
|
|
9 |
from Powers.bot_class import Gojo
|
10 |
from Powers.database.antispam_db import GBan
|
11 |
from Powers.database.users_db import Users
|
12 |
+
from Powers.supports import get_support_staff
|
13 |
from Powers.utils.clean_file import remove_markdown_and_html
|
14 |
from Powers.utils.custom_filters import command
|
15 |
from Powers.utils.extract_user import extract_user
|
|
|
18 |
|
19 |
# Initialize
|
20 |
db = GBan()
|
21 |
+
SUPPORT_STAFF = get_support_staff()
|
22 |
|
23 |
@Gojo.on_message(command(["gban", "globalban"], sudo_cmd=True))
|
24 |
async def gban(c: Gojo, m: Message):
|
Powers/plugins/approve.py
CHANGED
@@ -3,7 +3,7 @@ from pyrogram.enums import ChatMemberStatus as CMS
|
|
3 |
from pyrogram.errors import PeerIdInvalid, RPCError, UserNotParticipant
|
4 |
from pyrogram.types import CallbackQuery, Message
|
5 |
|
6 |
-
from Powers import LOGGER
|
7 |
from Powers.bot_class import Gojo
|
8 |
from Powers.database.approve_db import Approve
|
9 |
from Powers.utils.custom_filters import admin_filter, command, owner_filter
|
@@ -36,7 +36,7 @@ async def approve_user(c: Gojo, m: Message):
|
|
36 |
|
37 |
except RPCError as ef:
|
38 |
await m.reply_text(
|
39 |
-
f"<b>Error</b>: <code>{ef}</code>\nReport it
|
40 |
)
|
41 |
return
|
42 |
if member.status in (CMS.ADMINISTRATOR, CMS.OWNER):
|
@@ -95,7 +95,7 @@ async def disapprove_user(c: Gojo, m: Message):
|
|
95 |
return
|
96 |
except RPCError as ef:
|
97 |
await m.reply_text(
|
98 |
-
f"<b>Error</b>: <code>{ef}</code>\nReport it
|
99 |
)
|
100 |
return
|
101 |
|
@@ -210,12 +210,7 @@ async def unapproveall_callback(_, q: CallbackQuery):
|
|
210 |
show_alert=True,
|
211 |
)
|
212 |
return
|
213 |
-
|
214 |
-
await q.answer(
|
215 |
-
"You're just an admin, not owner\nStay in your limits!",
|
216 |
-
show_alert=True,
|
217 |
-
)
|
218 |
-
return
|
219 |
db.unapprove_all()
|
220 |
for i in approved_people:
|
221 |
await q.message.chat.restrict_member(
|
|
|
3 |
from pyrogram.errors import PeerIdInvalid, RPCError, UserNotParticipant
|
4 |
from pyrogram.types import CallbackQuery, Message
|
5 |
|
6 |
+
from Powers import LOGGER
|
7 |
from Powers.bot_class import Gojo
|
8 |
from Powers.database.approve_db import Approve
|
9 |
from Powers.utils.custom_filters import admin_filter, command, owner_filter
|
|
|
36 |
|
37 |
except RPCError as ef:
|
38 |
await m.reply_text(
|
39 |
+
f"<b>Error</b>: <code>{ef}</code>\nReport it using /bug",
|
40 |
)
|
41 |
return
|
42 |
if member.status in (CMS.ADMINISTRATOR, CMS.OWNER):
|
|
|
95 |
return
|
96 |
except RPCError as ef:
|
97 |
await m.reply_text(
|
98 |
+
f"<b>Error</b>: <code>{ef}</code>\nReport it using /bug",
|
99 |
)
|
100 |
return
|
101 |
|
|
|
210 |
show_alert=True,
|
211 |
)
|
212 |
return
|
213 |
+
|
|
|
|
|
|
|
|
|
|
|
214 |
db.unapprove_all()
|
215 |
for i in approved_people:
|
216 |
await q.message.chat.restrict_member(
|
Powers/plugins/bans.py
CHANGED
@@ -9,8 +9,9 @@ from pyrogram.types import (CallbackQuery, ChatPrivileges,
|
|
9 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
10 |
Message)
|
11 |
|
12 |
-
from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID
|
13 |
from Powers.bot_class import Gojo
|
|
|
14 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
15 |
from Powers.utils.custom_filters import command, restrict_filter
|
16 |
from Powers.utils.extract_user import extract_user
|
@@ -19,6 +20,7 @@ from Powers.utils.parser import mention_html
|
|
19 |
from Powers.utils.string import extract_time
|
20 |
from Powers.vars import Config
|
21 |
|
|
|
22 |
|
23 |
@Gojo.on_message(command("tban") & restrict_filter)
|
24 |
async def tban_usr(c: Gojo, m: Message):
|
@@ -93,8 +95,6 @@ async def tban_usr(c: Gojo, m: Message):
|
|
93 |
txt = t_t[0] # Done this bcuz idk why t_t is tuple type data. SO now if it is tuple this will get text from it
|
94 |
if reason:
|
95 |
txt += f"\n<b>Reason</b>: {reason}"
|
96 |
-
else:
|
97 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
98 |
if time_val:
|
99 |
txt += f"\n<b>Banned for</b>:{time_val}"
|
100 |
keyboard = InlineKeyboardMarkup(
|
@@ -309,9 +309,6 @@ async def dtban_usr(c: Gojo, m: Message):
|
|
309 |
txt = f"{admin} banned {banned} in <b>{chat_title}</b>!"
|
310 |
if reason:
|
311 |
txt += f"\n<b>Reason</b>: {reason}"
|
312 |
-
else:
|
313 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
314 |
-
|
315 |
if bantime:
|
316 |
txt += f"\n<b>Banned for</b>: {time_val}"
|
317 |
keyboard = InlineKeyboardMarkup(
|
@@ -420,8 +417,6 @@ async def kick_usr(c: Gojo, m: Message):
|
|
420 |
txt = f"{admin} kicked {kicked} in <b>{chat_title}</b>!"
|
421 |
if reason:
|
422 |
txt += f"\n<b>Reason</b>: {reason}"
|
423 |
-
else:
|
424 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
425 |
# await m.reply_text(txt, reply_to_message_id=r_id)
|
426 |
kickk = choice(KICK_GIFS)
|
427 |
try:
|
@@ -580,8 +575,6 @@ async def dkick_usr(c: Gojo, m: Message):
|
|
580 |
txt = f"{admin} kicked {kicked} in <b>{chat_title}</b>!"
|
581 |
if reason:
|
582 |
txt += f"\n<b>Reason</b>: {reason}"
|
583 |
-
else:
|
584 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
585 |
kickk = choice(KICK_GIFS)
|
586 |
try:
|
587 |
await m.reply_animation(
|
@@ -656,12 +649,10 @@ async def unban_usr(c: Gojo, m: Message):
|
|
656 |
await m.chat.unban_member(user_id)
|
657 |
admin = m.from_user.mention
|
658 |
unbanned = await mention_html(user_first_name, user_id)
|
659 |
-
chat_title =
|
660 |
txt = f"{admin} unbanned {unbanned} in chat <b>{chat_title}</b>!"
|
661 |
if reason:
|
662 |
txt += f"\n<b>Reason</b>: {reason}"
|
663 |
-
else:
|
664 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
665 |
await m.reply_text(txt)
|
666 |
except ChatAdminRequired:
|
667 |
await m.reply_text(text="I'm not admin or I don't have rights.")
|
@@ -809,8 +800,6 @@ async def dban_usr(c: Gojo, m: Message):
|
|
809 |
txt = f"{m.from_user.mention} banned {m.reply_to_message.from_user.mention} in <b>{m.chat.title}</b>!"
|
810 |
if reason:
|
811 |
txt += f"\n<b>Reason</b>: {reason}"
|
812 |
-
else:
|
813 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
814 |
keyboard = InlineKeyboardMarkup(
|
815 |
[
|
816 |
[
|
@@ -914,8 +903,7 @@ async def ban_usr(c: Gojo, m: Message):
|
|
914 |
txt = f"{m.from_user.mention} banned {banned} in <b>{m.chat.title}</b>!"
|
915 |
if reason:
|
916 |
txt += f"\n<b>Reason</b>: {reason}"
|
917 |
-
|
918 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
919 |
keyboard = InlineKeyboardMarkup(
|
920 |
[
|
921 |
[
|
@@ -1019,8 +1007,6 @@ async def kickme(c: Gojo, m: Message):
|
|
1019 |
txt = "Why not let me help you!"
|
1020 |
if reason:
|
1021 |
txt += f"\n<b>Reason</b>: {reason}"
|
1022 |
-
else:
|
1023 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
1024 |
await m.reply_animation(animation=str(choice(KICK_GIFS)), caption=txt)
|
1025 |
await m.chat.unban_member(m.from_user.id)
|
1026 |
except RPCError as ef:
|
|
|
9 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
10 |
Message)
|
11 |
|
12 |
+
from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID
|
13 |
from Powers.bot_class import Gojo
|
14 |
+
from Powers.supports import get_support_staff
|
15 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
16 |
from Powers.utils.custom_filters import command, restrict_filter
|
17 |
from Powers.utils.extract_user import extract_user
|
|
|
20 |
from Powers.utils.string import extract_time
|
21 |
from Powers.vars import Config
|
22 |
|
23 |
+
SUPPORT_STAFF = get_support_staff()
|
24 |
|
25 |
@Gojo.on_message(command("tban") & restrict_filter)
|
26 |
async def tban_usr(c: Gojo, m: Message):
|
|
|
95 |
txt = t_t[0] # Done this bcuz idk why t_t is tuple type data. SO now if it is tuple this will get text from it
|
96 |
if reason:
|
97 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
98 |
if time_val:
|
99 |
txt += f"\n<b>Banned for</b>:{time_val}"
|
100 |
keyboard = InlineKeyboardMarkup(
|
|
|
309 |
txt = f"{admin} banned {banned} in <b>{chat_title}</b>!"
|
310 |
if reason:
|
311 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
|
|
312 |
if bantime:
|
313 |
txt += f"\n<b>Banned for</b>: {time_val}"
|
314 |
keyboard = InlineKeyboardMarkup(
|
|
|
417 |
txt = f"{admin} kicked {kicked} in <b>{chat_title}</b>!"
|
418 |
if reason:
|
419 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
420 |
# await m.reply_text(txt, reply_to_message_id=r_id)
|
421 |
kickk = choice(KICK_GIFS)
|
422 |
try:
|
|
|
575 |
txt = f"{admin} kicked {kicked} in <b>{chat_title}</b>!"
|
576 |
if reason:
|
577 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
578 |
kickk = choice(KICK_GIFS)
|
579 |
try:
|
580 |
await m.reply_animation(
|
|
|
649 |
await m.chat.unban_member(user_id)
|
650 |
admin = m.from_user.mention
|
651 |
unbanned = await mention_html(user_first_name, user_id)
|
652 |
+
chat_title = m.chat.title
|
653 |
txt = f"{admin} unbanned {unbanned} in chat <b>{chat_title}</b>!"
|
654 |
if reason:
|
655 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
656 |
await m.reply_text(txt)
|
657 |
except ChatAdminRequired:
|
658 |
await m.reply_text(text="I'm not admin or I don't have rights.")
|
|
|
800 |
txt = f"{m.from_user.mention} banned {m.reply_to_message.from_user.mention} in <b>{m.chat.title}</b>!"
|
801 |
if reason:
|
802 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
803 |
keyboard = InlineKeyboardMarkup(
|
804 |
[
|
805 |
[
|
|
|
903 |
txt = f"{m.from_user.mention} banned {banned} in <b>{m.chat.title}</b>!"
|
904 |
if reason:
|
905 |
txt += f"\n<b>Reason</b>: {reason}"
|
906 |
+
|
|
|
907 |
keyboard = InlineKeyboardMarkup(
|
908 |
[
|
909 |
[
|
|
|
1007 |
txt = "Why not let me help you!"
|
1008 |
if reason:
|
1009 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
1010 |
await m.reply_animation(animation=str(choice(KICK_GIFS)), caption=txt)
|
1011 |
await m.chat.unban_member(m.from_user.id)
|
1012 |
except RPCError as ef:
|
Powers/plugins/birthday.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1 |
-
from datetime import date, datetime
|
2 |
-
from random import choice
|
3 |
from traceback import format_exc
|
4 |
|
5 |
-
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
6 |
from pyrogram import filters
|
7 |
from pyrogram.enums import ChatMemberStatus, ChatType
|
8 |
from pyrogram.types import CallbackQuery
|
@@ -18,7 +16,6 @@ if BDB_URI:
|
|
18 |
from Powers.plugins import bday_cinfo, bday_info
|
19 |
|
20 |
from Powers.utils.custom_filters import command
|
21 |
-
from Powers.utils.extras import birthday_wish
|
22 |
|
23 |
|
24 |
def give_date(date,form = "%d/%m/%Y"):
|
@@ -144,7 +141,7 @@ async def who_is_next(c: Gojo, m: Message):
|
|
144 |
break
|
145 |
if not users:
|
146 |
await xx.delete()
|
147 |
-
await m.reply_text("
|
148 |
return
|
149 |
txt = "🎊 Upcomming Birthdays Are 🎊\n"
|
150 |
for i in users:
|
@@ -186,6 +183,7 @@ async def cant_recall_it(c: Gojo, m: Message):
|
|
186 |
u_dobm = date(curr.year, u_dob.month, u_dob.day)
|
187 |
days_left = (u_dobm - curr).days
|
188 |
txt = f"User's birthday is coming🥳\nDays left : {days_left}"
|
|
|
189 |
await m.reply_text(txt)
|
190 |
return
|
191 |
|
@@ -227,60 +225,7 @@ async def switch_on_off(c:Gojo, q: CallbackQuery):
|
|
227 |
await q.edit_message_text(f"Done! I will {'wish' if data == 'yes' else 'not wish'}",reply_markup=IKM([[IKB("Close", "f_close")]]))
|
228 |
return
|
229 |
|
230 |
-
scheduler = AsyncIOScheduler()
|
231 |
-
scheduler.timezone = TIME_ZONE
|
232 |
-
scheduler_time = time(0,0,0)
|
233 |
-
async def send_wishish(JJK: Gojo):
|
234 |
-
c_list = Chats.list_chats_by_id()
|
235 |
-
blist = list(bday_info.find())
|
236 |
-
curr = datetime.now(TIME_ZONE).date()
|
237 |
-
cclist = list(bday_cinfo.find())
|
238 |
-
for i in blist:
|
239 |
-
dob = give_date(i["dob"])
|
240 |
-
if dob.month == curr.month and dob.day == curr.day:
|
241 |
-
for j in c_list:
|
242 |
-
if cclist and (j in cclist):
|
243 |
-
return
|
244 |
-
try:
|
245 |
-
agee = ""
|
246 |
-
if i["is_year"]:
|
247 |
-
agee = curr.year - dob.year
|
248 |
-
if str(agee).endswith("1"):
|
249 |
-
agee = f"{agee}st"
|
250 |
-
elif str(agee).endswith("2"):
|
251 |
-
agee = f"{agee}nd"
|
252 |
-
elif str(agee).endswith("3"):
|
253 |
-
agee = f"{agee}rd"
|
254 |
-
else:
|
255 |
-
agee = f"{agee}th"
|
256 |
-
U = await JJK.get_chat_member(chat_id=j,user_id=i["user_id"])
|
257 |
-
wish = choice(birthday_wish)
|
258 |
-
if U.status in [ChatMemberStatus.MEMBER,ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
|
259 |
-
xXx = await JJK.send_message(j,f"Happy {agee} birthday {U.user.mention}🥳\n{wish}")
|
260 |
-
try:
|
261 |
-
await xXx.pin()
|
262 |
-
except Exception:
|
263 |
-
pass
|
264 |
-
except Exception:
|
265 |
-
pass
|
266 |
|
267 |
-
""""
|
268 |
-
from datetime import date, datetime
|
269 |
-
|
270 |
-
#form =
|
271 |
-
num = "18/05/2005"
|
272 |
-
st = "18 May 2005"
|
273 |
-
timm = datetime.strptime(num,"%d/%m/%Y").date()
|
274 |
-
x = datetime.now().date()
|
275 |
-
if timm.month < x.month:
|
276 |
-
next_b = date(x.year + 1, timm.month, timm.day)
|
277 |
-
days_left = (next_b - x).days
|
278 |
-
else:
|
279 |
-
timmm = date(x.year, timm.month, timm.day)
|
280 |
-
days_left = (timmm - x).days
|
281 |
-
print(days_left)
|
282 |
-
print(x.year - timm.year)
|
283 |
-
"""
|
284 |
|
285 |
__PLUGIN__ = "birthday"
|
286 |
|
|
|
1 |
+
from datetime import date, datetime
|
|
|
2 |
from traceback import format_exc
|
3 |
|
|
|
4 |
from pyrogram import filters
|
5 |
from pyrogram.enums import ChatMemberStatus, ChatType
|
6 |
from pyrogram.types import CallbackQuery
|
|
|
16 |
from Powers.plugins import bday_cinfo, bday_info
|
17 |
|
18 |
from Powers.utils.custom_filters import command
|
|
|
19 |
|
20 |
|
21 |
def give_date(date,form = "%d/%m/%Y"):
|
|
|
141 |
break
|
142 |
if not users:
|
143 |
await xx.delete()
|
144 |
+
await m.reply_text("There are no upcoming birthdays of any user in this chat:/\nEither all the birthdays are passed or no user from this chat have registered their birthday")
|
145 |
return
|
146 |
txt = "🎊 Upcomming Birthdays Are 🎊\n"
|
147 |
for i in users:
|
|
|
183 |
u_dobm = date(curr.year, u_dob.month, u_dob.day)
|
184 |
days_left = (u_dobm - curr).days
|
185 |
txt = f"User's birthday is coming🥳\nDays left : {days_left}"
|
186 |
+
txt += f"\n\nBirthday on: {result['dob']}"
|
187 |
await m.reply_text(txt)
|
188 |
return
|
189 |
|
|
|
225 |
await q.edit_message_text(f"Done! I will {'wish' if data == 'yes' else 'not wish'}",reply_markup=IKM([[IKB("Close", "f_close")]]))
|
226 |
return
|
227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
|
230 |
__PLUGIN__ = "birthday"
|
231 |
|
Powers/plugins/botstaff.py
CHANGED
@@ -1,11 +1,14 @@
|
|
1 |
from pyrogram.errors import RPCError
|
2 |
from pyrogram.types import Message
|
3 |
|
4 |
-
from Powers import
|
5 |
from Powers.bot_class import Gojo
|
|
|
6 |
from Powers.utils.custom_filters import command
|
7 |
from Powers.utils.parser import mention_html
|
8 |
|
|
|
|
|
9 |
|
10 |
@Gojo.on_message(command("botstaff", dev_cmd=True))
|
11 |
async def botstaff(c: Gojo, m: Message):
|
|
|
1 |
from pyrogram.errors import RPCError
|
2 |
from pyrogram.types import Message
|
3 |
|
4 |
+
from Powers import LOGGER, OWNER_ID, WHITELIST_USERS
|
5 |
from Powers.bot_class import Gojo
|
6 |
+
from Powers.supports import get_support_staff
|
7 |
from Powers.utils.custom_filters import command
|
8 |
from Powers.utils.parser import mention_html
|
9 |
|
10 |
+
DEV_USERS = get_support_staff("dev")
|
11 |
+
SUDO_USERS = get_support_staff("sudo")
|
12 |
|
13 |
@Gojo.on_message(command("botstaff", dev_cmd=True))
|
14 |
async def botstaff(c: Gojo, m: Message):
|
Powers/plugins/dev.py
CHANGED
@@ -7,58 +7,192 @@ from sys import executable
|
|
7 |
from time import gmtime, strftime, time
|
8 |
from traceback import format_exc
|
9 |
|
|
|
10 |
from pyrogram.errors import (ChannelInvalid, ChannelPrivate, ChatAdminRequired,
|
11 |
EntityBoundsInvalid, FloodWait, MessageTooLong,
|
12 |
PeerIdInvalid, RPCError)
|
|
|
|
|
13 |
from pyrogram.types import Message
|
14 |
|
15 |
-
from Powers import (BOT_TOKEN,
|
16 |
-
|
17 |
from Powers.bot_class import Gojo
|
18 |
from Powers.database import MongoDB
|
19 |
from Powers.database.chats_db import Chats
|
20 |
-
from Powers.
|
|
|
|
|
|
|
21 |
from Powers.utils.clean_file import remove_markdown_and_html
|
22 |
from Powers.utils.custom_filters import command
|
23 |
from Powers.utils.extract_user import extract_user
|
24 |
from Powers.utils.parser import mention_markdown
|
25 |
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
return
|
32 |
-
split = m.
|
33 |
reply_to = m.reply_to_message
|
34 |
-
if
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
return
|
38 |
-
|
39 |
-
|
40 |
-
await m.reply_text("Give me an id")
|
41 |
-
return
|
42 |
-
elif reply_to:
|
43 |
-
user = reply_to.from_user.id
|
44 |
-
elif len(split) == 2:
|
45 |
try:
|
46 |
-
|
47 |
-
except Exception
|
48 |
-
await m.reply_text(
|
49 |
return
|
50 |
-
|
51 |
try:
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
return
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
return
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
return
|
61 |
-
|
62 |
@Gojo.on_message(command("ping", sudo_cmd=True))
|
63 |
async def ping(_, m: Message):
|
64 |
LOGGER.info(f"{m.from_user.id} used ping cmd in {m.chat.id}")
|
@@ -199,7 +333,7 @@ async def evaluate_code(c: Gojo, m: Message):
|
|
199 |
f"@{m.from_user.username} TREID TO FETCH ENV OF BOT \n userid = {m.from_user.id}",
|
200 |
)
|
201 |
for j in HARMFUL:
|
202 |
-
if j in evaluation:
|
203 |
if m.from_user.id != OWNER_ID:
|
204 |
evaluation = "Bhaag ja bsdk"
|
205 |
await c.send_message(
|
@@ -480,6 +614,58 @@ async def chat_broadcast(c: Gojo, m: Message):
|
|
480 |
|
481 |
return
|
482 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
483 |
@Gojo.on_message(command(["cleandb","cleandatabase"],sudo_cmd=True))
|
484 |
async def cleeeen(c:Gojo,m:Message):
|
485 |
x = await m.reply_text("Cleaning the database...")
|
@@ -509,7 +695,7 @@ __HELP__ = """
|
|
509 |
• /update : To update the bot with the main stream repo
|
510 |
|
511 |
**Dev's commands:**
|
512 |
-
• /
|
513 |
• /logs : Return the logs of bot.
|
514 |
• /neofetch : Fetch neo.
|
515 |
• /eval : Evaluate the given python code.
|
@@ -518,6 +704,11 @@ __HELP__ = """
|
|
518 |
• /uptime : Return the uptime of the bot.
|
519 |
• /leavechat : Bot will leave the provided chat.
|
520 |
• /chatbroadcast : Broadcast the messge to chats.
|
|
|
|
|
|
|
|
|
|
|
521 |
|
522 |
**Sudoer's command:**
|
523 |
• /ping : return the ping of the bot.
|
|
|
7 |
from time import gmtime, strftime, time
|
8 |
from traceback import format_exc
|
9 |
|
10 |
+
from pyrogram import filters
|
11 |
from pyrogram.errors import (ChannelInvalid, ChannelPrivate, ChatAdminRequired,
|
12 |
EntityBoundsInvalid, FloodWait, MessageTooLong,
|
13 |
PeerIdInvalid, RPCError)
|
14 |
+
from pyrogram.types import InlineKeyboardButton as IKB
|
15 |
+
from pyrogram.types import InlineKeyboardMarkup as IKM
|
16 |
from pyrogram.types import Message
|
17 |
|
18 |
+
from Powers import (BOT_TOKEN, LOG_DATETIME, LOGFILE, LOGGER, MESSAGE_DUMP,
|
19 |
+
OWNER_ID, UPTIME)
|
20 |
from Powers.bot_class import Gojo
|
21 |
from Powers.database import MongoDB
|
22 |
from Powers.database.chats_db import Chats
|
23 |
+
from Powers.database.support_db import SUPPORTS
|
24 |
+
from Powers.database.users_db import Users
|
25 |
+
from Powers.plugins.scheduled_jobs import clean_my_db
|
26 |
+
from Powers.supports import get_support_staff
|
27 |
from Powers.utils.clean_file import remove_markdown_and_html
|
28 |
from Powers.utils.custom_filters import command
|
29 |
from Powers.utils.extract_user import extract_user
|
30 |
from Powers.utils.parser import mention_markdown
|
31 |
|
32 |
|
33 |
+
def can_change_type(curr, to_user):
|
34 |
+
if curr == "dev" and to_user in ["whitelist","sudo"]:
|
35 |
+
return True
|
36 |
+
elif curr == "sudo" and to_user == "whitelist":
|
37 |
+
return True
|
38 |
+
else:
|
39 |
+
return False
|
40 |
+
|
41 |
+
@Gojo.on_message(command(["addsupport"]))
|
42 |
+
async def add_support(c: Gojo, m:Message):
|
43 |
+
support = SUPPORTS()
|
44 |
+
curr_user = support.get_support_type(m.from_user.id)
|
45 |
+
if not curr_user:
|
46 |
+
await m.reply_text("Stay in you limit")
|
47 |
return
|
48 |
+
split = m.command
|
49 |
reply_to = m.reply_to_message
|
50 |
+
if reply_to:
|
51 |
+
try:
|
52 |
+
userr = reply_to.from_user.id
|
53 |
+
except Exception:
|
54 |
+
await m.reply_text("Reply to an user")
|
55 |
+
return
|
56 |
+
curr = support.get_support_type(userr)
|
57 |
+
try:
|
58 |
+
to = split[1].lower()
|
59 |
+
except IndexError:
|
60 |
+
await m.reply_text("**USAGE**\n/addsupport [reply to message | user id] [dev | sudo | whitelist]")
|
61 |
+
return
|
62 |
+
if to not in ["dev","sudo","whitelist"]:
|
63 |
+
await m.reply_text("**USAGE**\n/addsupport [reply to message | user id] [dev | sudo | whitelist]")
|
64 |
+
return
|
65 |
+
if m.from_user.id == int(OWNER_ID):
|
66 |
+
if to == curr:
|
67 |
+
await m.reply_text(f"This user is already in {to} users")
|
68 |
+
return
|
69 |
+
elif curr:
|
70 |
+
kb = IKM(
|
71 |
+
[
|
72 |
+
[
|
73 |
+
IKB("Yes",f"change_support_type:{to}"),
|
74 |
+
IKB("No","change_support_type:no")
|
75 |
+
]
|
76 |
+
]
|
77 |
+
)
|
78 |
+
await m.reply_text(f"This is user is already in {curr} users\nDo you want to make him {to} user?",reply_markup=kb)
|
79 |
+
return
|
80 |
+
else:
|
81 |
+
support.insert_support_user(userr,to)
|
82 |
+
await m.reply_text(f"This user is now a {to} user")
|
83 |
+
return
|
84 |
+
can_do = can_change_type(curr_user,to)
|
85 |
+
if can_do:
|
86 |
+
if to == curr:
|
87 |
+
await m.reply_text(f"This user is already in {to} users")
|
88 |
+
return
|
89 |
+
elif curr:
|
90 |
+
kb = IKM(
|
91 |
+
[
|
92 |
+
[
|
93 |
+
IKB("Yes",f"change_support_type:{to}"),
|
94 |
+
IKB("No","change_support_type:no")
|
95 |
+
]
|
96 |
+
]
|
97 |
+
)
|
98 |
+
await m.reply_text(f"This is user is already in {curr} users\nDo you want to make him {to} user?",reply_markup=kb)
|
99 |
+
return
|
100 |
+
else:
|
101 |
+
support.insert_support_user(userr,to)
|
102 |
+
await m.reply_text(f"This user is now a {to} user")
|
103 |
+
return
|
104 |
+
else:
|
105 |
+
await m.reply_text("Sorry you can't do it")
|
106 |
return
|
107 |
+
elif len(split) >= 3:
|
108 |
+
user = split[1]
|
|
|
|
|
|
|
|
|
|
|
109 |
try:
|
110 |
+
userr,_,_ = extract_user(user)
|
111 |
+
except Exception:
|
112 |
+
await m.reply_text("Tell the user to start me first")
|
113 |
return
|
114 |
+
curr = support.get_support_type(userr)
|
115 |
try:
|
116 |
+
to = m.command[2].lower()
|
117 |
+
except IndexError:
|
118 |
+
await m.reply_text("**USAGE**\n/addsupport [reply to message | user id | username] [dev | sudo | whitelist]")
|
119 |
+
return
|
120 |
+
if to not in ["dev","sudo","whitelist"]:
|
121 |
+
await m.reply_text("**USAGE**\n/addsupport [reply to message | user id] [dev | sudo | whitelist]")
|
122 |
return
|
123 |
+
if m.from_user.id == int(OWNER_ID):
|
124 |
+
if to == curr:
|
125 |
+
await m.reply_text(f"This user is already in {to} users")
|
126 |
+
return
|
127 |
+
elif curr:
|
128 |
+
kb = IKM(
|
129 |
+
[
|
130 |
+
[
|
131 |
+
IKB("Yes",f"change_support_type:{to}"),
|
132 |
+
IKB("No","change_support_type:no")
|
133 |
+
]
|
134 |
+
]
|
135 |
+
)
|
136 |
+
await m.reply_text(f"This is user is already in {curr} users\nDo you want to make him {to} user?",reply_markup=kb)
|
137 |
+
return
|
138 |
+
else:
|
139 |
+
support.insert_support_user(userr,to)
|
140 |
+
await m.reply_text(f"This user is now a {to} user")
|
141 |
+
return
|
142 |
+
can_do = can_change_type(curr_user,to)
|
143 |
+
if can_do:
|
144 |
+
if to == curr:
|
145 |
+
await m.reply_text(f"This user is already in {to} users")
|
146 |
+
return
|
147 |
+
elif curr:
|
148 |
+
kb = IKM(
|
149 |
+
[
|
150 |
+
[
|
151 |
+
IKB("Yes",f"change_support_type:{to}"),
|
152 |
+
IKB("No","change_support_type:no")
|
153 |
+
]
|
154 |
+
]
|
155 |
+
)
|
156 |
+
await m.reply_text(f"This is user is already in {curr} users\nDo you want to make him {to} user?",reply_markup=kb)
|
157 |
+
return
|
158 |
+
else:
|
159 |
+
support.insert_support_user(userr,to)
|
160 |
+
await m.reply_text(f"This user is now a {to} user")
|
161 |
+
return
|
162 |
+
else:
|
163 |
+
await m.reply_text("Sorry you can't do it")
|
164 |
return
|
165 |
+
|
166 |
+
@Gojo.on_message(command("rmsupport"))
|
167 |
+
async def rm_support(c: Gojo, m: Message):
|
168 |
+
support = SUPPORTS()
|
169 |
+
curr_user = support.get_support_type(m.from_user.id)
|
170 |
+
if not curr_user:
|
171 |
+
await m.reply_text("Stay in you limit")
|
172 |
+
return
|
173 |
+
split = m.command
|
174 |
+
reply_to = m.reply_to_message
|
175 |
+
|
176 |
+
if reply_to:
|
177 |
+
try:
|
178 |
+
curr = reply_to.from_user.id
|
179 |
+
except Exception:
|
180 |
+
await m.reply_text("Reply to an user")
|
181 |
+
return
|
182 |
+
support.delete_support_user(curr)
|
183 |
+
await m.reply_text("Done! User now no longer belongs to the support staff")
|
184 |
+
elif len(split) >= 2:
|
185 |
+
try:
|
186 |
+
user,_,_ = extract_user(split[1])
|
187 |
+
except Exception:
|
188 |
+
await m.reply_text("Dunno who u r talking abt")
|
189 |
+
return
|
190 |
+
support.delete_support_user(user)
|
191 |
+
await m.reply_text("Done! User now no longer belongs to the support staff")
|
192 |
+
else:
|
193 |
+
await m.reply_text("**USAGE**\n/rmsupport [reply to user | user id | username]")
|
194 |
return
|
195 |
+
|
196 |
@Gojo.on_message(command("ping", sudo_cmd=True))
|
197 |
async def ping(_, m: Message):
|
198 |
LOGGER.info(f"{m.from_user.id} used ping cmd in {m.chat.id}")
|
|
|
333 |
f"@{m.from_user.username} TREID TO FETCH ENV OF BOT \n userid = {m.from_user.id}",
|
334 |
)
|
335 |
for j in HARMFUL:
|
336 |
+
if j in evaluation.split() or j in cmd:
|
337 |
if m.from_user.id != OWNER_ID:
|
338 |
evaluation = "Bhaag ja bsdk"
|
339 |
await c.send_message(
|
|
|
614 |
|
615 |
return
|
616 |
|
617 |
+
@Gojo.on_message(command(["forward","fwd"],dev_cmd=True))
|
618 |
+
async def forward_type_broadcast(c: Gojo, m: Message):
|
619 |
+
repl = m.reply_to_message
|
620 |
+
if not repl:
|
621 |
+
await m.reply_text("Please reply to message to broadcast it")
|
622 |
+
return
|
623 |
+
split = m.command
|
624 |
+
|
625 |
+
chat = Chats.list_chats_by_id()
|
626 |
+
user = [i["_id"] for i in Users.list_users()]
|
627 |
+
alll = chat + user
|
628 |
+
if len(split) != 2:
|
629 |
+
tag = "all"
|
630 |
+
else:
|
631 |
+
try:
|
632 |
+
if split[0].lower() == "-u":
|
633 |
+
tag = "user"
|
634 |
+
elif split[0].lower() == "-c":
|
635 |
+
tag = "chat"
|
636 |
+
else:
|
637 |
+
tag = "all"
|
638 |
+
except IndexError:
|
639 |
+
pass
|
640 |
+
if tag == "chat":
|
641 |
+
peers = chat
|
642 |
+
elif tag == "user":
|
643 |
+
peers = user
|
644 |
+
else:
|
645 |
+
peers = alll
|
646 |
+
|
647 |
+
xx = await m.reply_text("Broadcasting...")
|
648 |
+
|
649 |
+
failed = 0
|
650 |
+
total = len(peers)
|
651 |
+
for peer in peers:
|
652 |
+
try:
|
653 |
+
await repl.forward(int(peer))
|
654 |
+
await sleep(0.1)
|
655 |
+
except Exception:
|
656 |
+
failed += 1
|
657 |
+
pass
|
658 |
+
txt = f"Broadcasted message to {total-failed} peers out of {total}\nFailed to broadcast message to {failed} peers"
|
659 |
+
if not failed:
|
660 |
+
txt = f"Broadcasted message to {total} peers"
|
661 |
+
await m.reply_text(txt)
|
662 |
+
try:
|
663 |
+
await xx.delete()
|
664 |
+
except Exception:
|
665 |
+
pass
|
666 |
+
return
|
667 |
+
|
668 |
+
|
669 |
@Gojo.on_message(command(["cleandb","cleandatabase"],sudo_cmd=True))
|
670 |
async def cleeeen(c:Gojo,m:Message):
|
671 |
x = await m.reply_text("Cleaning the database...")
|
|
|
695 |
• /update : To update the bot with the main stream repo
|
696 |
|
697 |
**Dev's commands:**
|
698 |
+
• /addsupport [dev | sudo | whitelist] : Reply to message or give me user id or username
|
699 |
• /logs : Return the logs of bot.
|
700 |
• /neofetch : Fetch neo.
|
701 |
• /eval : Evaluate the given python code.
|
|
|
704 |
• /uptime : Return the uptime of the bot.
|
705 |
• /leavechat : Bot will leave the provided chat.
|
706 |
• /chatbroadcast : Broadcast the messge to chats.
|
707 |
+
• /forward (/fwd) [tag] : Forward message to peers according to tag. Default to all
|
708 |
+
Available tags:
|
709 |
+
`-u` : For users
|
710 |
+
`-c` : For chats
|
711 |
+
`-all` : For all
|
712 |
|
713 |
**Sudoer's command:**
|
714 |
• /ping : return the ping of the bot.
|
Powers/plugins/filters.py
CHANGED
@@ -212,7 +212,7 @@ async def send_filter_reply(c: Gojo, m: Message, trigger: str):
|
|
212 |
text = await escape_mentions_using_curly_brackets(m, filter_reply, parse_words)
|
213 |
teks, button = await parse_button(text)
|
214 |
button = await build_keyboard(button)
|
215 |
-
button =
|
216 |
textt = teks
|
217 |
try:
|
218 |
if msgtype == Types.TEXT:
|
|
|
212 |
text = await escape_mentions_using_curly_brackets(m, filter_reply, parse_words)
|
213 |
teks, button = await parse_button(text)
|
214 |
button = await build_keyboard(button)
|
215 |
+
button = ikb(button) if button else None
|
216 |
textt = teks
|
217 |
try:
|
218 |
if msgtype == Types.TEXT:
|
Powers/plugins/flood.py
CHANGED
@@ -10,15 +10,18 @@ from pyrogram.types import (CallbackQuery, ChatPermissions,
|
|
10 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
11 |
Message)
|
12 |
|
13 |
-
from Powers import LOGGER, SUPPORT_GROUP
|
14 |
from Powers.bot_class import Gojo
|
15 |
from Powers.database.approve_db import Approve
|
16 |
from Powers.database.flood_db import Floods
|
|
|
17 |
from Powers.utils.custom_filters import admin_filter, command
|
18 |
from Powers.utils.extras import BAN_GIFS, KICK_GIFS, MUTE_GIFS
|
19 |
from Powers.utils.kbhelpers import ikb
|
20 |
from Powers.vars import Config
|
21 |
|
|
|
|
|
22 |
on_key = ["on", "start", "disable"]
|
23 |
off_key = ["off", "end", "enable", "stop"]
|
24 |
|
@@ -408,7 +411,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
408 |
],
|
409 |
],
|
410 |
)
|
411 |
-
txt = "Don't dare to spam here if I am around!"
|
412 |
await m.reply_animation(
|
413 |
animation=str(choice(BAN_GIFS)),
|
414 |
caption=txt,
|
@@ -440,7 +443,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
440 |
elif action == "kick":
|
441 |
try:
|
442 |
await m.chat.ban_member(u_id)
|
443 |
-
txt = "Don't dare to spam here if I am around!"
|
444 |
await m.reply_animation(
|
445 |
animation=str(choice(KICK_GIFS)),
|
446 |
caption=txt,
|
@@ -483,7 +486,7 @@ async def flood_watcher(c: Gojo, m: Message):
|
|
483 |
],
|
484 |
],
|
485 |
)
|
486 |
-
txt = "Don't dare to spam here if I am around!"
|
487 |
await m.reply_animation(
|
488 |
animation=str(choice(MUTE_GIFS)),
|
489 |
caption=txt,
|
|
|
10 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
11 |
Message)
|
12 |
|
13 |
+
from Powers import LOGGER, SUPPORT_GROUP
|
14 |
from Powers.bot_class import Gojo
|
15 |
from Powers.database.approve_db import Approve
|
16 |
from Powers.database.flood_db import Floods
|
17 |
+
from Powers.supports import get_support_staff
|
18 |
from Powers.utils.custom_filters import admin_filter, command
|
19 |
from Powers.utils.extras import BAN_GIFS, KICK_GIFS, MUTE_GIFS
|
20 |
from Powers.utils.kbhelpers import ikb
|
21 |
from Powers.vars import Config
|
22 |
|
23 |
+
SUPPORT_STAFF = get_support_staff()
|
24 |
+
|
25 |
on_key = ["on", "start", "disable"]
|
26 |
off_key = ["off", "end", "enable", "stop"]
|
27 |
|
|
|
411 |
],
|
412 |
],
|
413 |
)
|
414 |
+
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming"
|
415 |
await m.reply_animation(
|
416 |
animation=str(choice(BAN_GIFS)),
|
417 |
caption=txt,
|
|
|
443 |
elif action == "kick":
|
444 |
try:
|
445 |
await m.chat.ban_member(u_id)
|
446 |
+
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming"
|
447 |
await m.reply_animation(
|
448 |
animation=str(choice(KICK_GIFS)),
|
449 |
caption=txt,
|
|
|
486 |
],
|
487 |
],
|
488 |
)
|
489 |
+
txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming"
|
490 |
await m.reply_animation(
|
491 |
animation=str(choice(MUTE_GIFS)),
|
492 |
caption=txt,
|
Powers/plugins/fun.py
CHANGED
@@ -5,13 +5,15 @@ from pyrogram import enums
|
|
5 |
from pyrogram.errors import MessageTooLong
|
6 |
from pyrogram.types import Message
|
7 |
|
8 |
-
from Powers import
|
9 |
from Powers.bot_class import Gojo
|
|
|
10 |
from Powers.utils import extras
|
11 |
from Powers.utils.custom_filters import command
|
12 |
from Powers.utils.extras import NOWYES as NO
|
13 |
from Powers.utils.extras import YESWNO as YES
|
14 |
|
|
|
15 |
|
16 |
@Gojo.on_message(command("shout"))
|
17 |
async def fun_shout(_, m: Message):
|
|
|
5 |
from pyrogram.errors import MessageTooLong
|
6 |
from pyrogram.types import Message
|
7 |
|
8 |
+
from Powers import LOGGER
|
9 |
from Powers.bot_class import Gojo
|
10 |
+
from Powers.supports import get_support_staff
|
11 |
from Powers.utils import extras
|
12 |
from Powers.utils.custom_filters import command
|
13 |
from Powers.utils.extras import NOWYES as NO
|
14 |
from Powers.utils.extras import YESWNO as YES
|
15 |
|
16 |
+
DEV_USERS = get_support_staff("dev")
|
17 |
|
18 |
@Gojo.on_message(command("shout"))
|
19 |
async def fun_shout(_, m: Message):
|
Powers/plugins/greetings.py
CHANGED
@@ -1,17 +1,20 @@
|
|
1 |
from html import escape
|
2 |
from secrets import choice
|
|
|
3 |
|
4 |
from pyrogram import enums, filters
|
5 |
from pyrogram.enums import ChatMemberStatus as CMS
|
6 |
from pyrogram.errors import ChatAdminRequired, RPCError
|
7 |
-
from pyrogram.types import ChatMemberUpdated,
|
8 |
|
9 |
-
from Powers import
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.antispam_db import GBan
|
12 |
from Powers.database.greetings_db import Greetings
|
|
|
13 |
from Powers.utils.cmd_senders import send_cmd
|
14 |
from Powers.utils.custom_filters import admin_filter, bot_admin_filter, command
|
|
|
15 |
from Powers.utils.msg_types import Types, get_wlcm_type
|
16 |
from Powers.utils.parser import escape_markdown, mention_html
|
17 |
from Powers.utils.string import (build_keyboard, escape_invalid_curly_brackets,
|
@@ -21,6 +24,8 @@ from Powers.vars import Config
|
|
21 |
# Initialize
|
22 |
gdb = GBan()
|
23 |
|
|
|
|
|
24 |
ChatType = enums.ChatType
|
25 |
|
26 |
|
@@ -159,7 +164,7 @@ async def save_wlcm(_, m: Message):
|
|
159 |
await m.reply_text("Please provide some data for this to reply with!")
|
160 |
return
|
161 |
|
162 |
-
db.set_welcome_text(text,file)
|
163 |
await m.reply_text("Saved welcome!")
|
164 |
return
|
165 |
|
@@ -197,7 +202,7 @@ async def save_gdbye(_, m: Message):
|
|
197 |
await m.reply_text("Please provide some data for this to reply with!")
|
198 |
return
|
199 |
|
200 |
-
db.set_goodbye_text(text,file)
|
201 |
await m.reply_text("Saved goodbye!")
|
202 |
return
|
203 |
|
@@ -289,7 +294,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
|
289 |
if status:
|
290 |
tek, button = await parse_button(hmm)
|
291 |
button = await build_keyboard(button)
|
292 |
-
button =
|
293 |
|
294 |
if "%%%" in tek:
|
295 |
filter_reply = tek.split("%%%")
|
@@ -322,7 +327,8 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
|
322 |
if jj:
|
323 |
db.set_cleanwlcm_id(int(jj.id))
|
324 |
except RPCError as e:
|
325 |
-
|
|
|
326 |
return
|
327 |
else:
|
328 |
return
|
@@ -360,7 +366,7 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated):
|
|
360 |
if status:
|
361 |
tek, button = await parse_button(hmm)
|
362 |
button = await build_keyboard(button)
|
363 |
-
button =
|
364 |
|
365 |
if "%%%" in tek:
|
366 |
filter_reply = tek.split("%%%")
|
@@ -400,7 +406,8 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated):
|
|
400 |
db.set_cleangoodbye_id(int(ooo.id))
|
401 |
return
|
402 |
except RPCError as e:
|
403 |
-
|
|
|
404 |
return
|
405 |
else:
|
406 |
return
|
@@ -432,11 +439,11 @@ async def welcome(c: Gojo, m: Message):
|
|
432 |
return
|
433 |
if args[1].lower() == "on":
|
434 |
db.set_current_welcome_settings(True)
|
435 |
-
await m.reply_text("
|
436 |
return
|
437 |
if args[1].lower() == "off":
|
438 |
db.set_current_welcome_settings(False)
|
439 |
-
await m.reply_text("
|
440 |
return
|
441 |
await m.reply_text("what are you trying to do ??")
|
442 |
return
|
@@ -448,10 +455,25 @@ async def welcome(c: Gojo, m: Message):
|
|
448 |
Welcome text:
|
449 |
""",
|
450 |
)
|
|
|
|
|
451 |
tek, button = await parse_button(oo)
|
452 |
button = await build_keyboard(button)
|
453 |
-
button =
|
454 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
455 |
return
|
456 |
|
457 |
|
@@ -479,11 +501,11 @@ async def goodbye(c: Gojo, m: Message):
|
|
479 |
return
|
480 |
if args[1].lower() == "on":
|
481 |
db.set_current_goodbye_settings(True)
|
482 |
-
await m.reply_text("
|
483 |
return
|
484 |
if args[1].lower() == "off":
|
485 |
db.set_current_goodbye_settings(False)
|
486 |
-
await m.reply_text("
|
487 |
return
|
488 |
await m.reply_text("what are you trying to do ??")
|
489 |
return
|
@@ -495,10 +517,26 @@ async def goodbye(c: Gojo, m: Message):
|
|
495 |
Goodbye text:
|
496 |
""",
|
497 |
)
|
|
|
|
|
498 |
tek, button = await parse_button(oo)
|
499 |
button = await build_keyboard(button)
|
500 |
-
button =
|
501 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
return
|
503 |
|
504 |
|
|
|
1 |
from html import escape
|
2 |
from secrets import choice
|
3 |
+
from traceback import format_exc
|
4 |
|
5 |
from pyrogram import enums, filters
|
6 |
from pyrogram.enums import ChatMemberStatus as CMS
|
7 |
from pyrogram.errors import ChatAdminRequired, RPCError
|
8 |
+
from pyrogram.types import ChatMemberUpdated, Message
|
9 |
|
10 |
+
from Powers import LOGGER
|
11 |
from Powers.bot_class import Gojo
|
12 |
from Powers.database.antispam_db import GBan
|
13 |
from Powers.database.greetings_db import Greetings
|
14 |
+
from Powers.supports import get_support_staff
|
15 |
from Powers.utils.cmd_senders import send_cmd
|
16 |
from Powers.utils.custom_filters import admin_filter, bot_admin_filter, command
|
17 |
+
from Powers.utils.kbhelpers import ikb
|
18 |
from Powers.utils.msg_types import Types, get_wlcm_type
|
19 |
from Powers.utils.parser import escape_markdown, mention_html
|
20 |
from Powers.utils.string import (build_keyboard, escape_invalid_curly_brackets,
|
|
|
24 |
# Initialize
|
25 |
gdb = GBan()
|
26 |
|
27 |
+
DEV_USERS = get_support_staff("dev")
|
28 |
+
|
29 |
ChatType = enums.ChatType
|
30 |
|
31 |
|
|
|
164 |
await m.reply_text("Please provide some data for this to reply with!")
|
165 |
return
|
166 |
|
167 |
+
db.set_welcome_text(text,msgtype,file)
|
168 |
await m.reply_text("Saved welcome!")
|
169 |
return
|
170 |
|
|
|
202 |
await m.reply_text("Please provide some data for this to reply with!")
|
203 |
return
|
204 |
|
205 |
+
db.set_goodbye_text(text,msgtype,file)
|
206 |
await m.reply_text("Saved goodbye!")
|
207 |
return
|
208 |
|
|
|
294 |
if status:
|
295 |
tek, button = await parse_button(hmm)
|
296 |
button = await build_keyboard(button)
|
297 |
+
button = ikb(button) if button else None
|
298 |
|
299 |
if "%%%" in tek:
|
300 |
filter_reply = tek.split("%%%")
|
|
|
327 |
if jj:
|
328 |
db.set_cleanwlcm_id(int(jj.id))
|
329 |
except RPCError as e:
|
330 |
+
LOGGER.error(e)
|
331 |
+
LOGGER.error(format_exc(e))
|
332 |
return
|
333 |
else:
|
334 |
return
|
|
|
366 |
if status:
|
367 |
tek, button = await parse_button(hmm)
|
368 |
button = await build_keyboard(button)
|
369 |
+
button = ikb(button) if button else None
|
370 |
|
371 |
if "%%%" in tek:
|
372 |
filter_reply = tek.split("%%%")
|
|
|
406 |
db.set_cleangoodbye_id(int(ooo.id))
|
407 |
return
|
408 |
except RPCError as e:
|
409 |
+
LOGGER.error(e)
|
410 |
+
LOGGER.error(format_exc(e))
|
411 |
return
|
412 |
else:
|
413 |
return
|
|
|
439 |
return
|
440 |
if args[1].lower() == "on":
|
441 |
db.set_current_welcome_settings(True)
|
442 |
+
await m.reply_text("I will greet newly joined member from now on.")
|
443 |
return
|
444 |
if args[1].lower() == "off":
|
445 |
db.set_current_welcome_settings(False)
|
446 |
+
await m.reply_text("I will stay quiet when someone joins.")
|
447 |
return
|
448 |
await m.reply_text("what are you trying to do ??")
|
449 |
return
|
|
|
455 |
Welcome text:
|
456 |
""",
|
457 |
)
|
458 |
+
UwU = db.get_welcome_media()
|
459 |
+
mtype = db.get_welcome_msgtype()
|
460 |
tek, button = await parse_button(oo)
|
461 |
button = await build_keyboard(button)
|
462 |
+
button = ikb(button) if button else None
|
463 |
+
if not UwU:
|
464 |
+
await c.send_message(
|
465 |
+
m.chat.id,
|
466 |
+
text=tek,
|
467 |
+
reply_markup=button,
|
468 |
+
disable_web_page_preview=True,
|
469 |
+
)
|
470 |
+
elif UwU:
|
471 |
+
await (await send_cmd(c,mtype))(
|
472 |
+
m.chat.id,
|
473 |
+
UwU,
|
474 |
+
caption=tek,
|
475 |
+
reply_markup=button,
|
476 |
+
)
|
477 |
return
|
478 |
|
479 |
|
|
|
501 |
return
|
502 |
if args[1].lower() == "on":
|
503 |
db.set_current_goodbye_settings(True)
|
504 |
+
await m.reply_text("I don't want but I will say goodbye to the fugitives")
|
505 |
return
|
506 |
if args[1].lower() == "off":
|
507 |
db.set_current_goodbye_settings(False)
|
508 |
+
await m.reply_text("I will stay quiet for fugitives")
|
509 |
return
|
510 |
await m.reply_text("what are you trying to do ??")
|
511 |
return
|
|
|
517 |
Goodbye text:
|
518 |
""",
|
519 |
)
|
520 |
+
UwU = db.get_goodbye_media()
|
521 |
+
mtype = db.get_goodbye_msgtype()
|
522 |
tek, button = await parse_button(oo)
|
523 |
button = await build_keyboard(button)
|
524 |
+
button = ikb(button) if button else None
|
525 |
+
if not UwU:
|
526 |
+
await c.send_message(
|
527 |
+
m.chat.id,
|
528 |
+
text=tek,
|
529 |
+
reply_markup=button,
|
530 |
+
disable_web_page_preview=True,
|
531 |
+
)
|
532 |
+
elif UwU:
|
533 |
+
await (await send_cmd(c,mtype))(
|
534 |
+
m.chat.id,
|
535 |
+
UwU,
|
536 |
+
caption=tek,
|
537 |
+
reply_markup=button,
|
538 |
+
)
|
539 |
+
return
|
540 |
return
|
541 |
|
542 |
|
Powers/plugins/info.py
CHANGED
@@ -9,10 +9,10 @@ from pyrogram.raw.functions.channels import GetFullChannel
|
|
9 |
from pyrogram.raw.functions.users import GetFullUser
|
10 |
from pyrogram.types import Message
|
11 |
|
12 |
-
from Powers import
|
13 |
-
WHITELIST_USERS)
|
14 |
from Powers.bot_class import Gojo
|
15 |
from Powers.database.antispam_db import GBan
|
|
|
16 |
from Powers.utils.custom_filters import command
|
17 |
from Powers.utils.extract_user import extract_user
|
18 |
from Powers.vars import Config
|
@@ -83,6 +83,10 @@ async def user_info(c: Gojo, user, already=False):
|
|
83 |
about = ll.full_user.about
|
84 |
except Exception:
|
85 |
pass
|
|
|
|
|
|
|
|
|
86 |
username = user.username
|
87 |
first_name = user.first_name
|
88 |
last_name = user.last_name
|
|
|
9 |
from pyrogram.raw.functions.users import GetFullUser
|
10 |
from pyrogram.types import Message
|
11 |
|
12 |
+
from Powers import LOGGER, OWNER_ID
|
|
|
13 |
from Powers.bot_class import Gojo
|
14 |
from Powers.database.antispam_db import GBan
|
15 |
+
from Powers.supports import get_support_staff
|
16 |
from Powers.utils.custom_filters import command
|
17 |
from Powers.utils.extract_user import extract_user
|
18 |
from Powers.vars import Config
|
|
|
83 |
about = ll.full_user.about
|
84 |
except Exception:
|
85 |
pass
|
86 |
+
SUPPORT_STAFF = get_support_staff()
|
87 |
+
DEV_USERS = get_support_staff("dev")
|
88 |
+
SUDO_USERS = get_support_staff("sudo")
|
89 |
+
WHITELIST_USERS = get_support_staff("whitelist")
|
90 |
username = user.username
|
91 |
first_name = user.first_name
|
92 |
last_name = user.last_name
|
Powers/plugins/locks.py
CHANGED
@@ -6,43 +6,41 @@ from pyrogram.enums import MessageEntityType as MET
|
|
6 |
from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError
|
7 |
from pyrogram.types import ChatPermissions, Message
|
8 |
|
9 |
-
from Powers import
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.approve_db import Approve
|
|
|
|
|
12 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
13 |
from Powers.utils.custom_filters import command, restrict_filter
|
14 |
from Powers.vars import Config
|
15 |
|
16 |
-
SUDO_LEVEL =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
anti_c_send = [-1001604479593]
|
19 |
-
anti_forward = [-1001604479593]
|
20 |
-
anti_forward_u = []
|
21 |
-
anti_forward_c = []
|
22 |
-
anti_links = []
|
23 |
@Gojo.on_message(command("locktypes"))
|
24 |
async def lock_types(_, m: Message):
|
25 |
await m.reply_text(
|
26 |
-
|
27 |
-
"**Lock Types:**\n"
|
28 |
-
" - `all` = Everything\n"
|
29 |
-
" - `msg` = Messages\n"
|
30 |
-
" - `media` = Media, such as Photo and Video.\n"
|
31 |
-
" - `polls` = Polls\n"
|
32 |
-
" - `invite` = Add users to Group\n"
|
33 |
-
" - `pin` = Pin Messages\n"
|
34 |
-
" - `info` = Change Group Info\n"
|
35 |
-
" - `webprev` = Web Page Previews\n"
|
36 |
-
" - `inlinebots`, `inline` = Inline bots\n"
|
37 |
-
" - `animations` = Animations\n"
|
38 |
-
" - `games` = Game Bots\n"
|
39 |
-
" - `stickers` = Stickers\n"
|
40 |
-
" - `anonchannel` = Send as chat will be locked\n"
|
41 |
-
" - `forwardall` = Forwarding from channel and user\n"
|
42 |
-
" - `forwardu` = Forwarding from user\n"
|
43 |
-
" - `forwardc` = Forwarding from channel\n"
|
44 |
-
" - `links | url` = Lock links"
|
45 |
-
),
|
46 |
)
|
47 |
return
|
48 |
|
@@ -82,6 +80,8 @@ async def lock_perm(c: Gojo, m: Message):
|
|
82 |
await prevent_approved(m)
|
83 |
return
|
84 |
|
|
|
|
|
85 |
if lock_type == "msg":
|
86 |
msg = False
|
87 |
perm = "messages"
|
@@ -126,51 +126,36 @@ async def lock_perm(c: Gojo, m: Message):
|
|
126 |
pin = False
|
127 |
perm = "pin"
|
128 |
elif lock_type in ["links", "url"]:
|
129 |
-
|
130 |
-
|
131 |
-
elif m.chat.id not in anti_links:
|
132 |
-
anti_links.append(m.chat.id)
|
133 |
-
else:
|
134 |
await m.reply_text("It is already on")
|
135 |
return
|
136 |
await m.reply_text("Locked links in the chat")
|
137 |
return
|
138 |
elif lock_type == "anonchannel":
|
139 |
-
|
140 |
-
|
141 |
-
elif m.chat.id not in anti_c_send:
|
142 |
-
anti_c_send.append(m.chat.id)
|
143 |
-
else:
|
144 |
await m.reply_text("It is already on")
|
145 |
return
|
146 |
await m.reply_text("Locked Send As Chat")
|
147 |
return
|
148 |
elif lock_type == "forwardall":
|
149 |
-
|
150 |
-
|
151 |
-
elif m.chat.id not in anti_forward:
|
152 |
-
anti_forward.append(m.chat.id)
|
153 |
-
else:
|
154 |
await m.reply_text("It is already on")
|
155 |
return
|
156 |
await m.reply_text("Locked Forward from user as well as channel")
|
157 |
return
|
158 |
elif lock_type == "forwardu":
|
159 |
-
|
160 |
-
|
161 |
-
elif m.chat.id not in anti_forward:
|
162 |
-
anti_forward_u.append(m.chat.id)
|
163 |
-
else:
|
164 |
await m.reply_text("It is already on")
|
165 |
return
|
166 |
await m.reply_text("Locked Forward message from user")
|
167 |
return
|
168 |
elif lock_type == "forwardc":
|
169 |
-
|
170 |
-
|
171 |
-
elif m.chat.id not in anti_forward:
|
172 |
-
anti_forward_c.append(m.chat.id)
|
173 |
-
else:
|
174 |
await m.reply_text("It is already on")
|
175 |
return
|
176 |
await m.reply_text("Locked Forward message from channel")
|
@@ -218,6 +203,13 @@ async def view_locks(_, m: Message):
|
|
218 |
if val:
|
219 |
return "✅"
|
220 |
return "❌"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
anon = False
|
222 |
if m.chat.id in anti_c_send:
|
223 |
anon = True
|
@@ -322,6 +314,8 @@ async def unlock_perm(c: Gojo, m: Message):
|
|
322 |
upin = get_uperm.can_pin_messages
|
323 |
ustickers = uanimations = ugames = uinlinebots = None
|
324 |
|
|
|
|
|
325 |
if unlock_type == "msg":
|
326 |
umsg = True
|
327 |
uperm = "messages"
|
@@ -366,57 +360,49 @@ async def unlock_perm(c: Gojo, m: Message):
|
|
366 |
upin = True
|
367 |
uperm = "pin"
|
368 |
elif unlock_type == "anonchannel":
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
anti_c_send.remove(m.chat.id)
|
374 |
-
await m.reply_text("Send as chat is now enabled for this chat")
|
375 |
-
return
|
376 |
-
except ValueError:
|
377 |
-
await m.reply_text("It is already off")
|
378 |
return
|
|
|
|
|
379 |
elif unlock_type in ["links", "url"]:
|
380 |
-
|
381 |
-
|
382 |
await m.reply_text("Sending link is now allowed")
|
383 |
return
|
384 |
-
|
385 |
-
await m.reply_text("
|
386 |
return
|
387 |
elif unlock_type == "forwardall":
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
anti_forward.remove(m.chat.id)
|
393 |
-
await m.reply_text("Forwarding content is now enabled for this chat")
|
394 |
-
return
|
395 |
-
except ValueError:
|
396 |
-
await m.reply_text("It is already off")
|
397 |
return
|
|
|
|
|
|
|
398 |
elif unlock_type == "forwardu":
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
anti_forward_u.remove(m.chat.id)
|
404 |
-
await m.reply_text("Forwarding content is now enabled for this chat")
|
405 |
-
return
|
406 |
-
except ValueError:
|
407 |
-
await m.reply_text("It is already off")
|
408 |
return
|
|
|
|
|
|
|
|
|
409 |
elif unlock_type == "forwardc":
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
anti_forward_c.remove(m.chat.id)
|
415 |
-
await m.reply_text("Forwarding content is now enabled for this chat")
|
416 |
-
return
|
417 |
-
except ValueError:
|
418 |
-
await m.reply_text("It is already off")
|
419 |
return
|
|
|
|
|
|
|
420 |
else:
|
421 |
await m.reply_text(
|
422 |
text="""Invalid Lock Type!
|
@@ -487,7 +473,10 @@ async def is_approved_user(c:Gojo, m: Message):
|
|
487 |
|
488 |
@Gojo.on_message(filters.all & ~filters.me,18)
|
489 |
async def lock_del_mess(c:Gojo, m: Message):
|
490 |
-
|
|
|
|
|
|
|
491 |
if m.chat.id not in all_chats:
|
492 |
return
|
493 |
if m.sender_chat and not (m.forward_from_chat or m.forward_from):
|
@@ -505,13 +494,13 @@ async def lock_del_mess(c:Gojo, m: Message):
|
|
505 |
return
|
506 |
elif m.forward_from or m.forward_from_chat:
|
507 |
if not is_approved:
|
508 |
-
if m.chat.id
|
509 |
await delete_messages(c,m)
|
510 |
return
|
511 |
-
elif m.chat.id
|
512 |
await delete_messages(c,m)
|
513 |
return
|
514 |
-
elif m.chat.id
|
515 |
await delete_messages(c,m)
|
516 |
return
|
517 |
|
@@ -532,6 +521,11 @@ __PLUGIN__ = "locks"
|
|
532 |
|
533 |
__alt_name__ = ["grouplock", "lock", "grouplocks"]
|
534 |
|
|
|
|
|
|
|
|
|
|
|
535 |
__HELP__ = """
|
536 |
**Locks**
|
537 |
|
|
|
6 |
from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError
|
7 |
from pyrogram.types import ChatPermissions, Message
|
8 |
|
9 |
+
from Powers import LOGGER
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.approve_db import Approve
|
12 |
+
from Powers.database.locks_db import LOCKS
|
13 |
+
from Powers.supports import get_support_staff
|
14 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
15 |
from Powers.utils.custom_filters import command, restrict_filter
|
16 |
from Powers.vars import Config
|
17 |
|
18 |
+
SUDO_LEVEL = get_support_staff("sudo_level")
|
19 |
+
|
20 |
+
l_t = """
|
21 |
+
**Lock Types:**
|
22 |
+
- `all` = Everything
|
23 |
+
- `msg` = Messages
|
24 |
+
- `media` = Media, such as Photo and Video.
|
25 |
+
- `polls` = Polls
|
26 |
+
- `invite` = Add users to Group
|
27 |
+
- `pin` = Pin Messages
|
28 |
+
- `info` = Change Group Info
|
29 |
+
- `webprev` = Web Page Previews
|
30 |
+
- `inlinebots`, `inline` = Inline bots
|
31 |
+
- `animations` = Animations
|
32 |
+
- `games` = Game Bots
|
33 |
+
- `stickers` = Stickers
|
34 |
+
- `anonchannel` = Send as chat will be locked
|
35 |
+
- `forwardall` = Forwarding from channel and user
|
36 |
+
- `forwardu` = Forwarding from user
|
37 |
+
- `forwardc` = Forwarding from channel
|
38 |
+
- `links | url` = Lock links"""
|
39 |
|
|
|
|
|
|
|
|
|
|
|
40 |
@Gojo.on_message(command("locktypes"))
|
41 |
async def lock_types(_, m: Message):
|
42 |
await m.reply_text(
|
43 |
+
l_t
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
)
|
45 |
return
|
46 |
|
|
|
80 |
await prevent_approved(m)
|
81 |
return
|
82 |
|
83 |
+
lock = LOCKS()
|
84 |
+
|
85 |
if lock_type == "msg":
|
86 |
msg = False
|
87 |
perm = "messages"
|
|
|
126 |
pin = False
|
127 |
perm = "pin"
|
128 |
elif lock_type in ["links", "url"]:
|
129 |
+
curr = lock.insert_lock_channel(m.chat.id, "anti_links")
|
130 |
+
if not curr:
|
|
|
|
|
|
|
131 |
await m.reply_text("It is already on")
|
132 |
return
|
133 |
await m.reply_text("Locked links in the chat")
|
134 |
return
|
135 |
elif lock_type == "anonchannel":
|
136 |
+
curr = lock.insert_lock_channel(m.chat.id,"anti_c_send")
|
137 |
+
if not curr:
|
|
|
|
|
|
|
138 |
await m.reply_text("It is already on")
|
139 |
return
|
140 |
await m.reply_text("Locked Send As Chat")
|
141 |
return
|
142 |
elif lock_type == "forwardall":
|
143 |
+
curr = lock.insert_lock_channel(m.chat.id,"anti_fwd")
|
144 |
+
if not curr:
|
|
|
|
|
|
|
145 |
await m.reply_text("It is already on")
|
146 |
return
|
147 |
await m.reply_text("Locked Forward from user as well as channel")
|
148 |
return
|
149 |
elif lock_type == "forwardu":
|
150 |
+
curr = lock.insert_lock_channel(m.chat.id,"anti_fwd_u")
|
151 |
+
if not curr:
|
|
|
|
|
|
|
152 |
await m.reply_text("It is already on")
|
153 |
return
|
154 |
await m.reply_text("Locked Forward message from user")
|
155 |
return
|
156 |
elif lock_type == "forwardc":
|
157 |
+
curr = lock.insert_lock_channel(m.chat.id,"anti_fwd_c")
|
158 |
+
if not curr:
|
|
|
|
|
|
|
159 |
await m.reply_text("It is already on")
|
160 |
return
|
161 |
await m.reply_text("Locked Forward message from channel")
|
|
|
203 |
if val:
|
204 |
return "✅"
|
205 |
return "❌"
|
206 |
+
|
207 |
+
lock = LOCKS()
|
208 |
+
anti_c_send = lock.get_lock_channel("anti_c_send")
|
209 |
+
anti_forward = lock.get_lock_channel("anti_fwd")
|
210 |
+
anti_forward_u = lock.get_lock_channel("anti_fwd_u")
|
211 |
+
anti_forward_c = lock.get_lock_channel("anti_fwd_c")
|
212 |
+
anti_links = lock.get_lock_channel("anti_links")
|
213 |
anon = False
|
214 |
if m.chat.id in anti_c_send:
|
215 |
anon = True
|
|
|
314 |
upin = get_uperm.can_pin_messages
|
315 |
ustickers = uanimations = ugames = uinlinebots = None
|
316 |
|
317 |
+
lock = LOCKS()
|
318 |
+
|
319 |
if unlock_type == "msg":
|
320 |
umsg = True
|
321 |
uperm = "messages"
|
|
|
360 |
upin = True
|
361 |
uperm = "pin"
|
362 |
elif unlock_type == "anonchannel":
|
363 |
+
curr = lock.remove_lock_channel(m.chat.id,"anti_c_send")
|
364 |
+
|
365 |
+
if not curr:
|
366 |
+
await m.reply_text("Send as chat is not allowed in this chat")
|
|
|
|
|
|
|
|
|
|
|
367 |
return
|
368 |
+
await m.reply_text("Send as chat is now enabled for this chat")
|
369 |
+
return
|
370 |
elif unlock_type in ["links", "url"]:
|
371 |
+
curr = lock.remove_lock_channel(m.chat.id,"anti_links")
|
372 |
+
if curr:
|
373 |
await m.reply_text("Sending link is now allowed")
|
374 |
return
|
375 |
+
else:
|
376 |
+
await m.reply_text("Sending link is not allowed")
|
377 |
return
|
378 |
elif unlock_type == "forwardall":
|
379 |
+
curr = lock.remove_lock_channel(m.chat.id,"anti_fwd")
|
380 |
+
|
381 |
+
if not curr:
|
382 |
+
await m.reply_text("Forwarding content is not allowed in this chat")
|
|
|
|
|
|
|
|
|
|
|
383 |
return
|
384 |
+
await m.reply_text("Forwarding content is now enabled for this chat")
|
385 |
+
return
|
386 |
+
|
387 |
elif unlock_type == "forwardu":
|
388 |
+
curr = lock.remove_lock_channel(m.chat.id,"anti_fwd_u")
|
389 |
+
|
390 |
+
if not curr:
|
391 |
+
await m.reply_text("Forwarding content from users is not allowed in this chat")
|
|
|
|
|
|
|
|
|
|
|
392 |
return
|
393 |
+
|
394 |
+
await m.reply_text("Forwarding content from users is now enabled for this chat")
|
395 |
+
return
|
396 |
+
|
397 |
elif unlock_type == "forwardc":
|
398 |
+
curr = lock.remove_lock_channel(m.chat.id,"anti_fwd_c")
|
399 |
+
|
400 |
+
if not curr:
|
401 |
+
await m.reply_text("Forwarding content from channel is not allowed in this chat")
|
|
|
|
|
|
|
|
|
|
|
402 |
return
|
403 |
+
await m.reply_text("Forwarding content from channel is now enabled for this chat")
|
404 |
+
return
|
405 |
+
|
406 |
else:
|
407 |
await m.reply_text(
|
408 |
text="""Invalid Lock Type!
|
|
|
473 |
|
474 |
@Gojo.on_message(filters.all & ~filters.me,18)
|
475 |
async def lock_del_mess(c:Gojo, m: Message):
|
476 |
+
lock = LOCKS()
|
477 |
+
all_chats = lock.get_lock_channel()
|
478 |
+
if not all_chats:
|
479 |
+
return
|
480 |
if m.chat.id not in all_chats:
|
481 |
return
|
482 |
if m.sender_chat and not (m.forward_from_chat or m.forward_from):
|
|
|
494 |
return
|
495 |
elif m.forward_from or m.forward_from_chat:
|
496 |
if not is_approved:
|
497 |
+
if lock.is_particular_lock(m.chat.id,"anti_fwd"):
|
498 |
await delete_messages(c,m)
|
499 |
return
|
500 |
+
elif lock.is_particular_lock(m.chat.id,"anti_fwd_u") and not m.forward_from_chat:
|
501 |
await delete_messages(c,m)
|
502 |
return
|
503 |
+
elif lock.is_particular_lock(m.chat.id,"anti_fwd_c") and m.forward_from_chat:
|
504 |
await delete_messages(c,m)
|
505 |
return
|
506 |
|
|
|
521 |
|
522 |
__alt_name__ = ["grouplock", "lock", "grouplocks"]
|
523 |
|
524 |
+
__buttons__ = [
|
525 |
+
[
|
526 |
+
("Lock Types", "LOCK_TYPES"),
|
527 |
+
],]
|
528 |
+
|
529 |
__HELP__ = """
|
530 |
**Locks**
|
531 |
|
Powers/plugins/muting.py
CHANGED
@@ -9,8 +9,9 @@ from pyrogram.types import (CallbackQuery, ChatPermissions,
|
|
9 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
10 |
Message)
|
11 |
|
12 |
-
from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID
|
13 |
from Powers.bot_class import Gojo
|
|
|
14 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
15 |
from Powers.utils.custom_filters import command, restrict_filter
|
16 |
from Powers.utils.extract_user import extract_user
|
@@ -19,6 +20,7 @@ from Powers.utils.parser import mention_html
|
|
19 |
from Powers.utils.string import extract_time
|
20 |
from Powers.vars import Config
|
21 |
|
|
|
22 |
|
23 |
@Gojo.on_message(command("tmute") & restrict_filter)
|
24 |
async def tmute_usr(c: Gojo, m: Message):
|
@@ -90,8 +92,6 @@ async def tmute_usr(c: Gojo, m: Message):
|
|
90 |
txt = f"Admin {admin} muted {muted}!"
|
91 |
if reason:
|
92 |
txt += f"\n<b>Reason</b>: {reason}"
|
93 |
-
else:
|
94 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
95 |
if mutetime:
|
96 |
txt += f"\n<b>Muted for</b>: {time_val}"
|
97 |
keyboard = InlineKeyboardMarkup(
|
@@ -203,8 +203,6 @@ async def dtmute_usr(c: Gojo, m: Message):
|
|
203 |
txt = f"Admin {admin} muted {muted}!"
|
204 |
if reason:
|
205 |
txt += f"\n<b>Reason</b>: {reason}"
|
206 |
-
else:
|
207 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
208 |
if mutetime:
|
209 |
txt += f"\n<b>Muted for</b>: {time_val}"
|
210 |
keyboard = InlineKeyboardMarkup(
|
@@ -384,8 +382,6 @@ async def mute_usr(c: Gojo, m: Message):
|
|
384 |
txt = f"Admin {admin} muted {muted}!"
|
385 |
if reason:
|
386 |
txt += f"\n<b>Reason</b>: {reason}"
|
387 |
-
else:
|
388 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
389 |
keyboard = InlineKeyboardMarkup(
|
390 |
[
|
391 |
[
|
@@ -543,8 +539,6 @@ async def dmute_usr(c: Gojo, m: Message):
|
|
543 |
txt = f"Admin {admin} muted {muted}!"
|
544 |
if reason:
|
545 |
txt += f"\n<b>Reason</b>: {reason}"
|
546 |
-
else:
|
547 |
-
txt += "\n<b>Reason</b>: Not Specified"
|
548 |
keyboard = InlineKeyboardMarkup(
|
549 |
[
|
550 |
[
|
|
|
9 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
10 |
Message)
|
11 |
|
12 |
+
from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID
|
13 |
from Powers.bot_class import Gojo
|
14 |
+
from Powers.supports import get_support_staff
|
15 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
16 |
from Powers.utils.custom_filters import command, restrict_filter
|
17 |
from Powers.utils.extract_user import extract_user
|
|
|
20 |
from Powers.utils.string import extract_time
|
21 |
from Powers.vars import Config
|
22 |
|
23 |
+
SUPPORT_STAFF = get_support_staff()
|
24 |
|
25 |
@Gojo.on_message(command("tmute") & restrict_filter)
|
26 |
async def tmute_usr(c: Gojo, m: Message):
|
|
|
92 |
txt = f"Admin {admin} muted {muted}!"
|
93 |
if reason:
|
94 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
95 |
if mutetime:
|
96 |
txt += f"\n<b>Muted for</b>: {time_val}"
|
97 |
keyboard = InlineKeyboardMarkup(
|
|
|
203 |
txt = f"Admin {admin} muted {muted}!"
|
204 |
if reason:
|
205 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
206 |
if mutetime:
|
207 |
txt += f"\n<b>Muted for</b>: {time_val}"
|
208 |
keyboard = InlineKeyboardMarkup(
|
|
|
382 |
txt = f"Admin {admin} muted {muted}!"
|
383 |
if reason:
|
384 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
385 |
keyboard = InlineKeyboardMarkup(
|
386 |
[
|
387 |
[
|
|
|
539 |
txt = f"Admin {admin} muted {muted}!"
|
540 |
if reason:
|
541 |
txt += f"\n<b>Reason</b>: {reason}"
|
|
|
|
|
542 |
keyboard = InlineKeyboardMarkup(
|
543 |
[
|
544 |
[
|
Powers/plugins/pin.py
CHANGED
@@ -97,7 +97,7 @@ async def unpin_message(c: Gojo, m: Message):
|
|
97 |
async def unpinall_message(_, m: Message):
|
98 |
await m.reply_text(
|
99 |
"Do you really want to unpin all messages in this chat?",
|
100 |
-
reply_markup=ikb([[("Yes", "
|
101 |
)
|
102 |
return
|
103 |
|
|
|
97 |
async def unpinall_message(_, m: Message):
|
98 |
await m.reply_text(
|
99 |
"Do you really want to unpin all messages in this chat?",
|
100 |
+
reply_markup=ikb([[("Yes", "unpin_all_in_this_chat"), ("No", "close_admin")]]),
|
101 |
)
|
102 |
return
|
103 |
|
Powers/plugins/report.py
CHANGED
@@ -6,13 +6,15 @@ from pyrogram.enums import ChatType
|
|
6 |
from pyrogram.errors import RPCError
|
7 |
from pyrogram.types import CallbackQuery, Message
|
8 |
|
9 |
-
from Powers import LOGGER
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.reporting_db import Reporting
|
|
|
12 |
from Powers.utils.custom_filters import admin_filter, command
|
13 |
from Powers.utils.kbhelpers import ikb
|
14 |
from Powers.utils.parser import mention_html
|
15 |
|
|
|
16 |
|
17 |
@Gojo.on_message(
|
18 |
command("reports") & (filters.private | admin_filter),
|
|
|
6 |
from pyrogram.errors import RPCError
|
7 |
from pyrogram.types import CallbackQuery, Message
|
8 |
|
9 |
+
from Powers import LOGGER
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.reporting_db import Reporting
|
12 |
+
from Powers.supports import get_support_staff
|
13 |
from Powers.utils.custom_filters import admin_filter, command
|
14 |
from Powers.utils.kbhelpers import ikb
|
15 |
from Powers.utils.parser import mention_html
|
16 |
|
17 |
+
SUPPORT_STAFF = get_support_staff()
|
18 |
|
19 |
@Gojo.on_message(
|
20 |
command("reports") & (filters.private | admin_filter),
|
Powers/plugins/scheduled_jobs.py
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
from asyncio import sleep
|
3 |
+
from traceback import format_exc
|
4 |
+
|
5 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
6 |
+
from pyrogram import Client
|
7 |
+
from pyrogram.enums import ChatMemberStatus as CMS
|
8 |
+
from pyrogram.errors import UserNotParticipant
|
9 |
+
|
10 |
+
from Powers import BDB_URI, LOGGER, MESSAGE_DUMP, TIME_ZONE
|
11 |
+
from Powers.database.approve_db import Approve
|
12 |
+
from Powers.database.blacklist_db import Blacklist
|
13 |
+
from Powers.database.chats_db import Chats
|
14 |
+
from Powers.database.disable_db import Disabling
|
15 |
+
from Powers.database.filters_db import Filters
|
16 |
+
from Powers.database.flood_db import Floods
|
17 |
+
from Powers.database.greetings_db import Greetings
|
18 |
+
from Powers.database.notes_db import Notes, NotesSettings
|
19 |
+
from Powers.database.pins_db import Pins
|
20 |
+
from Powers.database.reporting_db import Reporting
|
21 |
+
# from Powers.database.users_db import Users
|
22 |
+
from Powers.database.warns_db import Warns, WarnSettings
|
23 |
+
from Powers.utils.custom_filters import command
|
24 |
+
from Powers.vars import Config
|
25 |
+
|
26 |
+
|
27 |
+
async def clean_my_db(c:Client,is_cmd=False, id=None):
|
28 |
+
to_clean = list()
|
29 |
+
chats_list = Chats.list_chats_by_id()
|
30 |
+
to_clean.clear()
|
31 |
+
start = time.time()
|
32 |
+
for chats in chats_list:
|
33 |
+
try:
|
34 |
+
stat = await c.get_chat_member(chat_id=chats,user_id=Config.BOT_ID)
|
35 |
+
if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]:
|
36 |
+
to_clean.append(chats)
|
37 |
+
except UserNotParticipant:
|
38 |
+
to_clean.append(chats)
|
39 |
+
except Exception as e:
|
40 |
+
LOGGER.error(e)
|
41 |
+
LOGGER.error(format_exc())
|
42 |
+
if not is_cmd:
|
43 |
+
return e
|
44 |
+
else:
|
45 |
+
to_clean.append(chats)
|
46 |
+
for i in to_clean:
|
47 |
+
Approve(i).clean_approve()
|
48 |
+
Blacklist(i).clean_blacklist()
|
49 |
+
Chats.remove_chat(i)
|
50 |
+
Disabling(i).clean_disable()
|
51 |
+
Filters().rm_all_filters(i)
|
52 |
+
Floods().rm_flood(i)
|
53 |
+
Greetings(i).clean_greetings()
|
54 |
+
Notes().rm_all_notes(i)
|
55 |
+
NotesSettings().clean_notes(i)
|
56 |
+
Pins(i).clean_pins()
|
57 |
+
Reporting(i).clean_reporting()
|
58 |
+
Warns(i).clean_warn()
|
59 |
+
WarnSettings(i).clean_warns()
|
60 |
+
x = len(to_clean)
|
61 |
+
txt = f"#INFO\n\nCleaned db:\nTotal chats removed: {x}"
|
62 |
+
to_clean.clear()
|
63 |
+
nums = time.time()-start
|
64 |
+
if is_cmd:
|
65 |
+
txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}"
|
66 |
+
txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process"
|
67 |
+
await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
|
68 |
+
return txt
|
69 |
+
else:
|
70 |
+
txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process"
|
71 |
+
await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
|
72 |
+
return txt
|
73 |
+
|
74 |
+
|
75 |
+
if BDB_URI:
|
76 |
+
from Powers.plugins import bday_cinfo, bday_info
|
77 |
+
|
78 |
+
from datetime import datetime, time
|
79 |
+
from random import choice
|
80 |
+
|
81 |
+
from pyrogram.enums import ChatMemberStatus
|
82 |
+
|
83 |
+
from Powers.utils.extras import birthday_wish
|
84 |
+
|
85 |
+
|
86 |
+
def give_date(date,form = "%d/%m/%Y"):
|
87 |
+
datee = datetime.strptime(date,form).date()
|
88 |
+
return datee
|
89 |
+
|
90 |
+
scheduler = AsyncIOScheduler()
|
91 |
+
scheduler.timezone = TIME_ZONE
|
92 |
+
scheduler_time = time(0,0,0)
|
93 |
+
async def send_wishish(JJK: Client):
|
94 |
+
c_list = Chats.list_chats_by_id()
|
95 |
+
blist = list(bday_info.find())
|
96 |
+
curr = datetime.now(TIME_ZONE).date()
|
97 |
+
cclist = list(bday_cinfo.find())
|
98 |
+
for i in blist:
|
99 |
+
dob = give_date(i["dob"])
|
100 |
+
if dob.month == curr.month and dob.day == curr.day:
|
101 |
+
for j in c_list:
|
102 |
+
if cclist and (j in cclist):
|
103 |
+
return
|
104 |
+
try:
|
105 |
+
agee = ""
|
106 |
+
if i["is_year"]:
|
107 |
+
agee = curr.year - dob.year
|
108 |
+
if str(agee).endswith("1"):
|
109 |
+
agee = f"{agee}st"
|
110 |
+
elif str(agee).endswith("2"):
|
111 |
+
agee = f"{agee}nd"
|
112 |
+
elif str(agee).endswith("3"):
|
113 |
+
agee = f"{agee}rd"
|
114 |
+
else:
|
115 |
+
agee = f"{agee}th"
|
116 |
+
U = await JJK.get_chat_member(chat_id=j,user_id=i["user_id"])
|
117 |
+
wish = choice(birthday_wish)
|
118 |
+
if U.status in [ChatMemberStatus.MEMBER,ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
|
119 |
+
xXx = await JJK.send_message(j,f"Happy {agee} birthday {U.user.mention}🥳\n{wish}")
|
120 |
+
try:
|
121 |
+
await xXx.pin()
|
122 |
+
except Exception:
|
123 |
+
pass
|
124 |
+
except Exception:
|
125 |
+
pass
|
126 |
+
|
127 |
+
""""
|
128 |
+
from datetime import date, datetime
|
129 |
+
|
130 |
+
#form =
|
131 |
+
num = "18/05/2005"
|
132 |
+
st = "18 May 2005"
|
133 |
+
timm = datetime.strptime(num,"%d/%m/%Y").date()
|
134 |
+
x = datetime.now().date()
|
135 |
+
if timm.month < x.month:
|
136 |
+
next_b = date(x.year + 1, timm.month, timm.day)
|
137 |
+
days_left = (next_b - x).days
|
138 |
+
else:
|
139 |
+
timmm = date(x.year, timm.month, timm.day)
|
140 |
+
days_left = (timmm - x).days
|
141 |
+
print(days_left)
|
142 |
+
print(x.year - timm.year)
|
143 |
+
"""
|
144 |
+
|
Powers/plugins/search.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from traceback import format_exc
|
2 |
|
3 |
-
from pyrogram.types import Message
|
4 |
from search_engine_parser.core.engines.google import Search as GoogleSearch
|
5 |
from search_engine_parser.core.engines.myanimelist import Search as AnimeSearch
|
6 |
from search_engine_parser.core.engines.stackoverflow import \
|
@@ -11,6 +11,7 @@ from search_engine_parser.core.exceptions import (NoResultsFound,
|
|
11 |
from Powers import LOGGER, SUPPORT_CHANNEL
|
12 |
from Powers.bot_class import Gojo
|
13 |
from Powers.utils.custom_filters import command
|
|
|
14 |
from Powers.utils.kbhelpers import ikb
|
15 |
|
16 |
#have to add youtube
|
@@ -225,6 +226,47 @@ async def stack_search(c: Gojo, m: Message):
|
|
225 |
return
|
226 |
|
227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
__PLUGIN__ = "search"
|
229 |
|
230 |
|
@@ -241,7 +283,7 @@ __HELP__ = """
|
|
241 |
• /google `<query>` : Search the google for the given query.
|
242 |
• /anime `<query>` : Search myanimelist for the given query.
|
243 |
• /stack `<query>` : Search stackoverflow for the given query.
|
244 |
-
|
245 |
|
246 |
**Example:**
|
247 |
`/google pyrogram`: return top 5 reuslts.
|
|
|
1 |
from traceback import format_exc
|
2 |
|
3 |
+
from pyrogram.types import InputMediaPhoto, Message
|
4 |
from search_engine_parser.core.engines.google import Search as GoogleSearch
|
5 |
from search_engine_parser.core.engines.myanimelist import Search as AnimeSearch
|
6 |
from search_engine_parser.core.engines.stackoverflow import \
|
|
|
11 |
from Powers import LOGGER, SUPPORT_CHANNEL
|
12 |
from Powers.bot_class import Gojo
|
13 |
from Powers.utils.custom_filters import command
|
14 |
+
from Powers.utils.http_helper import *
|
15 |
from Powers.utils.kbhelpers import ikb
|
16 |
|
17 |
#have to add youtube
|
|
|
226 |
return
|
227 |
|
228 |
|
229 |
+
async def getText(message: Message):
|
230 |
+
# Credits: https://t.me/NovaXMod
|
231 |
+
# https://t.me/NovaXMod/98
|
232 |
+
"""Extract Text From Commands"""
|
233 |
+
text_to_return = message.text
|
234 |
+
if message.text is None:
|
235 |
+
return None
|
236 |
+
if " " in text_to_return:
|
237 |
+
try:
|
238 |
+
return message.text.split(None, 1)[1]
|
239 |
+
except IndexError:
|
240 |
+
return None
|
241 |
+
except Exception:
|
242 |
+
return None
|
243 |
+
else:
|
244 |
+
return None
|
245 |
+
|
246 |
+
@Gojo.on_message(command(["images","imgs"]))
|
247 |
+
async def get_image_search(_, m: Message):
|
248 |
+
# Credits: https://t.me/NovaXMod
|
249 |
+
# https://t.me/NovaXMod/98
|
250 |
+
query = await getText(m)
|
251 |
+
if not query:
|
252 |
+
await m.reply_text("**USAGE**\n /images [query]")
|
253 |
+
return
|
254 |
+
text = query.replace(" ", "%")
|
255 |
+
resp = get(f"https://nova-api-seven.vercel.app/api/images?name={text}")
|
256 |
+
if type(resp) == int:
|
257 |
+
await m.reply_text(f"Status code: {resp}\nUnable find any results regarding your query :/")
|
258 |
+
return
|
259 |
+
image_urls = resp.get("image_urls", [])[:10]
|
260 |
+
ab = await m.reply_text("Getting Your Images... Wait A Min..\nCredits: @NovaXMod")
|
261 |
+
Ok = []
|
262 |
+
for a in image_urls:
|
263 |
+
Ok.append(InputMediaPhoto(a))
|
264 |
+
try:
|
265 |
+
await m.reply_media_group(media=Ok)
|
266 |
+
await ab.delete()
|
267 |
+
except Exception:
|
268 |
+
await ab.edit("Error occurred while sending images. Please try again.")
|
269 |
+
|
270 |
__PLUGIN__ = "search"
|
271 |
|
272 |
|
|
|
283 |
• /google `<query>` : Search the google for the given query.
|
284 |
• /anime `<query>` : Search myanimelist for the given query.
|
285 |
• /stack `<query>` : Search stackoverflow for the given query.
|
286 |
+
• /images (/imgs) `<query>` : Get the images regarding to your query
|
287 |
|
288 |
**Example:**
|
289 |
`/google pyrogram`: return top 5 reuslts.
|
Powers/plugins/start.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
from random import choice
|
2 |
from time import gmtime, strftime, time
|
3 |
|
@@ -103,10 +104,11 @@ async def start(c: Gojo, m: Message):
|
|
103 |
quote=True,
|
104 |
)
|
105 |
return
|
|
|
106 |
try:
|
107 |
cpt = f"""
|
108 |
Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am Gojo ✨.
|
109 |
-
I'm here to help you manage your
|
110 |
Hit /help to find out more about how to use me in my full potential!
|
111 |
|
112 |
Join my [News Channel](https://t.me/gojo_bots_network) to get information on all the latest updates."""
|
@@ -145,7 +147,7 @@ async def start_back(_, q: CallbackQuery):
|
|
145 |
try:
|
146 |
cpt = f"""
|
147 |
Hey [{q.from_user.first_name}](http://t.me/{q.from_user.username})! I am Gojo ✨.
|
148 |
-
I'm here to help you manage your
|
149 |
Hit /help to find out more about how to use me in my full potential!
|
150 |
|
151 |
Join my [News Channel](http://t.me/gojo_bots_network) to get information on all the latest updates."""
|
@@ -167,7 +169,7 @@ async def commands_menu(_, q: CallbackQuery):
|
|
167 |
try:
|
168 |
cpt = f"""
|
169 |
Hey **[{q.from_user.first_name}](http://t.me/{q.from_user.username})**! I am Gojo✨.
|
170 |
-
I'm here to help you manage your
|
171 |
Commands available:
|
172 |
× /start: Start the bot
|
173 |
× /help: Give's you this message.
|
@@ -240,7 +242,7 @@ async def help_menu(_, m: Message):
|
|
240 |
keyboard = ikb(ou, True)
|
241 |
msg = f"""
|
242 |
Hey **[{m.from_user.first_name}](http://t.me/{m.from_user.username})**!I am Gojo✨.
|
243 |
-
I'm here to help you manage your
|
244 |
Commands available:
|
245 |
× /start: Start the bot
|
246 |
× /help: Give's you this message."""
|
|
|
1 |
+
import os
|
2 |
from random import choice
|
3 |
from time import gmtime, strftime, time
|
4 |
|
|
|
104 |
quote=True,
|
105 |
)
|
106 |
return
|
107 |
+
|
108 |
try:
|
109 |
cpt = f"""
|
110 |
Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am Gojo ✨.
|
111 |
+
I'm here to help you manage your group(s)!
|
112 |
Hit /help to find out more about how to use me in my full potential!
|
113 |
|
114 |
Join my [News Channel](https://t.me/gojo_bots_network) to get information on all the latest updates."""
|
|
|
147 |
try:
|
148 |
cpt = f"""
|
149 |
Hey [{q.from_user.first_name}](http://t.me/{q.from_user.username})! I am Gojo ✨.
|
150 |
+
I'm here to help you manage your group(s)!
|
151 |
Hit /help to find out more about how to use me in my full potential!
|
152 |
|
153 |
Join my [News Channel](http://t.me/gojo_bots_network) to get information on all the latest updates."""
|
|
|
169 |
try:
|
170 |
cpt = f"""
|
171 |
Hey **[{q.from_user.first_name}](http://t.me/{q.from_user.username})**! I am Gojo✨.
|
172 |
+
I'm here to help you manage your group(s)!
|
173 |
Commands available:
|
174 |
× /start: Start the bot
|
175 |
× /help: Give's you this message.
|
|
|
242 |
keyboard = ikb(ou, True)
|
243 |
msg = f"""
|
244 |
Hey **[{m.from_user.first_name}](http://t.me/{m.from_user.username})**!I am Gojo✨.
|
245 |
+
I'm here to help you manage your group(s)!
|
246 |
Commands available:
|
247 |
× /start: Start the bot
|
248 |
× /help: Give's you this message."""
|
Powers/plugins/stickers.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
import imghdr
|
2 |
import os
|
3 |
from asyncio import gather
|
4 |
from random import choice
|
@@ -64,7 +63,7 @@ async def sticker_id_gib(c: Gojo, m: Message):
|
|
64 |
async def kang(c:Gojo, m: Message):
|
65 |
if not m.reply_to_message:
|
66 |
return await m.reply_text("Reply to a sticker or image to kang it.")
|
67 |
-
elif not (m.reply_to_message.sticker or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]
|
68 |
return await m.reply_text("Reply to a sticker or image to kang it.")
|
69 |
if not m.from_user:
|
70 |
return await m.reply_text("You are anon admin, kang stickers in my pm.")
|
@@ -92,9 +91,9 @@ async def kang(c:Gojo, m: Message):
|
|
92 |
|
93 |
# Get the corresponding fileid, resize the file if necessary
|
94 |
try:
|
95 |
-
if is_requ or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]=="image"):
|
96 |
sizee = (await get_file_size(m.reply_to_message)).split()
|
97 |
-
if (sizee[1] == "mb" and sizee > 10) or sizee[1] == "gb":
|
98 |
await m.reply_text("File size is too big")
|
99 |
return
|
100 |
path = await m.reply_to_message.download()
|
@@ -113,8 +112,17 @@ async def kang(c:Gojo, m: Message):
|
|
113 |
LOGGER.error(format_exc())
|
114 |
return
|
115 |
try:
|
116 |
-
if is_requ or
|
117 |
# telegram doesn't allow animated and video sticker to be kanged as we do for normal stickers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
sticker = await create_sticker(
|
119 |
await upload_document(
|
120 |
c, path, m.chat.id
|
@@ -142,7 +150,7 @@ async def kang(c:Gojo, m: Message):
|
|
142 |
# Find an available pack & add the sticker to the pack; create a new pack if needed
|
143 |
# Would be a good idea to cache the number instead of searching it every single time...
|
144 |
kang_lim = 120
|
145 |
-
st_in = m.reply_to_message.sticker
|
146 |
st_type = "norm"
|
147 |
is_anim = is_vid = False
|
148 |
if st_in:
|
@@ -154,6 +162,19 @@ async def kang(c:Gojo, m: Message):
|
|
154 |
st_type = "vid"
|
155 |
kang_lim = 50
|
156 |
is_vid = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
packnum = 0
|
158 |
limit = 0
|
159 |
volume = 0
|
@@ -279,29 +300,51 @@ async def memify_it(c: Gojo, m: Message):
|
|
279 |
@Gojo.on_message(command(["getsticker","getst"]))
|
280 |
async def get_sticker_from_file(c: Gojo, m: Message):
|
281 |
Caption = f"Converted by:\n@{Config.BOT_USERNAME}"
|
282 |
-
if not m.reply_to_message:
|
283 |
-
await m.reply_text("Reply to a sticker or file")
|
284 |
-
return
|
285 |
repl = m.reply_to_message
|
286 |
-
if not
|
287 |
-
await m.reply_text("
|
288 |
return
|
289 |
-
|
290 |
-
|
|
|
291 |
return
|
|
|
|
|
292 |
x = await m.reply_text("Converting...")
|
293 |
if repl.sticker:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
upp = await repl.download()
|
295 |
-
up =
|
296 |
await x.delete()
|
297 |
-
await m.
|
298 |
os.remove(up)
|
299 |
return
|
300 |
-
|
301 |
-
|
302 |
-
up =
|
303 |
await x.delete()
|
304 |
-
await m.reply_sticker(up
|
305 |
os.remove(up)
|
306 |
return
|
307 |
|
@@ -315,7 +358,7 @@ __HELP__ = """
|
|
315 |
**User Commands:**
|
316 |
• /kang (/steal) <emoji>: Reply to a sticker or any supported media
|
317 |
• /stickerinfo (/stinfo) : Reply to any sticker to get it's info
|
318 |
-
• /getsticker (/getst) : Get sticker as photo or vice versa.
|
319 |
• /stickerid (/stid) : Reply to any sticker to get it's id
|
320 |
• /mmf <your text>: Reply to a normal sticker or a photo or video file to memify it. If you want to right text at bottom use `;right your message`
|
321 |
■ For e.g.
|
|
|
|
|
1 |
import os
|
2 |
from asyncio import gather
|
3 |
from random import choice
|
|
|
63 |
async def kang(c:Gojo, m: Message):
|
64 |
if not m.reply_to_message:
|
65 |
return await m.reply_text("Reply to a sticker or image to kang it.")
|
66 |
+
elif not (m.reply_to_message.animation or m.reply_to_message.sticker or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]in["image","video"])):
|
67 |
return await m.reply_text("Reply to a sticker or image to kang it.")
|
68 |
if not m.from_user:
|
69 |
return await m.reply_text("You are anon admin, kang stickers in my pm.")
|
|
|
91 |
|
92 |
# Get the corresponding fileid, resize the file if necessary
|
93 |
try:
|
94 |
+
if is_requ or m.reply_to_message.video or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]=="image"):
|
95 |
sizee = (await get_file_size(m.reply_to_message)).split()
|
96 |
+
if (sizee[1] == "mb" and int(sizee[0]) > 10) or sizee[1] == "gb":
|
97 |
await m.reply_text("File size is too big")
|
98 |
return
|
99 |
path = await m.reply_to_message.download()
|
|
|
112 |
LOGGER.error(format_exc())
|
113 |
return
|
114 |
try:
|
115 |
+
if is_requ or m.reply_to_message.animation or m.reply_to_message.video or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0] == "video"):
|
116 |
# telegram doesn't allow animated and video sticker to be kanged as we do for normal stickers
|
117 |
+
if m.reply_to_message.animation or m.reply_to_message.video or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0] == "video"):
|
118 |
+
path = await Vsticker(c, m.reply_to_message)
|
119 |
+
SIZE = os.path.getsize(path)
|
120 |
+
if SIZE > 261120:
|
121 |
+
await m.reply_text("File is too big")
|
122 |
+
os.remove(path)
|
123 |
+
return
|
124 |
+
else:
|
125 |
+
path = await m.reply_to_message.download()
|
126 |
sticker = await create_sticker(
|
127 |
await upload_document(
|
128 |
c, path, m.chat.id
|
|
|
150 |
# Find an available pack & add the sticker to the pack; create a new pack if needed
|
151 |
# Would be a good idea to cache the number instead of searching it every single time...
|
152 |
kang_lim = 120
|
153 |
+
st_in = m.reply_to_message.sticker
|
154 |
st_type = "norm"
|
155 |
is_anim = is_vid = False
|
156 |
if st_in:
|
|
|
162 |
st_type = "vid"
|
163 |
kang_lim = 50
|
164 |
is_vid = True
|
165 |
+
elif m.reply_to_message.document:
|
166 |
+
if m.reply_to_message.document.mime_type in ["application/x-bad-tgsticker", "application/x-tgsticker"]:
|
167 |
+
st_type = "ani"
|
168 |
+
kang_lim = 50
|
169 |
+
is_anim = True
|
170 |
+
elif m.reply_to_message.document.mime_type == "video/webm":
|
171 |
+
st_type = "vid"
|
172 |
+
kang_lim = 50
|
173 |
+
is_vid = True
|
174 |
+
elif m.reply_to_message.video or m.reply_to_message.animation or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0] == "video"):
|
175 |
+
st_type = "vid"
|
176 |
+
kang_lim = 50
|
177 |
+
is_vid = True
|
178 |
packnum = 0
|
179 |
limit = 0
|
180 |
volume = 0
|
|
|
300 |
@Gojo.on_message(command(["getsticker","getst"]))
|
301 |
async def get_sticker_from_file(c: Gojo, m: Message):
|
302 |
Caption = f"Converted by:\n@{Config.BOT_USERNAME}"
|
|
|
|
|
|
|
303 |
repl = m.reply_to_message
|
304 |
+
if not repl:
|
305 |
+
await m.reply_text("Reply to a sticker or file")
|
306 |
return
|
307 |
+
to_vid = False
|
308 |
+
if not (repl.animation or repl.video or repl.sticker or repl.photo or (repl.document and repl.document.mime_type.split("/")[0] in ["image","video"])):
|
309 |
+
await m.reply_text("I only support conversion of plain stickers, images, videos and animation for now")
|
310 |
return
|
311 |
+
if repl.animation or repl.video or (repl.document and repl.document.mime_type.split("/")[0]=="video"):
|
312 |
+
to_vid = True
|
313 |
x = await m.reply_text("Converting...")
|
314 |
if repl.sticker:
|
315 |
+
if repl.sticker.is_animated:
|
316 |
+
upp = await repl.download()
|
317 |
+
up = tgs_to_gif(upp,True)
|
318 |
+
await x.delete()
|
319 |
+
await m.reply_animation(up,caption=Caption)
|
320 |
+
os.remove(up)
|
321 |
+
return
|
322 |
+
elif repl.sticker.is_video:
|
323 |
+
upp = await repl.download()
|
324 |
+
up = await webm_to_gif(upp)
|
325 |
+
await x.delete()
|
326 |
+
await m.reply_animation(up,caption=Caption)
|
327 |
+
os.remove(up)
|
328 |
+
return
|
329 |
+
else:
|
330 |
+
upp = await repl.download()
|
331 |
+
up = toimage(upp,is_direc=True)
|
332 |
+
await x.delete()
|
333 |
+
await m.reply_photo(up,caption=Caption)
|
334 |
+
os.remove(up)
|
335 |
+
return
|
336 |
+
elif repl.photo:
|
337 |
upp = await repl.download()
|
338 |
+
up = tosticker(upp,is_direc=True)
|
339 |
await x.delete()
|
340 |
+
await m.reply_sticker(up)
|
341 |
os.remove(up)
|
342 |
return
|
343 |
+
|
344 |
+
elif to_vid:
|
345 |
+
up = await Vsticker(c,repl)
|
346 |
await x.delete()
|
347 |
+
await m.reply_sticker(up)
|
348 |
os.remove(up)
|
349 |
return
|
350 |
|
|
|
358 |
**User Commands:**
|
359 |
• /kang (/steal) <emoji>: Reply to a sticker or any supported media
|
360 |
• /stickerinfo (/stinfo) : Reply to any sticker to get it's info
|
361 |
+
• /getsticker (/getst) : Get sticker as photo, gif or vice versa.
|
362 |
• /stickerid (/stid) : Reply to any sticker to get it's id
|
363 |
• /mmf <your text>: Reply to a normal sticker or a photo or video file to memify it. If you want to right text at bottom use `;right your message`
|
364 |
■ For e.g.
|
Powers/plugins/utils.py
CHANGED
@@ -14,6 +14,7 @@ from wikipedia.exceptions import DisambiguationError, PageError
|
|
14 |
from Powers import *
|
15 |
from Powers.bot_class import Gojo
|
16 |
from Powers.database.users_db import Users
|
|
|
17 |
from Powers.utils.clean_file import remove_markdown_and_html
|
18 |
from Powers.utils.custom_filters import command
|
19 |
from Powers.utils.extract_user import extract_user
|
@@ -62,7 +63,7 @@ async def wiki(_, m: Message):
|
|
62 |
|
63 |
@Gojo.on_message(command("gdpr"))
|
64 |
async def gdpr_remove(_, m: Message):
|
65 |
-
if m.from_user.id in
|
66 |
await m.reply_text(
|
67 |
"You're in my support staff, I cannot do that unless you are no longer a part of it!",
|
68 |
)
|
@@ -239,6 +240,11 @@ async def github(_, m: Message):
|
|
239 |
return
|
240 |
r = r.json()
|
241 |
avtar = r.get("avatar_url", None)
|
|
|
|
|
|
|
|
|
|
|
242 |
url = r.get("html_url", None)
|
243 |
name = r.get("name", None)
|
244 |
company = r.get("company", None)
|
@@ -281,6 +287,12 @@ async def github(_, m: Message):
|
|
281 |
if bio:
|
282 |
REPLY += f"\n\n<b>🎯 Bio:</b> {bio}"
|
283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
if avtar:
|
285 |
return await m.reply_photo(photo=f"{avtar}", caption=REPLY)
|
286 |
await m.reply_text(REPLY)
|
@@ -407,7 +419,6 @@ async def reporting_query(c: Gojo, m: Message):
|
|
407 |
await c.send_message(OWNER_ID,f"New bug report\n{ppost}",disable_web_page_preview=True)
|
408 |
return
|
409 |
|
410 |
-
|
411 |
__PLUGIN__ = "utils"
|
412 |
_DISABLE_CMDS_ = ["paste", "wiki", "id", "gifid", "tr", "github", "git", "bug"]
|
413 |
__alt_name__ = ["util", "misc", "tools"]
|
|
|
14 |
from Powers import *
|
15 |
from Powers.bot_class import Gojo
|
16 |
from Powers.database.users_db import Users
|
17 |
+
from Powers.supports import get_support_staff
|
18 |
from Powers.utils.clean_file import remove_markdown_and_html
|
19 |
from Powers.utils.custom_filters import command
|
20 |
from Powers.utils.extract_user import extract_user
|
|
|
63 |
|
64 |
@Gojo.on_message(command("gdpr"))
|
65 |
async def gdpr_remove(_, m: Message):
|
66 |
+
if m.from_user.id in get_support_staff():
|
67 |
await m.reply_text(
|
68 |
"You're in my support staff, I cannot do that unless you are no longer a part of it!",
|
69 |
)
|
|
|
240 |
return
|
241 |
r = r.json()
|
242 |
avtar = r.get("avatar_url", None)
|
243 |
+
if avtar:
|
244 |
+
avtar = avtar.rsplit("=",1)
|
245 |
+
avtar.pop(-1)
|
246 |
+
avtar.append("5")
|
247 |
+
avtar = "=".join(avtar)
|
248 |
url = r.get("html_url", None)
|
249 |
name = r.get("name", None)
|
250 |
company = r.get("company", None)
|
|
|
287 |
if bio:
|
288 |
REPLY += f"\n\n<b>🎯 Bio:</b> {bio}"
|
289 |
|
290 |
+
kb = InlineKeyboardMarkup(
|
291 |
+
[
|
292 |
+
InlineKeyboardButton("")
|
293 |
+
]
|
294 |
+
)
|
295 |
+
|
296 |
if avtar:
|
297 |
return await m.reply_photo(photo=f"{avtar}", caption=REPLY)
|
298 |
await m.reply_text(REPLY)
|
|
|
419 |
await c.send_message(OWNER_ID,f"New bug report\n{ppost}",disable_web_page_preview=True)
|
420 |
return
|
421 |
|
|
|
422 |
__PLUGIN__ = "utils"
|
423 |
_DISABLE_CMDS_ = ["paste", "wiki", "id", "gifid", "tr", "github", "git", "bug"]
|
424 |
__alt_name__ = ["util", "misc", "tools"]
|
Powers/plugins/warns.py
CHANGED
@@ -6,17 +6,19 @@ from pyrogram.types import (CallbackQuery, ChatPermissions,
|
|
6 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
7 |
Message)
|
8 |
|
9 |
-
from Powers import LOGGER,
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.rules_db import Rules
|
12 |
from Powers.database.users_db import Users
|
13 |
from Powers.database.warns_db import Warns, WarnSettings
|
|
|
14 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
15 |
from Powers.utils.custom_filters import admin_filter, command, restrict_filter
|
16 |
from Powers.utils.extract_user import extract_user
|
17 |
from Powers.utils.parser import mention_html
|
18 |
from Powers.vars import Config
|
19 |
|
|
|
20 |
|
21 |
@Gojo.on_message(
|
22 |
command(["warn", "swarn", "dwarn"]) & restrict_filter,
|
|
|
6 |
InlineKeyboardButton, InlineKeyboardMarkup,
|
7 |
Message)
|
8 |
|
9 |
+
from Powers import LOGGER, TIME_ZONE
|
10 |
from Powers.bot_class import Gojo
|
11 |
from Powers.database.rules_db import Rules
|
12 |
from Powers.database.users_db import Users
|
13 |
from Powers.database.warns_db import Warns, WarnSettings
|
14 |
+
from Powers.supports import get_support_staff
|
15 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
16 |
from Powers.utils.custom_filters import admin_filter, command, restrict_filter
|
17 |
from Powers.utils.extract_user import extract_user
|
18 |
from Powers.utils.parser import mention_html
|
19 |
from Powers.vars import Config
|
20 |
|
21 |
+
SUPPORT_STAFF = get_support_staff()
|
22 |
|
23 |
@Gojo.on_message(
|
24 |
command(["warn", "swarn", "dwarn"]) & restrict_filter,
|
Powers/plugins/watchers.py
CHANGED
@@ -7,7 +7,7 @@ from pyrogram import filters
|
|
7 |
from pyrogram.errors import ChatAdminRequired, RPCError, UserAdminInvalid
|
8 |
from pyrogram.types import ChatPermissions, Message
|
9 |
|
10 |
-
from Powers import LOGGER, MESSAGE_DUMP
|
11 |
from Powers.bot_class import Gojo
|
12 |
from Powers.database.antispam_db import ANTISPAM_BANNED, GBan
|
13 |
from Powers.database.approve_db import Approve
|
@@ -15,13 +15,14 @@ from Powers.database.blacklist_db import Blacklist
|
|
15 |
from Powers.database.group_blacklist import BLACKLIST_CHATS
|
16 |
from Powers.database.pins_db import Pins
|
17 |
from Powers.database.warns_db import Warns, WarnSettings
|
|
|
18 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
19 |
from Powers.utils.parser import mention_html
|
20 |
from Powers.utils.regex_utils import regex_searcher
|
21 |
|
22 |
# Initialise
|
23 |
gban_db = GBan()
|
24 |
-
|
25 |
|
26 |
@Gojo.on_message(filters.linked_channel)
|
27 |
async def antichanpin_cleanlinked(c: Gojo, m: Message):
|
|
|
7 |
from pyrogram.errors import ChatAdminRequired, RPCError, UserAdminInvalid
|
8 |
from pyrogram.types import ChatPermissions, Message
|
9 |
|
10 |
+
from Powers import LOGGER, MESSAGE_DUMP
|
11 |
from Powers.bot_class import Gojo
|
12 |
from Powers.database.antispam_db import ANTISPAM_BANNED, GBan
|
13 |
from Powers.database.approve_db import Approve
|
|
|
15 |
from Powers.database.group_blacklist import BLACKLIST_CHATS
|
16 |
from Powers.database.pins_db import Pins
|
17 |
from Powers.database.warns_db import Warns, WarnSettings
|
18 |
+
from Powers.supports import get_support_staff
|
19 |
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
20 |
from Powers.utils.parser import mention_html
|
21 |
from Powers.utils.regex_utils import regex_searcher
|
22 |
|
23 |
# Initialise
|
24 |
gban_db = GBan()
|
25 |
+
SUPPORT_STAFF = get_support_staff()
|
26 |
|
27 |
@Gojo.on_message(filters.linked_channel)
|
28 |
async def antichanpin_cleanlinked(c: Gojo, m: Message):
|
Powers/plugins/web_con.py
CHANGED
@@ -262,7 +262,7 @@ async def song_down_up(c: Gojo, m: Message):
|
|
262 |
query = splited
|
263 |
XnX = await m.reply_text("⏳")
|
264 |
try:
|
265 |
-
|
266 |
await XnX.delete()
|
267 |
return
|
268 |
except KeyError:
|
|
|
262 |
query = splited
|
263 |
XnX = await m.reply_text("⏳")
|
264 |
try:
|
265 |
+
await youtube_downloader(c,m,query,is_direct,"a")
|
266 |
await XnX.delete()
|
267 |
return
|
268 |
except KeyError:
|
Powers/supports.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from Powers import DEV_USERS, OWNER_ID, SUDO_USERS, WHITELIST_USERS
|
2 |
+
from Powers.database.support_db import SUPPORTS
|
3 |
+
|
4 |
+
|
5 |
+
async def load_support_users():
|
6 |
+
support = SUPPORTS()
|
7 |
+
for i in DEV_USERS:
|
8 |
+
support.insert_support_user(int(i),"dev")
|
9 |
+
for i in SUDO_USERS:
|
10 |
+
support.insert_support_user(int(i),"sudo")
|
11 |
+
for i in WHITELIST_USERS:
|
12 |
+
support.insert_support_user(int(i),"whitelist")
|
13 |
+
return
|
14 |
+
|
15 |
+
def get_support_staff(want = "all"):
|
16 |
+
"""
|
17 |
+
dev, sudo, whitelist, dev_level, sudo_level, all
|
18 |
+
"""
|
19 |
+
support = SUPPORTS()
|
20 |
+
devs = support.get_particular_support("dev")
|
21 |
+
sudo = support.get_particular_support("sudo")
|
22 |
+
whitelist = support.get_particular_support("whitelist")
|
23 |
+
|
24 |
+
if want in ["dev","dev_level"]:
|
25 |
+
wanted = devs
|
26 |
+
elif want == "sudo":
|
27 |
+
wanted = sudo
|
28 |
+
elif want == "whitelist":
|
29 |
+
wanted = whitelist
|
30 |
+
elif want == "sudo_level":
|
31 |
+
wanted = sudo + devs
|
32 |
+
else:
|
33 |
+
wanted = list(set([int(OWNER_ID)] + devs + sudo + whitelist))
|
34 |
+
|
35 |
+
return wanted
|
Powers/utils/extras.py
CHANGED
@@ -695,6 +695,15 @@ StartPic = [
|
|
695 |
"https://graph.org/file/6d18195f6e0e55af91228.png",
|
696 |
"https://i.imgur.com/8l6cByn.jpg",
|
697 |
"https://graph.org/file/259a92d3482fc8627fe68.png",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
698 |
]
|
699 |
|
700 |
|
|
|
695 |
"https://graph.org/file/6d18195f6e0e55af91228.png",
|
696 |
"https://i.imgur.com/8l6cByn.jpg",
|
697 |
"https://graph.org/file/259a92d3482fc8627fe68.png",
|
698 |
+
"https://graph.org/file/d328fb0a7e30b866979d5.jpg",
|
699 |
+
"https://graph.org/file/cdbc22231afb0937e1a5d.jpg",
|
700 |
+
"https://graph.org/file/dd32af83434be92ef4f72.jpg",
|
701 |
+
"https://graph.org/file/9c97627158a8b6c23cd8b.jpg",
|
702 |
+
"https://graph.org/file/0bd63482afbc2844cb77d.jpg",
|
703 |
+
"https://graph.org/file/798a33ee39bca8014116c.jpg",
|
704 |
+
"https://graph.org/file/d0beb924887f45ab1c84e.jpg",
|
705 |
+
"https://graph.org/file/9e92625135caffcadcbae.jpg",
|
706 |
+
"https://graph.org/file/f377781fe8a1fe09fea55.jpg",
|
707 |
]
|
708 |
|
709 |
|
Powers/utils/http_helper.py
CHANGED
@@ -6,6 +6,8 @@ import requests
|
|
6 |
|
7 |
def get(url: str, *args, **kwargs):
|
8 |
resp = requests.get(url, *args, **kwargs)
|
|
|
|
|
9 |
try:
|
10 |
data = resp.json()
|
11 |
except Exception:
|
@@ -24,6 +26,8 @@ def head(url: str, *args, **kwargs):
|
|
24 |
|
25 |
def post(url: str, *args, **kwargs):
|
26 |
resp = requests.post(url, *args, **kwargs)
|
|
|
|
|
27 |
try:
|
28 |
data = resp.json()
|
29 |
except Exception:
|
|
|
6 |
|
7 |
def get(url: str, *args, **kwargs):
|
8 |
resp = requests.get(url, *args, **kwargs)
|
9 |
+
if resp.status_code != 200:
|
10 |
+
return resp.status_code
|
11 |
try:
|
12 |
data = resp.json()
|
13 |
except Exception:
|
|
|
26 |
|
27 |
def post(url: str, *args, **kwargs):
|
28 |
resp = requests.post(url, *args, **kwargs)
|
29 |
+
if resp.status_code != 200:
|
30 |
+
return resp.status_code
|
31 |
try:
|
32 |
data = resp.json()
|
33 |
except Exception:
|
Powers/utils/msg_types.py
CHANGED
@@ -50,7 +50,7 @@ async def get_note_type(m: Message):
|
|
50 |
data_type = Types.STICKER
|
51 |
|
52 |
elif m.reply_to_message.document:
|
53 |
-
if m.reply_to_message.document.mime_type
|
54 |
data_type = Types.ANIMATED_STICKER
|
55 |
else:
|
56 |
data_type = Types.DOCUMENT
|
@@ -89,7 +89,7 @@ async def get_note_type(m: Message):
|
|
89 |
async def get_filter_type(m: Message):
|
90 |
"""Get filter type."""
|
91 |
if len(m.text.split()) <= 1:
|
92 |
-
return None, None, None
|
93 |
|
94 |
data_type = None
|
95 |
content = None
|
@@ -118,7 +118,7 @@ async def get_filter_type(m: Message):
|
|
118 |
data_type = Types.STICKER
|
119 |
|
120 |
elif m.reply_to_message.document:
|
121 |
-
if m.reply_to_message.document.mime_type
|
122 |
data_type = Types.ANIMATED_STICKER
|
123 |
else:
|
124 |
data_type = Types.DOCUMENT
|
@@ -163,7 +163,7 @@ async def get_wlcm_type(m: Message):
|
|
163 |
raw_text = m.text.markdown if m.text else m.caption.markdown
|
164 |
args = raw_text.split(None, 1)
|
165 |
|
166 |
-
if not m.reply_to_message and m.text and len(m.text.split()) >= 2:
|
167 |
content = None
|
168 |
text = m.text.markdown.split(None, 1)[1]
|
169 |
data_type = Types.TEXT
|
@@ -180,15 +180,66 @@ async def get_wlcm_type(m: Message):
|
|
180 |
if len(args) >= 1 and m.reply_to_message.text: # not caption, text
|
181 |
data_type = Types.TEXT
|
182 |
|
183 |
-
elif m.reply_to_message.
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
|
187 |
elif m.reply_to_message.document:
|
188 |
-
|
189 |
-
data_type = Types.ANIMATED_STICKER
|
190 |
-
else:
|
191 |
-
data_type = Types.DOCUMENT
|
192 |
content = m.reply_to_message.document.file_id
|
193 |
|
194 |
elif m.reply_to_message.photo:
|
|
|
50 |
data_type = Types.STICKER
|
51 |
|
52 |
elif m.reply_to_message.document:
|
53 |
+
if m.reply_to_message.document.mime_type in ["application/x-bad-tgsticker", "application/x-tgsticker"]:
|
54 |
data_type = Types.ANIMATED_STICKER
|
55 |
else:
|
56 |
data_type = Types.DOCUMENT
|
|
|
89 |
async def get_filter_type(m: Message):
|
90 |
"""Get filter type."""
|
91 |
if len(m.text.split()) <= 1:
|
92 |
+
return None, None, None
|
93 |
|
94 |
data_type = None
|
95 |
content = None
|
|
|
118 |
data_type = Types.STICKER
|
119 |
|
120 |
elif m.reply_to_message.document:
|
121 |
+
if m.reply_to_message.document.mime_type in ["application/x-bad-tgsticker", "application/x-tgsticker"]:
|
122 |
data_type = Types.ANIMATED_STICKER
|
123 |
else:
|
124 |
data_type = Types.DOCUMENT
|
|
|
163 |
raw_text = m.text.markdown if m.text else m.caption.markdown
|
164 |
args = raw_text.split(None, 1)
|
165 |
|
166 |
+
if not m.reply_to_message and m.text and len(m.text.strip().split()) >= 2:
|
167 |
content = None
|
168 |
text = m.text.markdown.split(None, 1)[1]
|
169 |
data_type = Types.TEXT
|
|
|
180 |
if len(args) >= 1 and m.reply_to_message.text: # not caption, text
|
181 |
data_type = Types.TEXT
|
182 |
|
183 |
+
elif m.reply_to_message.document:
|
184 |
+
data_type = Types.DOCUMENT
|
185 |
+
content = m.reply_to_message.document.file_id
|
186 |
+
|
187 |
+
elif m.reply_to_message.photo:
|
188 |
+
content = m.reply_to_message.photo.file_id # last elem = best quality
|
189 |
+
data_type = Types.PHOTO
|
190 |
+
|
191 |
+
elif m.reply_to_message.audio:
|
192 |
+
content = m.reply_to_message.audio.file_id
|
193 |
+
data_type = Types.AUDIO
|
194 |
+
|
195 |
+
elif m.reply_to_message.voice:
|
196 |
+
content = m.reply_to_message.voice.file_id
|
197 |
+
data_type = Types.VOICE
|
198 |
+
|
199 |
+
elif m.reply_to_message.video:
|
200 |
+
content = m.reply_to_message.video.file_id
|
201 |
+
data_type = Types.VIDEO
|
202 |
+
|
203 |
+
elif m.reply_to_message.video_note:
|
204 |
+
content = m.reply_to_message.video_note.file_id
|
205 |
+
data_type = Types.VIDEO_NOTE
|
206 |
+
|
207 |
+
elif m.reply_to_message.animation:
|
208 |
+
content = m.reply_to_message.animation.file_id
|
209 |
+
data_type = Types.ANIMATION
|
210 |
+
|
211 |
+
else:
|
212 |
+
text = None
|
213 |
+
data_type = None
|
214 |
+
content = None
|
215 |
+
|
216 |
+
return text, data_type, content
|
217 |
+
|
218 |
+
async def get_afk_type(m: Message):
|
219 |
+
data_type = None
|
220 |
+
content = None
|
221 |
+
raw_text = m.text.markdown if m.text else m.caption.markdown
|
222 |
+
args = raw_text.split(None, 1)
|
223 |
+
|
224 |
+
if not m.reply_to_message and m.text and len(m.text.strip().split()) >= 2:
|
225 |
+
content = None
|
226 |
+
text = m.text.markdown.split(None, 1)[1]
|
227 |
+
data_type = Types.TEXT
|
228 |
+
|
229 |
+
elif m.reply_to_message:
|
230 |
+
|
231 |
+
if m.reply_to_message.text:
|
232 |
+
text = m.reply_to_message.text.markdown
|
233 |
+
elif m.reply_to_message.caption:
|
234 |
+
text = m.reply_to_message.caption.markdown
|
235 |
+
else:
|
236 |
+
text = ""
|
237 |
+
|
238 |
+
if len(args) >= 1 and m.reply_to_message.text: # not caption, text
|
239 |
+
data_type = Types.TEXT
|
240 |
|
241 |
elif m.reply_to_message.document:
|
242 |
+
data_type = Types.DOCUMENT
|
|
|
|
|
|
|
243 |
content = m.reply_to_message.document.file_id
|
244 |
|
245 |
elif m.reply_to_message.photo:
|
Powers/utils/start_utils.py
CHANGED
@@ -72,8 +72,8 @@ async def gen_start_kb(q: Message or CallbackQuery):
|
|
72 |
],
|
73 |
[
|
74 |
(
|
75 |
-
"
|
76 |
-
"https://t.me
|
77 |
"url",
|
78 |
),
|
79 |
(
|
|
|
72 |
],
|
73 |
[
|
74 |
(
|
75 |
+
"Essential",
|
76 |
+
"https://t.me/+PcVYvdzNt4E1YjM1",
|
77 |
"url",
|
78 |
),
|
79 |
(
|
Powers/utils/sticker_help.py
CHANGED
@@ -8,10 +8,24 @@ from typing import List, Tuple
|
|
8 |
from PIL import Image, ImageDraw, ImageFont
|
9 |
from pyrogram import errors, raw
|
10 |
from pyrogram.file_id import FileId
|
|
|
11 |
|
12 |
from Powers.bot_class import Gojo
|
13 |
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
async def get_sticker_set_by_name(
|
16 |
client: Gojo, name: str
|
17 |
) -> raw.base.messages.StickerSet:
|
@@ -97,7 +111,39 @@ async def resize_file_to_sticker_size(file_path: str,length:int=512,width:int=51
|
|
97 |
im.save(file_pathh)
|
98 |
os.remove(file_path)
|
99 |
return file_pathh
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
|
103 |
async def upload_document(
|
@@ -183,7 +229,7 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li
|
|
183 |
# img = Image.open(image_path)
|
184 |
# i_width, i_height = img.size
|
185 |
# m_font = ImageFont.truetype(
|
186 |
-
# "./extras/comic.ttf", int(
|
187 |
# )
|
188 |
# if ";" in text:
|
189 |
# upper_text, lower_text = text.split(";")
|
|
|
8 |
from PIL import Image, ImageDraw, ImageFont
|
9 |
from pyrogram import errors, raw
|
10 |
from pyrogram.file_id import FileId
|
11 |
+
from pyrogram.types import Message
|
12 |
|
13 |
from Powers.bot_class import Gojo
|
14 |
|
15 |
|
16 |
+
async def runcmd(cmd: str) -> Tuple[str, str, int, int]:
|
17 |
+
args = shlex.split(cmd)
|
18 |
+
process = await asyncio.create_subprocess_exec(
|
19 |
+
*args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
20 |
+
)
|
21 |
+
stdout, stderr = await process.communicate()
|
22 |
+
return (
|
23 |
+
stdout.decode("utf-8", "replace").strip(),
|
24 |
+
stderr.decode("utf-8", "replace").strip(),
|
25 |
+
process.returncode,
|
26 |
+
process.pid,
|
27 |
+
)
|
28 |
+
|
29 |
async def get_sticker_set_by_name(
|
30 |
client: Gojo, name: str
|
31 |
) -> raw.base.messages.StickerSet:
|
|
|
111 |
im.save(file_pathh)
|
112 |
os.remove(file_path)
|
113 |
return file_pathh
|
114 |
+
|
115 |
+
async def tgs_to_gif(file, tgs=False, video=False):
|
116 |
+
if tgs:
|
117 |
+
cmd = f"lottie_convert.py '{file}' 'gojo_satoru.gif'"
|
118 |
+
elif video:
|
119 |
+
cmd = f"ffmpeg -i '{file}' -c copy 'gojo_satoru.gif'"
|
120 |
+
await runcmd(cmd)
|
121 |
+
os.remove(file)
|
122 |
+
return 'gojo_satoru.gif'
|
123 |
+
|
124 |
+
async def webm_to_gif(file):
|
125 |
+
cmd = f"ffmpeg -i '{file}' 'goJo.gif'"
|
126 |
+
await runcmd(cmd)
|
127 |
+
os.remove(file)
|
128 |
+
return "goJo.gif"
|
129 |
|
130 |
+
async def Vsticker(c: Gojo, file: Message):
|
131 |
+
if file.animation:
|
132 |
+
file = file.animation
|
133 |
+
elif file.video:
|
134 |
+
file = file.video
|
135 |
+
_width_ = file.width
|
136 |
+
_height_ = file.height
|
137 |
+
if _height_ > _width_:
|
138 |
+
_height_, _width_ = (512, -1)
|
139 |
+
else:
|
140 |
+
_height_, _width_ = (-1, 512)
|
141 |
+
file = await c.download_media(file)
|
142 |
+
await runcmd(
|
143 |
+
f"ffmpeg -to 00:00:02.900 -i '{file}' -vf scale={_width_}:{_height_} -c:v libvpx-vp9 -crf 30 -b:v 560k -maxrate 560k -bufsize 256k -an 'VideoSticker.webm'"
|
144 |
+
)
|
145 |
+
os.remove(file)
|
146 |
+
return "VideoSticker.webm"
|
147 |
|
148 |
|
149 |
async def upload_document(
|
|
|
229 |
# img = Image.open(image_path)
|
230 |
# i_width, i_height = img.size
|
231 |
# m_font = ImageFont.truetype(
|
232 |
+
# "./extras/comic.ttf", int(i_width / 11)
|
233 |
# )
|
234 |
# if ";" in text:
|
235 |
# upper_text, lower_text = text.split(";")
|
Powers/utils/web_helpers.py
CHANGED
@@ -1,13 +1,16 @@
|
|
1 |
import json
|
2 |
import os
|
|
|
3 |
from urllib import parse
|
4 |
|
5 |
-
import yt_dlp
|
6 |
from pyrogram.types import InlineKeyboardButton as IKB
|
7 |
from pyrogram.types import InlineKeyboardMarkup as IKM
|
8 |
from pyrogram.types import Message
|
|
|
|
|
|
|
9 |
|
10 |
-
from Powers.bot_class import Gojo
|
11 |
from Powers.utils.http_helper import *
|
12 |
|
13 |
|
@@ -22,6 +25,12 @@ async def get_file_size(file: Message):
|
|
22 |
size = file.audio.file_size/1024
|
23 |
elif file.sticker:
|
24 |
size = file.sticker.file_size/1024
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
if size <= 1024:
|
27 |
return f"{round(size)} kb"
|
@@ -34,98 +43,30 @@ async def get_file_size(file: Message):
|
|
34 |
return f"{round(size)} gb"
|
35 |
|
36 |
|
37 |
-
|
38 |
-
""
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
self.max_results = max_results
|
45 |
-
self.videos = self._search()
|
46 |
-
|
47 |
-
def _search(self):
|
48 |
-
encoded_search = parse.quote_plus(self.search_terms)
|
49 |
-
BASE_URL = "https://youtube.com"
|
50 |
-
url = f"{BASE_URL}/results?search_query={encoded_search}"
|
51 |
-
response = requests.get(url).text
|
52 |
-
while "ytInitialData" not in response:
|
53 |
-
response = requests.get(url).text
|
54 |
-
results = self._parse_html(response)
|
55 |
-
if self.max_results is not None and len(results) > self.max_results:
|
56 |
-
return results[: self.max_results]
|
57 |
-
return results
|
58 |
-
|
59 |
-
def _parse_html(self, response):
|
60 |
-
results = []
|
61 |
-
start = response.index("ytInitialData") + len("ytInitialData") + 3
|
62 |
-
end = response.index("};", start) + 1
|
63 |
-
json_str = response[start:end]
|
64 |
-
data = json.loads(json_str)
|
65 |
-
|
66 |
-
videos = data["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"][
|
67 |
-
"sectionListRenderer"
|
68 |
-
]["contents"][0]["itemSectionRenderer"]["contents"]
|
69 |
-
|
70 |
-
for video in videos:
|
71 |
-
res = {}
|
72 |
-
if "videoRenderer" in video.keys():
|
73 |
-
video_data = video.get("videoRenderer", {})
|
74 |
-
res["id"] = video_data.get("videoId", None)
|
75 |
-
res["thumbnails"] = [
|
76 |
-
thumb.get("url", None)
|
77 |
-
for thumb in video_data.get("thumbnail", {}).get("thumbnails", [{}])
|
78 |
-
]
|
79 |
-
res["title"] = (
|
80 |
-
video_data.get("title", {}).get("runs", [[{}]])[0].get("text", None)
|
81 |
-
)
|
82 |
-
res["long_desc"] = (
|
83 |
-
video_data.get("descriptionSnippet", {})
|
84 |
-
.get("runs", [{}])[0]
|
85 |
-
.get("text", None)
|
86 |
-
)
|
87 |
-
res["channel"] = (
|
88 |
-
video_data.get("longBylineText", {})
|
89 |
-
.get("runs", [[{}]])[0]
|
90 |
-
.get("text", None)
|
91 |
-
)
|
92 |
-
res["duration"] = video_data.get("lengthText", {}).get("simpleText", 0)
|
93 |
-
res["views"] = video_data.get("viewCountText", {}).get("simpleText", 0)
|
94 |
-
res["publish_time"] = video_data.get("publishedTimeText", {}).get(
|
95 |
-
"simpleText", 0
|
96 |
-
)
|
97 |
-
res["url_suffix"] = (
|
98 |
-
video_data.get("navigationEndpoint", {})
|
99 |
-
.get("commandMetadata", {})
|
100 |
-
.get("webCommandMetadata", {})
|
101 |
-
.get("url", None)
|
102 |
-
)
|
103 |
-
results.append(res)
|
104 |
-
return results
|
105 |
-
|
106 |
-
def to_dict(self, clear_cache=True):
|
107 |
-
result = self.videos
|
108 |
-
if clear_cache:
|
109 |
-
self.videos = ""
|
110 |
-
return result
|
111 |
-
|
112 |
-
def to_json(self, clear_cache=True):
|
113 |
-
result = json.dumps({"videos": self.videos})
|
114 |
-
if clear_cache:
|
115 |
-
self.videos = ""
|
116 |
-
return result
|
117 |
-
|
118 |
|
119 |
# Gets yt result of given query.
|
120 |
-
async def song_search(query, max_results=1):
|
121 |
-
try:
|
122 |
-
results = json.loads(GOJO_YTS(query, max_results=max_results).to_json())
|
123 |
-
except KeyError:
|
124 |
-
return
|
125 |
yt_dict = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
nums = 1
|
128 |
-
for i in results["
|
129 |
durr = i['duration'].split(":")
|
130 |
if len(durr) == 3:
|
131 |
hour_to_sec = int(durr[0])*60*60
|
@@ -136,12 +77,15 @@ async def song_search(query, max_results=1):
|
|
136 |
total = minutes_to_sec + int(durr[1])
|
137 |
if not (total > 600):
|
138 |
dict_form = {
|
139 |
-
"link":
|
140 |
-
"title": i[
|
141 |
-
"views": i[
|
142 |
-
"channel": i[
|
143 |
-
"duration": i['duration'],
|
144 |
-
"
|
|
|
|
|
|
|
145 |
}
|
146 |
yt_dict.update({nums: dict_form})
|
147 |
nums += 1
|
@@ -149,7 +93,7 @@ async def song_search(query, max_results=1):
|
|
149 |
pass
|
150 |
return yt_dict
|
151 |
|
152 |
-
song_opts = {
|
153 |
"format": "bestaudio",
|
154 |
"addmetadata": True,
|
155 |
"key": "FFmpegMetadata",
|
@@ -186,67 +130,76 @@ video_opts = {
|
|
186 |
"outtmpl": "%(id)s.mp4",
|
187 |
"logtostderr": False,
|
188 |
"quiet": True,
|
189 |
-
}
|
190 |
|
191 |
|
192 |
|
193 |
async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str):
|
194 |
if type_ == "a":
|
195 |
-
opts = song_opts
|
196 |
video = False
|
197 |
song = True
|
198 |
elif type_ == "v":
|
199 |
-
opts = video_opts
|
200 |
video = True
|
201 |
song = False
|
202 |
-
ydl = yt_dlp.YoutubeDL(opts)
|
203 |
-
|
204 |
-
|
205 |
-
else:
|
206 |
-
dicti = await song_search(query, 1)
|
207 |
-
if not dicti:
|
208 |
-
await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
|
209 |
-
try:
|
210 |
-
query = dicti[1]['link']
|
211 |
-
except KeyError:
|
212 |
-
z = "KeyError"
|
213 |
-
return z
|
214 |
-
FILE = ydl.extract_info(query,download=video)
|
215 |
-
if int(FILE['duration']) > 600:
|
216 |
await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
url = query
|
223 |
-
|
224 |
-
|
225 |
-
f_path = f"{f_down}.mp3"
|
226 |
-
thumb = f"{f_down}.webp"
|
227 |
-
ydl.download([query])
|
228 |
-
elif video:
|
229 |
-
f_path = open(f"{FILE['id']}.mp4","rb")
|
230 |
cap = f"""
|
231 |
-
|
232 |
-
|
|
|
|
|
233 |
"""
|
234 |
kb = IKM(
|
235 |
[
|
236 |
[
|
237 |
-
IKB(f"✘ {uploader.capitalize()} ✘",url=f"{up_url}")
|
|
|
|
|
238 |
IKB(f"✘ Youtube url ✘", url=f"{url}")
|
239 |
]
|
240 |
]
|
241 |
)
|
242 |
-
if
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
await m.reply_audio(
|
248 |
os.remove(f_path)
|
|
|
249 |
os.remove(thumb)
|
250 |
return
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import json
|
2 |
import os
|
3 |
+
from traceback import format_exc
|
4 |
from urllib import parse
|
5 |
|
|
|
6 |
from pyrogram.types import InlineKeyboardButton as IKB
|
7 |
from pyrogram.types import InlineKeyboardMarkup as IKM
|
8 |
from pyrogram.types import Message
|
9 |
+
# import yt_dlp
|
10 |
+
from pytube import YouTube
|
11 |
+
from youtubesearchpython.__future__ import Video, VideosSearch
|
12 |
|
13 |
+
from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo
|
14 |
from Powers.utils.http_helper import *
|
15 |
|
16 |
|
|
|
25 |
size = file.audio.file_size/1024
|
26 |
elif file.sticker:
|
27 |
size = file.sticker.file_size/1024
|
28 |
+
elif file.animation:
|
29 |
+
size = file.animation.file_size/1024
|
30 |
+
elif file.voice:
|
31 |
+
size = file.voice.file_size/1024
|
32 |
+
elif file.video_note:
|
33 |
+
size = file.video_note.file_size/1024
|
34 |
|
35 |
if size <= 1024:
|
36 |
return f"{round(size)} kb"
|
|
|
43 |
return f"{round(size)} gb"
|
44 |
|
45 |
|
46 |
+
def get_duration_in_sec(dur: str):
|
47 |
+
duration = dur.split(":")
|
48 |
+
if len(duration) == 2:
|
49 |
+
dur = (int(duration[0]) * 60) + int(duration[1])
|
50 |
+
else:
|
51 |
+
dur = int(duration[0])
|
52 |
+
return dur
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
# Gets yt result of given query.
|
55 |
+
async def song_search(query, is_direct, max_results=1):
|
|
|
|
|
|
|
|
|
56 |
yt_dict = {}
|
57 |
+
try:
|
58 |
+
if is_direct:
|
59 |
+
vid = Video.getInfo(query)
|
60 |
+
query = vid["title"]
|
61 |
+
else:
|
62 |
+
query = query
|
63 |
+
videos = VideosSearch(query,max_results)
|
64 |
+
results = await videos.next()
|
65 |
+
except Exception as e:
|
66 |
+
print(e)
|
67 |
|
68 |
nums = 1
|
69 |
+
for i in results["result"]:
|
70 |
durr = i['duration'].split(":")
|
71 |
if len(durr) == 3:
|
72 |
hour_to_sec = int(durr[0])*60*60
|
|
|
77 |
total = minutes_to_sec + int(durr[1])
|
78 |
if not (total > 600):
|
79 |
dict_form = {
|
80 |
+
"link": i["link"],
|
81 |
+
"title": i["title"],
|
82 |
+
"views": i["viewCount"]["short"],
|
83 |
+
"channel": i["channel"]["link"],
|
84 |
+
"duration": i["accessibility"]['duration'],
|
85 |
+
"DURATION": i["duration"],
|
86 |
+
"thumbnail": i["richThumbnail"]["url"],
|
87 |
+
"published": i["publishedTime"],
|
88 |
+
"uploader": i ["channel"]["name"]
|
89 |
}
|
90 |
yt_dict.update({nums: dict_form})
|
91 |
nums += 1
|
|
|
93 |
pass
|
94 |
return yt_dict
|
95 |
|
96 |
+
"""song_opts = {
|
97 |
"format": "bestaudio",
|
98 |
"addmetadata": True,
|
99 |
"key": "FFmpegMetadata",
|
|
|
130 |
"outtmpl": "%(id)s.mp4",
|
131 |
"logtostderr": False,
|
132 |
"quiet": True,
|
133 |
+
}"""
|
134 |
|
135 |
|
136 |
|
137 |
async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str):
|
138 |
if type_ == "a":
|
139 |
+
# opts = song_opts
|
140 |
video = False
|
141 |
song = True
|
142 |
elif type_ == "v":
|
143 |
+
# opts = video_opts
|
144 |
video = True
|
145 |
song = False
|
146 |
+
# ydl = yt_dlp.YoutubeDL(opts)
|
147 |
+
dicti = await song_search(query, is_direct,1)
|
148 |
+
if not dicti and type(dicti) != str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
|
150 |
+
elif type(dicti) == str:
|
151 |
+
await m.reply_text(dicti)
|
152 |
+
return
|
153 |
+
try:
|
154 |
+
query = dicti[1]['link']
|
155 |
+
except KeyError:
|
156 |
+
return
|
157 |
+
yt = YouTube(query)
|
158 |
+
dicti = dicti[1]
|
159 |
+
f_name = dicti["title"]
|
160 |
+
views = dicti["views"]
|
161 |
+
up_url = dicti["channel"]
|
162 |
+
uploader = dicti["uploader"]
|
163 |
+
dura = dicti["duration"]
|
164 |
+
thumb = dicti["thumbnail"]
|
165 |
+
vid_dur = get_duration_in_sec(dicti["DURATION"])
|
166 |
+
published_on = dicti["published"]
|
167 |
+
thumb_ = await c.send_photo(-1001586309125,thumb)
|
168 |
+
# FILE = ydl.extract_info(query,download=video)
|
169 |
url = query
|
170 |
+
thumb = await thumb_.download()
|
171 |
+
await thumb_.delete()
|
|
|
|
|
|
|
|
|
|
|
172 |
cap = f"""
|
173 |
+
⤷ Name: `{f_name}`
|
174 |
+
⤷ Duration: `{dura}`
|
175 |
+
⤷ Views: `{views}`
|
176 |
+
⤷ Published: `{published_on}`
|
177 |
"""
|
178 |
kb = IKM(
|
179 |
[
|
180 |
[
|
181 |
+
IKB(f"✘ {uploader.capitalize()} ✘",url=f"{up_url}")
|
182 |
+
],
|
183 |
+
[
|
184 |
IKB(f"✘ Youtube url ✘", url=f"{url}")
|
185 |
]
|
186 |
]
|
187 |
)
|
188 |
+
if song:
|
189 |
+
audio_stream= yt.streams.filter(only_audio=True).first()
|
190 |
+
f_path = audio_stream.download("/youtube_downloads")
|
191 |
+
file_path = f"/youtube_downloads/{f_name.strip()}.mp3"
|
192 |
+
os.rename(f_path,file_path)
|
193 |
+
await m.reply_audio(file_path,caption=cap,reply_markup=kb,duration=vid_dur,thumb=thumb,title=f_name)
|
194 |
os.remove(f_path)
|
195 |
+
os.remove(file_path)
|
196 |
os.remove(thumb)
|
197 |
return
|
198 |
+
elif video:
|
199 |
+
video_stream = yt.streams.get_highest_resolution()
|
200 |
+
video_stream.download("/youtube_downloads",f"{f_name}.mp4")
|
201 |
+
file_path = f"/youtube_downloads/{f_name}.mp4"
|
202 |
+
await m.reply_video(file_path,caption=cap,reply_markup=kb,duration=vid_dur,thumb=thumb)
|
203 |
+
os.remove(file_path)
|
204 |
+
os.remove(thumb)
|
205 |
+
return
|
Powers/vars.py
CHANGED
@@ -15,7 +15,7 @@ class Config:
|
|
15 |
API_ID = int(config("API_ID", default="123"))
|
16 |
API_HASH = config("API_HASH", default=None)
|
17 |
OWNER_ID = int(config("OWNER_ID", default=1344569458))
|
18 |
-
MESSAGE_DUMP = int(config("MESSAGE_DUMP"
|
19 |
DEV_USERS = [
|
20 |
int(i)
|
21 |
for i in config(
|
@@ -64,7 +64,7 @@ class Development:
|
|
64 |
API_ID = 12345 # Your APP_ID from Telegram
|
65 |
API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
|
66 |
OWNER_ID = 1344569458 # Your telegram user id defult to mine
|
67 |
-
MESSAGE_DUMP = -
|
68 |
DEV_USERS = []
|
69 |
SUDO_USERS = []
|
70 |
WHITELIST_USERS = []
|
|
|
15 |
API_ID = int(config("API_ID", default="123"))
|
16 |
API_HASH = config("API_HASH", default=None)
|
17 |
OWNER_ID = int(config("OWNER_ID", default=1344569458))
|
18 |
+
MESSAGE_DUMP = int(config("MESSAGE_DUMP"))
|
19 |
DEV_USERS = [
|
20 |
int(i)
|
21 |
for i in config(
|
|
|
64 |
API_ID = 12345 # Your APP_ID from Telegram
|
65 |
API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
|
66 |
OWNER_ID = 1344569458 # Your telegram user id defult to mine
|
67 |
+
MESSAGE_DUMP = -100845454887 # Your Private Group ID for logs
|
68 |
DEV_USERS = []
|
69 |
SUDO_USERS = []
|
70 |
WHITELIST_USERS = []
|
README.md
CHANGED
@@ -172,6 +172,8 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
|
|
172 |
`API_HASH` You can get your api hash [here](my.telegram.org)
|
173 |
|
174 |
`DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
|
|
|
|
|
175 |
</details>
|
176 |
|
177 |
|
@@ -201,8 +203,6 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
|
|
201 |
|
202 |
`SUPPORT_GROUP`: Your Telegram support group chat username that users can contact in case of a problem.
|
203 |
|
204 |
-
`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`.
|
205 |
-
|
206 |
`PREFIX_HANDLER`: Something like '/' to execute commands.
|
207 |
|
208 |
`SUPPORT_CHANNEL`: Your Telegram support channel username where users can see bot updates.
|
|
|
172 |
`API_HASH` You can get your api hash [here](my.telegram.org)
|
173 |
|
174 |
`DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
|
175 |
+
|
176 |
+
`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`.
|
177 |
</details>
|
178 |
|
179 |
|
|
|
203 |
|
204 |
`SUPPORT_GROUP`: Your Telegram support group chat username that users can contact in case of a problem.
|
205 |
|
|
|
|
|
206 |
`PREFIX_HANDLER`: Something like '/' to execute commands.
|
207 |
|
208 |
`SUPPORT_CHANNEL`: Your Telegram support channel username where users can see bot updates.
|
Version/version 2.1.2.md
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# V 2.1.2
|
2 |
+
### Changes made:
|
3 |
+
- Fixed few bugs
|
4 |
+
- Improve the stability of the bot
|
5 |
+
- Few improvements
|
6 |
+
- Now you can kang sticker by replying to videos or animations
|
7 |
+
- Improved youtube support.
|
8 |
+
|
9 |
+
## Report issues [here](https://github.com/Gojo-Bots/Gojo_Satoru/issues/new/choose) if find any.
|
10 |
+
|
11 |
+
## Give ideas [here](https://github.com/Gojo-Bots/Gojo_Satoru/discussions/new?category=ideas) for next update.
|
12 |
+
|
13 |
+
## Trying our best to give the best
|
14 |
+
|
15 |
+
## Regards 🧑💻: [Captain Ezio](https://github.com/iamgojoof6eyes)
|
requirements.txt
CHANGED
@@ -4,6 +4,7 @@ apscheduler==3.10.4
|
|
4 |
asyncio==3.4.3
|
5 |
beautifulsoup4==4.12.2; python_full_version >= "3.6"
|
6 |
cachetools==5.2.0; python_version >= "3.7" and python_version < "4.0"
|
|
|
7 |
certifi==2023.7.22; python_version >= "3.7" and python_version < "4"
|
8 |
charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4" and python_full_version >= "3.6.0"
|
9 |
dnspython==2.2.1; python_version >= "3.6" and python_version < "4.0"
|
@@ -15,12 +16,13 @@ pillow == 10.0.0
|
|
15 |
prettyconf==2.2.1
|
16 |
pyaes==1.6.1; python_version >= "3.6" and python_version < "4.0"
|
17 |
pymongo==4.5.0
|
18 |
-
pyroaddon==1.0.6
|
19 |
pyrogram==2.0.106; python_version >= "3.8"
|
20 |
pysocks==1.7.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
|
21 |
python-dateutil==2.8.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0")
|
|
|
22 |
pytz==2023.3
|
23 |
pyyaml==6.0.1; python_version >= "3.6"
|
|
|
24 |
regex==2023.8.8; python_version >= "3.6"
|
25 |
requests==2.31.0
|
26 |
rfc3986==1.5.0; python_version >= "3.7"
|
@@ -35,4 +37,5 @@ ujson==5.8.0; python_version >= "3.7"
|
|
35 |
urllib3==1.26.11; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
|
36 |
uvloop==0.17.0
|
37 |
wikipedia==1.4.0
|
38 |
-
|
|
|
|
4 |
asyncio==3.4.3
|
5 |
beautifulsoup4==4.12.2; python_full_version >= "3.6"
|
6 |
cachetools==5.2.0; python_version >= "3.7" and python_version < "4.0"
|
7 |
+
captcha==0.5.0
|
8 |
certifi==2023.7.22; python_version >= "3.7" and python_version < "4"
|
9 |
charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4" and python_full_version >= "3.6.0"
|
10 |
dnspython==2.2.1; python_version >= "3.6" and python_version < "4.0"
|
|
|
16 |
prettyconf==2.2.1
|
17 |
pyaes==1.6.1; python_version >= "3.6" and python_version < "4.0"
|
18 |
pymongo==4.5.0
|
|
|
19 |
pyrogram==2.0.106; python_version >= "3.8"
|
20 |
pysocks==1.7.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
|
21 |
python-dateutil==2.8.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0")
|
22 |
+
pytube==15.0.0
|
23 |
pytz==2023.3
|
24 |
pyyaml==6.0.1; python_version >= "3.6"
|
25 |
+
qrcode==7.4.2
|
26 |
regex==2023.8.8; python_version >= "3.6"
|
27 |
requests==2.31.0
|
28 |
rfc3986==1.5.0; python_version >= "3.7"
|
|
|
37 |
urllib3==1.26.11; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
|
38 |
uvloop==0.17.0
|
39 |
wikipedia==1.4.0
|
40 |
+
youtube-search-python==1.6.6
|
41 |
+
yt-dlp@git+https://github.com/HellBoy-OP/yt-dp-fork.git@af1fd12f675220df6793fc019dff320bc76e8080
|