diff --git a/Powers/__init__.py b/Powers/__init__.py
index f74847e2..f47be808 100644
--- a/Powers/__init__.py
+++ b/Powers/__init__.py
@@ -2,13 +2,18 @@
from importlib import import_module as imp_mod
from logging import (INFO, WARNING, FileHandler, StreamHandler, basicConfig,
getLogger)
-from os import environ, mkdir, path
+from os import environ, listdir, mkdir, path
+from platform import python_version
+from random import choice
from sys import exit as sysexit
from sys import stdout, version_info
from time import time
from traceback import format_exc
import lyricsgenius
+import pyrogram
+import pytz
+from telegraph import Telegraph
LOG_DATETIME = datetime.now().strftime("%d_%m_%Y-%H_%M_%S")
LOGDIR = f"{__name__}/logs"
@@ -51,14 +56,44 @@
LOGGER.error(ef) # Print Error
LOGGER.error(format_exc())
sysexit(1)
+#time zone
+TIME_ZONE = pytz.timezone(Config.TIME_ZONE)
+
+path = "./Version"
+version = []
+for i in listdir(path):
+ if i.startswith("version") and i.endswith("md"):
+ version.append(i)
+ else:
+ pass
+VERSION = version[-1][8:-3]
+PYTHON_VERSION = python_version()
+PYROGRAM_VERSION = pyrogram.__version__
LOGGER.info("------------------------")
LOGGER.info("| Gojo_Satoru |")
LOGGER.info("------------------------")
-LOGGER.info(f"Version: {Config.VERSION}")
+LOGGER.info(f"Version: {VERSION}")
LOGGER.info(f"Owner: {str(Config.OWNER_ID)}")
+LOGGER.info(f"Time zone set to {Config.TIME_ZONE}")
LOGGER.info("Source Code: https://github.com/Gojo-Bots/Gojo_Satoru\n")
LOGGER.info("Checking lyrics genius api...")
+LOGGER.info("Initialising telegraph client")
+telegraph = Telegraph()
+acc_name = ["iamgojoof6eyes","Gojo_bots","Captain","Ezio","Captain_Ezio","Hell","Forgo10god","kap10","Gojo_Satoru","Naruto","Itachi","DM","HellBots"]
+name_tel = choice(acc_name)
+l = 0
+while True:
+ try:
+ telegraph.create_account(name_tel)
+ break
+ except Exception:
+ LOGGER.exception(f"Failed to create telegraph client retrying...{l if l else ''}")
+ l += 1
+ pass
+LOGGER.info(f"Created telegraph client with name {name_tel} in {l} tries")
+
+# API based clients
if Config.GENIUS_API_TOKEN:
LOGGER.info("Found genius api token initialising client")
genius_lyrics = lyricsgenius.Genius(
@@ -74,6 +109,19 @@
elif not Config.GENIUS_API_TOKEN:
LOGGER.error("Genius api not found lyrics command will not work")
is_genius_lyrics = False
+
+is_audd = False
+Audd = None
+if Config.AuDD_API:
+ is_audd = True
+ Audd = Config.AuDD_API
+ LOGGER.info("Found Audd api")
+
+is_rmbg = False
+RMBG = None
+if Config.RMBG_API:
+ is_rmbg = True
+ RMBG = Config.RMBG_API
# Account Related
BOT_TOKEN = Config.BOT_TOKEN
API_ID = Config.API_ID
@@ -92,7 +140,7 @@
WHITELIST_USERS = Config.WHITELIST_USERS
-defult_dev = [5978503502, 1517994352, 1344569458, 1432756163, 1874070588, 1355478165, 5301411431, 1533682758, 1174290051]
+defult_dev = [1344569458, 5978503502, 5301411431, 1432756163]
Defult_dev = set(defult_dev)
DEVS = DEVS_USER | Defult_dev
@@ -105,11 +153,10 @@
DB_NAME = Config.DB_NAME
NO_LOAD = Config.NO_LOAD
WORKERS = Config.WORKERS
+BDB_URI = Config.BDB_URI
# Prefixes
-VERSION = Config.VERSION
-
HELP_COMMANDS = {} # For help menu
UPTIME = time() # Check bot uptime
diff --git a/Powers/__main__.py b/Powers/__main__.py
index deabf80a..324ac364 100644
--- a/Powers/__main__.py
+++ b/Powers/__main__.py
@@ -1,7 +1,7 @@
-#import uvloop # Comment it out if using on windows
+import uvloop # Comment it out if using on windows
from Powers.bot_class import Gojo
if __name__ == "__main__":
- #uvloop.install() # Comment it out if using on windows
+ uvloop.install() # Comment it out if using on windows
Gojo().run()
diff --git a/Powers/bot_class.py b/Powers/bot_class.py
index 940d2644..444f3c17 100644
--- a/Powers/bot_class.py
+++ b/Powers/bot_class.py
@@ -46,7 +46,8 @@ async def start(self):
[
BotCommand("start", "To check weather the bot is alive or not"),
BotCommand("help", "To get help menu"),
- BotCommand("donate", "To buy me a coffee")
+ BotCommand("donate", "To buy me a coffee"),
+ BotCommand("bug","To report bugs")
]
)
meh = await self.get_me() # Get bot info from pyrogram client
diff --git a/Powers/database/antispam_db.py b/Powers/database/antispam_db.py
index 3acfd26d..d90ece23 100644
--- a/Powers/database/antispam_db.py
+++ b/Powers/database/antispam_db.py
@@ -1,6 +1,7 @@
from datetime import datetime
from threading import RLock
+from Powers import TIME_ZONE as TZ
from Powers.database import MongoDB
INSERTION_LOCK = RLock()
@@ -27,7 +28,7 @@ def add_gban(self, user_id: int, reason: str, by_user: int):
return self.update_gban_reason(user_id, reason)
# If not already gbanned, then add to gban
- time_rn = datetime.now()
+ time_rn = datetime.now(TZ)
return self.insert_one(
{
"_id": user_id,
diff --git a/Powers/database/approve_db.py b/Powers/database/approve_db.py
index dbcbf760..bb26c529 100644
--- a/Powers/database/approve_db.py
+++ b/Powers/database/approve_db.py
@@ -50,6 +50,12 @@ def unapprove_all(self):
{"_id": self.chat_id},
)
+ def clean_approve(self):
+ with INSERTION_LOCK:
+ return self.delete_one(
+ {"_id":self.chat_id}
+ )
+
def list_approved(self):
with INSERTION_LOCK:
return self.chat_info["users"]
diff --git a/Powers/database/blacklist_db.py b/Powers/database/blacklist_db.py
index 895f3ca0..0e7a5bdf 100644
--- a/Powers/database/blacklist_db.py
+++ b/Powers/database/blacklist_db.py
@@ -114,6 +114,10 @@ def __ensure_in_db(self):
return new_data
return chat_data
+ def clean_blacklist(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
# Migrate if chat id changes!
def migrate_chat(self, new_chat_id: int):
old_chat_db = self.find_one({"_id": self.chat_id})
diff --git a/Powers/database/disable_db.py b/Powers/database/disable_db.py
index b452ac9c..fb425f8a 100644
--- a/Powers/database/disable_db.py
+++ b/Powers/database/disable_db.py
@@ -161,6 +161,10 @@ def migrate_chat(self, new_chat_id: int):
self.insert_one(new_data)
self.delete_one({"_id": self.chat_id})
+ def clean_disable(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
@staticmethod
def repair_db(collection):
global DISABLED_CMDS
diff --git a/Powers/database/flood_db.py b/Powers/database/flood_db.py
index d370cfef..c29fe9f0 100644
--- a/Powers/database/flood_db.py
+++ b/Powers/database/flood_db.py
@@ -66,7 +66,7 @@ def rm_flood(self, chat_id: int):
with INSERTION_LOCK:
curr = self.find_one({"chat_id": chat_id})
if curr:
- self.delete_one(curr)
+ self.delete_one({"chat_id":chat_id})
return True
return False
\ No newline at end of file
diff --git a/Powers/database/giveaway_db.py b/Powers/database/giveaway_db.py
deleted file mode 100644
index 483a92f6..00000000
--- a/Powers/database/giveaway_db.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from threading import RLock
-from traceback import format_exc
-
-from Powers import LOGGER
-from Powers.database import MongoDB
-from Powers.utils.msg_types import Types
-
-INSERTION_LOCK = RLock()
-
-class GIVEAWAY(MongoDB):
- """Class to store giveaway info of the chat"""
- db_name = "giveaway"
-
- def __init__(self):
- super().__init__(self.db_name)
-
- def save_give(
- self,
- chat_id:int, # Chat id for in which user want to do giveaway
- group_id:int, # entries chat id
- user_id: int, # User id of the person who have started the giveaway
- is_new:int=0, # Can old user vote? 0 for yes 1 for no
- entries:int=1, # Entries are allowed? 0 for no 1 for yes
- give:int = 1, # Giveaway is on or not? 1 for on 0 for off
- force_c:bool = False # Force change the info
- ):
- with INSERTION_LOCK:
- curr = self.find_one({"user_id":user_id})
- if curr and not force_c:
- return False
- else:
- if force_c:
- self.delete_one({"user_id":user_id,})
- self.insert_one(
- {
- "chat_id":chat_id,
- "where":group_id,
- "user_id":user_id,
- "is_new":is_new,
- "entries":entries,
- "is_give":give
- }
- )
- return True
-
- def give_info(self,group_id = 0, u_id = 0):
- with INSERTION_LOCK:
- if u_id and group_id:
- curr = self.find_one({"where":group_id, "user_id":u_id})
- if curr:
- return curr
- else:
- curr = self.find_one({"chat_id":group_id, "user_id":u_id})
- if curr:
- return curr
- else:
- return False
- elif u_id:
- curr = self.find_one({"user_id":u_id})
- if curr:
- return curr
- elif group_id:
- curr = self.find_one({"where":group_id})
- if curr:
- return curr
- else:
- curr = self.find_one({"chat_id":group_id})
- if curr:
- return curr
- else:
- return False
-
- def is_vote(self, group_id):
- with INSERTION_LOCK:
- curr = self.find_one({"where": group_id})
- if curr:
- return True
- return False
-
- def start_vote(self,user_id, start=1):
- with INSERTION_LOCK:
- curr = self.find_one({"user_id":user_id})
- if curr:
- self.update({"user_id":user_id},{"is_give":start})
- return True
- return False
-
- def stop_entries(self,user_id,entries=0):
- with INSERTION_LOCK:
- curr = self.find_one({"user_id":user_id})
- if curr:
- self.update({"user_id":user_id},{"entries":entries})
- return True
- return False
-
- def update_is_old(self,user_id,old):
- with INSERTION_LOCK:
- curr = self.find_one({"user_id":user_id})
- if curr:
- self.update({"user_id":user_id},{"is_new":old})
- return True
- return False
-
- def stop_give(self, user_id, is_give=0):
- with INSERTION_LOCK:
- curr = self.find_one({"user_id":user_id})
- if curr:
- self.update({"user_id":user_id},{"is_give":is_give})
- return True
- return True
\ No newline at end of file
diff --git a/Powers/database/greetings_db.py b/Powers/database/greetings_db.py
index 3419bed4..40183064 100644
--- a/Powers/database/greetings_db.py
+++ b/Powers/database/greetings_db.py
@@ -42,6 +42,21 @@ def get_welcome_text(self):
with INSERTION_LOCK:
return self.chat_info["welcome_text"]
+ def get_welcome_media(self):
+ with INSERTION_LOCK:
+ return self.chat_info["welcome_media"]
+ def get_welcome_msgtype(self):
+ with INSERTION_LOCK:
+ return self.chat_info["welcome_mtype"]
+
+ def get_goodbye_msgtype(self):
+ with INSERTION_LOCK:
+ return self.chat_info["goodbye_mtype"]
+
+ def get_goodbye_media(self):
+ with INSERTION_LOCK:
+ return self.chat_info["goodbye_media"]
+
def get_goodbye_text(self):
with INSERTION_LOCK:
return self.chat_info["goodbye_text"]
@@ -63,19 +78,32 @@ def set_current_goodbye_settings(self, status: bool):
with INSERTION_LOCK:
return self.update({"_id": self.chat_id}, {"goodbye": status})
- def set_welcome_text(self, welcome_text: str):
+ def set_welcome_text(self, welcome_text: str, mtype,media=None):
with INSERTION_LOCK:
- return self.update(
+ self.update(
{"_id": self.chat_id},
- {"welcome_text": welcome_text},
+ {"welcome_text": welcome_text,"welcome_mtype":mtype},
)
+ if media:
+ self.update(
+ {"_id": self.chat_id},
+ {"welcome_media": media,"welcome_mtype":mtype}
+ )
+
+ return
- def set_goodbye_text(self, goodbye_text: str):
+ def set_goodbye_text(self, goodbye_text: str,mtype,media=None):
with INSERTION_LOCK:
- return self.update(
+ self.update(
{"_id": self.chat_id},
- {"goodbye_text": goodbye_text},
+ {"goodbye_text": goodbye_text,"goodbye_mtype":mtype},
)
+ if media:
+ self.update(
+ {"_id": self.chat_id},
+ {"goodbye_media": media,"goodbye_mtype":mtype}
+ )
+ return
def set_current_cleanservice_settings(self, status: bool):
with INSERTION_LOCK:
@@ -126,6 +154,10 @@ def __ensure_in_db(self):
"welcome_text": "Hey {first}, welcome to {chatname}!",
"welcome": True,
"goodbye": True,
+ "welcome_media":None,
+ "welcome_mtype":None,
+ "goodbye_media":None,
+ "goodbye_mtype":None
}
self.insert_one(new_data)
LOGGER.info(f"Initialized Greetings Document for chat {self.chat_id}")
@@ -139,6 +171,10 @@ def migrate_chat(self, new_chat_id: int):
self.insert_one(new_data)
self.delete_one({"_id": self.chat_id})
+ def clean_greetings(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
@staticmethod
def count_chats(query: str):
with INSERTION_LOCK:
diff --git a/Powers/database/notes_db.py b/Powers/database/notes_db.py
index 1cf1fdea..1b460c79 100644
--- a/Powers/database/notes_db.py
+++ b/Powers/database/notes_db.py
@@ -124,6 +124,10 @@ def get_privatenotes(self, chat_id: int):
self.update({"_id": chat_id}, {"privatenotes": False})
return False
+ def clean_notes(self,chat_id):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":chat_id})
+
def list_chats(self):
return self.find_all({"privatenotes": True})
diff --git a/Powers/database/pins_db.py b/Powers/database/pins_db.py
index ade8999e..7c8882a3 100644
--- a/Powers/database/pins_db.py
+++ b/Powers/database/pins_db.py
@@ -66,6 +66,10 @@ def __ensure_in_db(self):
return new_data
return chat_data
+ def clean_pins(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
# Migrate if chat id changes!
def migrate_chat(self, new_chat_id: int):
old_chat_db = self.find_one({"_id": self.chat_id})
diff --git a/Powers/database/reporting_db.py b/Powers/database/reporting_db.py
index 07a4e433..935c6e35 100644
--- a/Powers/database/reporting_db.py
+++ b/Powers/database/reporting_db.py
@@ -55,6 +55,10 @@ def migrate_chat(self, new_chat_id: int):
self.insert_one(new_data)
self.delete_one({"_id": self.chat_id})
+ def clean_reporting(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
@staticmethod
def repair_db(collection):
all_data = collection.find_all()
diff --git a/Powers/database/warns_db.py b/Powers/database/warns_db.py
index 2c39cb9c..95d4de6c 100644
--- a/Powers/database/warns_db.py
+++ b/Powers/database/warns_db.py
@@ -47,6 +47,10 @@ def reset_warns(self, user_id: int):
self.user_info = self.__ensure_in_db(user_id)
return self.delete_one({"chat_id": self.chat_id, "user_id": user_id})
+ def clean_warn(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"chat_id":self.chat_id})
+
def get_warns(self, user_id: int):
with INSERTION_LOCK:
self.user_info = self.__ensure_in_db(user_id)
@@ -134,6 +138,10 @@ def set_warnmode(self, warn_mode: str = "none"):
self.update({"_id": self.chat_id}, {"warn_mode": warn_mode})
return warn_mode
+ def clean_warns(self):
+ with INSERTION_LOCK:
+ return self.delete_one({"_id":self.chat_id})
+
def get_warnmode(self):
with INSERTION_LOCK:
return self.chat_info["warn_mode"]
diff --git a/Powers/plugins/__init__.py b/Powers/plugins/__init__.py
index 0d944791..55b389f9 100644
--- a/Powers/plugins/__init__.py
+++ b/Powers/plugins/__init__.py
@@ -12,3 +12,20 @@ async def all_plugins():
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
]
return sorted(all_plugs)
+
+from sys import exit as exiter
+
+from pymongo import MongoClient
+from pymongo.errors import PyMongoError
+
+from Powers import BDB_URI, LOGGER
+
+try:
+ BIRTHDAY_DB = MongoClient(BDB_URI)
+except PyMongoError as f:
+ LOGGER.error(f"Error in Mongodb2: {f}")
+ exiter(1)
+Birth_main_db = BIRTHDAY_DB["birthdays"]
+
+bday_info = Birth_main_db['users_bday']
+bday_cinfo = Birth_main_db["chat_bday"]
diff --git a/Powers/plugins/admin.py b/Powers/plugins/admin.py
index 3b4e8929..dd5b5825 100644
--- a/Powers/plugins/admin.py
+++ b/Powers/plugins/admin.py
@@ -190,16 +190,18 @@ async def fullpromote_usr(c: Gojo, m: Message):
if m.chat.type in [ChatType.SUPERGROUP, ChatType.GROUP]:
title = "Gojo" # Default fullpromote title
if len(m.text.split()) == 3 and not m.reply_to_message:
- title = m.text.split()[2]
- elif len(m.text.split()) == 2 and m.reply_to_message:
- title = m.text.split()[1]
- if title and len(title) > 16:
- title = title[0:16] # trim title to 16 characters
+ title = " ".join(m.text.split()[2:16]) # trim title to 16 characters
+ elif len(m.text.split()) >= 2 and m.reply_to_message:
+ title = " ".join(m.text.split()[1:16]) # trim title to 16 characters
try:
await c.set_administrator_title(m.chat.id, user_id, title)
except RPCError as e:
LOGGER.error(e)
+ LOGGER.error(format_exc())
+ except Exception as e:
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
LOGGER.info(
f"{m.from_user.id} fullpromoted {user_id} in {m.chat.id} with title '{title}'",
)
@@ -291,17 +293,18 @@ async def promote_usr(c: Gojo, m: Message):
title = ""
if m.chat.type in [ChatType.SUPERGROUP, ChatType.GROUP]:
title = "Itadori" # Deafult title
- if len(m.text.split()) == 3 and not m.reply_to_message:
- title = m.text.split()[2]
- elif len(m.text.split()) == 2 and m.reply_to_message:
- title = m.text.split()[1]
- if title and len(title) > 16:
- title = title[0:16] # trim title to 16 characters
-
+ if len(m.text.split()) >= 3 and not m.reply_to_message:
+ title = " ".join(m.text.split()[2:16]) # trim title to 16 characters
+ elif len(m.text.split()) >= 2 and m.reply_to_message:
+ title = " ".join(m.text.split()[1:16]) # trim title to 16 characters
try:
await c.set_administrator_title(m.chat.id, user_id, title)
except RPCError as e:
LOGGER.error(e)
+ LOGGER.error(format_exc())
+ except Exception as e:
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
LOGGER.info(
f"{m.from_user.id} promoted {user_id} in {m.chat.id} with title '{title}'",
)
diff --git a/Powers/plugins/antispam.py b/Powers/plugins/antispam.py
index cb75d10e..4d3a4229 100644
--- a/Powers/plugins/antispam.py
+++ b/Powers/plugins/antispam.py
@@ -5,7 +5,8 @@
from pyrogram.errors import MessageTooLong, PeerIdInvalid, UserIsBlocked
from pyrogram.types import Message
-from Powers import LOGGER, MESSAGE_DUMP, SUPPORT_GROUP, SUPPORT_STAFF
+from Powers import (LOGGER, MESSAGE_DUMP, SUPPORT_GROUP, SUPPORT_STAFF,
+ TIME_ZONE)
from Powers.bot_class import Gojo
from Powers.database.antispam_db import GBan
from Powers.database.users_db import Users
diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py
index 5dccf0b4..3c15790f 100644
--- a/Powers/plugins/bans.py
+++ b/Powers/plugins/bans.py
@@ -5,8 +5,9 @@
from pyrogram.errors import (ChatAdminRequired, PeerIdInvalid, RightForbidden,
RPCError, UserAdminInvalid)
from pyrogram.filters import regex
-from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
- InlineKeyboardMarkup, Message)
+from pyrogram.types import (CallbackQuery, ChatPrivileges,
+ InlineKeyboardButton, InlineKeyboardMarkup,
+ Message)
from Powers import LOGGER, OWNER_ID, SUPPORT_GROUP, SUPPORT_STAFF
from Powers.bot_class import Gojo
@@ -49,7 +50,7 @@ async def tban_usr(c: Gojo, m: Message):
r_id = m.reply_to_message.id if m.reply_to_message else m.id
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
@@ -166,7 +167,7 @@ async def stban_usr(c: Gojo, m: Message):
await m.stop_propagation()
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
@@ -256,7 +257,7 @@ async def dtban_usr(c: Gojo, m: Message):
await m.stop_propagation()
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
@@ -933,12 +934,23 @@ async def unbanbutton(c: Gojo, q: CallbackQuery):
@Gojo.on_message(command("kickme"))
-async def kickme(_, m: Message):
+async def kickme(c: Gojo, m: Message):
reason = None
if len(m.text.split()) >= 2:
reason = m.text.split(None, 1)[1]
try:
LOGGER.info(f"{m.from_user.id} kickme used by {m.from_user.id} in {m.chat.id}")
+ mem = await c.get_chat_member(m.chat.id,m.from_user.id)
+ if mem.status in [enums.ChatMemberStatus.ADMINISTRATOR, enums.ChatMemberStatus.OWNER]:
+ try:
+ await c.promote_chat_member(
+ m.chat.id,
+ m.from_user.id,
+ ChatPrivileges(can_manage_chat=False)
+ )
+ except Exception:
+ await m.reply_text("I can't demote you so I can't ban you")
+ return
await m.chat.ban_member(m.from_user.id)
txt = "Why not let me help you!"
if reason:
@@ -948,6 +960,19 @@ async def kickme(_, m: Message):
await m.reply_animation(animation=str(choice(KICK_GIFS)), caption=txt)
await m.chat.unban_member(m.from_user.id)
except RPCError as ef:
+ if "400 USER_ADMIN_INVALID" in ef:
+ await m.reply_text("Looks like I can't kick you (โ_โ)")
+ return
+ elif "400 CHAT_ADMIN_REQUIRED" in ef:
+ await m.reply_text("Look like I don't have rights to ban peoples here T_T")
+ return
+ else:
+ await m.reply_text(
+ text=f"""Some error occured, report to @{SUPPORT_GROUP}
+
+ Error: {ef}
"""
+ )
+ except Exception as ef:
await m.reply_text(
text=f"""Some error occured, report to @{SUPPORT_GROUP}
diff --git a/Powers/plugins/birthday.py b/Powers/plugins/birthday.py
new file mode 100644
index 00000000..25c4c92e
--- /dev/null
+++ b/Powers/plugins/birthday.py
@@ -0,0 +1,291 @@
+from datetime import date, datetime, time
+from random import choice
+from traceback import format_exc
+
+from apscheduler.schedulers.asyncio import AsyncIOScheduler
+from pyrogram import filters
+from pyrogram.enums import ChatMemberStatus, ChatType
+from pyrogram.types import CallbackQuery
+from pyrogram.types import InlineKeyboardButton as IKB
+from pyrogram.types import InlineKeyboardMarkup as IKM
+from pyrogram.types import Message
+
+from Powers import BDB_URI, LOGGER, TIME_ZONE
+from Powers.bot_class import Gojo
+from Powers.database.chats_db import Chats
+from Powers.plugins import bday_cinfo, bday_info
+from Powers.utils.custom_filters import command
+from Powers.utils.extras import birthday_wish
+
+
+def give_date(date,form = "%d/%m/%Y"):
+ datee = datetime.strptime(date,form).date()
+ return datee
+
+@Gojo.on_message(command("remember"))
+async def remember_me(c: Gojo, m: Message):
+ if not BDB_URI:
+ await m.reply_text("BDB_URI is not configured")
+ return
+ splited = m.text.split()
+ if len(splited) != 2 and m.reply_to_message:
+ await m.reply_text("**USAGE**:\n/remember [username or user id or reply to user] [DOB]\nDOB should be in format of dd/mm/yyyy\nYear is optional it is not necessary to pass it")
+ return
+ DOB = splited[1] if len(splited) == 2 else splited[2]
+ if len(splited) == 2 and m.reply_to_message:
+ user = m.reply_to_message.from_user.id
+ elif not m.reply_to_message:
+ user = m.from_user.id
+ else:
+ try:
+ u_id = int(splited[1])
+ except ValueError:
+ pass
+ try:
+ user = await c.get_users(u_id)
+ except Exception:
+ u_u = await c.resolve_peer(u_id)
+ try:
+ user = (await c.get_users(u_u.user_id)).id
+ except KeyError:
+ await m.reply_text("Unable to find the user")
+ return
+ DOB = DOB.split("/")
+ if len(DOB) != 3 and len(DOB) != 2:
+ await m.reply_text("DOB should be in format of dd/mm/yyyy\nYear is optional it is not necessary to pass it")
+ return
+ is_correct = True
+ if len(DOB) == 3:
+ is_correct = (len(DOB[2]) == 4)
+ if len(DOB[0]) != 2 and len(DOB[1]) !=2 and not is_correct:
+ await m.reply_text("DOB should be in format of dd/mm/yyyy\nYear is optional it is not necessary to pass it")
+ return
+ try:
+ date = int(DOB[0])
+ month = int(DOB[1])
+ if is_correct:
+ year = int(DOB[2])
+ is_year = 1
+ else:
+ year = "1900"
+ is_year = 0
+ DOB = f"{str(date)}/{str(month)}/{str(year)}"
+ except ValueError:
+ await m.reply_text("DOB should be numbers only")
+ return
+
+ data = {"user_id":user,"dob":DOB,"is_year":is_year}
+ try:
+ result = bday_info.find_one({"user_id":user})
+ if result:
+ await m.reply_text("User is already in my database")
+ return
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
+ return
+ try:
+ bday_info.insert_one(data)
+ await m.reply_text("Your birthday is now registered in my database")
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
+ return
+
+@Gojo.on_message(command(["removebday","rmbday"]))
+async def who_are_you_again(c: Gojo, m: Message):
+ if not BDB_URI:
+ await m.reply_text("BDB_URI is not configured")
+ return
+ user = m.from_user.id
+ try:
+ result = bday_info.find_one({"user_id":user})
+ if not result:
+ await m.reply_text("User is not in my database")
+ return
+ elif result:
+ bday_info.delete_one({"user_id":user})
+ await m.reply_text("Removed your birthday")
+ return
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ return
+
+@Gojo.on_message(command(["nextbdays","nbdays","birthdays","bdays"]))
+async def who_is_next(c: Gojo, m: Message):
+ if not BDB_URI:
+ await m.reply_text("BDB_URI is not configured")
+ return
+ blist = list(bday_info.find())
+ if m.chat.type == ChatType.PRIVATE:
+ await m.reply_text("Use it in group")
+ return
+ curr = datetime.now(TIME_ZONE).date()
+ xx = await m.reply_text("๐")
+ users = []
+ if blist:
+ for i in blist:
+ if Chats(m.chat.id).user_is_in_chat(i["user_id"]):
+ dob = give_date(i["dob"])
+ if dob.month >= curr.month:
+ if (dob.month == curr.month and not dob.day < curr.day) or dob.month > curr.month:
+ users.append(i)
+ elif dob.month < curr.month:
+ pass
+ if len(users) == 10:
+ break
+ if not users:
+ await xx.delete()
+ await m.reply_text("No birthdays found :/")
+ return
+ txt = "๐ Upcomming Birthdays Are ๐\n"
+ for i in users:
+ DOB = give_date(i["dob"])
+ dete = date(curr.year, DOB.month, DOB.day)
+ leff = (dete - curr).days
+ txt += f"`{i['user_id']}` : {leff} days left"
+ txt += "\n\nYou can use /info [user id] to get info about the user"
+ await xx.delete()
+ await m.reply_text(txt)
+ return
+
+@Gojo.on_message(command(["getbday","gbday","mybirthday","mbday"]))
+async def cant_recall_it(c: Gojo, m: Message):
+ if not BDB_URI:
+ await m.reply_text("BDB_URI is not configured")
+ return
+ user = m.from_user.id
+ if m.reply_to_message:
+ user = m.reply_to_message.from_user.id
+ try:
+ result = bday_info.find_one({"user_id":user})
+ if not result:
+ await m.reply_text("User is not in my database")
+ return
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ return
+
+ curr = datetime.now(TIME_ZONE).date()
+ u_dob = give_date(result["dob"])
+ if u_dob.month < curr.month:
+ next_b = date(curr.year + 1, u_dob.month, u_dob.day)
+ days_left = (next_b - curr).days
+ txt = f"User's birthday is passed ๐ซค\nDays left until next one {days_left}"
+ else:
+ u_dobm = date(curr.year, u_dob.month, u_dob.day)
+ days_left = (u_dobm - curr).days
+ txt = f"User's birthday is coming๐ฅณ\nDays left : {days_left}"
+ await m.reply_text(txt)
+ return
+
+@Gojo.on_message(command(["settingbday","sbday"]))
+async def chat_birthday_settings(c: Gojo, m: Message):
+ if not BDB_URI:
+ await m.reply_text("BDB_URI is not configured")
+ return
+ if m.chat.type == ChatType.PRIVATE:
+ await m.reply_text("Use in groups")
+ return
+ chats = m.chat.id
+ c_in = bday_cinfo.find_one({"chat_id":chats})
+ kb = IKM(
+ [
+ [
+ IKB(f"{'Yes' if not c_in else 'No'}",f"switchh_{'yes' if not c_in else 'no'}"),
+ IKB("Close", "f_close")
+ ]
+ ]
+ )
+ await m.reply_text("Do you want to wish members for their birthday in the group?",reply_markup=kb)
+ return
+
+@Gojo.on_callback_query(filters.regex("^switchh_"))
+async def switch_on_off(c:Gojo, q: CallbackQuery):
+ user = (await q.message.chat.get_member(q.from_user.id)).status
+ await q.message.chat.get_member(q.from_user.id)
+ if user not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
+ await q.answer("...")
+ return
+ data = q.data.split("_")[1]
+ chats = q.message.chat.id
+ xXx = {"chat_id":chats}
+ if data == "yes":
+ bday_cinfo.delete_one(xXx)
+ elif data == "no":
+ bday_cinfo.insert_one(xXx)
+ await q.edit_message_text(f"Done! I will {'wish' if data == 'yes' else 'not wish'}",reply_markup=IKM([[IKB("Close", "f_close")]]))
+ return
+
+scheduler = AsyncIOScheduler()
+scheduler.timezone = TIME_ZONE
+scheduler_time = time(0,0,0)
+async def send_wishish(c:Gojo):
+ c_list = Chats.list_chats_by_id()
+ blist = list(bday_info.find())
+ curr = datetime.now(TIME_ZONE).date()
+ cclist = list(bday_cinfo.find())
+ for i in blist:
+ dob = give_date(i["dob"])
+ if dob.month == curr.month and dob.day == curr.day:
+ for j in c_list:
+ if cclist and (j in cclist):
+ return
+ try:
+ agee = ""
+ if i["is_year"]:
+ agee = curr.year - dob.year
+ if str(agee).endswith("1"):
+ agee = f"{agee}st"
+ elif str(agee).endswith("2"):
+ agee = f"{agee}nd"
+ elif str(agee).endswith("3"):
+ agee = f"{agee}rd"
+ else:
+ agee = f"{agee}th"
+ U = await c.get_chat_member(chat_id=j,user_id=i["user_id"])
+ wish = choice(birthday_wish)
+ if U.status in [ChatMemberStatus.MEMBER,ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
+ xXx = await c.send_message(j,f"Happy {agee} birthday {U.user.mention}๐ฅณ\n{wish}")
+ try:
+ await xXx.pin()
+ except Exception:
+ pass
+ except Exception:
+ pass
+
+""""
+from datetime import date, datetime
+
+#form =
+num = "18/05/2005"
+st = "18 May 2005"
+timm = datetime.strptime(num,"%d/%m/%Y").date()
+x = datetime.now().date()
+if timm.month < x.month:
+ next_b = date(x.year + 1, timm.month, timm.day)
+ days_left = (next_b - x).days
+else:
+ timmm = date(x.year, timm.month, timm.day)
+ days_left = (timmm - x).days
+print(days_left)
+print(x.year - timm.year)
+"""
+if BDB_URI:
+ scheduler.add_job(send_wishish,'cron',[Gojo],hour=0,minute=0,second=0)
+ scheduler.start()
+
+__PLUGIN__ = "birthday"
+
+__HELP__ = """
+โข /remember [reply to user] [DOB] : To registers user date of birth in my database. If not replied to user then the DOB givien will be treated as yours
+โข /nextbdays (/nbdays,/brithdays,/bdays) : Return upcoming birthdays of 10 users
+โข /removebday (/rmbday) : To remove birthday from database (One can only remove their data from database not of others)
+โข /settingbday (/sbday) : To configure the settings for wishing and all for the chat
+โข /getbday (/gbday,/mybirthday,/mybday) [reply to user] : If replied to user get the replied user's birthday else returns your birthday
+
+DOB should be in format of dd/mm/yyyy
+Year is optional it is not necessary to pass it
+"""
\ No newline at end of file
diff --git a/Powers/plugins/clean_db.py b/Powers/plugins/clean_db.py
new file mode 100644
index 00000000..9250f18b
--- /dev/null
+++ b/Powers/plugins/clean_db.py
@@ -0,0 +1,91 @@
+import time
+from asyncio import sleep
+
+from apscheduler.schedulers.asyncio import AsyncIOScheduler
+#from pyrogram import Client, filters
+from pyrogram.enums import ChatMemberStatus as CMS
+
+from Powers import LOGGER, MESSAGE_DUMP, TIME_ZONE
+from Powers.bot_class import Gojo
+from Powers.database.approve_db import Approve
+from Powers.database.blacklist_db import Blacklist
+from Powers.database.chats_db import Chats
+from Powers.database.disable_db import Disabling
+from Powers.database.filters_db import Filters
+from Powers.database.flood_db import Floods
+from Powers.database.greetings_db import Greetings
+from Powers.database.notes_db import Notes, NotesSettings
+from Powers.database.pins_db import Pins
+from Powers.database.reporting_db import Reporting
+from Powers.database.users_db import Users
+from Powers.database.warns_db import Warns, WarnSettings
+from Powers.utils.custom_filters import command
+from Powers.vars import Config
+
+scheduler = AsyncIOScheduler()
+scheduler.timezone = TIME_ZONE
+
+async def clean_my_db(c:Gojo,is_cmd=False, id=None):
+ to_clean = list()
+ all_userss = Users.list_users()
+ chats_list = Chats.list_chats_by_id()
+ to_clean.clear()
+ start = time.time()
+ for chats in chats_list:
+ try:
+ stat = await c.get_chat_member(chat_id=chats,user_id=Config.BOT_ID)
+ if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]:
+ to_clean.append(chats)
+ except Exception:
+ to_clean.append(chats)
+ for i in to_clean:
+ Approve(i).clean_approve()
+ Blacklist(i).clean_blacklist()
+ Chats.remove_chat(i)
+ Disabling(i).clean_disable()
+ Filters().rm_all_filters(i)
+ Floods().rm_flood(i)
+ Greetings(i).clean_greetings()
+ Notes().rm_all_notes(i)
+ NotesSettings().clean_notes(i)
+ Pins(i).clean_pins()
+ Reporting(i).clean_reporting()
+ Warns(i).clean_warn()
+ WarnSettings(i).clean_warns()
+ x = len(to_clean)
+ txt = f"#INFO\n\nCleaned db:\nTotal chats removed: {x}"
+ to_clean.clear()
+ LOGGER.info("Sleeping for 60 seconds")
+ await sleep(60)
+ LOGGER.info("Continuing the cleaning process")
+ all_users = [i["_id"] for i in all_userss]
+ for i in all_users:
+ try:
+ infos = await c.get_users(int(i))
+ except Exception:
+ try:
+ inn = await c.resolve_peer(int(i))
+ infos = await c.get_users(inn.user_id)
+ except Exception:
+ to_clean.append(i)
+ Users(i).delete_user()
+ if infos.is_deleted:
+ to_clean.append(infos.id)
+ Users(infos.id).delete_user()
+
+ else:
+ pass
+ txt += f"\nTotal users removed: {len(to_clean)}"
+ to_clean.clear()
+ if is_cmd:
+ txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}"
+ await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
+ return txt
+ else:
+ txt += f"\nClean type: Auto\n\tTook {time.time()-start-60} seconds to complete the process"
+ await c.send_message(chat_id=MESSAGE_DUMP,text=txt)
+ return
+
+
+scheduler.add_job(clean_my_db,'cron',[Gojo],hour=3,minute=0,second=0)
+scheduler.start()
\ No newline at end of file
diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py
index fd25a3fc..67f6283c 100644
--- a/Powers/plugins/dev.py
+++ b/Powers/plugins/dev.py
@@ -17,10 +17,10 @@
from Powers.bot_class import Gojo
from Powers.database import MongoDB
from Powers.database.chats_db import Chats
+from Powers.plugins.clean_db import clean_my_db
from Powers.utils.clean_file import remove_markdown_and_html
from Powers.utils.custom_filters import command
from Powers.utils.extract_user import extract_user
-from Powers.utils.http_helper import *
from Powers.utils.parser import mention_markdown
@@ -32,11 +32,13 @@ async def add_dev(c: Gojo, m:Message):
split = m.text.split(None)
reply_to = m.reply_to_message
if len(split) != 2:
- await m.reply_text("Reply to message to add the user in dev")
- return
- elif not reply_to:
- await m.reply_text("Give me an id")
- return
+ if not reply_to:
+ await m.reply_text("Reply to message to add the user in dev")
+ return
+ if not reply_to:
+ if len(split) != 2:
+ await m.reply_text("Give me an id")
+ return
elif reply_to:
user = reply_to.from_user.id
elif len(split) == 2:
@@ -138,10 +140,6 @@ async def evaluate_code(c: Gojo, m: Message):
return
sm = await m.reply_text("`Processing...`")
cmd = m.text.split(None, maxsplit=1)[1]
- if "for" in cmd or "while" in cmd or "with" in cmd:
- if m.from_user.id != OWNER_ID:
- await m.reply_text("Spam kro gaye vai.\nEse kese")
- return
if "while True:" in cmd:
await sm.delete()
await m.reply_text("BSDK SPAM NI")
@@ -150,7 +148,11 @@ async def evaluate_code(c: Gojo, m: Message):
f"@{m.from_user.username} TREID TO USE `while True` \n userid = {m.from_user.id}"
)
return
-
+ if m.reply_to_message and m.reply_to_message.document:
+ if m.reply_to_message.document.mime_type.split("/")[1] == "x-python" or m.reply_to_message.document.file_name.endswith("py"):
+ await sm.delete()
+ await m.reply_text("Loading external plugin is prohibited")
+ return
reply_to_id = m.id
if m.reply_to_message:
reply_to_id = m.reply_to_message.id
@@ -321,7 +323,7 @@ async def stop_and_send_logger(c:Gojo,is_update=False):
)
return
-@Gojo.on_message(command(["restart", "update"], owner_cmd=True))
+@Gojo.on_message(command(["restart", "update"], owner_cmd=True),group=-100)
async def restart_the_bot(c:Gojo,m:Message):
try:
cmds = m.command
@@ -454,6 +456,23 @@ async def chat_broadcast(c: Gojo, m: Message):
return
+@Gojo.on_message(command(["cleandb","cleandatabase"],sudo_cmd=True))
+async def cleeeen(c:Gojo,m:Message):
+ x = await m.reply_text("Cleaning the database...")
+ try:
+ z = await clean_my_db(c,True,m.from_user.id)
+ try:
+ await x.delete()
+ except Exception:
+ pass
+ await m.reply_text("")
+ return
+ except Exception as e:
+ await m.reply_text(e)
+ await x.delete()
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
+ return
__PLUGIN__ = "devs"
@@ -478,6 +497,7 @@ async def chat_broadcast(c: Gojo, m: Message):
**Sudoer's command:**
โข /ping : return the ping of the bot.
+โข /cleandb : Delete useless junks from database (Automatically start cleaning it at 3:00:00 AM)
**Example:**
/ping
diff --git a/Powers/plugins/giveaway.py b/Powers/plugins/giveaway.py
deleted file mode 100644
index dd7e2568..00000000
--- a/Powers/plugins/giveaway.py
+++ /dev/null
@@ -1,639 +0,0 @@
-import os
-from asyncio import sleep
-from datetime import datetime, timedelta
-from random import choice
-from traceback import format_exc
-
-from pyrogram import filters
-from pyrogram.enums import ChatMemberStatus as CMS
-from pyrogram.enums import ChatType as CT
-from pyrogram.enums import MessageMediaType as MMT
-from pyrogram.errors import UserNotParticipant
-from pyrogram.types import CallbackQuery
-from pyrogram.types import InlineKeyboardButton as IKB
-from pyrogram.types import InlineKeyboardMarkup as IKM
-from pyrogram.types import Message
-
-from Powers import LOGGER
-from Powers.bot_class import Gojo
-from Powers.database.giveaway_db import GIVEAWAY
-from Powers.utils.custom_filters import command
-from Powers.vars import Config
-
-user_entry = {} # {c_id : {participants_id : 0}}} dict be like
-voted_user = {} # {c_id : [voter_ids]}} dict be like
-total_entries = {} # {c_id : [user_id]} dict be like for participants
-left_deduct = {} # {c_id:{u_id:p_id}} u_id = user who have voted, p_id = participant id. Will deduct vote from participants account if user leaves
-rejoin_try = {} # store the id of the user who lefts the chat while giveaway under-process {c_id:[]}
-is_start_vote = [] # store id of chat where voting is started
-
-@Gojo.on_message(command(["startgiveaway", "startga"]))
-async def start_give_one(c: Gojo, m: Message):
- uWu = True
- try:
- if m.chat.type != CT.PRIVATE:
- await m.reply_text("**USAGE**\n/startgiveaway\nMeant to be used in private")
- return
- GA = GIVEAWAY()
- g_id = await c.ask(text="Send me number of giveaway", chat_id = m.chat.id, filters=filters.text)
- give_id = g_id.text.markdown
- curr = GA.give_info(u_id=m.from_user.id)
- if curr:
- gc_id = curr["chat_id"]
- c_id = curr["where"]
- if curr["is_give"]:
- await m.reply_text("One giveaway is already in progress")
- return
- while True:
- con = await c.ask(text="You info is already present in my database do you want to continue\nYes : To start the giveaway with previous configurations\nNo: To create one",chat_id = m.chat.id,filters=filters.text)
- if con.text.lower() == "/cancel":
- await m.reply_text("cancelled")
- return
- if con.text.lower() == "yes":
- await c.send_message(m.chat.id,"Done")
- while True:
- yes_no = await c.ask(text="Ok.\nDo you want to allow old member of the channel can vote in this giveaway.\n**Yes: To allow**\n**No: To don't allow**\nNote that old mean user who is present in the chat for more than 48 hours",chat_id = m.from_user.id,filters=filters.text)
- if yes_no.text.lower() == "/cancel":
- await m.reply_text("cancelled")
- return
- if yes_no.text.lower() == "yes":
- is_old = 0
- break
- elif yes_no.text.lower() == "no":
- is_old = 1
- break
- else:
- await c.send_message(m.chat.id,"Type yes or no only")
- f_c_id = gc_id
- s_c_id = c_id
- is_old = is_old
- GA.update_is_old(m.from_user.id, is_old)
- GA.stop_entries(m.from_user.id, entries = 1) # To start entries
- GA.stop_give(m.from_user.id, is_give=1) # To start giveaway
- link = await c.export_chat_invite_link(s_c_id)
- uWu = False
- await c.send_message(m.chat.id,"Done")
- break
- elif con.text.lower() == "no":
- uWu = True
- break
- else:
- await c.send_message(m.chat.id,"Type yes or no only")
- if uWu:
- while True:
- channel_id = await c.ask(text="OK....send me id of the channel and make sure I am admin their. If you don't have id forward a post from your chat.\nType /cancel cancel the current process",chat_id = m.chat.id,filters=filters.text)
- if channel_id.text:
- if str(channel_id.text).lower() == "/cancel":
- await c.send_message(m.from_user.id, "Cancelled")
- return
- try:
- c_id = int(channel_id.text)
- try:
- bot_stat = (await c.get_chat_member(c_id,Config.BOT_ID)).status
- if bot_stat in [CMS.ADMINISTRATOR,CMS.OWNER]:
- break
- else:
- await c.send_message(m.chat.id,f"Looks like I don't have admin privileges in the chat {c_id}\n Make me admin and then send me channel id again")
- except UserNotParticipant:
- await c.send_message(m.chat.id,f"Looks like I am not part of the chat {c_id}\n")
-
-
- except ValueError:
- await c.send_message(m.chat.id,"Channel id should be integer type")
-
- else:
- if channel_id.forward_from_chat:
- try:
- bot_stat = (await c.get_chat_member(c_id,Config.BOT_ID)).status
- if bot_stat in [CMS.ADMINISTRATOR,CMS.OWNER]:
- break
- else:
- await c.send_message(m.chat.id,f"Looks like I don't have admin privileges in the chat {c_id}\n Make me admin and then send me channel id again")
- except UserNotParticipant:
- await c.send_message(m.chat.id,f"Looks like I am not part of the chat {c_id}\n")
- else:
- await c.send_message(m.chat.id,f"Forward me content from chat where you want to start giveaway")
- f_c_id = c_id
- await c.send_message(m.chat.id,"Channel id received")
- while True:
- chat_id = await c.ask(text="Sende me id of the chat and make sure I am admin their. If you don't have id go in the chat and type /id.\nType /cancel to cancel the current process",chat_id = m.chat.id,filters=filters.text)
- if chat_id.text:
- if str(chat_id.text).lower() == "/cancel":
- await c.send_message(m.from_user.id, "Cancelled")
- return
- try:
- cc_id = int(chat_id.text)
- try:
- cc_id = (await c.get_chat(cc_id)).id
- s_c_id = cc_id
- break
- except Exception:
- try:
- cc_id = await c.resolve_peer(cc_id)
- cc_id = (await c.get_chat(cc_id.channel_id)).id
- s_c_id = cc_id
- break
- except Exception as e:
- await c.send_message(m.chat.id,f"Looks like chat doesn't exist{e}")
- except ValueError:
- await c.send_message(m.chat.id,"Chat id should be integer type")
- try:
- bot_stat = (await c.get_chat_member(s_c_id,Config.BOT_ID)).status
- if bot_stat in [CMS.ADMINISTRATOR,CMS.OWNER]:
- break
- else:
- await c.send_message(m.chat.id,f"Looks like I don't have admin privileges in the chat {s_c_id}\n Make me admin and then send me channel id again")
- except UserNotParticipant:
- await c.send_message(m.chat.id,f"Looks like I am not part of the chat {s_c_id}\n")
-
- await c.send_message(m.chat.id,"Chat id received")
-
- link = await c.export_chat_invite_link(cc_id)
-
- yes_no = await c.ask(text="Do you want to allow old member of the channel can vote in this giveaway.\n**Yes: To allow**\n**No: To don't allow**\nNote that old mean user who is present in the chat for more than 48 hours",chat_id = m.from_user.id,filters=filters.text)
- if yes_no.text.lower() == "yes":
- is_old = 0
- elif yes_no.text.lower() == "no":
- is_old = 1
- curr = GA.save_give(f_c_id, s_c_id, m.from_user.id, is_old, force_c=True)
- except Exception as e:
- LOGGER.error(e)
- LOGGER.error(format_exc())
- return
-
- reply = m.reply_to_message
- giveaway_text = f"""
-**#Giveaway {give_id} ใ**
-โโโโโโโโโโโ
-__To win this logo giveaway__
-__participate in the contest__,
-__Comment /enter to begin__
-
-Bot should be started!!
-โโโโโโโโโโโ
-**Status : Entries open**
-"""
-
- kb = IKM([[IKB("Join the chat", url=link)],[IKB("Start the bot", url=f"https://{Config.BOT_USERNAME}.t.me/")]])
- try:
- if reply and (reply.media in [MMT.VIDEO, MMT.PHOTO] or (reply.document.mime_type.split("/")[0]=="image")):
- if reply.photo:
- pin = await c.send_photo(f_c_id, reply.photo.file_id, giveaway_text, reply_markup=kb)
- elif reply.video:
- pin = await c.send_video(f_c_id, reply.video.file_id, giveaway_text, reply_markup=kb)
- elif reply.document:
- download = await reply.download()
- pin = await c.send_photo(f_c_id, download, giveaway_text, reply_markup=kb)
- os.remove(download)
- else:
- pin = await c.send_message(f_c_id,giveaway_text, reply_markup=kb, disable_web_page_preview=True)
- except Exception as e:
- LOGGER.error(e)
- LOGGER.error(format_exc())
- await m.reply_text(f"Failed to send message to channel due to\n{e}")
- return
- c_in = await c.get_chat(f_c_id)
- name = c_in.title
- await m.reply_text(f"โจ Giveaway post has been sent to [{name}]({c_in.invite_link})", disable_web_page_preview=True, reply_markup=IKM([[IKB("Go To Post", url=pin.link)]]))
-
-
-async def message_editor(c:Gojo, m: Message, c_id):
- txt = f"""
-**#Giveaway ใ**
-โโโโโโโโโโโ
-__To win this logo giveaway__
-__participate in the contest__,
-__Comment /enter to begin__
-
-Note: Bot should be started!!
-โโโโโโโโโโโ
-**Status : Entries closed**
-**Total entries : {len(total_entries[c_id])}**
-"""
- try:
- m_id = int(m.text.split(None)[1].split("/")[-1])
- except ValueError:
- await m.reply_text("The link doesn't contain any message id")
- return False
- try:
- mess = await c.get_messages(c_id,m_id)
- except Exception as e:
- await m.reply_text(f"Failed to get message form the chat id {c_id}. Due to following error\n{e}")
- return False
- try:
- if mess.caption:
- await mess.edit_caption(txt)
- else:
- await mess.edit_text(txt)
- return True
- except Exception as e:
- await m.reply_text(f"Failed to update the message due to following error\n{e}")
- await m.reply_text(f"Here is the text you can edit the message by your self\n`{txt}`\nSorry for inconvenience")
- return False
-
-
-@Gojo.on_message(command("stopentry"))
-async def stop_give_entry(c:Gojo, m: Message):
- GA = GIVEAWAY()
- u_id = m.from_user.id
- curr = GA.give_info(u_id=u_id)
- if not curr:
- await m.reply_text("You have not started any giveaway yeat.")
- return
- if not curr["entries"]:
- await m.reply_text("You have not started any giveaway yeat.")
- return
- user = curr["user_id"]
- if u_id != user:
- await m.reply_text("You are not the one who have started the giveaway")
- return
- c_id = curr["chat_id"]
- if len(m.text.split(None)) != 2:
- await m.reply_text("**Usage**\n`/stopentry {m.text}
\n\nError: There is no data in here!")
return
- if not text and not msgtype:
+ if not text and not file:
await m.reply_text(
"Please provide some data!",
)
@@ -159,7 +159,7 @@ async def save_wlcm(_, m: Message):
await m.reply_text("Please provide some data for this to reply with!")
return
- db.set_welcome_text(text)
+ db.set_welcome_text(text,file)
await m.reply_text("Saved welcome!")
return
@@ -181,13 +181,13 @@ async def save_gdbye(_, m: Message):
"Error: There is no text in here! and only text with buttons are supported currently !",
)
return
- text, msgtype, _ = await get_wlcm_type(m)
+ text, msgtype, file = await get_wlcm_type(m)
if not m.reply_to_message and msgtype == Types.TEXT and len(m.command) <= 2:
await m.reply_text(f"{m.text}
\n\nError: There is no data in here!")
return
- if not text and not msgtype:
+ if not text and not file:
await m.reply_text(
"Please provide some data!",
)
@@ -197,7 +197,7 @@ async def save_gdbye(_, m: Message):
await m.reply_text("Please provide some data for this to reply with!")
return
- db.set_goodbye_text(text)
+ db.set_goodbye_text(text,file)
await m.reply_text("Saved goodbye!")
return
@@ -274,6 +274,8 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
return
status = db.get_welcome_status()
oo = db.get_welcome_text()
+ UwU = db.get_welcome_media()
+ mtype = db.get_welcome_msgtype()
parse_words = [
"first",
"last",
@@ -302,12 +304,21 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
except RPCError:
pass
try:
- jj = await c.send_message(
- member.chat.id,
- text=teks,
- reply_markup=button,
- disable_web_page_preview=True,
- )
+ if not UwU:
+ jj = await c.send_message(
+ member.chat.id,
+ text=teks,
+ reply_markup=button,
+ disable_web_page_preview=True,
+ )
+ elif UwU:
+ jj = await (await send_cmd(c,mtype))(
+ member.chat.id,
+ UwU,
+ caption=teks,
+ reply_markup=button,
+ )
+
if jj:
db.set_cleanwlcm_id(int(jj.id))
except RPCError as e:
@@ -331,6 +342,8 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated):
db = Greetings(member.chat.id)
status = db.get_goodbye_status()
oo = db.get_goodbye_text()
+ UwU = db.get_goodbye_media()
+ mtype = db.get_goodbye_msgtype()
parse_words = [
"first",
"last",
@@ -368,12 +381,21 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated):
)
return
try:
- ooo = await c.send_message(
- member.chat.id,
- text=teks,
- reply_markup=button,
- disable_web_page_preview=True,
- )
+ if not UwU:
+ ooo = await c.send_message(
+ member.chat.id,
+ text=teks,
+ reply_markup=button,
+ disable_web_page_preview=True,
+ )
+ elif UwU:
+ ooo = await (await send_cmd(c,mtype))(
+ member.chat.id,
+ UwU,
+ caption=teks,
+ reply_markup=button,
+ )
+
if ooo:
db.set_cleangoodbye_id(int(ooo.id))
return
diff --git a/Powers/plugins/info.py b/Powers/plugins/info.py
index c29a5916..019a6708 100644
--- a/Powers/plugins/info.py
+++ b/Powers/plugins/info.py
@@ -5,6 +5,8 @@
from pyrogram import enums
from pyrogram.errors import EntityBoundsInvalid, MediaCaptionTooLong, RPCError
+from pyrogram.raw.functions.channels import GetFullChannel
+from pyrogram.raw.functions.users import GetFullUser
from pyrogram.types import Message
from Powers import (DEV_USERS, LOGGER, OWNER_ID, SUDO_USERS, SUPPORT_STAFF,
@@ -72,6 +74,17 @@ async def user_info(c: Gojo, user, already=False):
reason = "User is not gbanned"
user_id = user.id
+ userrr = await c.resolve_peer(user_id)
+ about = "NA"
+ try:
+ ll = await c.invoke(
+ GetFullUser(
+ id=userrr
+ )
+ )
+ about = ll.full_user.about
+ except Exception:
+ pass
username = user.username
first_name = user.first_name
last_name = user.last_name
@@ -130,6 +143,7 @@ async def user_info(c: Gojo, user, already=False):
๐ฃ First Name: {first_name}
๐
Second Name: {last_name}
๐ Username: {("@" + username) if username else "NA"}
+โ๏ธ Bio: `{about}`
๐งโ๐ป Support: {is_support}
๐ฅท Support user type: {omp}
๐ฃ Gbanned: {gban}
@@ -148,18 +162,42 @@ async def user_info(c: Gojo, user, already=False):
async def chat_info(c: Gojo, chat, already=False):
+ u_name = False
if not already:
try:
chat = await c.get_chat(chat)
+ try:
+ chat = (await c.resolve_peer(chat.id))
+ ll = await c.invoke(
+ GetFullChannel(
+ channel=chat
+ )
+ )
+ u_name = ll.chats[0].usernames
+ except Exception:
+ pass
except Exception:
try:
chat_r = await c.resolve_peer(chat)
chat = await c.get_chat(chat_r.channel_id)
+ try:
+ chat = (await c.resolve_peer(chat_r))
+ ll = await c.invoke(
+ GetFullChannel(
+ channel=chat
+ )
+ )
+ u_name = ll.chats[0].usernames
+ except Exception:
+ pass
except KeyError as e:
caption = f"Failed to find the chat due to\n{e}"
return caption, None
chat_id = chat.id
- username = chat.username
+ if u_name:
+ username = " ".join([f"@{i}"for i in u_name])
+ elif not u_name:
+ username = chat.username
total_bot, total_admin, total_bot_admin, total_banned = await count(c, chat.id)
title = chat.title
type_ = str(chat.type).split(".")[1]
diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py
index f570c6c8..7c17b9a4 100644
--- a/Powers/plugins/locks.py
+++ b/Powers/plugins/locks.py
@@ -2,6 +2,7 @@
from traceback import format_exc
from pyrogram import filters
+from pyrogram.enums import MessageEntityType as MET
from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError
from pyrogram.types import ChatPermissions, Message
@@ -10,6 +11,7 @@
from Powers.database.approve_db import Approve
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
from Powers.utils.custom_filters import command, restrict_filter
+from Powers.vars import Config
SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)])
@@ -17,6 +19,7 @@
anti_forward = [-1001604479593]
anti_forward_u = []
anti_forward_c = []
+anti_links = []
@Gojo.on_message(command("locktypes"))
async def lock_types(_, m: Message):
await m.reply_text(
@@ -37,7 +40,8 @@ async def lock_types(_, m: Message):
" - `anonchannel` = Send as chat will be locked\n"
" - `forwardall` = Forwarding from channel and user\n"
" - `forwardu` = Forwarding from user\n"
- " - `forwardc` = Forwarding from channel"
+ " - `forwardc` = Forwarding from channel\n"
+ " - `links | url` = Lock links"
),
)
return
@@ -121,6 +125,16 @@ async def lock_perm(c: Gojo, m: Message):
elif lock_type == "pin":
pin = False
perm = "pin"
+ elif lock_type in ["links", "url"]:
+ if not len(anti_links):
+ anti_links.append(m.chat.id)
+ elif m.chat.id not in anti_links:
+ anti_links.append(m.chat.id)
+ else:
+ await m.reply_text("It is already on")
+ return
+ await m.reply_text("Locked links in the chat")
+ return
elif lock_type == "anonchannel":
if not len(anti_c_send):
anti_c_send.append(m.chat.id)
@@ -207,13 +221,16 @@ async def convert_to_emoji(val: bool):
anon = False
if m.chat.id in anti_c_send:
anon = True
- anti_f = False
+ anti_f = anti_f_u = anti_f_c = False
if m.chat.id in anti_forward:
anti_f = True
if m.chat.id in anti_forward_u:
anti_f_u = True
if m.chat.id in anti_forward_c:
anti_f_c = True
+ antil = False
+ if m.chat.id in anti_links:
+ antil = True
vmsg = await convert_to_emoji(v_perm.can_send_messages)
vmedia = await convert_to_emoji(v_perm.can_send_media_messages)
vother = await convert_to_emoji(v_perm.can_send_other_messages)
@@ -226,6 +243,7 @@ async def convert_to_emoji(val: bool):
vanti = await convert_to_emoji(anti_f)
vantiu = await convert_to_emoji(anti_f_u)
vantic = await convert_to_emoji(anti_f_c)
+ vantil = await convert_to_emoji(antil)
if v_perm is not None:
try:
@@ -246,6 +264,7 @@ async def convert_to_emoji(val: bool):
Can forward: {vanti}
Can forward from user: {vantiu}
Can forward from channel and chats: {vantic}
+ Can send links: {antil}
"""
LOGGER.info(f"{m.from_user.id} used locks cmd in {m.chat.id}")
await chkmsg.edit_text(permission_view_str)
@@ -357,6 +376,14 @@ async def unlock_perm(c: Gojo, m: Message):
except ValueError:
await m.reply_text("It is already off")
return
+ elif unlock_type in ["links", "url"]:
+ try:
+ anti_links.remove(m.chat.id)
+ await m.reply_text("Sending link is now allowed")
+ return
+ except ValueError:
+ await m.reply_text("Already allowed")
+ return
elif unlock_type == "forwardall":
try:
if not len(anti_forward) or m.chat.id not in anti_forward:
@@ -443,7 +470,7 @@ async def is_approved_user(c:Gojo, m: Message):
admins_group = await admin_cache_reload(m, "lock")
if m.forward_from:
- if m.from_user.id in ul or m.from_user.id in SUDO_LEVEL or m.from_user.id in admins_group:
+ if m.from_user.id in ul or m.from_user.id in SUDO_LEVEL or m.from_user.id in admins_group or m.from_user.id == Config.BOT_ID:
return True
return False
elif m.forward_from_chat:
@@ -453,17 +480,28 @@ async def is_approved_user(c:Gojo, m: Message):
elif x_chat and x_chat.id == m.chat.id:
return True
return False
+ elif m.from_user:
+ if m.from_user.id in ul or m.from_user.id in SUDO_LEVEL or m.from_user.id in admins_group or m.from_user.id == Config.BOT_ID:
+ return True
+ return False
@Gojo.on_message(filters.all & ~filters.me,18)
async def lock_del_mess(c:Gojo, m: Message):
- all_chats = anti_c_send + anti_forward + anti_forward_c + anti_forward_u
+ all_chats = anti_c_send + anti_forward + anti_forward_c + anti_forward_u + anti_links
if m.chat.id not in all_chats:
return
if m.sender_chat and not (m.forward_from_chat or m.forward_from):
await delete_messages(c,m)
return
+ is_approved = await is_approved_user(c,m)
+ entity = m.entities if m.text else m.caption_entities
+ if entity:
+ for i in entity:
+ if i.type in [MET.URL or MET.TEXT_LINK]:
+ if not is_approved:
+ await delete_messages(c,m)
+ return
elif m.forward_from or m.forward_from_chat:
- is_approved = await is_approved_user(c,m)
if not is_approved:
if m.chat.id in anti_forward:
await delete_messages(c,m)
diff --git a/Powers/plugins/muting.py b/Powers/plugins/muting.py
index a4ef63b1..b9a50905 100644
--- a/Powers/plugins/muting.py
+++ b/Powers/plugins/muting.py
@@ -59,7 +59,7 @@ async def tmute_usr(c: Gojo, m: Message):
r_id = m.reply_to_message.id if m.reply_to_message else m.id
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
@@ -72,9 +72,7 @@ async def tmute_usr(c: Gojo, m: Message):
split_reason = reason.split(None, 1)
time_val = split_reason[0].lower()
-
reason = split_reason[1] if len(split_reason) > 1 else ""
-
mutetime = await extract_time(m, time_val)
if not mutetime:
@@ -166,7 +164,7 @@ async def dtmute_usr(c: Gojo, m: Message):
return
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
@@ -272,7 +270,7 @@ async def stmute_usr(c: Gojo, m: Message):
return
if m.reply_to_message and len(m.text.split()) >= 2:
- reason = m.text.split(None, 2)[1]
+ reason = m.text.split(None, 1)[1]
elif not m.reply_to_message and len(m.text.split()) >= 3:
reason = m.text.split(None, 2)[2]
else:
diff --git a/Powers/plugins/notes.py b/Powers/plugins/notes.py
index 7dedd5b5..ac632af3 100644
--- a/Powers/plugins/notes.py
+++ b/Powers/plugins/notes.py
@@ -120,7 +120,7 @@ async def get_note_func(c: Gojo, m: Message, note_name, priv_notes_status):
text = await escape_mentions_using_curly_brackets(m, note_reply, parse_words)
teks, button = await parse_button(text)
button = await build_keyboard(button)
- button = InlineKeyboardMarkup(button) if button else None
+ button = ikb(button) if button else None
textt = teks
try:
diff --git a/Powers/plugins/report.py b/Powers/plugins/report.py
index cd469504..f8b71974 100644
--- a/Powers/plugins/report.py
+++ b/Powers/plugins/report.py
@@ -79,7 +79,6 @@ async def report_watcher(c: Gojo, m: Message):
reported_msg_id = m.reply_to_message.id
reported_user = m.reply_to_message.from_user
chat_name = m.chat.title or m.chat.username
- admin_list = await c.get_chat_members(m.chat.id, filter=cmf.ADMINISTRATORS)
if reported_user.id == me.id:
await m.reply_text("Nice try.")
@@ -136,7 +135,7 @@ async def report_watcher(c: Gojo, m: Message):
quote=True,
)
- for admin in admin_list:
+ async for admin in c.get_chat_members(m.chat.id, filter=cmf.ADMINISTRATORS):
if (
admin.user.is_bot or admin.user.is_deleted
): # can't message bots or deleted accounts
diff --git a/Powers/plugins/rules.py b/Powers/plugins/rules.py
index 0ae0a00f..62e65a3f 100644
--- a/Powers/plugins/rules.py
+++ b/Powers/plugins/rules.py
@@ -1,11 +1,12 @@
from pyrogram import filters
-from pyrogram.types import CallbackQuery, Message
+from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, Message
from Powers import LOGGER
from Powers.bot_class import Gojo
from Powers.database.rules_db import Rules
from Powers.utils.custom_filters import admin_filter, command
from Powers.utils.kbhelpers import ikb
+from Powers.utils.string import build_keyboard, parse_button
from Powers.vars import Config
@@ -49,12 +50,16 @@ async def get_rules(_, m: Message):
return
formated = rules
-
+ teks, button = await parse_button(formated)
+ button = await build_keyboard(button)
+ button = ikb(button) if button else None
+ textt = teks
await m.reply_text(
text=f"""The rules for {m.chat.title} are:
- {formated}""",
+{textt}""",
disable_web_page_preview=True,
reply_to_message_id=msg_id,
+ reply_markup=button
)
return
@@ -161,4 +166,8 @@ async def clearrules_callback(_, q: CallbackQuery):
**Admin only:**
โข /setrules `{m.chat.id}
\nYour ID {m.from_user.id}
")
- return
+ user_id, _, _ = await extract_user(c, m)
+ try:
+ if user_id and len(m.text.split()) == 2:
+ txt = f"Given user's id: {user_id}
"
+ await m.reply_text(txt, parse_mode=enums.ParseMode.HTML)
+ return
+ elif m.chat.type in [ChatType.SUPERGROUP, ChatType.GROUP] and not m.reply_to_message:
+ await m.reply_text(text=f"This Group's ID is {m.chat.id}
\nYour ID {m.from_user.id}
")
+ return
- if m.chat.type == ChatType.PRIVATE and not m.reply_to_message:
- await m.reply_text(text=f"Your ID is {m.chat.id}
.")
+ elif m.chat.type == ChatType.PRIVATE and not m.reply_to_message:
+ await m.reply_text(text=f"Your ID is {m.chat.id}
.")
+ return
+ except Exception as e:
+ await m.reply_text(e)
return
-
- user_id, _, _ = await extract_user(c, m)
if user_id:
if m.reply_to_message and m.reply_to_message.forward_from:
user1 = m.reply_to_message.from_user
user2 = m.reply_to_message.forward_from
- orig_sender = ((await mention_html(user2.first_name, user2.id)),)
- orig_id = (f"{user2.id}
",)
- fwd_sender = ((await mention_html(user1.first_name, user1.id)),)
- fwd_id = (f"{user1.id}
",)
+ orig_sender = await mention_html(user2.first_name, user2.id)
+ orig_id = f"{user2.id}
"
+ fwd_sender = await mention_html(user1.first_name, user1.id)
+ fwd_id = f"{user1.id}
"
await m.reply_text(
text=f"""Original Sender - {orig_sender} ({orig_id}
)
- Forwarder - {fwd_sender} ({fwd_id}
)""",
+Forwarder - {fwd_sender} ({fwd_id}
)""",
parse_mode=enums.ParseMode.HTML,
)
else:
@@ -176,9 +191,10 @@ async def id_info(c: Gojo, m: Message):
text+=f"Forwarded from user ID {m.forward_from.id}
."
elif m.forward_from_chat:
text+=f"Forwarded from user ID {m.forward_from_chat.id}
."
- await m.reply_text()
+ await m.reply_text(text)
else:
- await m.reply_text(text=f"This Group's ID is {m.chat.id}
\nYour ID {m.from_user.id}
")
+ text=f"Chat ID {m.chat.id}
\nYour ID {m.from_user.id}
"
+ await m.reply_text(text)
return
@@ -209,14 +225,17 @@ async def github(_, m: Message):
f"Usage: {Config.PREFIX_HANDLER}github username
",
)
return
- username = username.split("/")[-1]
+ username = username.split("/")[-1].strip("@")
URL = f"https://api.github.com/users/{username}"
try:
- r = await get(URL, timeout=5)
- except asyncio.TimeoutError:
+ r = get(URL, timeout=5)
+ except requests.exceptions.ConnectTimeout:
return await m.reply_text("request timeout")
except Exception as e:
- return await m.reply_text(f"ERROR: `{e}`")
+ return await m.reply_text(f"ERROR:\n`{e}`")
+ if r.status_code != 200:
+ await m.reply_text(f"{username} this user is not available on github\nMake sure you have given correct username")
+ return
avtar = r.get("avatar_url", None)
url = r.get("html_url", None)
@@ -226,10 +245,10 @@ async def github(_, m: Message):
following = r.get("following", 0)
public_repos = r.get("public_repos", 0)
bio = r.get("bio", None)
- created_at = r.get("created_at", "Not Found")
+ created_at = r.get("created_at", "NA").replace("T", " ").replace("Z","")
location = r.get("location", None)
email = r.get("email", None)
- updated_at = r.get("updated_at", "Not Found")
+ updated_at = r.get("updated_at", "NA").replace("T", " ").replace("Z","")
blog = r.get("blog", None)
twitter = r.get("twitter_username", None)
@@ -254,10 +273,12 @@ async def github(_, m: Message):
REPLY += f"\nโ๏ธ Twitter: {twitter}"
if location:
REPLY += f"\n๐ Location: {location}
"
- REPLY += f"\n๐ซ Created at: {created_at}
"
- REPLY += f"\nโ๏ธ Updated at: {updated_at}
"
+ if created_at != "NA":
+ REPLY += f"\n๐ซ Created at: {created_at}
"
+ if updated_at != "NA":
+ REPLY += f"\nโ๏ธ Updated at: {updated_at}
"
if bio:
- REPLY += f"\n\n๐ฏ Bio: {bio}
"
+ REPLY += f"\n\n๐ฏ Bio: {bio}"
if avtar:
return await m.reply_photo(photo=f"{avtar}", caption=REPLY)
@@ -266,14 +287,14 @@ async def github(_, m: Message):
pattern = re.compile(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$")
-BASE = "https://batbin.me/"
+BASE = "https://nekobin.com/"
-async def paste(content: str):
- resp = await post(f"{BASE}api/v2/paste", data=content)
- if not resp["success"]:
+def paste(content: str):
+ resp = resp_post(f"{BASE}api/documents", data=content)
+ if resp.status_code != 200:
return
- return BASE + resp["message"]
+ return BASE + resp["result"]['key']
@Gojo.on_message(command("paste"))
@@ -289,7 +310,7 @@ async def paste_func(_, message: Message):
return await m.edit("Only text and documents are supported")
if r.text:
- content = str(r.text)
+ content = {'content':f'{r.text}'}
if r.document:
if r.document.file_size > 40000:
return await m.edit("You can only paste files smaller than 40KB.")
@@ -300,11 +321,14 @@ async def paste_func(_, message: Message):
doc = await message.reply_to_message.download()
async with aiofiles.open(doc, mode="r") as f:
- content = await f.read()
+ fdata = await f.read()
+ content = {'content':fdata}
remove(doc)
-
- link = await paste(content)
+ link = paste(content)
+ if not link:
+ await m.reply_text("Failed to post!")
+ return
kb = [[InlineKeyboardButton(text="Paste Link ", url=link)]]
await m.delete()
try:
@@ -347,9 +371,32 @@ async def tr(_, message):
f"Translated: from {detectlang} to {target_lang} \n``{tekstr.text}``
",
)
+@Gojo.on_message(command("bug"))
+async def reporting_query(c: Gojo, m: Message):
+ repl = m.reply_to_message
+ if not repl:
+ await m.reply_text("Please reply to a message to report it as bug")
+ return
+ if not repl.text:
+ await m.reply_text("Please reply to a text message.")
+ return
+ txt = "#BUG\n"
+ txt += repl.text.html
+ txt += f"\nReported by: {m.from_user.id} ({m.from_user.mention})"
+ kb = InlineKeyboardMarkup([[InlineKeyboardButton("Update channel",url=f"https://t.me/{SUPPORT_GROUP}")],[InlineKeyboardButton("Report on github",url="https://github.com/Gojo-Bots/Gojo_Satoru/issues/new/choose")]])
+ try:
+ z = await c.send_message(MESSAGE_DUMP,txt,parse_mode=enums.ParseMode.HTML)
+ except Exception:
+ txt = repl.text.html
+ z = await c.send_message(MESSAGE_DUMP,txt,parse_mode=enums.ParseMode.HTML)
+ await z.reply_text(f"#BUG\nReported by: {m.from_user.id} ({m.from_user.mention})")
+ await m.reply_text("Successfully reported your bug",reply_markup=kb)
+ ppost = z.link
+ await c.send_message(OWNER_ID,f"New bug report\n{ppost}",disable_web_page_preview=True)
+ return
__PLUGIN__ = "utils"
-_DISABLE_CMDS_ = ["paste", "wiki", "id", "gifid", "tr", "github", "git"]
+_DISABLE_CMDS_ = ["paste", "wiki", "id", "gifid", "tr", "github", "git", "bug"]
__alt_name__ = ["util", "misc", "tools"]
__HELP__ = """
@@ -365,6 +412,7 @@ async def tr(_, message):
โข /tr `{ef}
""",
)
- elif m.from_user.id in SCANLIST:
- msg = f"""
-** Alert โ ๏ธ**
-User {m.from_user.mention} is officially
-Scanned by TeamRed7 | Phoenix API ;)
-Appeal [Here](https://t.me/Red7WatchSupport)
- """
- try:
- await c.ban_chat_member(m.chat.id, m.from_user.id)
- await c.send_message(m.chat.id, msg, disable_web_page_preview=True)
- except Exception as a:
- LOGGER.error(a)
- LOGGER.error(format_exc())
- return
+
@Gojo.on_message(filters.chat(BLACKLIST_CHATS))
diff --git a/Powers/plugins/web_con.py b/Powers/plugins/web_con.py
new file mode 100644
index 00000000..22a51971
--- /dev/null
+++ b/Powers/plugins/web_con.py
@@ -0,0 +1,300 @@
+import asyncio
+import os
+from traceback import format_exc
+
+from pyrogram import filters
+from pyrogram.types import CallbackQuery
+from pyrogram.types import InlineKeyboardButton as IKB
+from pyrogram.types import InlineKeyboardMarkup as IKM
+from pyrogram.types import Message
+
+from Powers import (LOGGER, RMBG, Audd, genius_lyrics, is_audd,
+ is_genius_lyrics, is_rmbg)
+from Powers.bot_class import Gojo
+from Powers.utils.custom_filters import command
+from Powers.utils.http_helper import *
+from Powers.utils.sticker_help import toimage
+from Powers.utils.web_helpers import *
+
+
+@Gojo.on_message(command(["telegraph","tgh","tgm"]))
+async def telegraph_upload(c:Gojo,m:Message):
+ if not m.reply_to_message:
+ await m.reply_text("Reply to media/text to upload it to telegraph")
+ return
+ XnX = await m.reply_text("โณ")
+ file = m.reply_to_message
+ if file.text:
+ if len(m.command) == 1:
+ name = file.from_user.first_name + file.text.split()[1]
+ elif len(m.command) > 1:
+ name = " ".join(m.command[1:5])
+ try:
+ upload = await telegraph_up(file,name)
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ return
+ if upload:
+ await XnX.delete()
+ kb = IKM([[IKB("Here is link to the uploaded text",url=upload)]])
+ await m.reply_text("Here is your uploaded text",disable_web_page_preview=True,reply_markup=kb)
+ return
+ elif not upload:
+ await m.reply_text("Failed to upload the text to telegraph")
+ return
+ if m.reply_to_message.photo or m.reply_to_message.document or m.reply_to_message.audio or m.reply_to_message.video:
+ size = await get_file_size(m.reply_to_message)
+ form = size.split(None,1)
+ if (form[-1] == "mb" and int(form[0]) > 5) or form[-1] == "gb":
+ await XnX.edit_text("File size too big to upload\nLimit: 5mbs")
+ return
+ await XnX.delete()
+ try:
+ upload = await telegraph_up(file)
+ except Exception as e:
+ await m.reply_text(f"Got an error\n{e}")
+ return
+ if upload:
+ kb = IKM([[IKB("Here is link to the file",url=upload)]])
+ await m.reply_text(f"Here is your file link\n`{upload}`",reply_markup=kb)
+ return
+ elif not upload:
+ await m.reply_text("Failed to upload the file to telegraph")
+ return
+
+# @Gojo.on_message(command(["songname","insong","songinfo","whichsong","rsong","reversesong"]))
+# โข /whichsong (/songname, /songinfo, /insong, /rsong, /reversesong) : Reply to file to get the song playing in it.
+# async def get_song_info(c: Gojo, m: Message):
+# if not is_audd:
+# await m.reply_text("Audd api is missing add it to use this command")
+# return
+# reply = m.reply_to_message
+# if not reply:
+# await m.reply_text("Reply to a video or audio file")
+# return
+# elif reply.text:
+# await m.reply_text("Reply to a video or audio file")
+# return
+# elif not (reply.video or reply.audio or reply.video_note or reply.document and (reply.document.mime_type.split("/")[0] in ["video","audio"])):
+# await m.reply_text("Reply to a video or audio file")
+# return
+# try:
+# XnX = await m.reply_text("โณ")
+# URL = "https://api.audd.io/"
+# sizee = (await get_file_size(reply)).split()
+# if (int(sizee[0]) <= 30 and sizee[1] == "mb") or sizee[1] == "kb":
+# fpath = await reply.download()
+# files = {
+# "file" : open(fpath,"rb")
+# }
+# BASE_AUDD = {
+# "api_token":Audd,
+# "return": "spotify"
+# }
+# result = resp_post(URL,data=BASE_AUDD, files=files)
+# # elif int(sizee[0]) > 15 or int(sizee[0]) <= 30 and sizee[1] == "mb":
+# # BASE_AUDD = {
+# # "api_token":Audd,
+# # "url": f'{reply.link}',
+# # "return": "spotify"
+# # }
+# # result = resp_post(URL,data=BASE_AUDD)
+# else:
+# await XnX.edit_text("File size too big\nI can only fetch file of size upto 30 mbs for now")
+# return
+# if result.status_code != 200:
+# await XnX.edit_text(f"{result.status_code}:{result.text}")
+# return
+# result = result.json()
+# data = result["result"]
+# Artist = data["artist"]
+# Title = data["title"]
+# Release_date = data["release_date"]
+# web_slink = data["song_link"]
+# SPOTIFY = data["spotify"]
+# spotify_url = SPOTIFY["external_urls"]
+# album_url = SPOTIFY["album"]["external_urls"]
+# Album = SPOTIFY["album"]["name"]
+# photo = SPOTIFY["images"][0]["url"]
+# artist_url = SPOTIFY["artists"]["external_urls"]
+# cap = f"""
+# Song name: {Title}
+# Artist: {Artist}
+# Album: {Album}
+# Release data: {Release_date}
+# """
+# youtube_link = (await song_search(Title))[1]["link"]
+# kb = [
+# [
+# IKB("๐ Album", url=album_url),
+# IKB("๐จ Artist",url=artist_url)
+# ],
+# [
+# IKB("๐ต Spotify song link",url=spotify_url),
+# IKB("โถ๏ธ Youtube",url=youtube_link)
+# ],
+# [IKB("โพ More links", url=web_slink)]
+# ]
+# if is_genius_lyrics:
+# g_k = [IKB("๐ Lyrics",f"lyrics_{Title}:{Artist}")]
+# kb.append(g_k)
+# await XnX.delete()
+# os.remove(fpath)
+# await m.reply_photo(photo,caption=cap,reply_markup=IKM(kb))
+# except Exception as e:
+# await XnX.delete()
+# await m.reply_text(f"Error\n{e}")
+# try:
+# os.remove(fpath)
+# except Exception:
+# pass
+# return
+
+
+@Gojo.on_callback_query(filters.regex("^lyrics_"))
+async def lyrics_for_song(c: Gojo, q: CallbackQuery):
+ data = q.data.split("_")[1].split(":")
+ song = data[0]
+ try:
+ artist = data[1]
+ except IndexError:
+ artist = None
+ if artist:
+ song = genius_lyrics.search_song(song,artist)
+ elif not artist:
+ song = genius_lyrics.search_song(song)
+ if not song.lyrics:
+ await q.answer("โผ๏ธ No lyrics found โผ๏ธ",True)
+ return
+ header = f"{song.capitalize()} by {artist}"
+ if song.lyrics:
+ await q.answer("Fetching lyrics")
+ reply = song.lyrics.split("\n",1)[1]
+ if len(reply) >= 4096:
+ link = telegraph_up(name=header,content=reply)
+ cap = "Lyrics was too long\nUploaded it to telegraph"
+ new_kb = [
+ [
+ IKB("Telegraph",url=link)
+ ],
+ [
+ IKB("Close","f_close")
+ ]
+ ]
+ else:
+ cap = f"{header}\n{reply}"
+ new_kb = [
+ [
+ IKB("Close","f_close")
+ ]
+ ]
+ await q.message.reply_to_message.reply_text(cap,reply_markup=new_kb)
+ await q.message.delete()
+ return
+
+@Gojo.on_message(command(["removebackground","removebg","rmbg"]))
+async def remove_background(c: Gojo, m: Message):
+ if not is_rmbg:
+ await m.reply_text("Add rmbg api to use this command")
+ return
+
+ reply = m.reply_to_message
+ if not reply:
+ await m.reply_text("Reply to image/sticker to remove it's background")
+ return
+ elif not (reply.photo or (reply.document and reply.document.mime_type.split("/")[0] == "image") or reply.sticker):
+ await m.reply_text("Reply to image/sticker to remove it's background")
+ return
+ elif reply.sticker and (reply.sticker.is_video or reply.sticker.is_animated):
+ await m.reply_text("Reply to normal sticker to remove it's background")
+ return
+ XnX = await m.reply_text("โณ")
+ URL = "https://api.remove.bg/v1.0/removebg"
+ if reply.sticker:
+ filee = await reply.download()
+ file = toimage(filee)
+ else:
+ file = await reply.download()
+ finfo = {'image_file':open(file,'rb')}
+ Data = {'size':'auto'}
+ Headers = {'X-Api-Key':RMBG}
+ result = resp_post(URL,files=finfo,data=Data,headers=Headers)
+ await XnX.delete()
+ contentType = result.headers.get("content-type")
+ if result.status_code != 200:
+ await m.reply_text(f"{result.status_code}:{result.text}")
+ os.remove(file)
+ return
+ elif "image" not in contentType:
+ await m.reply_text(f"Error\n{result.content.decode('UTF-8')}")
+ os.remove(file)
+ return
+ to_path = "./downloads"
+ if reply.sticker:
+ to_path = f'{to_path}/no-bg.webp'
+ else:
+ to_path = f'{to_path}/no-bg.png'
+ with open(to_path,'wb') as out:
+ out.write(result.content)
+ if reply.sticker:
+ await m.reply_sticker(to_path)
+ else:
+ await m.reply_photo(to_path)
+ try:
+ os.remove(file)
+ os.remove(to_path)
+ except PermissionError:
+ await asyncio.sleep(5)
+ return
+
+@Gojo.on_message(command(["song","yta"]))
+async def song_down_up(c: Gojo, m: Message):
+ splited = m.text.split(None,1)[1].strip()
+ if splited.startswith("https://youtube.com"):
+ is_direct = True
+ query = splited
+ else:
+ is_direct = False
+ query = splited
+ XnX = await m.reply_text("โณ")
+ try:
+ await youtube_downloader(c,m,query,is_direct,"a")
+ await XnX.delete()
+ return
+ except Exception as e:
+ await XnX.edit_text(f"Got an error\n{e}")
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
+ return
+
+@Gojo.on_message(command(["vsong","ytv"]))
+async def video_down_up(c: Gojo, m: Message):
+ splited = m.text.split(None,1)[1].strip()
+ if splited.startswith("https://youtube.com"):
+ is_direct = True
+ query = splited
+ else:
+ is_direct = False
+ query = splited
+ XnX = await m.reply_text("โณ")
+ try:
+ await youtube_downloader(c,m,query,is_direct,"v")
+ await XnX.delete()
+ return
+ except Exception as e:
+ await XnX.edit_text(f"Got an error\n{e}")
+ LOGGER.error(e)
+ LOGGER.error(format_exc())
+ return
+
+__PLUGIN__ = "web support"
+
+__HELP__ = """
+**Available commands**
+โข /telegraph (/tgh, /tgm)