From e58eb2ad4aaf050727cac03b2d61f3e560a4ad7c Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Fri, 5 Jan 2024 00:25:20 +0530 Subject: [PATCH 01/19] Pre update bug fixes --- Powers/plugins/bans.py | 20 ++++++++++++++++++-- Powers/plugins/greetings.py | 10 +++++++++- Powers/plugins/locks.py | 2 +- Powers/plugins/scheduled_jobs.py | 6 +++--- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py index 77546880..b558fb55 100644 --- a/Powers/plugins/bans.py +++ b/Powers/plugins/bans.py @@ -3,7 +3,7 @@ from pyrogram import enums from pyrogram.errors import (ChatAdminRequired, PeerIdInvalid, RightForbidden, - RPCError, UserAdminInvalid) + RPCError, UserAdminInvalid, UserNotParticipant) from pyrogram.filters import regex from pyrogram.types import (CallbackQuery, ChatPrivileges, InlineKeyboardButton, InlineKeyboardMarkup, @@ -137,6 +137,8 @@ async def tban_usr(c: Gojo, m: Message): await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RightForbidden: await m.reply_text(text="I don't have enough rights to ban this user.") except RPCError as ef: @@ -227,6 +229,8 @@ async def stban_usr(c: Gojo, m: Message): await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RightForbidden: await m.reply_text(text="I don't have enough rights to ban this user.") except RPCError as ef: @@ -444,6 +448,8 @@ async def kick_usr(c: Gojo, m: Message): await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RightForbidden: await m.reply_text(text="I don't have enough rights to ban this user.") except RPCError as ef: @@ -512,6 +518,8 @@ async def skick_usr(c: Gojo, m: Message): await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RightForbidden: await m.reply_text(text="I don't have enough rights to kick this user.") except RPCError as ef: @@ -601,6 +609,8 @@ async def dkick_usr(c: Gojo, m: Message): ) except RightForbidden: await m.reply_text(text="I don't have enough rights to kick this user.") + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RPCError as ef: await m.reply_text( text=f"""Some error occured, report it using `/bug` @@ -730,6 +740,8 @@ async def sban_usr(c: Gojo, m: Message): ) except RightForbidden: await m.reply_text(text="I don't have enough rights to ban this user.") + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RPCError as ef: await m.reply_text( text=f"""Some error occured, report it using `/bug` @@ -830,6 +842,8 @@ async def dban_usr(c: Gojo, m: Message): ) except RightForbidden: await m.reply_text(text="I don't have enough rights to ban this user.") + except UserNotParticipant: + await m.reply_text("User is not part of the group") except RPCError as ef: await m.reply_text( text=f"""Some error occured, report it using `/bug` @@ -938,6 +952,8 @@ async def ban_usr(c: Gojo, m: Message): await m.reply_text( "I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?", ) + except UserNotParticipant: + await m.reply_text("User is not part of the group") except UserAdminInvalid: await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." @@ -968,7 +984,7 @@ async def unbanbutton(c: Gojo, q: CallbackQuery): ) return - if not user.privileges.can_restrict_members and q.from_user.id != OWNER_ID: + elif user and not user.privileges.can_restrict_members and q.from_user.id != OWNER_ID: await q.answer( "You don't have enough permission to do this!\nStay in your limits!", show_alert=True, diff --git a/Powers/plugins/greetings.py b/Powers/plugins/greetings.py index b9cdbd85..98fa1ce6 100644 --- a/Powers/plugins/greetings.py +++ b/Powers/plugins/greetings.py @@ -2,7 +2,7 @@ from secrets import choice from traceback import format_exc -from pyrogram import enums, filters +from pyrogram import emoji, enums, filters from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.errors import ChatAdminRequired, RPCError from pyrogram.types import ChatMemberUpdated, Message @@ -301,6 +301,10 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): teks = choice(filter_reply) else: teks = tek + + if not teks: + teks = f"A wild {user.mention} appeared in {member.chat.title}! Everyone be aware." + ifff = db.get_current_cleanwelcome_id() gg = db.get_current_cleanwelcome_settings() if ifff and gg: @@ -375,6 +379,10 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): teks = choice(filter_reply) else: teks = tek + + if not teks: #Just in case + teks = f"Thanks for being part of this group {user.mention}. But I don't like your arrogance and leaving the group {emoji.EYES}" + ifff = db.get_current_cleangoodbye_id() iii = db.get_current_cleangoodbye_settings() if ifff and iii: diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index a877499c..df5cf3f4 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -478,7 +478,7 @@ async def lock_del_mess(c:Gojo, m: Message): all_chats = lock.get_lock_channel() if not all_chats: return - if m.chat.id not in all_chats: + if m.chat and m.chat.id not in all_chats: return if m.sender_chat and not (m.forward_from_chat or m.forward_from): if m.sender_chat.id == m.chat.id: diff --git a/Powers/plugins/scheduled_jobs.py b/Powers/plugins/scheduled_jobs.py index 923cb743..f610dbee 100644 --- a/Powers/plugins/scheduled_jobs.py +++ b/Powers/plugins/scheduled_jobs.py @@ -1,4 +1,4 @@ -import time +import time as TIME from asyncio import sleep from traceback import format_exc @@ -28,7 +28,7 @@ async def clean_my_db(c:Client,is_cmd=False, id=None): to_clean = list() chats_list = Chats.list_chats_by_id() to_clean.clear() - start = time.time() + start = TIME.time() for chats in chats_list: try: stat = await c.get_chat_member(chat_id=chats,user_id=Config.BOT_ID) @@ -60,7 +60,7 @@ async def clean_my_db(c:Client,is_cmd=False, id=None): x = len(to_clean) txt = f"#INFO\n\nCleaned db:\nTotal chats removed: {x}" to_clean.clear() - nums = time.time()-start + nums = TIME.time()-start if is_cmd: txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}" txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process" From ad95a0b8a7ec22127485aa906a889830591cfae8 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Fri, 5 Jan 2024 02:25:23 +0530 Subject: [PATCH 02/19] Pre planned features for `V 2.2.0` --- Powers/__init__.py | 12 +-- Powers/plugins/afk.py | 161 +++++++++++++++++++++++++++++++++ Powers/plugins/auto_join.py | 146 ++++++++++++++++++++++++++++++ Powers/plugins/botstaff.py | 57 ------------ Powers/plugins/flood.py | 32 +------ Powers/plugins/start.py | 59 +++++++++++- Powers/plugins/stickers.py | 26 ++++++ Powers/plugins/utils.py | 59 +++++++++++- Powers/utils/custom_filters.py | 74 ++++++++++++++- Powers/utils/extract_user.py | 1 + Powers/utils/start_utils.py | 5 +- Powers/utils/sticker_help.py | 151 +++++++------------------------ Powers/vars.py | 2 +- 13 files changed, 564 insertions(+), 221 deletions(-) create mode 100644 Powers/plugins/afk.py create mode 100644 Powers/plugins/auto_join.py delete mode 100644 Powers/plugins/botstaff.py diff --git a/Powers/__init__.py b/Powers/__init__.py index 04196bf2..bab53c74 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -96,12 +96,12 @@ is_genius_lyrics = False 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_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 diff --git a/Powers/plugins/afk.py b/Powers/plugins/afk.py new file mode 100644 index 00000000..7439f53e --- /dev/null +++ b/Powers/plugins/afk.py @@ -0,0 +1,161 @@ +from datetime import datetime +from random import choice + +from pyrogram import filters +from pyrogram.enums import ParseMode as PM +from pyrogram.types import Message + +from Powers.bot_class import Gojo +from Powers.database.afk_db import AFK +from Powers.plugins import till_date +from Powers.utils.cmd_senders import send_cmd +from Powers.utils.custom_filters import afk_filter, command +from Powers.utils.msg_types import Types, get_afk_type + +res = [ + "{first} is resting for a while...", + "{first} living his real life, go and live yours.", + "{first} is quite busy now-a-days.", + "I am looking for {first} too...tell me if you see him/her around", + "{first} ran away from the chat...", + "{first} is busy in his/her work ||simping||", + "{first} is busy saving the world", + "{first} is now tired fighting all the curses" +] + +back = [ + "{first} is finally back to life", + "{first} welcome back", + "{first} the spy is back watch what you talk about" + "{first} is now finally back from the dead" +] + +@Gojo.on_message(command(["afk","brb"]) & ~filters.private) +async def going_afk(c: Gojo, m: Message): + user = m.from_user.id + chat = m.chat.id + afk = AFK() + text, data_type, content = await get_afk_type(m) + + time = str(datetime.now()).rsplit(".",1)[0] + + if len(m.command) == 1: + text = choice(res) + + elif len(m.command) > 1: + text = m.text.markdown.split(None,1)[1] + + if not data_type: + data_type = Types.TEXT + + afk.insert_afk(chat,user,str(time),text,data_type,content) + + await m.reply_text(f"{m.from_user.mention} is now AFK") + + return + +async def get_hours(hour:str): + tim = hour.strip().split(":") + txt = "" + if int(tim[0]): + txt += tim[0] + " hours " + if int(tim[1]): + txt += tim[1] + " minutes " + if int(round(float(tim[2]))): + txt += str(round(float(tim[2]))) + " seconds" + + return txt + + +@Gojo.on_message(afk_filter) +async def afk_checker(c: Gojo, m: Message): + afk = AFK() + back_ = choice(back) + user = m.from_user.id + chat = m.chat.id + repl = m.reply_to_message + + if repl and repl.from_user: + rep_user = repl.from_user.id + else: + rep_user = False + + is_afk = afk.check_afk(chat,user) + is_rep_afk = False + if rep_user: + is_rep_afk = afk.check_afk(chat,rep_user) + + if is_rep_afk and rep_user != user: + con = afk.get_afk(chat,rep_user) + time = till_date(con["time"]) + media = con["media"] + media_type = con["media_type"] + tim_ = datetime.now() - time + tim_ = str(tim_).split(",") + tim = await get_hours(tim_[-1]) + if len(tim_) == 1: + tims = tim + elif len(tim_) == 2: + tims = tim_[0] + " " + tim + reason = f"{repl.from_user.first_name} is afk since {tims}\n" + if con['reason'] not in res: + reason += f"\nDue to: {con['reason'].format(first=repl.from_user.first_name)}" + else: + reason += f"\n{con['reason'].format(first=repl.from_user.first_name)}" + txt = reason + + if media_type == Types.TEXT: + await (await send_cmd(c,media_type))( + chat, + txt, + parse_mode=PM.MARKDOWN, + reply_to_message_id=m.id, + ) + else: + await (await send_cmd(c,media_type))( + chat, + media, + txt, + parse_mode=PM.MARKDOWN, + reply_to_message_id=repl.id + ) + + if is_afk: + txt = False + try: + txt = m.command[0] + except Exception: + pass + + if txt and txt in ["afk","brb"]: + return + else: + con = afk.get_afk(chat,user) + time = till_date(con["time"]) + tim_ = datetime.now() - time + tim_ = str(tim_).split(",") + tim = await get_hours(tim_[-1]) + if len(tim_) == 1: + tims = tim + elif len(tim_) == 2: + tims = tim_[0] + " " + tim + txt = back_.format(first=m.from_user.mention) + f"\n\nAfk for: {tims}" + await m.reply_text(txt) + afk.delete_afk(chat,user) + return + +__PLUGIN__ = "afk" + +_DISABLE_CMDS_ = ["afk","brb"] + +__alt_name__ = ["brb"] + +__HELP__ = """ +**AFK** +• /afk (/brb) [reason | reply to a message] + +`reply to a message` can be any media or text +""" + + + diff --git a/Powers/plugins/auto_join.py b/Powers/plugins/auto_join.py new file mode 100644 index 00000000..72b4ad50 --- /dev/null +++ b/Powers/plugins/auto_join.py @@ -0,0 +1,146 @@ +from pyrogram import filters +from pyrogram.enums import ChatMemberStatus as CMS +from pyrogram.types import CallbackQuery, ChatJoinRequest +from pyrogram.types import InlineKeyboardButton as ikb +from pyrogram.types import InlineKeyboardMarkup as ikm +from pyrogram.types import Message + +from Powers.bot_class import Gojo +from Powers.database.autojoin_db import AUTOJOIN +from Powers.supports import get_support_staff +from Powers.utils.custom_filters import admin_filter, auto_join_filter, command + +SUPPORT_STAFF = get_support_staff() + +@Gojo.on_message(command(["joinreq"]) & admin_filter) +async def accept_join_requests(c: Gojo, m: Message): + if m.chat.id == m.from_user.id: + await m.reply_text("Use it in groups") + return + + split = m.command + a_j = AUTOJOIN() + + if len(split) == 1: + txt = "**USAGE**\n/joinreq [on | off]" + await m.reply_text(txt) + return + else: + yes_no = split[1].lower() + if yes_no not in ["on","off"]: + txt = "**USAGE**\n/joinreq [on | off]" + await m.reply_text(txt) + return + + else: + if yes_no == "on": + is_al = a_j.load_autojoin(m.chat.id) + + if is_al: + txt = "Now I will approve all the join request of the chat\nIf you want that I will just notify admins about the join request use command\n//joinreqmode [manual | auto]" + await m.reply_text(txt) + return + else: + txt = "Auto approve join request is already on for this chat\nIf you want that I will just notify admins about the join request use command\n/joinreqmode [manual | auto]" + await m.reply_text(txt) + return + + elif yes_no == "off": + a_j.remove_autojoin(m.chat.id) + txt = "Now I will neither auto approve join request nor notify any admins about it" + await m.reply_text(txt) + return + +@Gojo.on_message(command("joinreqmode") & admin_filter) +async def join_request_mode(c: Gojo, m: Message): + if m.chat.id == m.from_user.id: + await m.reply_text("Use it in groups") + return + u_text = "**USAGE**\n/joinreqmode [auto | manual]\nauto: auto approve joins\nmanual: will notify admin about the join request" + + split = m.command + a_j = AUTOJOIN() + + if len(split) == 1: + await m.reply_text(u_text) + return + + else: + auto_manual = split[1] + if auto_manual not in ["auto","manual"]: + await m.reply_text(u_text) + return + else: + a_j.update_join_type(m.chat.id,auto_manual) + txt = "Changed join request type" + await m.reply_text(txt) + return + + +@Gojo.on_chat_join_request(auto_join_filter) +async def join_request_handler(c: Gojo, j: ChatJoinRequest): + user = j.from_user.id + userr = j.from_user + chat = j.chat.id + aj = AUTOJOIN() + join_type = aj.get_autojoin(chat) + + if not join_type: + return + if join_type == "auto" or user in SUPPORT_STAFF: + await c.approve_chat_join_request(chat,user) + + elif join_type == "manual": + txt = "New join request is available\n**USER's INFO**\n" + txt += f"Name: {userr.first_name} {userr.last_name if userr.last_name else ''}" + txt += f"Mention: {userr.mention}" + txt += f"Id: {user}" + txt += f"Scam: {'True' if userr.is_scam else 'False'}" + if userr.username: + txt+= f"Username: @{userr.username}" + kb = [ + [ + ikb("Accept",f"accept_joinreq_uest_{user}"), + ikb("Decline",f"decline_joinreq_uest_{user}") + ] + ] + await c.send_message(chat,txt,reply_markup=ikm(kb)) + return + +@Gojo.on_callback_query(filters.regex("^accept_joinreq_uest_") | filters.regex("^decline_joinreq_uest_")) +async def accept_decline_request(c:Gojo, q: CallbackQuery): + user_id = q.from_user.id + user_status = (await q.message.chat.get_member(user_id)).status + if user_status not in {CMS.OWNER, CMS.ADMINISTRATOR}: + await q.answer( + "You're not even an admin, don't try this explosive shit!", + show_alert=True, + ) + return + + split = q.data.split("_") + chat = q.message.chat.id + user = int(split[-1]) + data = split[0] + + if data == "accept": + await c.approve_chat_join_request(chat,user) + await q.answer(f"APPROVED: {user}",True) + elif data == "decline": + await c.decline_chat_join_request(chat,user) + await q.answer(f"DECLINED: {user}") + + return + +__PLUGIN__ = "auto join" + +__alt_name__ = ["join_request"] + + +__HELP__ = """ +**Auto join request** + +**Admin commands:** +• /joinreq [on | off]: To switch on auto accept join request +• /joinreqmode [auto | manual]: `auto` to accept join request automatically and `manual` to get notified when new join request is available +""" \ No newline at end of file diff --git a/Powers/plugins/botstaff.py b/Powers/plugins/botstaff.py deleted file mode 100644 index a19ab60d..00000000 --- a/Powers/plugins/botstaff.py +++ /dev/null @@ -1,57 +0,0 @@ -from pyrogram.errors import RPCError -from pyrogram.types import Message - -from Powers import LOGGER, OWNER_ID, WHITELIST_USERS -from Powers.bot_class import Gojo -from Powers.supports import get_support_staff -from Powers.utils.custom_filters import command -from Powers.utils.parser import mention_html - -DEV_USERS = get_support_staff("dev") -SUDO_USERS = get_support_staff("sudo") - -@Gojo.on_message(command("botstaff", dev_cmd=True)) -async def botstaff(c: Gojo, m: Message): - try: - owner = await c.get_users(OWNER_ID) - reply = f"🌟 Owner: {(await mention_html(owner.first_name, OWNER_ID))} ({OWNER_ID})\n" - except RPCError: - pass - true_dev = list(set(DEV_USERS) - {OWNER_ID}) - reply += "\nDevelopers ⚡️:\n" - if not true_dev: - reply += "No Dev Users\n" - else: - for each_user in true_dev: - user_id = int(each_user) - try: - user = await c.get_users(user_id) - reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" - except RPCError: - pass - true_sudo = list(set(SUDO_USERS) - set(DEV_USERS)) - reply += "\nSudo Users 🐉:\n" - if true_sudo == []: - reply += "No Sudo Users\n" - else: - for each_user in true_sudo: - user_id = int(each_user) - try: - user = await c.get_users(user_id) - reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" - except RPCError: - pass - reply += "\nWhitelisted Users 🐺:\n" - if WHITELIST_USERS == []: - reply += "No additional whitelisted users\n" - else: - for each_user in WHITELIST_USERS: - user_id = int(each_user) - try: - user = await c.get_users(user_id) - reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" - except RPCError: - pass - await m.reply_text(reply) - LOGGER.info(f"{m.from_user.id} fetched botstaff in {m.chat.id}") - return diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 8459091f..06cc19dc 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -15,7 +15,7 @@ from Powers.database.approve_db import Approve from Powers.database.flood_db import Floods from Powers.supports import get_support_staff -from Powers.utils.custom_filters import admin_filter, command +from Powers.utils.custom_filters import admin_filter, command, flood_filter from Powers.utils.extras import BAN_GIFS, KICK_GIFS, MUTE_GIFS from Powers.utils.kbhelpers import ikb from Powers.vars import Config @@ -330,41 +330,17 @@ async def reverse_callbacks(c: Gojo, q: CallbackQuery): return dic = {} -@Gojo.on_message(filters.all & ~filters.bot | ~filters.private, 10) +@Gojo.on_message(flood_filter & ~admin_filter) async def flood_watcher(c: Gojo, m: Message): c_id = m.chat.id - if not m.chat: - return - Flood = Floods() - try: - u_id = m.from_user.id - except AttributeError: - return # Get this error when the message received is not by an user and return + u_id = m.from_user.id is_flood = Flood.is_chat(c_id) - if not is_flood: - return # return of chat is not in anti flood protection - - app_users = Approve(m.chat.id).list_approved() - - if u_id in {i[0] for i in app_users}: - return #return if the user is approved - - if not is_flood or u_id in SUPPORT_STAFF: - return #return if the user is in support_staff - - try: - user_status = (await m.chat.get_member(m.from_user.id)).status - except Exception: - return - - if user_status in [CMS.OWNER, CMS.ADMINISTRATOR]: - return #return if the user is owner or admin - + action = is_flood[2] limit = int(is_flood[0]) within = int(is_flood[1]) diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index 620fdbf1..ba67cce7 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -1,4 +1,3 @@ -import os from random import choice from time import gmtime, strftime, time @@ -6,16 +5,18 @@ from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.enums import ChatType from pyrogram.errors import (MediaCaptionTooLong, MessageNotModified, - QueryIdInvalid, UserIsBlocked) + QueryIdInvalid, RPCError, UserIsBlocked) from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import (HELP_COMMANDS, LOGGER, PYROGRAM_VERSION, PYTHON_VERSION, - UPTIME, VERSION) +from Powers import (HELP_COMMANDS, LOGGER, OWNER_ID, PYROGRAM_VERSION, + PYTHON_VERSION, UPTIME, VERSION, WHITELIST_USERS) from Powers.bot_class import Gojo +from Powers.supports import get_support_staff from Powers.utils.custom_filters import command from Powers.utils.extras import StartPic from Powers.utils.kbhelpers import ikb +from Powers.utils.parser import mention_html from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg, get_private_note, get_private_rules) from Powers.vars import Config @@ -301,3 +302,53 @@ async def get_module_info(c: Gojo, q: CallbackQuery): await c.send_message(chat_id=q.message.chat.id,text=help_msg,) await q.answer() return + +DEV_USERS = get_support_staff("dev") +SUDO_USERS = get_support_staff("sudo") + +@Gojo.on_callback_query(filters.regex("^give_bot_staffs$")) +async def give_bot_staffs(c: Gojo, q: CallbackQuery): + try: + owner = await c.get_users(OWNER_ID) + reply = f"🌟 Owner: {(await mention_html(owner.first_name, OWNER_ID))} ({OWNER_ID})\n" + except RPCError: + pass + true_dev = list(set(DEV_USERS) - {OWNER_ID}) + reply += "\nDevelopers ⚡️:\n" + if not true_dev: + reply += "No Dev Users\n" + else: + for each_user in true_dev: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + true_sudo = list(set(SUDO_USERS) - set(DEV_USERS)) + reply += "\nSudo Users 🐉:\n" + if true_sudo == []: + reply += "No Sudo Users\n" + else: + for each_user in true_sudo: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + reply += "\nWhitelisted Users 🐺:\n" + if WHITELIST_USERS == []: + reply += "No additional whitelisted users\n" + else: + for each_user in WHITELIST_USERS: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + + await q.edit_message_caption(reply,reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("« Back","start_back")]])) + return + diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index f2fd72f5..2d6ba98e 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -241,6 +241,32 @@ async def kang(c:Gojo, m: Message): LOGGER.error(format_exc()) return +@Gojo.on_message(command(["rmsticker", "removesticker"])) +async def remove_sticker_from_pack(c: Gojo, m: Message): + if not m.reply_to_message or not m.reply_to_message.sticker: + return await m.reply_text( + "Reply to a sticker to remove it from the pack." + ) + + sticker = m.reply_to_message.sticker + + to_modify = await m.reply_text(f"Removing the sticker from your pack") + sticker_set = await get_sticker_set_by_name(c, sticker.set_name) + + if not sticker_set: + await to_modify.edit_text("This sticker is not part for your pack") + return + + try: + await remove_sticker(c, sticker.file_id) + await to_modify.edit_text(f"Successfully removed [sticker]({m.reply_to_message.link}) from {sticker_set.set.title}") + except Exception as e: + await to_modify.delete() + await m.reply_text(f"Failed to remove sticker due to:\n{e}\nPlease report this bug using `/bug`") + LOGGER.error(e) + LOGGER.error(format_exc()) + return + @Gojo.on_message(command(["mmfb","mmfw","mmf"])) async def memify_it(c: Gojo, m: Message): diff --git a/Powers/plugins/utils.py b/Powers/plugins/utils.py index 0dc983c2..dfdc4558 100644 --- a/Powers/plugins/utils.py +++ b/Powers/plugins/utils.py @@ -6,7 +6,7 @@ import aiofiles from gpytranslate import Translator from pyrogram import enums, filters -from pyrogram.errors import MessageTooLong, PeerIdInvalid +from pyrogram.errors import MessageTooLong, PeerIdInvalid, RPCError from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from wikipedia import summary from wikipedia.exceptions import DisambiguationError, PageError @@ -21,6 +21,9 @@ from Powers.utils.http_helper import * from Powers.utils.parser import mention_html +DEV_USERS = get_support_staff("dev") +SUDO_USERS = get_support_staff("sudo") + @Gojo.on_message(command("wiki")) async def wiki(_, m: Message): @@ -331,8 +334,8 @@ async def paste_func(_, message: Message): content = r.text exe = "txt" if r.document: - if r.document.file_size > 40000: - return await m.edit("You can only paste files smaller than 40KB.") + # if r.document.file_size > 40000: + # return await m.edit("You can only paste files smaller than 40KB.") if not pattern.search(r.document.mime_type): return await m.edit("Only text files can be pasted.") @@ -419,6 +422,54 @@ async def reporting_query(c: Gojo, m: Message): await c.send_message(OWNER_ID,f"New bug report\n{ppost}",disable_web_page_preview=True) return + +@Gojo.on_message(command("botstaffs")) +async def botstaff(c: Gojo, m: Message): + try: + owner = await c.get_users(OWNER_ID) + reply = f"🌟 Owner: {(await mention_html(owner.first_name, OWNER_ID))} ({OWNER_ID})\n" + except RPCError: + pass + true_dev = list(set(DEV_USERS) - {OWNER_ID}) + reply += "\nDevelopers ⚡️:\n" + if not true_dev: + reply += "No Dev Users\n" + else: + for each_user in true_dev: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + true_sudo = list(set(SUDO_USERS) - set(DEV_USERS)) + reply += "\nSudo Users 🐉:\n" + if true_sudo == []: + reply += "No Sudo Users\n" + else: + for each_user in true_sudo: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + reply += "\nWhitelisted Users 🐺:\n" + if WHITELIST_USERS == []: + reply += "No additional whitelisted users\n" + else: + for each_user in WHITELIST_USERS: + user_id = int(each_user) + try: + user = await c.get_users(user_id) + reply += f"• {(await mention_html(user.first_name, user_id))} ({user_id})\n" + except RPCError: + pass + await m.reply_text(reply) + LOGGER.info(f"{m.from_user.id} fetched botstaff in {m.chat.id}") + return + + __PLUGIN__ = "utils" _DISABLE_CMDS_ = ["paste", "wiki", "id", "gifid", "tr", "github", "git", "bug"] __alt_name__ = ["util", "misc", "tools"] @@ -429,7 +480,6 @@ async def reporting_query(c: Gojo, m: Message): Some utils provided by bot to make your tasks easy! • /id: Get the current group id. If used by replying to a message, get that user's id. -• /info: Get information about a user. • /gifid: Reply to a gif to me to tell you its file ID. • /lyrics ``-`` : Find your song and give the lyrics of the song • /wiki: ``: wiki your query. @@ -437,6 +487,7 @@ async def reporting_query(c: Gojo, m: Message): • /git ``: Search for the user using github api! • /weebify `` or ``: To weebify the text. • /bug : To report a bug +• /botstaffs : Give the list of the bot staffs. **Example:** `/git iamgojoof6eyes`: this fetches the information about a user from the database.""" diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 570a1477..521ee73e 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -7,10 +7,14 @@ from pyrogram.enums import ChatType from pyrogram.errors import RPCError, UserNotParticipant from pyrogram.filters import create -from pyrogram.types import CallbackQuery, Message +from pyrogram.types import CallbackQuery, ChatJoinRequest, Message from Powers import DEV_USERS, OWNER_ID, SUDO_USERS +from Powers.database.afk_db import AFK +from Powers.database.approve_db import Approve +from Powers.database.autojoin_db import AUTOJOIN from Powers.database.disable_db import Disabling +from Powers.database.flood_db import Floods from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.vars import Config @@ -302,7 +306,75 @@ async def can_pin_message_func(_, __, m): return status +async def auto_join_check_filter(_, __, j: ChatJoinRequest): + chat = j.chat.id + aj = AUTOJOIN() + join_type = aj.get_autojoin(chat) + + if not join_type: + return False + else: + return True + +async def afk_check_filter(_, __, m: Message): + if not m.from_user: + return False + + if m.from_user.is_bot: + return False + + if m.chat.type == ChatType.PRIVATE: + return False + + afk = AFK() + user = m.from_user.id + chat = m.chat.id + repl = m.reply_to_message + + if repl and repl.from_user: + rep_user = repl.from_user.id + else: + rep_user = False + + is_afk = afk.check_afk(chat,user) + is_rep_afk = False + if rep_user: + is_rep_afk = afk.check_afk(chat,rep_user) + + if not is_rep_afk and not is_afk: + return False + else: + return True + +async def flood_check_filter(_, __, m: Message): + Flood = Floods() + if not m.chat: + return False + + if not m.from_user: + return False + + if m.chat.type == ChatType.PRIVATE: + return False + + u_id = m.from_user.id + c_id = m.chat.id + is_flood = Flood.is_chat(c_id) + + app_users = Approve(m.chat.id).list_approved() + + if not is_flood or u_id in SUDO_LEVEL: + return False + + elif u_id in {i[0] for i in app_users}: + return False + + else: + return True +flood_filter = create(flood_check_filter) +afk_filter = create(afk_check_filter) +auto_join_filter = create(auto_join_check_filter) admin_filter = create(admin_check_func) owner_filter = create(owner_check_func) restrict_filter = create(restrict_check_func) diff --git a/Powers/utils/extract_user.py b/Powers/utils/extract_user.py index ebbb18fd..69bfa0d0 100644 --- a/Powers/utils/extract_user.py +++ b/Powers/utils/extract_user.py @@ -98,6 +98,7 @@ async def extract_user(c: Gojo, m: Message) -> Tuple[int, str, str]: user = await c.get_users(user_r.user_id) except Exception as ef: return await m.reply_text(f"User not found ! Error: {ef}") + user_id = user.id user_first_name = user.first_name user_name = user.username LOGGER.error(ef) diff --git a/Powers/utils/start_utils.py b/Powers/utils/start_utils.py index 6ff56041..74ef1fa1 100644 --- a/Powers/utils/start_utils.py +++ b/Powers/utils/start_utils.py @@ -44,9 +44,8 @@ async def gen_start_kb(q: Message or CallbackQuery): "url", ), ( - "Support 👥", - f"https://t.me/{SUPPORT_GROUP}", - "url", + "Bot Staffs 🚔", + f"give_bot_staffs", ), ], [ diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index d7bfcfc5..04c5b23f 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -3,12 +3,14 @@ import os import shlex import textwrap +from time import time from typing import List, Tuple from PIL import Image, ImageDraw, ImageFont from pyrogram import errors, raw from pyrogram.file_id import FileId from pyrogram.types import Message +from unidecode import unidecode from Powers.bot_class import Gojo @@ -181,6 +183,10 @@ async def get_document_from_file_id( file_reference=decoded.file_reference, ) +async def remove_sticker(c: Gojo, stickerid: str) -> raw.base.messages.StickerSet: + sticker = await get_document_from_file_id(stickerid) + return await c.invoke(raw.functions.stickers.RemoveStickerFromSet(sticker=sticker)) + async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> list: _split = text.split(";", 1) @@ -194,19 +200,36 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li image = Image.open(image_path) width, height = image.size - font_size = int(width / 11) + font_size = int((30 / 500) * width) font = ImageFont.truetype("./extras/comic.ttf", font_size) draw = ImageDraw.Draw(image) - upper_text_width, _ = draw.textsize(upper_text, font=font) - lower_text_width, lower_text_height = draw.textsize(lower_text, font=font) - - upper_text_position = ((width - upper_text_width) // 2, height // 10) - lower_text_position = ((width - lower_text_width) // 2, height - lower_text_height - (height // 10)) - - draw.text(upper_text_position, upper_text, font=font, fill=fiill) - draw.text(lower_text_position, lower_text, font=font, fill=fiill) + curr_height, padding = 20, 5 + for utext in textwrap.wrap(upper_text, 25): + upper_width = draw.textlength(utext, font=font) + draw.text( + ((width - upper_width) / 2, curr_height), + unidecode(utext), + (255, 255, 255), + font, + stroke_width=3, + stroke_fill=fiill, + ) + curr_height += font_size + padding + + curr_height = height - font_size + for ltext in reversed(textwrap.wrap(lower_text, 25)): + lower_width = draw.textlength(ltext, font=font) + draw.text( + ((width - lower_width) / 2, curr_height - font_size), + ltext, + (255, 255, 255), + font, + stroke_width=3, + stroke_fill=fiill, + ) + curr_height -= font_size + padding if sticker: stick_path = image_path @@ -214,7 +237,7 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li stick_path = await resize_file_to_sticker_size(image_path) image1 = image_path - image2 = tosticker(stick_path,"@memesofdank_memer_hu_vai.webp") + image2 = tosticker(stick_path,f"@GojoSuperbot_{int(time())}.webp") image.save(image1) image.save(image2) @@ -224,113 +247,7 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li return [image1, image2] -# async def draw_meme(image_path, text:str,stick): -# """Hellbot se churaya hai hue hue hue...""" -# img = Image.open(image_path) -# i_width, i_height = img.size -# m_font = ImageFont.truetype( -# "./extras/comic.ttf", int(i_width / 11) -# ) -# if ";" in text: -# upper_text, lower_text = text.split(";") -# else: -# upper_text = text -# lower_text = "" -# draw = ImageDraw.Draw(img) -# current_h, pad = 10, 5 -# if upper_text: -# for u_text in textwrap.wrap(upper_text,width=15,subsequent_indent=" "): -# u_width, u_height = draw.textsize(u_text, font=m_font) -# draw.text( -# xy=(((i_width - u_width) / 2) - 1, int((current_h / 640) * i_width)), -# text=u_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=(((i_width - u_width) / 2) + 1, int((current_h / 640) * i_width)), -# text=u_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=((i_width - u_width) / 2, int(((current_h / 640) * i_width)) - 1), -# text=u_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=(((i_width - u_width) / 2), int(((current_h / 640) * i_width)) + 1), -# text=u_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=((i_width - u_width) / 2, int((current_h / 640) * i_width)), -# text=u_text, -# font=m_font, -# fill=(255, 255, 255), -# ) -# current_h += u_height + pad -# if lower_text: -# for l_text in textwrap.wrap(upper_text,width=15,subsequent_indent=" "): -# u_width, u_height = draw.textsize(l_text, font=m_font) -# draw.text( -# xy=( -# ((i_width - u_width) / 2) - 1, -# i_height - u_height - int((20 / 640) * i_width), -# ), -# text=l_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=( -# ((i_width - u_width) / 2) + 1, -# i_height - u_height - int((20 / 640) * i_width), -# ), -# text=l_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=( -# (i_width - u_width) / 2, -# (i_height - u_height - int((20 / 640) * i_width)) - 1, -# ), -# text=l_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=( -# (i_width - u_width) / 2, -# (i_height - u_height - int((20 / 640) * i_width)) + 1, -# ), -# text=l_text, -# font=m_font, -# fill=(0, 0, 0), -# ) -# draw.text( -# xy=( -# (i_width - u_width) / 2, -# i_height - u_height - int((20 / 640) * i_width), -# ), -# text=l_text, -# font=m_font, -# fill=(255, 255, 255), -# ) -# current_h += u_height + pad - -# hue = image_path -# if stick: -# stick_path = image_path -# else: -# stick_path = await resize_file_to_sticker_size(hue) -# mee = tosticker(stick_path,"@memesofdank_memer_hu_vai.webp") -# img.save(hue) -# img.save(mee) -# return hue, mee + def toimage(image, filename=None, is_direc=False): filename = filename if filename else "gojo.jpg" diff --git a/Powers/vars.py b/Powers/vars.py index d934048c..3600b782 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -38,7 +38,7 @@ class Config: ).split(None) ] GENIUS_API_TOKEN = config("GENIUS_API",default=None) - AuDD_API = config("AuDD_API",default=None) + # AuDD_API = config("AuDD_API",default=None) RMBG_API = config("RMBG_API",default=None) DB_URI = config("DB_URI", default="") DB_NAME = config("DB_NAME", default="gojo_satarou") From b5544d071721b0473c0886a5757c7268abc63bd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 04:19:42 +0000 Subject: [PATCH 03/19] Bump peter-evans/create-pull-request from 5 to 6 Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5 to 6. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v6) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pre-commit-autoupdate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index f7106d75..1a553d88 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -15,7 +15,7 @@ jobs: - name: Run pre-commit autoupdate run: pre-commit autoupdate - name: Create Pull Request - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} branch: update/pre-commit-autoupdate From 0cce49172a3c9adc3329fca158d3ba5151c0d3e4 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Sat, 10 Feb 2024 23:08:58 +0530 Subject: [PATCH 04/19] Working on `v 2.2.0` --- Powers/database/locks_db.py | 20 ++++++++++++++++++-- Powers/plugins/admin.py | 5 +++-- Powers/plugins/antispam.py | 20 +++++++++++++++++++- Powers/plugins/auto_join.py | 7 +++++-- Powers/plugins/bans.py | 19 ++++++++++++++++++- Powers/plugins/chat_blacklist.py | 32 ++++++++++++++++++++++++++++++++ Powers/plugins/dev.py | 9 ++++++--- Powers/plugins/disable.py | 20 ++++++++++++++++++++ Powers/plugins/flood.py | 3 ++- Powers/plugins/info.py | 14 +++++++++----- Powers/plugins/locks.py | 10 ++++++---- Powers/plugins/muting.py | 10 +++++++++- Powers/plugins/report.py | 4 ++-- Powers/plugins/warns.py | 13 ++++++++++--- Powers/plugins/watchers.py | 4 ++-- Powers/utils/admin_check.py | 7 ++++--- Powers/utils/custom_filters.py | 13 ++++++------- Powers/utils/start_utils.py | 6 +++--- 18 files changed, 174 insertions(+), 42 deletions(-) diff --git a/Powers/database/locks_db.py b/Powers/database/locks_db.py index c301e189..2e33eeae 100644 --- a/Powers/database/locks_db.py +++ b/Powers/database/locks_db.py @@ -5,6 +5,7 @@ INSERTION_LOCK = RLock() +lock_t = ["anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links"] class LOCKS(MongoDB): """Class to store locks""" @@ -15,8 +16,17 @@ def __init__(self) -> None: def insert_lock_channel(self, chat: int, locktype: str): """ - locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links + locktypes: all, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links """ + if locktype == "all": + for i in lock_t: + curr = self.find_one({"chat_id":chat,"locktype":i}) + if curr: + continue + if i in ["anti_fwd_u", "anti_fwd_c"]: + continue + self.insert_one({"chat_id":chat,"locktype":i}) + return True curr = self.find_one({"chat_id":chat,"locktype":locktype}) if curr: return False @@ -29,8 +39,14 @@ def insert_lock_channel(self, chat: int, locktype: str): def remove_lock_channel(self, chat: int, locktype: str): """ - locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links + locktypes: all, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links """ + if locktype == "all": + for i in lock_t: + curr = self.find_one({"chat_id":chat,"locktype":i}) + if curr: + self.delete_one({"chat_id":chat,"locktype":i}) + return True curr = self.find_one({"chat_id":chat,"locktype":locktype}) if curr: with INSERTION_LOCK: diff --git a/Powers/plugins/admin.py b/Powers/plugins/admin.py index 1268a094..1b143f19 100644 --- a/Powers/plugins/admin.py +++ b/Powers/plugins/admin.py @@ -24,8 +24,6 @@ from Powers.utils.parser import mention_html from Powers.vars import Config -SUPPORT_STAFF = get_support_staff() -DEV_LEVEL = get_support_staff("dev_level") @Gojo.on_message(command("adminlist")) async def adminlist_show(_, m: Message): @@ -110,6 +108,7 @@ async def reload_admins(_, m: Message): return await m.reply_text( "This command is made to be used in groups only!", ) + SUPPORT_STAFF = get_support_staff() if ( (m.chat.id in set(TEMP_ADMIN_CACHE_BLOCK.keys())) and (m.from_user.id not in SUPPORT_STAFF) @@ -420,6 +419,8 @@ async def demote_usr(c: Gojo, m: Message): @Gojo.on_message(command("invitelink")) async def get_invitelink(c: Gojo, m: Message): # Bypass the bot devs, sudos and owner + + DEV_LEVEL = get_support_staff("dev_level") if m.from_user.id not in DEV_LEVEL: user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_invite_users and user.status != CMS.OWNER: diff --git a/Powers/plugins/antispam.py b/Powers/plugins/antispam.py index 1ca9ab81..4b017644 100644 --- a/Powers/plugins/antispam.py +++ b/Powers/plugins/antispam.py @@ -18,7 +18,6 @@ # Initialize db = GBan() -SUPPORT_STAFF = get_support_staff() @Gojo.on_message(command(["gban", "globalban"], sudo_cmd=True)) async def gban(c: Gojo, m: Message): @@ -39,6 +38,8 @@ async def gban(c: Gojo, m: Message): else: gban_reason = m.text.split(None, 2)[2] + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text(text="This user is part of my Support!, Can't ban our own!") return @@ -92,6 +93,8 @@ async def ungban(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text(text="This user is part of my Support!, Can't ban our own!") return @@ -169,3 +172,18 @@ async def gban_list(_, m: Message): LOGGER.info(f"{m.from_user.id} exported gbanlist in {m.chat.id}") return + +__PLUGIN__ = "global" + +__alt_name__ = ["antispam", "global"] + + +__HELP__ = """ +**Global** + +**Sudo commands:** +• /gban [reply to user | user id | username]: Add the user in the global ban watchlist. +• /ungban [reply to user | user id | username]: Remove the user from the global ban watchlist. +• /numgbans : Give number of users who are banned globally. +• /gbanlist : Give list of globally banned users. +""" \ No newline at end of file diff --git a/Powers/plugins/auto_join.py b/Powers/plugins/auto_join.py index 72b4ad50..367558d2 100644 --- a/Powers/plugins/auto_join.py +++ b/Powers/plugins/auto_join.py @@ -10,7 +10,6 @@ from Powers.supports import get_support_staff from Powers.utils.custom_filters import admin_filter, auto_join_filter, command -SUPPORT_STAFF = get_support_staff() @Gojo.on_message(command(["joinreq"]) & admin_filter) async def accept_join_requests(c: Gojo, m: Message): @@ -21,6 +20,9 @@ async def accept_join_requests(c: Gojo, m: Message): split = m.command a_j = AUTOJOIN() + try: + await + if len(split) == 1: txt = "**USAGE**\n/joinreq [on | off]" await m.reply_text(txt) @@ -84,7 +86,8 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): chat = j.chat.id aj = AUTOJOIN() join_type = aj.get_autojoin(chat) - + SUPPORT_STAFF = get_support_staff() + if not join_type: return if join_type == "auto" or user in SUPPORT_STAFF: diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py index b558fb55..e933bb4e 100644 --- a/Powers/plugins/bans.py +++ b/Powers/plugins/bans.py @@ -20,7 +20,6 @@ from Powers.utils.string import extract_time from Powers.vars import Config -SUPPORT_STAFF = get_support_staff() @Gojo.on_message(command("tban") & restrict_filter) async def tban_usr(c: Gojo, m: Message): @@ -40,6 +39,8 @@ async def tban_usr(c: Gojo, m: Message): await m.reply_text("WTF?? Why would I ban myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -160,6 +161,8 @@ async def stban_usr(c: Gojo, m: Message): await m.reply_text(text="I can't ban nothing!") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + try: user_id, _, _ = await extract_user(c, m) except Exception: @@ -266,6 +269,8 @@ async def dtban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text(text="I am not going to ban one of my support staff") LOGGER.info( @@ -394,6 +399,8 @@ async def kick_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -483,6 +490,8 @@ async def skick_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -555,6 +564,8 @@ async def dkick_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -704,6 +715,8 @@ async def sban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -783,6 +796,8 @@ async def dban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -882,6 +897,8 @@ async def ban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." diff --git a/Powers/plugins/chat_blacklist.py b/Powers/plugins/chat_blacklist.py index b6c25b90..84bedbea 100644 --- a/Powers/plugins/chat_blacklist.py +++ b/Powers/plugins/chat_blacklist.py @@ -1,5 +1,6 @@ from traceback import format_exc +from pyrogram.enums import ChatType as CT from pyrogram.errors import PeerIdInvalid, RPCError from pyrogram.types import Message @@ -33,6 +34,13 @@ async def blacklist_chat(c: Gojo, m: Message): await replymsg.edit_text( f"Added the following chats to Blacklist.\n{', '.join(chat_ids)}.", ) + else: + if m.chat.type == CT.PRIVATE: + await m.reply_text("Use in groups") + else: + chat_id = m.chat.id + db.add_chat(chat_id) + await m.reply_text("Added this chat to blacklist chats") return @@ -63,6 +71,16 @@ async def unblacklist_chat(c: Gojo, m: Message): await replymsg.edit_text( f"Removed the following chats to Blacklist.\n{', '.join(chat_ids)}.", ) + else: + if m.chat.type == CT.PRIVATE: + await m.reply_text("Use in groups") + else: + chat_id = m.chat.id + bl_chats = bl_chats = db.list_all_chats() + if chat_id not in bl_chats: + await m.reply_text("This chat is not in my list of blacklisted chats") + else: + await m.reply_text("Removed this chat from blacklist chats") return @@ -84,3 +102,17 @@ async def list_blacklist_chats(_, m: Message): txt = "No chats are currently blacklisted!" await m.reply_text(txt) return + + +__PLUGIN__ = "Chat blacklist" + + + +__HELP__ = """ +**Chat blacklist** + +**Dev commands:** +• /blchat [space separated id or username of chats]: Add chats to black list if given or the current chat. +• /rmblchat [space separated id or username of chats]: Remove chats from black list if given or the current chat. +• /blchats: Give the list of blacklisted chats +""" \ No newline at end of file diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py index 8a5064c4..9c75b39c 100644 --- a/Powers/plugins/dev.py +++ b/Powers/plugins/dev.py @@ -181,10 +181,13 @@ async def rm_support(c: Gojo, m: Message): return elif len(split) >= 2: try: - curr,_,_ = extract_user(m) + curr = int(split[1]) except Exception: - await m.reply_text("Dunno who u r talking abt") - return + try: + curr,_,_ = extract_user(m) + except Exception: + await m.reply_text("Dunno who u r talking abt") + return else: await m.reply_text("**USAGE**\n/rmsupport [reply to user | user id | username]") return diff --git a/Powers/plugins/disable.py b/Powers/plugins/disable.py index 21e0804e..e2334947 100644 --- a/Powers/plugins/disable.py +++ b/Powers/plugins/disable.py @@ -148,3 +148,23 @@ async def enablealll(_, q: CallbackQuery): LOGGER.info(f"{user_id} enabled all in {q.message.chat.id}") await q.message.edit_text("Enabled all!", show_alert=True) return + + +__PLUGIN__ = "disable able" + +__alt_name__ = ["disable commands", "disable"] + + +__HELP__ = """ +**Disable commands** + +**Admin commands:** +• /disable [command]: To disable the given command. +• /disabledel [on | off]: Will delete the command which is disabled. +• /enable [command]: To enable the given command. +• /disableable : Give all disableable commands. +• /disabled : Give all disabled commands. + +**Owner command:** +• /enableall : Enable all the disabled commands. +""" \ No newline at end of file diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 06cc19dc..6015eaf7 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -20,7 +20,6 @@ from Powers.utils.kbhelpers import ikb from Powers.vars import Config -SUPPORT_STAFF = get_support_staff() on_key = ["on", "start", "disable"] off_key = ["off", "end", "enable", "stop"] @@ -192,6 +191,7 @@ async def flood_set(c: Gojo, m: Message): @Gojo.on_callback_query(filters.regex("^f_")) async def callbacks(c: Gojo, q: CallbackQuery): + SUPPORT_STAFF = get_support_staff() data = q.data if data == "f_close": await q.answer("Closed") @@ -291,6 +291,7 @@ async def reverse_callbacks(c: Gojo, q: CallbackQuery): data = q.data.split("_") action = data[1] user_id = int(q.data.split("=")[1]) + SUPPORT_STAFF = get_support_staff() if not q.from_user: return q.answer("Looks like you are not an user 👀") if action == "ban": diff --git a/Powers/plugins/info.py b/Powers/plugins/info.py index 9ef892bb..2f6fa6c4 100644 --- a/Powers/plugins/info.py +++ b/Powers/plugins/info.py @@ -146,10 +146,15 @@ async def user_info(c: Gojo, user, already=False): 🔅 Second Name: {last_name} 🔍 Username: {("@" + username) if username else "NA"} ✍️ Bio: `{about}` -🧑‍💻 Support: {is_support} -🥷 Support user type: {omp} -💣 Gbanned: {gban} -☠️ Gban reason: {reason} +🧑‍💻 Support: {is_support}\n""" + if is_support: + caption += f"🥷 Support user type: {omp}\n💣 Gbanned: {gban}\n" + else: + caption += f"💣 Gbanned: {gban}\n" + + if gban: + caption += f"☠️ Gban reason: {reason}\n" + caption += f""" 🌐 DC ID: {dc_id} ✋ RESTRICTED: {is_restricted} ✅ VERIFIED: {is_verified} @@ -157,7 +162,6 @@ async def user_info(c: Gojo, user, already=False): ⚠️ SCAM : {is_scam} 🤖 BOT: {is_bot} 👀 Last seen: {last_date} - """ return caption, photo_id diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index df5cf3f4..cab91cd5 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -15,8 +15,6 @@ from Powers.utils.custom_filters import command, restrict_filter from Powers.vars import Config -SUDO_LEVEL = get_support_staff("sudo_level") - l_t = """ **Lock Types:** - `all` = Everything @@ -67,10 +65,12 @@ async def lock_perm(c: Gojo, m: Message): invite = get_perm.can_invite_users pin = get_perm.can_pin_messages stickers = animations = games = inlinebots = None + lock = LOCKS() if lock_type == "all": try: await c.set_chat_permissions(chat_id, ChatPermissions()) + lock.insert_lock_channel(m.chat.id, "all") LOGGER.info(f"{m.from_user.id} locked all permissions in {m.chat.id}") except ChatNotModified: pass @@ -80,7 +80,6 @@ async def lock_perm(c: Gojo, m: Message): await prevent_approved(m) return - lock = LOCKS() if lock_type == "msg": msg = False @@ -280,6 +279,7 @@ async def unlock_perm(c: Gojo, m: Message): return if unlock_type == "all": + lock = LOCKS() try: await c.set_chat_permissions( chat_id, @@ -294,6 +294,7 @@ async def unlock_perm(c: Gojo, m: Message): can_pin_messages=True, ), ) + lock.remove_lock_channel(m.chat.id,"all") LOGGER.info(f"{m.from_user.id} unlocked all permissions in {m.chat.id}") except ChatNotModified: pass @@ -314,7 +315,6 @@ async def unlock_perm(c: Gojo, m: Message): upin = get_uperm.can_pin_messages ustickers = uanimations = ugames = uinlinebots = None - lock = LOCKS() if unlock_type == "msg": umsg = True @@ -455,6 +455,8 @@ async def is_approved_user(c:Gojo, m: Message): except KeyError: admins_group = await admin_cache_reload(m, "lock") + SUDO_LEVEL = get_support_staff("sudo_level") + 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 or m.from_user.id == Config.BOT_ID: return True diff --git a/Powers/plugins/muting.py b/Powers/plugins/muting.py index 1b0a459d..95d4f77e 100644 --- a/Powers/plugins/muting.py +++ b/Powers/plugins/muting.py @@ -20,7 +20,6 @@ from Powers.utils.string import extract_time from Powers.vars import Config -SUPPORT_STAFF = get_support_staff() @Gojo.on_message(command("tmute") & restrict_filter) async def tmute_usr(c: Gojo, m: Message): @@ -40,6 +39,8 @@ async def tmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", @@ -152,6 +153,7 @@ async def dtmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", @@ -260,6 +262,7 @@ async def stmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", @@ -353,6 +356,7 @@ async def mute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", @@ -438,6 +442,8 @@ async def smute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + SUPPORT_STAFF = get_support_staff() + if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", @@ -509,6 +515,8 @@ async def dmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return + + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", diff --git a/Powers/plugins/report.py b/Powers/plugins/report.py index 0871fcb0..9f064fef 100644 --- a/Powers/plugins/report.py +++ b/Powers/plugins/report.py @@ -14,7 +14,6 @@ from Powers.utils.kbhelpers import ikb from Powers.utils.parser import mention_html -SUPPORT_STAFF = get_support_staff() @Gojo.on_message( command("reports") & (filters.private | admin_filter), @@ -85,7 +84,8 @@ async def report_watcher(c: Gojo, m: Message): if reported_user.id == me.id: await m.reply_text("Nice try.") return - + + SUPPORT_STAFF = get_support_staff() if reported_user.id in SUPPORT_STAFF: await m.reply_text("Uh? You reporting my support team?") return diff --git a/Powers/plugins/warns.py b/Powers/plugins/warns.py index 157de69f..b2b0bbb2 100644 --- a/Powers/plugins/warns.py +++ b/Powers/plugins/warns.py @@ -18,7 +18,6 @@ from Powers.utils.parser import mention_html from Powers.vars import Config -SUPPORT_STAFF = get_support_staff() @Gojo.on_message( command(["warn", "swarn", "dwarn"]) & restrict_filter, @@ -49,6 +48,7 @@ async def warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." @@ -151,6 +151,7 @@ async def reset_warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: await m.reply_text( "They are support users, cannot be restriced, how am I then supposed to unrestrict them?", @@ -186,6 +187,7 @@ async def list_warns(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: await m.reply_text("This user has no warns!") LOGGER.info( @@ -234,6 +236,7 @@ async def remove_warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return + SUPPORT_STAFF = get_support_staff() if user_id in SUPPORT_STAFF: await m.reply_text("This user has no warns!") LOGGER.info( @@ -300,15 +303,17 @@ async def remove_last_warn_btn(c: Gojo, q: CallbackQuery): ) if action == "kick": try: - timee = timeee = datetime.now(TIME_ZONE) + timedelta(minutes=45) + timee = datetime.now(TIME_ZONE) + timedelta(minutes=45) await c.ban_chat_member(chat_id, user_id, until_date=timee) await q.message.edit_text( ( f"Admin {(await mention_html(q.from_user.first_name, q.from_user.id))} " - "kicked user " + "kicked user they can't join the chat for 45 minutes" f"{(await mention_html(user_first_name, user_id))} for last warning!" ), ) + warn_db = Warns(q.message.chat.id) + warn_db.reset_warns(user_id) except RPCError as err: await q.message.edit_text( f"🛑 Failed to Kick\nError:\n{err}", @@ -388,5 +393,7 @@ async def warnlimit(_, m: Message): • /warnmode ``: Set the chat's warn mode. • /warnlimit ``: Set the number of warnings before users are punished. +**IF THE USER IS KICKED THEN THEY WILL BE TEMPORARILY BANNED FOR 45 MINUTES** + **Examples:** `/warn @user`: this warns a user in the chat.""" diff --git a/Powers/plugins/watchers.py b/Powers/plugins/watchers.py index b1124a0f..311cea9c 100644 --- a/Powers/plugins/watchers.py +++ b/Powers/plugins/watchers.py @@ -22,7 +22,6 @@ # Initialise gban_db = GBan() -SUPPORT_STAFF = get_support_staff() @Gojo.on_message(filters.linked_channel) async def antichanpin_cleanlinked(c: Gojo, m: Message): @@ -124,7 +123,8 @@ async def perform_action_blacklist(m: Message, action: str, trigger: str): ), ) return - + + SUPPORT_STAFF = get_support_staff() if m.from_user.id in SUPPORT_STAFF: # Don't work on Support Staff! return diff --git a/Powers/utils/admin_check.py b/Powers/utils/admin_check.py index d5a14c43..bc882d4f 100644 --- a/Powers/utils/admin_check.py +++ b/Powers/utils/admin_check.py @@ -5,9 +5,6 @@ from Powers import DEV_USERS, LOGGER, OWNER_ID, SUDO_USERS -SUDO_LEVEL = SUDO_USERS + DEV_USERS + [int(OWNER_ID)] -DEV_LEVEL = DEV_USERS + [int(OWNER_ID)] - async def admin_check(m: Message or CallbackQuery) -> bool: """Checks if user is admin or not.""" @@ -16,6 +13,8 @@ async def admin_check(m: Message or CallbackQuery) -> bool: if isinstance(m, CallbackQuery): user_id = m.message.from_user.id + SUDO_LEVEL = SUDO_USERS + DEV_USERS + [int(OWNER_ID)] + try: if user_id in SUDO_LEVEL: return True @@ -66,6 +65,8 @@ async def owner_check(m: Message or CallbackQuery) -> bool: user_id = m.message.from_user.id m = m.message + SUDO_LEVEL = SUDO_USERS + DEV_USERS + [int(OWNER_ID)] + try: if user_id in SUDO_LEVEL: return True diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 521ee73e..3e192dc8 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -18,9 +18,6 @@ from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.vars import Config -SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) -DEV_LEVEL = set(DEV_USERS + [int(OWNER_ID)]) - def command( commands: Union[str, List[str]], @@ -52,11 +49,11 @@ async def func(flt, _, m: Message): if owner_cmd and (m.from_user.id != OWNER_ID): # Only owner allowed to use this...! return False - + DEV_LEVEL = set(DEV_USERS + [int(OWNER_ID)]) if dev_cmd and (m.from_user.id not in DEV_LEVEL): # Only devs allowed to use this...! return False - + SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) if sudo_cmd and (m.from_user.id not in SUDO_LEVEL): # Only sudos and above allowed to use it return False @@ -73,7 +70,7 @@ async def func(flt, _, m: Message): m.command = [matches.group(1)] if matches.group(1) not in flt.commands: return False - if bool(m.chat and m.chat.type in {ChatType.SUPERGROUP}): + if bool(m.chat and m.chat.type in {ChatType.SUPERGROUP, ChatType.GROUP}): try: user_status = (await m.chat.get_member(m.from_user.id)).status except UserNotParticipant: @@ -293,6 +290,7 @@ async def can_pin_message_func(_, __, m): return True # Bypass the bot devs, sudos and owner + SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) if m.from_user.id in SUDO_LEVEL: return True @@ -362,7 +360,8 @@ async def flood_check_filter(_, __, m: Message): is_flood = Flood.is_chat(c_id) app_users = Approve(m.chat.id).list_approved() - + SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) + if not is_flood or u_id in SUDO_LEVEL: return False diff --git a/Powers/utils/start_utils.py b/Powers/utils/start_utils.py index 74ef1fa1..6d5bbae4 100644 --- a/Powers/utils/start_utils.py +++ b/Powers/utils/start_utils.py @@ -53,7 +53,7 @@ async def gen_start_kb(q: Message or CallbackQuery): "📚 Commands & Help", "commands" ), ( - "👾 Bot info", + "Bot info 👾", "bot_curr_info" ) ], @@ -71,12 +71,12 @@ async def gen_start_kb(q: Message or CallbackQuery): ], [ ( - "Essential", + "❗️ Essential", "https://t.me/+PcVYvdzNt4E1YjM1", "url", ), ( - "Powered by", + "Powered by ⚡️", f"https://{Config.SUPPORT_CHANNEL}.t.me", "url", ), From 33f38b0adaf412a9dcd50a648eb3d1ec82f7cdc3 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Sun, 11 Feb 2024 17:59:16 +0530 Subject: [PATCH 05/19] progress... --- Powers/database/locks_db.py | 35 +++++++++----- Powers/plugins/auto_join.py | 42 +++++++++++++---- Powers/plugins/birthday.py | 2 +- Powers/plugins/flood.py | 1 - Powers/plugins/locks.py | 92 ++++++++++++++++++++++++------------- 5 files changed, 117 insertions(+), 55 deletions(-) diff --git a/Powers/database/locks_db.py b/Powers/database/locks_db.py index 2e33eeae..eb6bb55a 100644 --- a/Powers/database/locks_db.py +++ b/Powers/database/locks_db.py @@ -5,7 +5,7 @@ INSERTION_LOCK = RLock() -lock_t = ["anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links"] +lock_t = ["bot", "anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links"] class LOCKS(MongoDB): """Class to store locks""" @@ -16,7 +16,7 @@ def __init__(self) -> None: def insert_lock_channel(self, chat: int, locktype: str): """ - locktypes: all, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links + locktypes: all, bot, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links """ if locktype == "all": for i in lock_t: @@ -39,7 +39,7 @@ def insert_lock_channel(self, chat: int, locktype: str): def remove_lock_channel(self, chat: int, locktype: str): """ - locktypes: all, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links + locktypes: all, bot, anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links """ if locktype == "all": for i in lock_t: @@ -55,23 +55,34 @@ def remove_lock_channel(self, chat: int, locktype: str): else: return False - def get_lock_channel(self, locktype: str="all"): + def get_lock_channel(self, locktype: str="all", chat:int = 0): """ - locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links + locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links, bot """ - if locktype not in ["anti_c_send","anti_fwd","anti_fwd_u","anti_fwd_c","anti_links", "all"]: + if locktype not in ["anti_c_send","anti_fwd","anti_fwd_u","anti_fwd_c","anti_links", "bot", "all"]: return False else: if locktype == "all": find = {} else: find = {"locktype":locktype} - curr = self.find_all(find) - if not curr: - list_ = [] - else: - list_ = [i["chat_id"] for i in curr] - return list_ + if chat: + if find: + curr = self.find_one({"chat_id":chat, "locktype":locktype}) + return bool(curr) + else: + to_return = [] + for i in lock_t: + curr = self.find_one({"chat_id":chat, "locktype":i}) + to_return.append(bool(curr)) + return all(to_return) + else: + curr = self.find_all(find) + if not curr: + list_ = [] + else: + list_ = [i["chat_id"] for i in curr] + return list_ def merge_u_and_c(self, chat: int, locktype: str): if locktype == "anti_fwd_u": diff --git a/Powers/plugins/auto_join.py b/Powers/plugins/auto_join.py index 367558d2..f7cc8fe5 100644 --- a/Powers/plugins/auto_join.py +++ b/Powers/plugins/auto_join.py @@ -1,3 +1,5 @@ +from traceback import format_exc + from pyrogram import filters from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.types import CallbackQuery, ChatJoinRequest @@ -5,6 +7,7 @@ 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.autojoin_db import AUTOJOIN from Powers.supports import get_support_staff @@ -21,8 +24,15 @@ async def accept_join_requests(c: Gojo, m: Message): a_j = AUTOJOIN() try: - await - + status = (await m.chat.get_member(c.me.id)).status + if status != CMS.ADMINISTRATOR: + await m.reply_text("I should be admin to accept and reject join requests") + return + except Exception as ef: + await m.reply_text(f"Some error occured, report it using `/bug`\nError: {ef}") + LOGGER.error(ef) + LOGGER.error(format_exc()) + return if len(split) == 1: txt = "**USAGE**\n/joinreq [on | off]" await m.reply_text(txt) @@ -91,8 +101,12 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): if not join_type: return if join_type == "auto" or user in SUPPORT_STAFF: - await c.approve_chat_join_request(chat,user) - + try: + await c.approve_chat_join_request(chat,user) + except Exception as ef: + await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") + LOGGER.error(ef) + LOGGER.error(format_exc()) elif join_type == "manual": txt = "New join request is available\n**USER's INFO**\n" txt += f"Name: {userr.first_name} {userr.last_name if userr.last_name else ''}" @@ -113,6 +127,7 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): @Gojo.on_callback_query(filters.regex("^accept_joinreq_uest_") | filters.regex("^decline_joinreq_uest_")) async def accept_decline_request(c:Gojo, q: CallbackQuery): user_id = q.from_user.id + chat = q.message.chat.id user_status = (await q.message.chat.get_member(user_id)).status if user_status not in {CMS.OWNER, CMS.ADMINISTRATOR}: await q.answer( @@ -127,11 +142,22 @@ async def accept_decline_request(c:Gojo, q: CallbackQuery): data = split[0] if data == "accept": - await c.approve_chat_join_request(chat,user) - await q.answer(f"APPROVED: {user}",True) + try: + await c.approve_chat_join_request(chat,user) + await q.answer(f"APPROVED: {user}",True) + except Exception as ef: + await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") + LOGGER.error(ef) + LOGGER.error(format_exc()) + elif data == "decline": - await c.decline_chat_join_request(chat,user) - await q.answer(f"DECLINED: {user}") + try: + await c.decline_chat_join_request(chat,user) + await q.answer(f"DECLINED: {user}") + except Exception as ef: + await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") + LOGGER.error(ef) + LOGGER.error(format_exc()) return diff --git a/Powers/plugins/birthday.py b/Powers/plugins/birthday.py index 7c15c23c..447505c6 100644 --- a/Powers/plugins/birthday.py +++ b/Powers/plugins/birthday.py @@ -177,7 +177,7 @@ async def cant_recall_it(c: Gojo, m: Message): u_dob = give_date(result["dob"]) formatted = str(u_dob.strftime('%d' + '%B %Y'))[2:-5] day = int(result["dob"].split('/')[0]) - suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day if day < 20 else day % 10, 'th') + suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day % 10, 'th') bday_on = f"{day}{suffix} {formatted}" if u_dob.month < curr.month: next_b = date(curr.year + 1, u_dob.month, u_dob.day) diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 6015eaf7..dacfd7b8 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -20,7 +20,6 @@ from Powers.utils.kbhelpers import ikb from Powers.vars import Config - on_key = ["on", "start", "disable"] off_key = ["off", "end", "enable", "stop"] diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index cab91cd5..9bf698a8 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -1,8 +1,10 @@ from asyncio import sleep +from datetime import datetime, timedelta from traceback import format_exc from pyrogram import filters from pyrogram.enums import MessageEntityType as MET +from pyrogram.enums import MessageServiceType as MST from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError from pyrogram.types import ChatPermissions, Message @@ -124,6 +126,13 @@ async def lock_perm(c: Gojo, m: Message): elif lock_type == "pin": pin = False perm = "pin" + elif lock_type == "bot": + curr = lock.insert_lock_channel(m.chat.id,"bot") + if not curr: + await m.reply_text("It is already on") + return + await m.reply_text("Restricted adding bots in the chat.") + return elif lock_type in ["links", "url"]: curr = lock.insert_lock_channel(m.chat.id, "anti_links") if not curr: @@ -202,26 +211,15 @@ async def convert_to_emoji(val: bool): if val: return "✅" return "❌" - + lock = LOCKS() - anti_c_send = lock.get_lock_channel("anti_c_send") - anti_forward = lock.get_lock_channel("anti_fwd") - anti_forward_u = lock.get_lock_channel("anti_fwd_u") - anti_forward_c = lock.get_lock_channel("anti_fwd_c") - anti_links = lock.get_lock_channel("anti_links") - anon = False - if m.chat.id in anti_c_send: - anon = True - 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 + anon= lock.get_lock_channel("anti_c_send", m.chat.id) + anti_f = lock.get_lock_channel("anti_fwd", m.chat.id) + anti_f_u = lock.get_lock_channel("anti_fwd_u", m.chat.id) + anti_f_c = lock.get_lock_channel("anti_fwd_c", m.chat.id) + antil = lock.get_lock_channel("anti_links", m.chat.id) + bots = lock.get_lock_channel("bot", m.chat.id) + 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) @@ -235,6 +233,7 @@ async def convert_to_emoji(val: bool): vantiu = await convert_to_emoji(anti_f_u) vantic = await convert_to_emoji(anti_f_c) vantil = await convert_to_emoji(antil) + vantibot = await convert_to_emoji(bots) if v_perm is not None: try: @@ -255,7 +254,8 @@ 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} + Can send links: {vantil} + Can send links: {vantibot} """ LOGGER.info(f"{m.from_user.id} used locks cmd in {m.chat.id}") await chkmsg.edit_text(permission_view_str) @@ -278,8 +278,8 @@ async def unlock_perm(c: Gojo, m: Message): await m.reply_text(text="Specify a permission to unlock!") return + lock = LOCKS() if unlock_type == "all": - lock = LOCKS() try: await c.set_chat_permissions( chat_id, @@ -359,6 +359,12 @@ async def unlock_perm(c: Gojo, m: Message): elif unlock_type == "pin": upin = True uperm = "pin" + elif unlock_type == "bot": + curr = lock.remove_lock_channel(m.chat.id,"bot") + if not curr: + m.reply_text("User already can add bots in the chat") + return + await m.reply_text("User are now allowed to add bots in the chat.") elif unlock_type == "anonchannel": curr = lock.remove_lock_channel(m.chat.id,"anti_c_send") @@ -474,6 +480,26 @@ async def is_approved_user(c:Gojo, m: Message): return True return False +@Gojo.on_message(filters.service & filters.group, 19) +async def servicess(c: Gojo, m: Message): + if m.service != MST.NEW_CHAT_MEMBERS: + return + approved = await is_approved_user(c,m) + if approved: + return + for i in m.new_chat_members: + if i.is_bot: + try: + timee = datetime.now() + timedelta(minutes=5) + await m.chat.ban_member(i.id,until_date=timee) + sleep(1) + except Exception as ef: + LOGGER.error(ef) + LOGGER.error(format_exc()) + return + + + @Gojo.on_message(filters.group & ~filters.me,18) async def lock_del_mess(c:Gojo, m: Message): lock = LOCKS() @@ -488,24 +514,24 @@ async def lock_del_mess(c:Gojo, m: Message): await delete_messages(c,m) return is_approved = await is_approved_user(c,m) + if is_approved: + return 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: - if not is_approved: - if lock.is_particular_lock(m.chat.id,"anti_fwd"): - await delete_messages(c,m) - return - elif lock.is_particular_lock(m.chat.id,"anti_fwd_u") and not m.forward_from_chat: - await delete_messages(c,m) - return - elif lock.is_particular_lock(m.chat.id,"anti_fwd_c") and m.forward_from_chat: await delete_messages(c,m) return + elif m.forward_from or m.forward_from_chat: + if lock.is_particular_lock(m.chat.id,"anti_fwd"): + await delete_messages(c,m) + return + elif lock.is_particular_lock(m.chat.id,"anti_fwd_u") and not m.forward_from_chat: + await delete_messages(c,m) + return + elif lock.is_particular_lock(m.chat.id,"anti_fwd_c") and m.forward_from_chat: + await delete_messages(c,m) + return async def prevent_approved(m: Message): approved_users = Approve(m.chat.id).list_approved() From a1ab08c6513ade21f6ae3449cf32ccf6f6d8c5fc Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Tue, 13 Feb 2024 22:20:20 +0530 Subject: [PATCH 06/19] Progress --- Powers/__init__.py | 12 +- Powers/__main__.py | 4 +- Powers/bot_class.py | 12 +- Powers/database/afk_db.py | 34 ++--- Powers/database/approve_db.py | 22 ++- Powers/database/autojoin_db.py | 26 ++-- Powers/database/blacklist_db.py | 5 +- Powers/database/captcha_db.py | 48 ++++--- Powers/database/disable_db.py | 8 +- Powers/database/filters_db.py | 3 +- Powers/database/flood_db.py | 21 +-- Powers/database/greetings_db.py | 30 +++-- Powers/database/locks_db.py | 59 ++++---- Powers/database/notes_db.py | 7 +- Powers/database/pins_db.py | 2 +- Powers/database/reporting_db.py | 8 +- Powers/database/rules_db.py | 3 +- Powers/database/support_db.py | 30 ++--- Powers/database/users_db.py | 3 +- Powers/database/warns_db.py | 19 ++- Powers/plugins/__init__.py | 1 + Powers/plugins/captcha.py | 230 ++++++++++++++++++++++++++++++++ Powers/plugins/formatting.py | 4 +- Powers/plugins/locks.py | 122 ++++++++++------- Powers/plugins/muting.py | 4 +- Powers/plugins/start.py | 135 +++++++++++-------- Powers/supports.py | 13 +- Powers/utils/caching.py | 3 +- Powers/utils/captcha_helper.py | 26 ++-- Powers/utils/custom_filters.py | 24 ++-- Powers/utils/extract_user.py | 2 +- Powers/utils/extras.py | 7 +- Powers/utils/http_helper.py | 2 +- Powers/utils/kbhelpers.py | 5 +- Powers/utils/msg_types.py | 1 + Powers/utils/start_utils.py | 8 +- Powers/utils/sticker_help.py | 28 ++-- Powers/utils/string.py | 37 ++++- Powers/utils/web_helpers.py | 32 ++--- Powers/vars.py | 10 +- 40 files changed, 711 insertions(+), 339 deletions(-) create mode 100644 Powers/plugins/captcha.py diff --git a/Powers/__init__.py b/Powers/__init__.py index bab53c74..9802ff03 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -13,6 +13,7 @@ import lyricsgenius import pyrogram import pytz +from apscheduler.schedulers.asyncio import AsyncIOScheduler LOG_DATETIME = datetime.now().strftime("%d_%m_%Y-%H_%M_%S") LOGDIR = f"{__name__}/logs" @@ -55,7 +56,7 @@ LOGGER.error(ef) # Print Error LOGGER.error(format_exc()) sysexit(1) -#time zone +# time zone TIME_ZONE = pytz.timezone(Config.TIME_ZONE) path = "./Version" @@ -126,7 +127,6 @@ WHITELIST_USERS = Config.WHITELIST_USERS - defult_dev = [1344569458, 1432756163, 5294360309] + [int(OWNER_ID)] Defult_dev = set(defult_dev) @@ -147,16 +147,17 @@ HELP_COMMANDS = {} # For help menu UPTIME = time() # Check bot uptime -from apscheduler.schedulers.asyncio import AsyncIOScheduler scheduler = AsyncIOScheduler(timezone=TIME_ZONE) + async def load_cmds(all_plugins): """Loads all the plugins in bot.""" for single in all_plugins: # If plugin in NO_LOAD, skip the plugin if single.lower() in [i.lower() for i in Config.NO_LOAD]: - LOGGER.warning(f"Not loading '{single}' s it's added in NO_LOAD list") + LOGGER.warning( + f"Not loading '{single}' s it's added in NO_LOAD list") continue imported_module = imp_mod(f"Powers.plugins.{single}") @@ -197,6 +198,7 @@ async def load_cmds(all_plugins): LOGGER.warning(f"Not loading Plugins - {NO_LOAD}") return ( - ", ".join((i.split(".")[1]).capitalize() for i in list(HELP_COMMANDS.keys())) + ", ".join((i.split(".")[1]).capitalize() + for i in list(HELP_COMMANDS.keys())) + "\n" ) diff --git a/Powers/__main__.py b/Powers/__main__.py index 98a7dec8..45157c98 100644 --- a/Powers/__main__.py +++ b/Powers/__main__.py @@ -2,7 +2,5 @@ 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 42c5effc..cdad2714 100644 --- a/Powers/bot_class.py +++ b/Powers/bot_class.py @@ -24,7 +24,6 @@ ) - class Gojo(Client): """Starts the Pyrogram Client on the Bot Token when we do 'python3 -m Powers'""" @@ -45,10 +44,11 @@ async def start(self): await super().start() await self.set_bot_commands( [ - BotCommand("start", "To check weather the bot is alive or not"), + 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("bug","To report bugs") + BotCommand("bug", "To report bugs") ] ) meh = await self.get_me() # Get bot info from pyrogram client @@ -68,9 +68,11 @@ async def start(self): cmd_list = await load_cmds(await all_plugins()) await load_support_users() LOGGER.info(f"Plugins Loaded: {cmd_list}") - scheduler.add_job(clean_my_db,'cron',[self],hour=3,minute=0,second=0) + scheduler.add_job(clean_my_db, 'cron', [ + self], hour=3, minute=0, second=0) if BDB_URI: - scheduler.add_job(send_wishish,'cron',[self],hour=0,minute=0,second=0) + scheduler.add_job(send_wishish, 'cron', [ + self], hour=0, minute=0, second=0) scheduler.start() # Send a message to MESSAGE_DUMP telling that the # bot has started and has loaded all plugins! diff --git a/Powers/database/afk_db.py b/Powers/database/afk_db.py index a91a5eb7..0b2baad8 100644 --- a/Powers/database/afk_db.py +++ b/Powers/database/afk_db.py @@ -13,43 +13,45 @@ class AFK(MongoDB): def __init__(self) -> None: super().__init__(self.db_name) - def insert_afk(self, chat_id, user_id, time, reason, media_type,media=None): + def insert_afk(self, chat_id, user_id, time, reason, media_type, media=None): with INSERTION_LOCK: curr = self.check_afk(chat_id=chat_id, user_id=user_id) if curr: if reason: - self.update({"chat_id":chat_id,"user_id":user_id},{"reason":reason,"time":time}) + self.update({"chat_id": chat_id, "user_id": user_id}, { + "reason": reason, "time": time}) if media: - self.update({"chat_id":chat_id,"user_id":user_id},{'media':media,'media_type':media_type,"time":time}) + self.update({"chat_id": chat_id, "user_id": user_id}, { + 'media': media, 'media_type': media_type, "time": time}) return True else: self.insert_one( { - "chat_id":chat_id, - "user_id":user_id, - "reason":reason, - "time":time, - "media":media, - "media_type":media_type + "chat_id": chat_id, + "user_id": user_id, + "reason": reason, + "time": time, + "media": media, + "media_type": media_type } ) return True def check_afk(self, chat_id, user_id): - curr = self.find_one({"chat_id":chat_id,"user_id":user_id}) + curr = self.find_one({"chat_id": chat_id, "user_id": user_id}) if curr: return True return False - + def get_afk(self, chat_id, user_id): - curr = self.find_one({"chat_id":chat_id,"user_id":user_id}) + curr = self.find_one({"chat_id": chat_id, "user_id": user_id}) if curr: return curr return - + def delete_afk(self, chat_id, user_id): with INSERTION_LOCK: - curr = self.check_afk(chat_id,user_id) + curr = self.check_afk(chat_id, user_id) if curr: - self.delete_one({"chat_id":chat_id,"user_id":user_id}) - return \ No newline at end of file + self.delete_one({"chat_id": chat_id, "user_id": user_id}) + return diff --git a/Powers/database/approve_db.py b/Powers/database/approve_db.py index 3cef38a3..f9c3314c 100644 --- a/Powers/database/approve_db.py +++ b/Powers/database/approve_db.py @@ -1,11 +1,16 @@ from threading import RLock + from Powers import LOGGER from Powers.database import MongoDB + INSERTION_LOCK = RLock() + + class Approve(MongoDB): """Class for managing Approves in Chats in Bot.""" # Database name to connect to to preform operations db_name = "approve" + def __init__(self, chat_id: int) -> None: super().__init__(self.db_name) self.chat_id = chat_id @@ -22,7 +27,6 @@ def check_approve(self, user_id: int): else: j = False return j - def add_approve(self, user_id: int, user_name: str): with INSERTION_LOCK: @@ -33,6 +37,7 @@ def add_approve(self, user_id: int, user_name: str): {"users": self.chat_info["users"]}, ) return True + def remove_approve(self, user_id: int): with INSERTION_LOCK: if self.check_approve(user_id): @@ -47,50 +52,61 @@ def remove_approve(self, user_id: int): {"users": self.chat_info["users"]}, ) return True + def unapprove_all(self): with INSERTION_LOCK: return self.delete_one( {"_id": self.chat_id}, ) + def clean_approve(self): with INSERTION_LOCK: return self.delete_one( - {"_id":self.chat_id} + {"_id": self.chat_id} ) + def list_approved(self): with INSERTION_LOCK: return self.chat_info["users"] + def count_approved(self): with INSERTION_LOCK: return len(self.chat_info["users"]) + def load_from_db(self): return self.find_all() + def __ensure_in_db(self): chat_data = self.find_one({"_id": self.chat_id}) if not chat_data: new_data = {"_id": self.chat_id, "users": []} self.insert_one(new_data) - LOGGER.info(f"Initialized Approve Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Approve Document for chat {self.chat_id}") return new_data return chat_data # Migrate if chat id changes! + def migrate_chat(self, new_chat_id: int): old_chat_db = self.find_one({"_id": self.chat_id}) new_data = old_chat_db.update({"_id": new_chat_id}) self.insert_one(new_data) self.delete_one({"_id": self.chat_id}) + @staticmethod def count_all_approved(): with INSERTION_LOCK: collection = MongoDB(Approve.db_name) all_data = collection.find_all() return sum(len(i["users"]) for i in all_data if len(i["users"]) >= 1) + @staticmethod def count_approved_chats(): with INSERTION_LOCK: collection = MongoDB(Approve.db_name) all_data = collection.find_all() return sum(len(i["users"]) >= 1 for i in all_data) + @staticmethod def repair_db(collection): all_data = collection.find_all() diff --git a/Powers/database/autojoin_db.py b/Powers/database/autojoin_db.py index 3328e1f5..3bff8a50 100644 --- a/Powers/database/autojoin_db.py +++ b/Powers/database/autojoin_db.py @@ -15,36 +15,36 @@ class AUTOJOIN(MongoDB): def __init__(self) -> None: super().__init__(self.db_name) - def load_autojoin(self, chat,mode="auto"): + def load_autojoin(self, chat, mode="auto"): """ type = auto or notify auto to auto accept join requests notify to notify the admins about the join requests """ - curr = self.find_one({"chat_id":chat,}) + curr = self.find_one({"chat_id": chat, }) if not curr: with INSERTION_LOCK: - self.insert_one({"chat_id":chat,"type":mode}) + self.insert_one({"chat_id": chat, "type": mode}) return True return False - def get_autojoin(self,chat): - curr = self.find_one({"chat_id":chat}) + def get_autojoin(self, chat): + curr = self.find_one({"chat_id": chat}) if not curr: return False else: return curr["type"] - def update_join_type(self,chat,mode): - curr = self.find_one({"chat_id":chat}) + def update_join_type(self, chat, mode): + curr = self.find_one({"chat_id": chat}) if curr: - self.update({"chat_id":chat},{"type":mode}) - return + self.update({"chat_id": chat}, {"type": mode}) + return else: return - def remove_autojoin(self,chat): - curr = self.find_one({"chat_id":chat}) + def remove_autojoin(self, chat): + curr = self.find_one({"chat_id": chat}) if curr: - self.delete_one({"chat_id":chat}) - return \ No newline at end of file + self.delete_one({"chat_id": chat}) + return diff --git a/Powers/database/blacklist_db.py b/Powers/database/blacklist_db.py index 0e7a5bdf..b2f29cef 100644 --- a/Powers/database/blacklist_db.py +++ b/Powers/database/blacklist_db.py @@ -110,13 +110,14 @@ def __ensure_in_db(self): "reason": "Automated blacklisted word: {{}}", } self.insert_one(new_data) - LOGGER.info(f"Initialized Blacklist Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Blacklist Document for chat {self.chat_id}") return new_data return chat_data def clean_blacklist(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) # Migrate if chat id changes! def migrate_chat(self, new_chat_id: int): diff --git a/Powers/database/captcha_db.py b/Powers/database/captcha_db.py index 8c55563c..62b70449 100644 --- a/Powers/database/captcha_db.py +++ b/Powers/database/captcha_db.py @@ -13,15 +13,15 @@ class CAPTCHA(MongoDB): def __init__(self) -> None: super().__init__(self.db_name) - def insert_captcha(self, chat, captcha_type:str="qr", captcha_action:str = "mute"): + def insert_captcha(self, chat, captcha_type: str = "qr", captcha_action: str = "mute"): with INSERTION_LOCK: curr = self.is_captcha(chat) if not curr: self.insert_one( { - "chat_id":chat, - "captcha_type":captcha_type, - "captcha_action":captcha_action + "chat_id": chat, + "captcha_type": captcha_type, + "captcha_action": captcha_action } ) return @@ -36,29 +36,31 @@ def update_type(self, chat, captcha_type): with INSERTION_LOCK: curr = self.is_captcha(chat) if curr: - self.update({"chat_id":chat},{"captcha_type":captcha_type}) + self.update({"chat_id": chat}, {"captcha_type": captcha_type}) return def update_action(self, chat, captcha_action): with INSERTION_LOCK: curr = self.is_captcha(chat) if curr: - self.update({"chat_id":chat},{"captcha_action":captcha_action}) + self.update({"chat_id": chat}, { + "captcha_action": captcha_action}) return - + def remove_captcha(self, chat): with INSERTION_LOCK: curr = self.is_captcha(chat) if curr: - self.delete_one({"chat_id":chat}) + self.delete_one({"chat_id": chat}) return def get_captcha(self, chat): - curr = self.find_one({"chat_id":chat}) + curr = self.find_one({"chat_id": chat}) if curr: return curr return False + class CAPTCHA_DATA(MongoDB): """class to store captcha data""" db_name = "captcha_data" @@ -67,47 +69,49 @@ def __init__(self) -> None: super().__init__(self.db_name) def load_cap_data(self, chat, user, data): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if not curr: with INSERTION_LOCK: - self.insert_one({"chat_id":chat,"user_id":user,"data":data}) + self.insert_one( + {"chat_id": chat, "user_id": user, "data": data}) return True else: return def get_cap_data(self, chat, user): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if curr: return curr["data"] else: return False def remove_cap_data(self, chat, user): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if curr: with INSERTION_LOCK: - self.delete_one({"chat_id":chat,"user_id":user}) + self.delete_one({"chat_id": chat, "user_id": user}) return def store_message_id(self, chat, user, message): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if not curr: with INSERTION_LOCK: - self.insert_one({"chat_id":chat,"user_id":user,"message_id":message}) + self.insert_one( + {"chat_id": chat, "user_id": user, "message_id": message}) return else: - return - + return + def is_already_data(self, chat, user): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if curr: return curr["message_id"] else: return False def del_message_id(self, chat, user): - curr = self.find_one({"chat_id":chat,"user_id":user}) + curr = self.find_one({"chat_id": chat, "user_id": user}) if curr: with INSERTION_LOCK: - self.delete_one({"chat_id":chat,"user_id":user}) - return \ No newline at end of file + self.delete_one({"chat_id": chat, "user_id": user}) + return diff --git a/Powers/database/disable_db.py b/Powers/database/disable_db.py index fb425f8a..e4b21430 100644 --- a/Powers/database/disable_db.py +++ b/Powers/database/disable_db.py @@ -146,9 +146,11 @@ def __ensure_in_db(self): "commands": [], "action": "none", } - DISABLED_CMDS[self.chat_id] = {"commands": [], "action": "none"} + DISABLED_CMDS[self.chat_id] = { + "commands": [], "action": "none"} self.insert_one(new_data) - LOGGER.info(f"Initialized Disabling Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Disabling Document for chat {self.chat_id}") return new_data DISABLED_CMDS[self.chat_id] = chat_data return chat_data @@ -163,7 +165,7 @@ def migrate_chat(self, new_chat_id: int): def clean_disable(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) @staticmethod def repair_db(collection): diff --git a/Powers/database/filters_db.py b/Powers/database/filters_db.py index d3fda53d..fa6c3dc5 100644 --- a/Powers/database/filters_db.py +++ b/Powers/database/filters_db.py @@ -71,7 +71,8 @@ def count_filter_aliases(self): curr = self.find_all() if curr: return len( - [z for z in (i["keyword"].split("|") for i in curr) if len(z) >= 2], + [z for z in (i["keyword"].split("|") + for i in curr) if len(z) >= 2], ) return 0 diff --git a/Powers/database/flood_db.py b/Powers/database/flood_db.py index c29fe9f0..99528ec3 100644 --- a/Powers/database/flood_db.py +++ b/Powers/database/flood_db.py @@ -7,6 +7,7 @@ INSERTION_LOCK = RLock() + class Floods(MongoDB): """Class to store flood limit and action of a chat""" db_name = "flood" @@ -24,7 +25,7 @@ def save_flood( with INSERTION_LOCK: curr = self.find_one({"chat_id": chat_id}) if curr: - if not(limit == int(curr['limit']) and within == int(curr['within']) and action == str(curr['action'])): + if not (limit == int(curr['limit']) and within == int(curr['within']) and action == str(curr['action'])): return self.update( { "chat_id": chat_id @@ -36,37 +37,37 @@ def save_flood( } ) else: - return + return else: return self.insert_one( { - "chat_id" : chat_id, + "chat_id": chat_id, "limit": limit, "within": within, - "action" : action + "action": action }, ) - + def is_chat(self, chat_id: int): with INSERTION_LOCK: curr = self.find_one({"chat_id": chat_id}) if curr: - action = [str(curr['limit']), str(curr['within']), str(curr['action'])] + action = [str(curr['limit']), str( + curr['within']), str(curr['action'])] return action return False - + def get_action(self, chat_id: int): with INSERTION_LOCK: curr = self.find_one({"chat_id": chat_id}) if curr: return curr['action'] return "Flood haven't set" - + def rm_flood(self, chat_id: int): with INSERTION_LOCK: curr = self.find_one({"chat_id": chat_id}) if curr: - self.delete_one({"chat_id":chat_id}) + self.delete_one({"chat_id": chat_id}) return True return False - \ No newline at end of file diff --git a/Powers/database/greetings_db.py b/Powers/database/greetings_db.py index 29165b79..d758dfe4 100644 --- a/Powers/database/greetings_db.py +++ b/Powers/database/greetings_db.py @@ -45,6 +45,7 @@ def get_welcome_text(self): 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"] @@ -78,32 +79,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, mtype,media=None): + def set_welcome_text(self, welcome_text: str, mtype, media=None): with INSERTION_LOCK: self.update( {"_id": self.chat_id}, - {"welcome_text": welcome_text,"welcome_mtype":mtype}, + {"welcome_text": welcome_text, "welcome_mtype": mtype}, ) if media: self.update( {"_id": self.chat_id}, - {"welcome_media": media,"welcome_mtype":mtype} + {"welcome_media": media, "welcome_mtype": mtype} ) - return + return - def set_goodbye_text(self, goodbye_text: str,mtype,media=None): + def set_goodbye_text(self, goodbye_text: str, mtype, media=None): with INSERTION_LOCK: self.update( {"_id": self.chat_id}, - {"goodbye_text": goodbye_text,"goodbye_mtype":mtype}, + {"goodbye_text": goodbye_text, "goodbye_mtype": mtype}, ) if media: self.update( {"_id": self.chat_id}, - {"goodbye_media": media,"goodbye_mtype":mtype} + {"goodbye_media": media, "goodbye_mtype": mtype} ) - return + return def set_current_cleanservice_settings(self, status: bool): with INSERTION_LOCK: @@ -154,13 +155,14 @@ def __ensure_in_db(self): "welcome_text": "Hey {first}, welcome to {chatname}!", "welcome": True, "goodbye": True, - "welcome_media":False, - "welcome_mtype":False, - "goodbye_media":False, - "goodbye_mtype":False + "welcome_media": False, + "welcome_mtype": False, + "goodbye_media": False, + "goodbye_mtype": False } self.insert_one(new_data) - LOGGER.info(f"Initialized Greetings Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Greetings Document for chat {self.chat_id}") return new_data return chat_data @@ -173,7 +175,7 @@ def migrate_chat(self, new_chat_id: int): def clean_greetings(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) @staticmethod def count_chats(query: str): diff --git a/Powers/database/locks_db.py b/Powers/database/locks_db.py index eb6bb55a..6637c002 100644 --- a/Powers/database/locks_db.py +++ b/Powers/database/locks_db.py @@ -5,10 +5,13 @@ INSERTION_LOCK = RLock() -lock_t = ["bot", "anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links"] +lock_t = ["bot", "anti_c_send", "anti_fwd", + "anti_fwd_u", "anti_fwd_c", "anti_links"] + + class LOCKS(MongoDB): """Class to store locks""" - + db_name = "locks" def __init__(self) -> None: @@ -20,21 +23,21 @@ def insert_lock_channel(self, chat: int, locktype: str): """ if locktype == "all": for i in lock_t: - curr = self.find_one({"chat_id":chat,"locktype":i}) - if curr: - continue - if i in ["anti_fwd_u", "anti_fwd_c"]: - continue - self.insert_one({"chat_id":chat,"locktype":i}) + curr = self.find_one({"chat_id": chat, "locktype": i}) + if curr: + continue + if i in ["anti_fwd_u", "anti_fwd_c"]: + continue + self.insert_one({"chat_id": chat, "locktype": i}) return True - curr = self.find_one({"chat_id":chat,"locktype":locktype}) + curr = self.find_one({"chat_id": chat, "locktype": locktype}) if curr: return False else: with INSERTION_LOCK: - hmm = self.merge_u_and_c(chat,locktype) + hmm = self.merge_u_and_c(chat, locktype) if not hmm: - self.insert_one({"chat_id":chat,"locktype":locktype}) + self.insert_one({"chat_id": chat, "locktype": locktype}) return True def remove_lock_channel(self, chat: int, locktype: str): @@ -43,40 +46,41 @@ def remove_lock_channel(self, chat: int, locktype: str): """ if locktype == "all": for i in lock_t: - curr = self.find_one({"chat_id":chat,"locktype":i}) - if curr: - self.delete_one({"chat_id":chat,"locktype":i}) + curr = self.find_one({"chat_id": chat, "locktype": i}) + if curr: + self.delete_one({"chat_id": chat, "locktype": i}) return True - curr = self.find_one({"chat_id":chat,"locktype":locktype}) + curr = self.find_one({"chat_id": chat, "locktype": locktype}) if curr: with INSERTION_LOCK: - self.delete_one({"chat_id":chat,"locktype":locktype}) + self.delete_one({"chat_id": chat, "locktype": locktype}) return True else: return False - def get_lock_channel(self, locktype: str="all", chat:int = 0): + def get_lock_channel(self, locktype: str = "all", chat: int = 0): """ locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links, bot """ - if locktype not in ["anti_c_send","anti_fwd","anti_fwd_u","anti_fwd_c","anti_links", "bot", "all"]: + if locktype not in ["anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links", "bot", "all"]: return False else: if locktype == "all": find = {} else: - find = {"locktype":locktype} + find = {"locktype": locktype} if chat: if find: - curr = self.find_one({"chat_id":chat, "locktype":locktype}) + curr = self.find_one( + {"chat_id": chat, "locktype": locktype}) return bool(curr) else: to_return = [] for i in lock_t: - curr = self.find_one({"chat_id":chat, "locktype":i}) + curr = self.find_one({"chat_id": chat, "locktype": i}) to_return.append(bool(curr)) return all(to_return) - else: + else: curr = self.find_all(find) if not curr: list_ = [] @@ -86,15 +90,15 @@ def get_lock_channel(self, locktype: str="all", chat:int = 0): def merge_u_and_c(self, chat: int, locktype: str): if locktype == "anti_fwd_u": - curr = self.find_one({"chat_id":chat,"locktype":"anti_fwd_c"}) + curr = self.find_one({"chat_id": chat, "locktype": "anti_fwd_c"}) elif locktype == "anti_fwd_c": - curr = self.find_one({"chat_id":chat,"locktype":"anti_fwd_u"}) + curr = self.find_one({"chat_id": chat, "locktype": "anti_fwd_u"}) else: return False if curr: - self.delete_one({"chat_id":chat,"locktype":locktype}) - self.insert_one({"chat_id":chat,"locktype":"anti_fwd"}) + self.delete_one({"chat_id": chat, "locktype": locktype}) + self.insert_one({"chat_id": chat, "locktype": "anti_fwd"}) return True else: return False @@ -103,9 +107,8 @@ def is_particular_lock(self, chat: int, locktype: str): """ locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links """ - curr = self.find_one({"chat_id":chat,"locktype":locktype}) + curr = self.find_one({"chat_id": chat, "locktype": locktype}) if curr: return True else: return False - \ No newline at end of file diff --git a/Powers/database/notes_db.py b/Powers/database/notes_db.py index 1b460c79..ad8b7570 100644 --- a/Powers/database/notes_db.py +++ b/Powers/database/notes_db.py @@ -57,7 +57,8 @@ def get_note_by_hash(self, note_hash: str): def get_all_notes(self, chat_id: int): with INSERTION_LOCK: curr = self.find_all({"chat_id": chat_id}) - note_list = sorted([(note["note_name"], note["hash"]) for note in curr]) + note_list = sorted([(note["note_name"], note["hash"]) + for note in curr]) return note_list def rm_note(self, chat_id: int, note_name: str): @@ -124,9 +125,9 @@ def get_privatenotes(self, chat_id: int): self.update({"_id": chat_id}, {"privatenotes": False}) return False - def clean_notes(self,chat_id): + def clean_notes(self, chat_id): with INSERTION_LOCK: - return self.delete_one({"_id":chat_id}) + 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 7c8882a3..6edfc137 100644 --- a/Powers/database/pins_db.py +++ b/Powers/database/pins_db.py @@ -68,7 +68,7 @@ def __ensure_in_db(self): def clean_pins(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) # Migrate if chat id changes! def migrate_chat(self, new_chat_id: int): diff --git a/Powers/database/reporting_db.py b/Powers/database/reporting_db.py index 935c6e35..6009d49d 100644 --- a/Powers/database/reporting_db.py +++ b/Powers/database/reporting_db.py @@ -42,9 +42,11 @@ def __ensure_in_db(self): chat_data = self.find_one({"_id": self.chat_id}) if not chat_data: chat_type = self.get_chat_type() - new_data = {"_id": self.chat_id, "status": True, "chat_type": chat_type} + new_data = {"_id": self.chat_id, + "status": True, "chat_type": chat_type} self.insert_one(new_data) - LOGGER.info(f"Initialized Language Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Language Document for chat {self.chat_id}") return new_data return chat_data @@ -57,7 +59,7 @@ def migrate_chat(self, new_chat_id: int): def clean_reporting(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) @staticmethod def repair_db(collection): diff --git a/Powers/database/rules_db.py b/Powers/database/rules_db.py index 3e82a247..0704cd89 100644 --- a/Powers/database/rules_db.py +++ b/Powers/database/rules_db.py @@ -68,7 +68,8 @@ def __ensure_in_db(self): if not chat_data: new_data = {"_id": self.chat_id, "privrules": False, "rules": ""} self.insert_one(new_data) - LOGGER.info(f"Initialized Language Document for chat {self.chat_id}") + LOGGER.info( + f"Initialized Language Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/support_db.py b/Powers/database/support_db.py index 70f935c1..35148c81 100644 --- a/Powers/database/support_db.py +++ b/Powers/database/support_db.py @@ -5,6 +5,7 @@ INSERTION_LOCK = RLock() + class SUPPORTS(MongoDB): """ class to store support users in database @@ -12,7 +13,7 @@ class to store support users in database """ db_name = "supports" - + def __init__(self) -> None: super().__init__(self.db_name) @@ -22,49 +23,48 @@ def insert_support_user(self, user_id, support_type): with INSERTION_LOCK: self.insert_one( { - "user_id":user_id, - "support_type":support_type + "user_id": user_id, + "support_type": support_type } ) return - def update_support_user_type(self,user,new_type): + def update_support_user_type(self, user, new_type): curr = self.is_support_user(user) if curr: with INSERTION_LOCK: self.update( { - "user_id":user + "user_id": user }, { - "support_type":new_type + "support_type": new_type } ) return - def is_support_user(self, user_id): - curr = self.find_one({"user_id":user_id}) + curr = self.find_one({"user_id": user_id}) if curr: return True return False - def delete_support_user(self,user): + def delete_support_user(self, user): curr = self.is_support_user(user) if curr: with INSERTION_LOCK: - self.delete_one({"user_id":user}) + self.delete_one({"user_id": user}) return - def get_particular_support(self,support_type): - curr = self.find_all({"support_type":support_type}) + def get_particular_support(self, support_type): + curr = self.find_all({"support_type": support_type}) if curr: return [i['user_id'] for i in curr] else: return [] - def get_support_type(self,user): - curr = self.find_one({"user_id":user}) + def get_support_type(self, user): + curr = self.find_one({"user_id": user}) if curr: return curr["support_type"] - return False \ No newline at end of file + return False diff --git a/Powers/database/users_db.py b/Powers/database/users_db.py index 08d9f16d..d9135055 100644 --- a/Powers/database/users_db.py +++ b/Powers/database/users_db.py @@ -67,7 +67,8 @@ def get_user_info(user_id: int or str): def __ensure_in_db(self): chat_data = self.find_one({"_id": self.user_id}) if not chat_data: - new_data = {"_id": self.user_id, "username": "", "name": "unknown_till_now"} + new_data = {"_id": self.user_id, + "username": "", "name": "unknown_till_now"} self.insert_one(new_data) LOGGER.info(f"Initialized User Document for {self.user_id}") return new_data diff --git a/Powers/database/warns_db.py b/Powers/database/warns_db.py index 95d4de6c..216705d4 100644 --- a/Powers/database/warns_db.py +++ b/Powers/database/warns_db.py @@ -49,7 +49,7 @@ def reset_warns(self, user_id: int): def clean_warn(self): with INSERTION_LOCK: - return self.delete_one({"chat_id":self.chat_id}) + return self.delete_one({"chat_id": self.chat_id}) def get_warns(self, user_id: int): with INSERTION_LOCK: @@ -93,12 +93,14 @@ def repair_db(collection): f"Repairing Approve Database - setting '{key}:{val}' for {data['user_id']} in {data['chat_id']}", ) collection.update( - {"chat_id": data["chat_id"], "user_id": data["user_id"]}, + {"chat_id": data["chat_id"], + "user_id": data["user_id"]}, {key: val}, ) def __ensure_in_db(self, user_id: int): - chat_data = self.find_one({"chat_id": self.chat_id, "user_id": user_id}) + chat_data = self.find_one( + {"chat_id": self.chat_id, "user_id": user_id}) if not chat_data: new_data = { "chat_id": self.chat_id, @@ -107,7 +109,8 @@ def __ensure_in_db(self, user_id: int): "num_warns": 0, } self.insert_one(new_data) - LOGGER.info(f"Initialized Warn Document for {user_id} in {self.chat_id}") + LOGGER.info( + f"Initialized Warn Document for {user_id} in {self.chat_id}") return new_data return chat_data @@ -123,9 +126,11 @@ def __init__(self, chat_id: int) -> None: def __ensure_in_db(self): chat_data = self.find_one({"_id": self.chat_id}) if not chat_data: - new_data = {"_id": self.chat_id, "warn_mode": "none", "warn_limit": 3} + new_data = {"_id": self.chat_id, + "warn_mode": "none", "warn_limit": 3} self.insert_one(new_data) - LOGGER.info(f"Initialized Warn Settings Document for {self.chat_id}") + LOGGER.info( + f"Initialized Warn Settings Document for {self.chat_id}") return new_data return chat_data @@ -140,7 +145,7 @@ def set_warnmode(self, warn_mode: str = "none"): def clean_warns(self): with INSERTION_LOCK: - return self.delete_one({"_id":self.chat_id}) + return self.delete_one({"_id": self.chat_id}) def get_warnmode(self): with INSERTION_LOCK: diff --git a/Powers/plugins/__init__.py b/Powers/plugins/__init__.py index cd4ed62e..aa74eba6 100644 --- a/Powers/plugins/__init__.py +++ b/Powers/plugins/__init__.py @@ -38,3 +38,4 @@ def till_date(date): form = "%Y-%m-%d %H:%M:%S" z = datetime.strptime(date,form) return z + diff --git a/Powers/plugins/captcha.py b/Powers/plugins/captcha.py new file mode 100644 index 00000000..a9ce22de --- /dev/null +++ b/Powers/plugins/captcha.py @@ -0,0 +1,230 @@ +from random import shuffle +from traceback import format_exc + +import pyrogram +from pyrogram import filters +from pyrogram.types import CallbackQuery, ChatMemberUpdated, ChatPermissions +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.captcha_db import CAPTCHA, CAPTCHA_DATA +from Powers.supports import get_support_staff +from Powers.utils.captcha_helper import (genrator, get_image_captcha, + get_qr_captcha) +from Powers.utils.custom_filters import admin_filter, command + + +@Gojo.on_message(command("captcha") & admin_filter & ~filters.private) +async def start_captcha(c: Gojo, m: Message): + captcha = CAPTCHA() + split = m.command + if len(split) == 1: + is_cap = captcha.is_captcha(m.chat.id) + if is_cap: + txt = "Captcha verification is currently **on** for this chat" + else: + txt = "Captcha verification is currently **off** for this chat" + await m.reply_text(txt) + return + else: + on_off = split[1].lower() + if on_off in ["on", "yes", "enable"]: + captcha.insert_captcha(m.chat.id) + await m.reply_text("Captcha verification is now **on** for this chat") + return + elif on_off in ["off", "no", "disable"]: + captcha.remove_captcha(m.chat.id) + await m.reply_text("Captcha verification is now **off** for this chat") + return + else: + await m.reply_text("**USAGE**\n/captcha [on | yes | enable | off | no | disable]") + return + + +@Gojo.on_message(command("captchamode") & admin_filter & ~filters.private) +async def set_captcha_mode(c: Gojo, m: Message): + split = m.command + captcha = CAPTCHA() + if len(split) == 1: + curr = captcha.get_captcha(m.chat.id) + if curr: + capatcha_type = curr["captcha_type"] + await m.reply_text(f"Current captcha verification methode is {capatcha_type}\nAvailable methodes:\n■ qr\n■ image") + return + else: + await m.reply_text("Captcha verification is off for the current chat") + return + else: + type_ = split[1].lower() + if type_ == "qr": + captcha.update_type(m.chat.id, "qr") + await m.reply_text("Captcha verification is now changed to qr code") + return + elif type_ == "image": + captcha.update_type(m.chat.id, "image") + await m.reply_text("Captcha verication is now changed to image") + return + else: + await m.reply_text("**USAGE**\n/captchamode [qr | image]") + return + + +@Gojo.on_callback_query(filters.regex("^captcha_")) +async def captcha_codes_check(c: Gojo, q: CallbackQuery): + split = q.data.split("_") + chat = int(split[1]) + user = int(split[2]) + code = split[3] + + if q.from_user.id != user: + await q.answer("Not for you BAKA!") + return + + c_data = CAPTCHA_DATA() + code_ = c_data.get_cap_data(chat, user) + + if code_ == code: + cap = "You guessed the captcha right...Now you can talk in the chat with no restrictions" + c_data.remove_cap_data(chat, user) + await q.answer(cap, True) + try: + await q.message.chat.unban_member(user) + except Exception as e: + await q.message.reply_text(f"Unable to unmute {q.from_user.mention} this user") + await q.message.reply_text(e) + return + await c.send_message(chat, f"{q.from_user.mention} now you are free to talk") + await q.message.delete() + return + else: + caps = q.message.caption.split(":") + tries = int(caps[1].strip()) - 1 + caps.pop(-1) + caps.append(f" {tries}") + new_cap = ":".join(caps) + await q.answer(f"Wrong\nTries left: {tries}", True) + if not tries: + new_cap = f"You have zero tries left now. I am going to kick you know coz you failed to solve captcha...see yaa {q.from_user.mention}" + try: + await q.message.chat.ban_member(user) + except Exception as e: + await q.message.reply_text("Failed to kick member") + return + await q.message.delete() + await q.message.reply_text(new_cap) + await c.unban_chat_member(chat, user) + + else: + await q.edit_message_caption(new_cap, reply_markup=q.message.reply_markup) + return + + +@Gojo.on_chat_member_updated(filters.group, group=3) +async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): + chat = u.chat.id + + if u.new_chat_member: + + user = u.new_chat_member.user.id + userr = u.new_chat_member.user + + is_qr = CAPTCHA().is_captcha(chat) + if not is_qr: + return + + captcha = CAPTCHA() + cap_data = CAPTCHA_DATA() + + SUPPORT_STAFF = get_support_staff() + if user in SUPPORT_STAFF: + return + + captcha_type = captcha.get_captcha(chat) + + is_already = cap_data.is_already_data(chat, user) + + mess = False + try: + if is_already: + mess = await c.get_messages(chat, int(is_already)) + except Exception: + cap_data.del_message_id(chat, is_already) + mess = False + is_already = False + + if is_already and not mess: + cap_data.del_message_id(chat, is_already) + return + + try: + await c.restrict_chat_member(chat, user, ChatPermissions()) + except Exception as e: + LOGGER.error(e) + LOGGER.error(format_exc()) + return + + if not is_already: + if captcha_type == "qr": + pic = await get_qr_captcha(chat, user) + cap = f"Please {userr.mention} scan this qr code with your phone to verify that you are human" + ms = await c.send_photo(chat, pic, caption=cap) + cap_data.store_message_id(chat, user, ms.id) + return + elif captcha_type == "image": + img, code = await get_image_captcha(chat, user) + cap = f"Please {userr.mention} please choose the correct code from the one given bellow\nYou have three tries if you get all three wrong u will be kicked from the chat.\nTries left: 3" + cap_data.load_cap_data(chat, user, code) + rand = [code] + while len(rand) != 5: + hehe = genrator() + rand.append(hehe) + + shuffle(rand) + + ini = f"captcha_{chat}_{user}_" + + kb = ikm( + [ + [ + IKB(rand[0], ini+rand[0]) + ], + [ + IKB(rand[1], ini+rand[1]) + ], + [ + IKB(rand[2], ini+rand[2]) + ], + [ + IKB(rand[3], ini+rand[3]) + ], + [ + IKB(rand[4], ini+rand[4]) + ] + ] + ) + await c.send_photo(chat, img, caption=cap, reply_markup=kb) + return + elif is_already and mess: + kb = ikm( + [ + [ + IKB("Click here to verify", url=mess.link) + ] + ] + ) + await c.send_message(f"{userr.mention} your verification is already pending", reply_markup=kb) + return + else: + await c.unban_chat_member(chat, user) + return + + +__PLUGIN__ = "captcha" + +__HELP__ = """ +• /captcha [on|yes|enable|off|no|disable] : To enable or disable captcha verification +• /captchamode [qr|image] : To change captcha mode +""" diff --git a/Powers/plugins/formatting.py b/Powers/plugins/formatting.py index f9bc65d5..8d639dbf 100644 --- a/Powers/plugins/formatting.py +++ b/Powers/plugins/formatting.py @@ -73,10 +73,12 @@ async def get_formatting_info(c: Gojo, q: CallbackQuery): parse_mode=enums.ParseMode.HTML, ) except MediaCaptionTooLong: + kb = ikb([[("Back", "DELETEEEE")]]) await c.send_message( chat_id=q.message.chat.id, text=txt, - parse_mode=enums.ParseMode.HTML,) + parse_mode=enums.ParseMode.HTML, + reply_markup=kb) elif cmd == "fillings": await q.edit_message_caption( caption="""Fillings diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index 9bf698a8..9390dbc1 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -6,7 +6,7 @@ from pyrogram.enums import MessageEntityType as MET from pyrogram.enums import MessageServiceType as MST from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError -from pyrogram.types import ChatPermissions, Message +from pyrogram.types import CallbackQuery, ChatPermissions, Message from Powers import LOGGER from Powers.bot_class import Gojo @@ -15,6 +15,7 @@ from Powers.supports import get_support_staff from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.utils.custom_filters import command, restrict_filter +from Powers.utils.kbhelpers import ikb from Powers.vars import Config l_t = """ @@ -37,6 +38,7 @@ - `forwardc` = Forwarding from channel - `links | url` = Lock links""" + @Gojo.on_message(command("locktypes")) async def lock_types(_, m: Message): await m.reply_text( @@ -73,7 +75,8 @@ async def lock_perm(c: Gojo, m: Message): try: await c.set_chat_permissions(chat_id, ChatPermissions()) lock.insert_lock_channel(m.chat.id, "all") - LOGGER.info(f"{m.from_user.id} locked all permissions in {m.chat.id}") + LOGGER.info( + f"{m.from_user.id} locked all permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -82,7 +85,6 @@ async def lock_perm(c: Gojo, m: Message): await prevent_approved(m) return - if lock_type == "msg": msg = False perm = "messages" @@ -127,7 +129,7 @@ async def lock_perm(c: Gojo, m: Message): pin = False perm = "pin" elif lock_type == "bot": - curr = lock.insert_lock_channel(m.chat.id,"bot") + curr = lock.insert_lock_channel(m.chat.id, "bot") if not curr: await m.reply_text("It is already on") return @@ -141,28 +143,28 @@ async def lock_perm(c: Gojo, m: Message): await m.reply_text("Locked links in the chat") return elif lock_type == "anonchannel": - curr = lock.insert_lock_channel(m.chat.id,"anti_c_send") + curr = lock.insert_lock_channel(m.chat.id, "anti_c_send") if not curr: await m.reply_text("It is already on") return await m.reply_text("Locked Send As Chat") return elif lock_type == "forwardall": - curr = lock.insert_lock_channel(m.chat.id,"anti_fwd") + curr = lock.insert_lock_channel(m.chat.id, "anti_fwd") if not curr: await m.reply_text("It is already on") return await m.reply_text("Locked Forward from user as well as channel") return elif lock_type == "forwardu": - curr = lock.insert_lock_channel(m.chat.id,"anti_fwd_u") + curr = lock.insert_lock_channel(m.chat.id, "anti_fwd_u") if not curr: await m.reply_text("It is already on") return await m.reply_text("Locked Forward message from user") return elif lock_type == "forwardc": - curr = lock.insert_lock_channel(m.chat.id,"anti_fwd_c") + curr = lock.insert_lock_channel(m.chat.id, "anti_fwd_c") if not curr: await m.reply_text("It is already on") return @@ -182,7 +184,8 @@ async def lock_perm(c: Gojo, m: Message): ChatPermissions( can_send_messages=msg, can_send_media_messages=media, - can_send_other_messages=any([stickers, animations, games, inlinebots]), + can_send_other_messages=any( + [stickers, animations, games, inlinebots]), can_add_web_page_previews=webprev, can_send_polls=polls, can_change_info=info, @@ -190,7 +193,8 @@ async def lock_perm(c: Gojo, m: Message): can_pin_messages=pin, ), ) - LOGGER.info(f"{m.from_user.id} locked selected permissions in {m.chat.id}") + LOGGER.info( + f"{m.from_user.id} locked selected permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -211,9 +215,9 @@ async def convert_to_emoji(val: bool): if val: return "✅" return "❌" - + lock = LOCKS() - anon= lock.get_lock_channel("anti_c_send", m.chat.id) + anon = lock.get_lock_channel("anti_c_send", m.chat.id) anti_f = lock.get_lock_channel("anti_fwd", m.chat.id) anti_f_u = lock.get_lock_channel("anti_fwd_u", m.chat.id) anti_f_c = lock.get_lock_channel("anti_fwd_c", m.chat.id) @@ -294,8 +298,9 @@ async def unlock_perm(c: Gojo, m: Message): can_pin_messages=True, ), ) - lock.remove_lock_channel(m.chat.id,"all") - LOGGER.info(f"{m.from_user.id} unlocked all permissions in {m.chat.id}") + lock.remove_lock_channel(m.chat.id, "all") + LOGGER.info( + f"{m.from_user.id} unlocked all permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -315,7 +320,6 @@ async def unlock_perm(c: Gojo, m: Message): upin = get_uperm.can_pin_messages ustickers = uanimations = ugames = uinlinebots = None - if unlock_type == "msg": umsg = True uperm = "messages" @@ -360,21 +364,21 @@ async def unlock_perm(c: Gojo, m: Message): upin = True uperm = "pin" elif unlock_type == "bot": - curr = lock.remove_lock_channel(m.chat.id,"bot") + curr = lock.remove_lock_channel(m.chat.id, "bot") if not curr: m.reply_text("User already can add bots in the chat") return await m.reply_text("User are now allowed to add bots in the chat.") elif unlock_type == "anonchannel": - curr = lock.remove_lock_channel(m.chat.id,"anti_c_send") - + curr = lock.remove_lock_channel(m.chat.id, "anti_c_send") + if not curr: await m.reply_text("Send as chat is not allowed in this chat") return await m.reply_text("Send as chat is now enabled for this chat") return elif unlock_type in ["links", "url"]: - curr = lock.remove_lock_channel(m.chat.id,"anti_links") + curr = lock.remove_lock_channel(m.chat.id, "anti_links") if curr: await m.reply_text("Sending link is now allowed") return @@ -382,33 +386,33 @@ async def unlock_perm(c: Gojo, m: Message): await m.reply_text("Sending link is not allowed") return elif unlock_type == "forwardall": - curr = lock.remove_lock_channel(m.chat.id,"anti_fwd") - + curr = lock.remove_lock_channel(m.chat.id, "anti_fwd") + if not curr: await m.reply_text("Forwarding content is not allowed in this chat") return await m.reply_text("Forwarding content is now enabled for this chat") return - + elif unlock_type == "forwardu": - curr = lock.remove_lock_channel(m.chat.id,"anti_fwd_u") - + curr = lock.remove_lock_channel(m.chat.id, "anti_fwd_u") + if not curr: await m.reply_text("Forwarding content from users is not allowed in this chat") return - + await m.reply_text("Forwarding content from users is now enabled for this chat") return - + elif unlock_type == "forwardc": - curr = lock.remove_lock_channel(m.chat.id,"anti_fwd_c") - + curr = lock.remove_lock_channel(m.chat.id, "anti_fwd_c") + if not curr: await m.reply_text("Forwarding content from channel is not allowed in this chat") return await m.reply_text("Forwarding content from channel is now enabled for this chat") return - + else: await m.reply_text( text="""Invalid Lock Type! @@ -418,7 +422,8 @@ async def unlock_perm(c: Gojo, m: Message): return try: - LOGGER.info(f"{m.from_user.id} unlocked selected permissions in {m.chat.id}") + LOGGER.info( + f"{m.from_user.id} unlocked selected permissions in {m.chat.id}") await c.set_chat_permissions( chat_id, ChatPermissions( @@ -444,7 +449,8 @@ async def unlock_perm(c: Gojo, m: Message): await prevent_approved(m) return -async def delete_messages(c:Gojo, m: Message): + +async def delete_messages(c: Gojo, m: Message): try: await m.delete() return @@ -453,14 +459,15 @@ async def delete_messages(c:Gojo, m: Message): LOGGER.error(format_exc()) return -async def is_approved_user(c:Gojo, m: Message): + +async def is_approved_user(c: Gojo, m: Message): approved_users = Approve(m.chat.id).list_approved() ul = [user[0] for user in approved_users] try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = await admin_cache_reload(m, "lock") - + SUDO_LEVEL = get_support_staff("sudo_level") if m.forward_from: @@ -480,28 +487,28 @@ async def is_approved_user(c:Gojo, m: Message): return True return False + @Gojo.on_message(filters.service & filters.group, 19) async def servicess(c: Gojo, m: Message): if m.service != MST.NEW_CHAT_MEMBERS: return - approved = await is_approved_user(c,m) + approved = await is_approved_user(c, m) if approved: return for i in m.new_chat_members: if i.is_bot: try: timee = datetime.now() + timedelta(minutes=5) - await m.chat.ban_member(i.id,until_date=timee) + await m.chat.ban_member(i.id, until_date=timee) sleep(1) except Exception as ef: LOGGER.error(ef) LOGGER.error(format_exc()) return - -@Gojo.on_message(filters.group & ~filters.me,18) -async def lock_del_mess(c:Gojo, m: Message): +@Gojo.on_message(filters.group & ~filters.me, 18) +async def lock_del_mess(c: Gojo, m: Message): lock = LOCKS() all_chats = lock.get_lock_channel() if not all_chats: @@ -511,28 +518,29 @@ async def lock_del_mess(c:Gojo, m: Message): if m.sender_chat and not (m.forward_from_chat or m.forward_from): if m.sender_chat.id == m.chat.id: return - await delete_messages(c,m) + await delete_messages(c, m) return - is_approved = await is_approved_user(c,m) + is_approved = await is_approved_user(c, m) if is_approved: return 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]: - await delete_messages(c,m) + await delete_messages(c, m) return elif m.forward_from or m.forward_from_chat: - if lock.is_particular_lock(m.chat.id,"anti_fwd"): - await delete_messages(c,m) + if lock.is_particular_lock(m.chat.id, "anti_fwd"): + await delete_messages(c, m) return - elif lock.is_particular_lock(m.chat.id,"anti_fwd_u") and not m.forward_from_chat: - await delete_messages(c,m) + elif lock.is_particular_lock(m.chat.id, "anti_fwd_u") and not m.forward_from_chat: + await delete_messages(c, m) return - elif lock.is_particular_lock(m.chat.id,"anti_fwd_c") and m.forward_from_chat: - await delete_messages(c,m) + elif lock.is_particular_lock(m.chat.id, "anti_fwd_c") and m.forward_from_chat: + await delete_messages(c, m) return + async def prevent_approved(m: Message): approved_users = Approve(m.chat.id).list_approved() ul = [user[0] for user in approved_users] @@ -553,7 +561,7 @@ async def prevent_approved(m: Message): __buttons__ = [ [ ("Lock Types", "LOCK_TYPES"), - ],] + ], ] __HELP__ = """ **Locks** @@ -569,3 +577,21 @@ async def prevent_approved(m: Message): **Example:** `/lock media`: this locks all the media messages in the chat.""" + + +@Gojo.on_callback_query(filters.regex("^LOCK_TYPES")) +async def lock_types_callback(c: Gojo, q: CallbackQuery): + data = q.data + + if data == "LOCK_TYPES": + kb = ikb([[("Back", "LOCK_TYPES_back")]]) + await q.edit_message_caption( + l_t, + reply_markup=kb + ) + else: + kb = ikb([[("Lock Types", "LOCK_TYPES")]]) + await q.edit_message_caption( + __HELP__, + reply_markup=kb + ) diff --git a/Powers/plugins/muting.py b/Powers/plugins/muting.py index 95d4f77e..7705e977 100644 --- a/Powers/plugins/muting.py +++ b/Powers/plugins/muting.py @@ -634,14 +634,14 @@ async def unmutebutton(c: Gojo, q: CallbackQuery): user_id = int(splitter[1]) user = await q.message.chat.get_member(q.from_user.id) - if not user: + if not user or not user.privileges: await q.answer( "You don't have enough permission to do this!\nStay in your limits!", show_alert=True, ) return - if not user.privileges.can_restrict_members and user.id != OWNER_ID: + if not user.privileges.can_restrict_members: await q.answer( "You don't have enough permission to do this!\nStay in your limits!", show_alert=True, diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index ba67cce7..d5e130a5 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -1,3 +1,4 @@ +import os from random import choice from time import gmtime, strftime, time @@ -19,6 +20,7 @@ from Powers.utils.parser import mention_html from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg, get_private_note, get_private_rules) +from Powers.utils.string import encode_decode from Powers.vars import Config @@ -33,7 +35,7 @@ async def donate(_, m: Message): All the fund would be put into my services such as database, storage and hosting! -You can donate by contacting my owner: [Captain Ezio](http://t.me/iamgojoof6eyes) +You can donate by contacting my owner: [Captain D. Ezio](http://t.me/iamgojoof6eyes) """ LOGGER.info(f"{m.from_user.id} fetched donation text in {m.chat.id}") @@ -76,13 +78,14 @@ async def start(c: Gojo, m: Message): ): await get_private_note(c, m, help_option) return - + if help_option.startswith("rules"): - LOGGER.info(f"{m.from_user.id} fetched privaterules in {m.chat.id}") + LOGGER.info( + f"{m.from_user.id} fetched privaterules in {m.chat.id}") await get_private_rules(c, m, help_option) return - help_msg, help_kb = await get_help_msg(m, help_option) + help_msg, help_kb = await get_help_msg(c, m, help_option) if not help_msg: return @@ -95,7 +98,7 @@ async def start(c: Gojo, m: Message): quote=True, ) return - if len(help_option.split("_",1)) == 2: + if len(help_option.split("_", 1)) == 2: if help_option.split("_")[1] == "help": await m.reply_photo( photo=str(choice(StartPic)), @@ -105,10 +108,28 @@ async def start(c: Gojo, m: Message): quote=True, ) return - + elif help_option.split("_", 1)[0] == "qrcaptcha": + decoded = encode_decode( + help_option.split("_", 1)[1], "decode") + decode = decoded.split(":") + chat = decode[0] + user = decode[1] + if m.from_user.id != int(user): + await m.reply_text("Not for you Baka") + return + try: + await c.unban_chat_member(int(chat), int(user)) + try: + os.remove(f"captcha_verification{chat}_{user}.png") + except Exception: + pass + return + except Exception: + return + try: cpt = f""" -Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am Gojo ✨. +Hey [{m.from_user.first_name}](http://t.me/{m.from_user.username})! I am {c.me.first_name} ✨. I'm here to help you manage your group(s)! Hit /help to find out more about how to use me in my full potential! @@ -123,31 +144,31 @@ async def start(c: Gojo, m: Message): except UserIsBlocked: LOGGER.warning(f"Bot blocked by {m.from_user.id}") else: - kb = InlineKeyboardMarkup( - [ - [ - InlineKeyboardButton( - "Connect me to pm", - url=f"https://{Config.BOT_USERNAME}.t.me/", - ), - ], - ], - ) - - await m.reply_photo( - photo=str(choice(StartPic)), - caption="I'm alive :3", - reply_markup=kb, - quote=True, - ) + kb = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Connect me to pm", + url=f"https://{Config.BOT_USERNAME}.t.me/", + ), + ], + ], + ) + + await m.reply_photo( + photo=str(choice(StartPic)), + caption="I'm alive :3", + reply_markup=kb, + quote=True, + ) return @Gojo.on_callback_query(filters.regex("^start_back$")) -async def start_back(_, q: CallbackQuery): +async def start_back(c: Gojo, q: CallbackQuery): try: cpt = f""" -Hey [{q.from_user.first_name}](http://t.me/{q.from_user.username})! I am Gojo ✨. +Hey [{q.from_user.first_name}](http://t.me/{q.from_user.username})! I am {c.me.first_name} ✨. I'm here to help you manage your group(s)! Hit /help to find out more about how to use me in my full potential! @@ -164,12 +185,12 @@ async def start_back(_, q: CallbackQuery): @Gojo.on_callback_query(filters.regex("^commands$")) -async def commands_menu(_, q: CallbackQuery): +async def commands_menu(c: Gojo, q: CallbackQuery): ou = await gen_cmds_kb(q.message) keyboard = ikb(ou, True) try: cpt = f""" -Hey **[{q.from_user.first_name}](http://t.me/{q.from_user.username})**! I am Gojo✨. +Hey **[{q.from_user.first_name}](http://t.me/{q.from_user.username})**! I am {c.me.first_name}✨. I'm here to help you manage your group(s)! Commands available: × /start: Start the bot @@ -194,14 +215,15 @@ async def commands_menu(_, q: CallbackQuery): @Gojo.on_message(command("help")) -async def help_menu(_, m: Message): +async def help_menu(c: Gojo, m: Message): if len(m.text.split()) >= 2: - textt = m.text.replace(" ","_",).replace("_"," ",1) + textt = m.text.replace(" ", "_",).replace("_", " ", 1) help_option = (textt.split(None)[1]).lower() - help_msg, help_kb = await get_help_msg(m, help_option) + help_msg, help_kb = await get_help_msg(c, m, help_option) if not help_msg: - LOGGER.error(f"No help_msg found for help_option - {help_option}!!") + LOGGER.error( + f"No help_msg found for help_option - {help_option}!!") return LOGGER.info( @@ -226,14 +248,14 @@ async def help_menu(_, m: Message): photo=str(choice(StartPic)), caption=f"Press the button below to get help for {help_option}", reply_markup=InlineKeyboardMarkup( - [ [ - InlineKeyboardButton( - "Help", - url=f"t.me/{Config.BOT_USERNAME}?start={help_option}", - ), + [ + InlineKeyboardButton( + "Help", + url=f"t.me/{Config.BOT_USERNAME}?start={help_option}", + ), + ], ], - ], ), ) else: @@ -242,21 +264,21 @@ async def help_menu(_, m: Message): ou = await gen_cmds_kb(m) keyboard = ikb(ou, True) msg = f""" -Hey **[{m.from_user.first_name}](http://t.me/{m.from_user.username})**!I am Gojo✨. +Hey **[{m.from_user.first_name}](http://t.me/{m.from_user.username})**!I am {c.me.first_name}✨. I'm here to help you manage your group(s)! Commands available: × /start: Start the bot × /help: Give's you this message.""" else: keyboard = InlineKeyboardMarkup( - [ [ - InlineKeyboardButton( - "Help", - url=f"t.me/{Config.BOT_USERNAME}?start=start_help", - ), + [ + InlineKeyboardButton( + "Help", + url=f"t.me/{Config.BOT_USERNAME}?start=start_help", + ), + ], ], - ], ) msg = "Contact me in PM to get the list of possible commands." @@ -268,6 +290,7 @@ async def help_menu(_, m: Message): return + @Gojo.on_callback_query(filters.regex("^bot_curr_info$")) async def give_curr_info(c: Gojo, q: CallbackQuery): start = time() @@ -285,6 +308,7 @@ async def give_curr_info(c: Gojo, q: CallbackQuery): await q.answer(txt, show_alert=True) return + @Gojo.on_callback_query(filters.regex("^plugins.")) async def get_module_info(c: Gojo, q: CallbackQuery): module = q.data.split(".", 1)[1] @@ -293,19 +317,21 @@ async def get_module_info(c: Gojo, q: CallbackQuery): help_kb = HELP_COMMANDS[f"plugins.{module}"]["buttons"] try: - await q.edit_message_caption( - caption=help_msg, - parse_mode=enums.ParseMode.MARKDOWN, - reply_markup=ikb(help_kb, True, todo="commands"), - ) + await q.edit_message_caption( + caption=help_msg, + parse_mode=enums.ParseMode.MARKDOWN, + reply_markup=ikb(help_kb, True, todo="commands"), + ) except MediaCaptionTooLong: - await c.send_message(chat_id=q.message.chat.id,text=help_msg,) + kb = ikb([[("Back", "DELETEEEE")]]) + await c.send_message(chat_id=q.message.chat.id, text=help_msg, reply_markup=kb) await q.answer() return DEV_USERS = get_support_staff("dev") SUDO_USERS = get_support_staff("sudo") + @Gojo.on_callback_query(filters.regex("^give_bot_staffs$")) async def give_bot_staffs(c: Gojo, q: CallbackQuery): try: @@ -349,6 +375,11 @@ async def give_bot_staffs(c: Gojo, q: CallbackQuery): except RPCError: pass - await q.edit_message_caption(reply,reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("« Back","start_back")]])) + await q.edit_message_caption(reply, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("« Back", "start_back")]])) return + +@Gojo.on_callback_query(filters.regex("^DELETEEEE$")) +async def delete_back(_, q: CallbackQuery): + await q.message.delete() + return diff --git a/Powers/supports.py b/Powers/supports.py index 6bee9455..36309f86 100644 --- a/Powers/supports.py +++ b/Powers/supports.py @@ -5,14 +5,15 @@ async def load_support_users(): support = SUPPORTS() for i in DEV_USERS: - support.insert_support_user(int(i),"dev") + support.insert_support_user(int(i), "dev") for i in SUDO_USERS: - support.insert_support_user(int(i),"sudo") + support.insert_support_user(int(i), "sudo") for i in WHITELIST_USERS: - support.insert_support_user(int(i),"whitelist") + support.insert_support_user(int(i), "whitelist") return -def get_support_staff(want = "all"): + +def get_support_staff(want="all"): """ dev, sudo, whitelist, dev_level, sudo_level, all """ @@ -21,7 +22,7 @@ def get_support_staff(want = "all"): sudo = support.get_particular_support("sudo") whitelist = support.get_particular_support("whitelist") - if want in ["dev","dev_level"]: + if want in ["dev", "dev_level"]: wanted = devs elif want == "sudo": wanted = sudo @@ -32,4 +33,4 @@ def get_support_staff(want = "all"): else: wanted = list(set([int(OWNER_ID)] + devs + sudo + whitelist)) - return wanted \ No newline at end of file + return wanted diff --git a/Powers/utils/caching.py b/Powers/utils/caching.py index f6e102da..1545af23 100644 --- a/Powers/utils/caching.py +++ b/Powers/utils/caching.py @@ -14,7 +14,8 @@ # admins stay cached for 30 mins ADMIN_CACHE = TTLCache(maxsize=512, ttl=(60 * 30), timer=perf_counter) # Block from refreshing admin list for 10 mins -TEMP_ADMIN_CACHE_BLOCK = TTLCache(maxsize=512, ttl=(60 * 10), timer=perf_counter) +TEMP_ADMIN_CACHE_BLOCK = TTLCache( + maxsize=512, ttl=(60 * 10), timer=perf_counter) async def admin_cache_reload(m: Message or CallbackQuery, status=None) -> List[int]: diff --git a/Powers/utils/captcha_helper.py b/Powers/utils/captcha_helper.py index 204dd65c..ac82922a 100644 --- a/Powers/utils/captcha_helper.py +++ b/Powers/utils/captcha_helper.py @@ -12,7 +12,8 @@ initial = f"t.me/{Config.BOT_USERNAME}?start=qrcaptcha_" captchaa = CAPTCHA_DATA() -async def get_qr_captcha(chat,user): + +async def get_qr_captcha(chat, user): encode = f"{chat}:{user}" encoded = encode_decode(encode) final = initial+encoded @@ -21,11 +22,13 @@ async def get_qr_captcha(chat,user): qr.save(name) return name + def genrator(): - alpha = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] + alpha = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] rand_alpha = choice(alpha) - if_ = randint(0,1) - + if_ = randint(0, 1) + if if_: new_alpha = rand_alpha.upper() else: @@ -33,24 +36,23 @@ def genrator(): list_ = [new_alpha] while len(list_) != 4: - xXx = randrange(0,9) + xXx = randrange(0, 9) list_.append(xXx) str_ = "" while len(str_) != 4: OwO = choice(list_) - str_ += OwO + str_ += OwO return str_ -async def get_image_captcha(chat,user): + +async def get_image_captcha(chat, user): str_ = genrator() - captchaa.load_cap_data(chat,user,str_) + captchaa.load_cap_data(chat, user, str_) name = f"captcha_img_{chat}_{user}.png" - image = ImageCaptcha(280,90) + image = ImageCaptcha(280, 90) cap = image.generate(str_) - image.write(str_,name) + image.write(str_, name) return name, str_ - - diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 3e192dc8..dc430f06 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -186,7 +186,7 @@ async def owner_check_func(_, __, m: Message or CallbackQuery): if m.chat.type not in [ChatType.SUPERGROUP, ChatType.GROUP]: return False - + if not m.from_user: return False @@ -264,7 +264,6 @@ async def changeinfo_check_func(_, __, m): if m.sender_chat: return True - user = await m.chat.get_member(m.from_user.id) if user.status in [CMS.ADMINISTRATOR, CMS.OWNER] and user.privileges.can_change_info: @@ -304,16 +303,18 @@ async def can_pin_message_func(_, __, m): return status + async def auto_join_check_filter(_, __, j: ChatJoinRequest): chat = j.chat.id aj = AUTOJOIN() join_type = aj.get_autojoin(chat) - + if not join_type: return False else: return True + async def afk_check_filter(_, __, m: Message): if not m.from_user: return False @@ -323,7 +324,7 @@ async def afk_check_filter(_, __, m: Message): if m.chat.type == ChatType.PRIVATE: return False - + afk = AFK() user = m.from_user.id chat = m.chat.id @@ -334,16 +335,17 @@ async def afk_check_filter(_, __, m: Message): else: rep_user = False - is_afk = afk.check_afk(chat,user) + is_afk = afk.check_afk(chat, user) is_rep_afk = False if rep_user: - is_rep_afk = afk.check_afk(chat,rep_user) + is_rep_afk = afk.check_afk(chat, rep_user) if not is_rep_afk and not is_afk: return False else: return True + async def flood_check_filter(_, __, m: Message): Flood = Floods() if not m.chat: @@ -351,23 +353,23 @@ async def flood_check_filter(_, __, m: Message): if not m.from_user: return False - + if m.chat.type == ChatType.PRIVATE: return False u_id = m.from_user.id c_id = m.chat.id is_flood = Flood.is_chat(c_id) - + app_users = Approve(m.chat.id).list_approved() SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) - + if not is_flood or u_id in SUDO_LEVEL: return False - + elif u_id in {i[0] for i in app_users}: return False - + else: return True diff --git a/Powers/utils/extract_user.py b/Powers/utils/extract_user.py index 69bfa0d0..6f0d37e8 100644 --- a/Powers/utils/extract_user.py +++ b/Powers/utils/extract_user.py @@ -30,7 +30,7 @@ async def extract_user(c: Gojo, m: Message) -> Tuple[int, str, str]: elif required_entity.type in (entity.MENTION, entity.PHONE_NUMBER): # new long user ids are identified as phone_number user_found = m.text[ - required_entity.offset : ( + required_entity.offset: ( required_entity.offset + required_entity.length ) ] diff --git a/Powers/utils/extras.py b/Powers/utils/extras.py index a2d91fba..ee0a1eba 100644 --- a/Powers/utils/extras.py +++ b/Powers/utils/extras.py @@ -514,7 +514,8 @@ ) -DECIDE = ("Yes.", "No.", "Maybe.", "Who the hell cares?", "No one give a damn about it") +DECIDE = ("Yes.", "No.", "Maybe.", "Who the hell cares?", + "No one give a damn about it") INSULT_STRINGS = [ "`Owww ... Such a stupid idiot.`", @@ -707,7 +708,7 @@ ] -birthday_wish = [ +birthday_wish = [ "Wishing you a happy birthday filled with love and joy.", "Hope your birthday is as wonderful as you are.", "Happy birthday to someone who deserves an exceptional day.", @@ -783,4 +784,4 @@ "Happy birthday to someone who brings a smile to my face every day, may your day be as wonderful as you are.", "Sending you all my love and warmest wishes on your special day, may your year be filled with love and happiness.", "May your birthday be a time to appreciate all the people who make your life special, and cherish all the memories you've created.", - "Wishing you a birthday that's as beautiful as you are, filled with joy and celebration.",] + "Wishing you a birthday that's as beautiful as you are, filled with joy and celebration.", ] diff --git a/Powers/utils/http_helper.py b/Powers/utils/http_helper.py index 04341217..6894075b 100644 --- a/Powers/utils/http_helper.py +++ b/Powers/utils/http_helper.py @@ -48,7 +48,7 @@ async def multipost(url: str, times: int, *args, **kwargs): def resp_get(url: str, *args, **kwargs): - return requests.get(url, *args, **kwargs) + return requests.get(url, *args, **kwargs) def resp_post(url: str, *args, **kwargs): diff --git a/Powers/utils/kbhelpers.py b/Powers/utils/kbhelpers.py index 5692c8f7..f7bcd750 100644 --- a/Powers/utils/kbhelpers.py +++ b/Powers/utils/kbhelpers.py @@ -22,7 +22,8 @@ def ikb(rows=None, back=False, todo="start_back"): for row in rows: line = [] for button in row: - button = btn(*button) # Will make the kb which don't have "." in them + # Will make the kb which don't have "." in them + button = btn(*button) line.append(button) lines.append(line) except TypeError: @@ -32,7 +33,7 @@ def ikb(rows=None, back=False, todo="start_back"): button = btn(*button) # InlineKeyboardButton line.append(button) lines.append(line) - if back: + if back: back_btn = [(btn("« Back", todo))] lines.append(back_btn) return InlineKeyboardMarkup(inline_keyboard=lines) diff --git a/Powers/utils/msg_types.py b/Powers/utils/msg_types.py index 69464dfd..08a633cb 100644 --- a/Powers/utils/msg_types.py +++ b/Powers/utils/msg_types.py @@ -215,6 +215,7 @@ async def get_wlcm_type(m: Message): return text, data_type, content + async def get_afk_type(m: Message): data_type = None content = None diff --git a/Powers/utils/start_utils.py b/Powers/utils/start_utils.py index 6d5bbae4..2d34479c 100644 --- a/Powers/utils/start_utils.py +++ b/Powers/utils/start_utils.py @@ -30,7 +30,7 @@ async def gen_cmds_kb(m: Message or CallbackQuery): cmds = sorted(list(HELP_COMMANDS.keys())) kb = [cmd.lower() for cmd in cmds] - return [kb[i : i + 3] for i in range(0, len(kb), 3)] + return [kb[i: i + 3] for i in range(0, len(kb), 3)] async def gen_start_kb(q: Message or CallbackQuery): @@ -238,7 +238,7 @@ async def get_private_rules(_, m: Message, help_option: str): return "" -async def get_help_msg(m: Message or CallbackQuery, help_option: str): +async def get_help_msg(c: Gojo, m: Message or CallbackQuery, help_option: str): """Helper function for getting help_msg and it's keyboard.""" help_msg = None help_kb = None @@ -266,12 +266,12 @@ async def get_help_msg(m: Message or CallbackQuery, help_option: str): f"{m.from_user.id} fetched help for {help_option} in {m.chat.id}", ) else: - if isinstance(m,CallbackQuery): + if isinstance(m, CallbackQuery): mes = m.message else: mes = m help_msg = f""" -Hey **[{mes.from_user.first_name}](http://t.me/{mes.from_user.username})**!I am Gojo✨. +Hey **[{mes.from_user.first_name}](http://t.me/{mes.from_user.username})**!I am {c.me.first_name}✨. I'm here to help you manage your groups! Commands available: × /start: Start the bot diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 04c5b23f..32feb0c4 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -28,6 +28,7 @@ async def runcmd(cmd: str) -> Tuple[str, str, int, int]: process.pid, ) + async def get_sticker_set_by_name( client: Gojo, name: str ) -> raw.base.messages.StickerSet: @@ -42,15 +43,14 @@ async def get_sticker_set_by_name( return None - async def create_sticker_set( client: Gojo, owner: int, title: str, short_name: str, stickers: List[raw.base.InputStickerSetItem], - animated:bool=False, - video:bool=False + animated: bool = False, + video: bool = False ) -> raw.base.messages.StickerSet: return await client.invoke( raw.functions.stickers.CreateStickerSet( @@ -85,11 +85,10 @@ async def create_sticker( return raw.types.InputStickerSetItem(document=sticker, emoji=emoji) - STICKER_DIMENSIONS = (512, 512) -async def resize_file_to_sticker_size(file_path: str,length:int=512,width:int=512) -> str: +async def resize_file_to_sticker_size(file_path: str, length: int = 512, width: int = 512) -> str: im = Image.open(file_path) if (im.width, im.height) < STICKER_DIMENSIONS: size1 = im.width @@ -114,6 +113,7 @@ async def resize_file_to_sticker_size(file_path: str,length:int=512,width:int=51 os.remove(file_path) return file_pathh + async def tgs_to_gif(file, tgs=False, video=False): if tgs: cmd = f"lottie_convert.py '{file}' 'gojo_satoru.gif'" @@ -123,12 +123,14 @@ async def tgs_to_gif(file, tgs=False, video=False): os.remove(file) return 'gojo_satoru.gif' + async def webm_to_gif(file): cmd = f"ffmpeg -i '{file}' 'goJo.gif'" await runcmd(cmd) os.remove(file) return "goJo.gif" - + + async def Vsticker(c: Gojo, file: Message): if file.animation: file = file.animation @@ -155,7 +157,8 @@ async def upload_document( raw.functions.messages.UploadMedia( peer=await client.resolve_peer(chat_id), media=raw.types.InputMediaUploadedDocument( - mime_type=client.guess_mime_type(file_path) or "application/zip", + mime_type=client.guess_mime_type( + file_path) or "application/zip", file=await client.save_file(file_path), attributes=[ raw.types.DocumentAttributeFilename( @@ -183,6 +186,7 @@ async def get_document_from_file_id( file_reference=decoded.file_reference, ) + async def remove_sticker(c: Gojo, stickerid: str) -> raw.base.messages.StickerSet: sticker = await get_document_from_file_id(stickerid) return await c.invoke(raw.functions.stickers.RemoveStickerFromSet(sticker=sticker)) @@ -237,7 +241,7 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li stick_path = await resize_file_to_sticker_size(image_path) image1 = image_path - image2 = tosticker(stick_path,f"@GojoSuperbot_{int(time())}.webp") + image2 = tosticker(stick_path, f"@GojoSuperbot_{int(time())}.webp") image.save(image1) image.save(image2) @@ -247,12 +251,10 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li return [image1, image2] - - def toimage(image, filename=None, is_direc=False): filename = filename if filename else "gojo.jpg" if is_direc: - os.rename(image,filename) + os.rename(image, filename) return filename img = Image.open(image) if img.mode != "RGB": @@ -265,11 +267,11 @@ def toimage(image, filename=None, is_direc=False): def tosticker(response, filename=None, is_direc=False): filename = filename if filename else "gojo.webp" if is_direc: - os.rename(response,filename) + os.rename(response, filename) return filename image = Image.open(response) if image.mode != "RGB": image.convert("RGB") image.save(filename, "webp") os.remove(response) - return filename \ No newline at end of file + return filename diff --git a/Powers/utils/string.py b/Powers/utils/string.py index 487f408a..2051ff0e 100644 --- a/Powers/utils/string.py +++ b/Powers/utils/string.py @@ -1,3 +1,4 @@ +import base64 from datetime import datetime, timedelta from html import escape from re import compile as compile_re @@ -9,7 +10,8 @@ from Powers import TIME_ZONE from Powers.utils.parser import escape_markdown -BTN_URL_REGEX = compile_re(r"(\[([^\[]+?)\]\(buttonurl:(?:/{0,2})(.+?)(:same)?\))") +BTN_URL_REGEX = compile_re( + r"(\[([^\[]+?)\]\(buttonurl:(?:/{0,2})(.+?)(:same)?\))") async def extract_time(m: Message, time_val: str): @@ -26,7 +28,7 @@ async def extract_time(m: Message, time_val: str): elif unit == "h": bantime = initial_time + timedelta(hours=int(time_num)) elif unit == "d": - bantime = initial_time + timedelta(days=int(time_num)) + bantime = initial_time + timedelta(days=int(time_num)) else: # how even...? return "" @@ -54,8 +56,9 @@ async def parse_button(text: str): # if even, not escaped -> create button if n_escapes % 2 == 0: # create a thruple with button label, url, and newline status - buttons.append((match.group(2), match.group(3), bool(match.group(4)))) - note_data += markdown_note[prev : match.start(1)] + buttons.append( + (match.group(2), match.group(3), bool(match.group(4)))) + note_data += markdown_note[prev: match.start(1)] prev = match.end(1) # if odd, escaped -> move along else: @@ -98,7 +101,7 @@ async def escape_invalid_curly_brackets(text: str, valids: List[str]) -> str: success = True break if success: - new_text += text[idx : idx + len(v) + 2] + new_text += text[idx: idx + len(v) + 2] idx += len(v) + 2 continue new_text += "{{" @@ -173,7 +176,7 @@ async def split_quotes(text: str): # 1 to avoid starting quote, and counter is exclusive so avoids ending key = await remove_escapes(text[1:counter].strip()) # index will be in range, or `else` would have been executed and returned - rest = text[counter + 1 :].strip() + rest = text[counter + 1:].strip() if not key: key = text[0] + text[0] return list(filter(None, [key, rest])) @@ -192,3 +195,25 @@ async def remove_escapes(text: str) -> str: else: res += text[counter] return res + + +async def encode_decode(string: str, to_do="encode"): + """ + Function to encode or decode strings + string: string to be decoded or encoded + to_do: encode to encode the string or decode to decode the string + """ + if to_do.lower() == "encode": + encodee = string.encode("ascii") + base64_ = base64.b64encode(encodee) + B64 = base64_.decode("ascii") + + elif to_do.lower() == "decode": + decodee = string.encode("ascii") + base64_ = base64.b64decode(decodee) + B64 = base64_.decode("ascii") + + else: + B64 = None + + return B64 diff --git a/Powers/utils/web_helpers.py b/Powers/utils/web_helpers.py index a27572b4..79c77316 100644 --- a/Powers/utils/web_helpers.py +++ b/Powers/utils/web_helpers.py @@ -16,6 +16,7 @@ backUP = "https://artfiles.alphacoders.com/160/160160.jpeg" + async def get_file_size(file: Message): if file.photo: size = file.photo.file_size/1024 @@ -33,7 +34,7 @@ async def get_file_size(file: Message): size = file.voice.file_size/1024 elif file.video_note: size = file.video_note.file_size/1024 - + if size <= 1024: return f"{round(size)} kb" elif size > 1024: @@ -54,6 +55,8 @@ def get_duration_in_sec(dur: str): return dur # Gets yt result of given query. + + async def song_search(query, is_direct, max_results=1): yt_dict = {} try: @@ -62,7 +65,7 @@ async def song_search(query, is_direct, max_results=1): query = vid["title"] else: query = query - videos = VideosSearch(query,max_results) + videos = VideosSearch(query, max_results) results = await videos.next() except Exception as e: LOGGER.error(e) @@ -87,8 +90,8 @@ async def song_search(query, is_direct, max_results=1): "duration": i["accessibility"]['duration'], "DURATION": i["duration"], "published": i["publishedTime"], - "uploader": i ["channel"]["name"] - } + "uploader": i["channel"]["name"] + } try: thumb = {"thumbnail": i["richThumbnail"]["url"]} except Exception: @@ -140,8 +143,7 @@ async def song_search(query, is_direct, max_results=1): }""" - -async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str): +async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, type_: str): if type_ == "a": # opts = song_opts video = False @@ -151,7 +153,7 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str video = True song = False # ydl = yt_dlp.YoutubeDL(opts) - dicti = await song_search(query, is_direct,1) + dicti = await song_search(query, is_direct, 1) if not dicti and type(dicti) != str: await m.reply_text("File with duration less than or equals to 10 minutes is allowed only") elif type(dicti) == str: @@ -172,14 +174,14 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str vid_dur = get_duration_in_sec(dicti["DURATION"]) published_on = dicti["published"] if thumb: - thumb_ = await c.send_photo(MESSAGE_DUMP,thumb) + thumb_ = await c.send_photo(MESSAGE_DUMP, thumb) else: - thumb_ = await c.send_photo(MESSAGE_DUMP,backUP) + thumb_ = await c.send_photo(MESSAGE_DUMP, backUP) # FILE = ydl.extract_info(query,download=video) url = query thumb = await thumb_.download() if not thumb: - thumb = await resize_file_to_sticker_size(thumb,320,320) + thumb = await resize_file_to_sticker_size(thumb, 320, 320) await thumb_.delete() cap = f""" ⤷ Name: `{f_name}` @@ -192,7 +194,7 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str kb = IKM( [ [ - IKB(f"✘ {uploader.capitalize()} ✘",url=f"{up_url}") + IKB(f"✘ {uploader.capitalize()} ✘", url=f"{up_url}") ], [ IKB(f"✘ Youtube url ✘", url=f"{url}") @@ -200,12 +202,12 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str ] ) if song: - audio_stream= yt.streams.filter(only_audio=True).first() + audio_stream = yt.streams.filter(only_audio=True).first() f_path = audio_stream.download() # file_path = f"./youtube_downloads/{f_name.strip()}.mp3" file_path = f"./{f_name.strip()}.mp3" - os.rename(f_path,file_path) - await m.reply_audio(file_path,caption=cap,reply_markup=kb,duration=vid_dur,thumb=thumb,title=f_name) + os.rename(f_path, file_path) + await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name) # os.remove(f_path) os.remove(file_path) os.remove(thumb) @@ -214,7 +216,7 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str video_stream = yt.streams.get_highest_resolution() file_path = video_stream.download() # file_path = f"./youtube_downloads/{f_name}.mp4" - await m.reply_video(file_path,caption=cap,reply_markup=kb,duration=vid_dur,thumb=thumb) + await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb) os.remove(file_path) os.remove(thumb) return diff --git a/Powers/vars.py b/Powers/vars.py index 3600b782..2f3c58eb 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -37,18 +37,18 @@ class Config: default="", ).split(None) ] - GENIUS_API_TOKEN = config("GENIUS_API",default=None) + GENIUS_API_TOKEN = config("GENIUS_API", default=None) # AuDD_API = config("AuDD_API",default=None) - RMBG_API = config("RMBG_API",default=None) + RMBG_API = config("RMBG_API", default=None) DB_URI = config("DB_URI", default="") DB_NAME = config("DB_NAME", default="gojo_satarou") - BDB_URI = config("BDB_URI",default=None) + BDB_URI = config("BDB_URI", default=None) NO_LOAD = config("NO_LOAD", default="").split() PREFIX_HANDLER = config("PREFIX_HANDLER", default="/").split() SUPPORT_GROUP = config("SUPPORT_GROUP", default="gojo_bots_network") SUPPORT_CHANNEL = config("SUPPORT_CHANNEL", default="gojo_bots_network") WORKERS = int(config("WORKERS", default=16)) - TIME_ZONE = config("TIME_ZONE",default='Asia/Kolkata') + TIME_ZONE = config("TIME_ZONE", default='Asia/Kolkata') BOT_USERNAME = "" BOT_ID = "" BOT_NAME = "" @@ -73,7 +73,7 @@ class Development: NO_LOAD = [] GENIUS_API_TOKEN = "" RMBG_API = "" - PREFIX_HANDLER = ["!", "/","$"] + PREFIX_HANDLER = ["!", "/", "$"] SUPPORT_GROUP = "SUPPORT_GROUP" SUPPORT_CHANNEL = "SUPPORT_CHANNEL" VERSION = "VERSION" From 6320980a24757febd29348a14c7a85c76865f757 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Sat, 20 Apr 2024 18:16:58 +0530 Subject: [PATCH 07/19] `V 2.2.0` few more changes left --- Powers/__init__.py | 19 ++- Powers/plugins/bans.py | 2 +- Powers/plugins/formatting.py | 76 +++++++++--- Powers/plugins/locks.py | 4 +- Powers/plugins/start.py | 80 +++++++++++-- Powers/plugins/web_con.py | 84 +++++++------ Powers/utils/custom_filters.py | 2 +- Powers/utils/extras.py | 1 + Powers/utils/sticker_help.py | 3 +- Powers/utils/web_helpers.py | 77 ++++-------- Powers/utils/web_scrapper.py | 207 +++++++++++++++++++++++++++++++++ Powers/vars.py | 7 +- README.md | 4 + app.json | 19 +++ requirements.txt | 1 + 15 files changed, 467 insertions(+), 119 deletions(-) create mode 100644 Powers/utils/web_scrapper.py diff --git a/Powers/__init__.py b/Powers/__init__.py index 9802ff03..bb348d48 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -1,3 +1,4 @@ +import shutil from datetime import datetime from importlib import import_module as imp_mod from logging import (INFO, WARNING, FileHandler, StreamHandler, basicConfig, @@ -21,6 +22,9 @@ # Make Logs directory if it does not exixts if not path.isdir(LOGDIR): mkdir(LOGDIR) +else: + shutil.rmtree(LOGDIR) + mkdir(LOGDIR) LOGFILE = f"{LOGDIR}/{__name__}_{LOG_DATETIME}_log.txt" @@ -59,9 +63,9 @@ # time zone TIME_ZONE = pytz.timezone(Config.TIME_ZONE) -path = "./Version" +Vpath = "./Version" version = [] -for i in listdir(path): +for i in listdir(Vpath): if i.startswith("version") and i.endswith("md"): version.append(i) else: @@ -134,6 +138,9 @@ DEVS = DEVS_USER | Defult_dev DEV_USERS = list(DEVS) +CHROME_BIN = Config.CHROME_BIN +CHROME_DRIVER = Config.CHROME_DRIVER + # Plugins, DB and Workers DB_URI = Config.DB_URI DB_NAME = Config.DB_NAME @@ -148,6 +155,14 @@ UPTIME = time() # Check bot uptime +#Make dir +youtube_dir = "./Youtube/" +if not path.isdir(youtube_dir): + mkdir(youtube_dir) +else: + shutil.rmtree(youtube_dir) + mkdir(youtube_dir) + scheduler = AsyncIOScheduler(timezone=TIME_ZONE) diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py index e933bb4e..4c274663 100644 --- a/Powers/plugins/bans.py +++ b/Powers/plugins/bans.py @@ -487,7 +487,7 @@ async def skick_usr(c: Gojo, m: Message): return if user_id == Config.BOT_ID: - await m.reply_text("Huh, why would I kick myself?") + await m.reply_text("Nuh Hu, why would I kick myself?") await m.stop_propagation() SUPPORT_STAFF = get_support_staff() diff --git a/Powers/plugins/formatting.py b/Powers/plugins/formatting.py index 8d639dbf..d727370e 100644 --- a/Powers/plugins/formatting.py +++ b/Powers/plugins/formatting.py @@ -39,14 +39,7 @@ async def markdownhelp(_, m: Message): return -@Gojo.on_callback_query(filters.regex("^formatting.")) -async def get_formatting_info(c: Gojo, q: CallbackQuery): - cmd = q.data.split(".")[1] - kb = ikb([[("Back", "back.formatting")]]) - - if cmd == "md_formatting": - - txt = """Markdown Formatting +md_txt = """Markdown Formatting You can format your message using bold, italic, underline, strike and much more. Go ahead and experiment! **Note**: It supports telegram user based formatting as well as html and markdown formattings. @@ -66,19 +59,74 @@ async def get_formatting_info(c: Gojo, q: CallbackQuery): [button 2](buttonurl://example.com:same) [button 3](buttonurl://example.com) This will show button 1 and 2 on the same line, while 3 will be underneath.""" + +async def get_splited_formatting(msg, page=1): + msg = msg.split("\n") + l = len(msg) + new_msg = "" + total = l // 10 + first = 10 * (page - 1) + last = 10 * page + if not first: + for i in msg[first:last]: + new_msg += f"{i}\n" + kb = [ + [ + ("Next page ▶️", f"next_format_{page+1}") + ] + ] + else: + first += 1 + if page == total: + for i in msg[first:]: + new_msg += f"{i}\n" + kb = [ + [ + ("◀️ Previous page", f"next_format_{page-1}") + ] + ] + else: + for i in msg[first:last]: + new_msg += f"{i}\n" + kb = [ + [ + ("◀️ Previous page", f"next_format_{page-1}"), + ("Next page ▶️", f"next_format_{page+1}") + ] + ] + + + kb = ikb(kb, True, "back.formatting") + + return new_msg, kb + +@Gojo.on_callback_query(filters.regex(r"^next_format_.*[0-9]$")) +async def change_formatting_page(c: Gojo, q: CallbackQuery): + page = q.data.split("_")[-1] + txt, kb = await get_splited_formatting(md_txt, int(page)) + await q.edit_message_caption(txt, reply_markup=kb,parse_mode=enums.ParseMode.HTML,) + return + +@Gojo.on_callback_query(filters.regex("^formatting.")) +async def get_formatting_info(c: Gojo, q: CallbackQuery): + cmd = q.data.split(".")[1] + kb = ikb([[("Back", "back.formatting")]]) + + if cmd == "md_formatting": + try: await q.edit_message_caption( - caption=txt, + caption=md_txt, reply_markup=kb, parse_mode=enums.ParseMode.HTML, ) except MediaCaptionTooLong: - kb = ikb([[("Back", "DELETEEEE")]]) - await c.send_message( - chat_id=q.message.chat.id, - text=txt, + txt, kb = await get_splited_formatting(md_txt) + await q.edit_message_caption( + caption=txt, + reply_markup=kb, parse_mode=enums.ParseMode.HTML, - reply_markup=kb) + ) elif cmd == "fillings": await q.edit_message_caption( caption="""Fillings diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index 9390dbc1..acd051e3 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -36,7 +36,9 @@ - `forwardall` = Forwarding from channel and user - `forwardu` = Forwarding from user - `forwardc` = Forwarding from channel -- `links | url` = Lock links""" +- `links | url` = Lock links +- `bot` = Adding bot will be forbidden +""" @Gojo.on_message(command("locktypes")) diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index d5e130a5..29aa79c8 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -18,8 +18,9 @@ from Powers.utils.extras import StartPic from Powers.utils.kbhelpers import ikb from Powers.utils.parser import mention_html -from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg, - get_private_note, get_private_rules) +from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, + get_private_note, get_private_rules, + iter_msg) from Powers.utils.string import encode_decode from Powers.vars import Config @@ -85,7 +86,7 @@ async def start(c: Gojo, m: Message): await get_private_rules(c, m, help_option) return - help_msg, help_kb = await get_help_msg(c, m, help_option) + help_msg, help_kb = await iter_msg(c, m, help_option) if not help_msg: return @@ -219,7 +220,7 @@ async def help_menu(c: Gojo, m: Message): if len(m.text.split()) >= 2: textt = m.text.replace(" ", "_",).replace("_", " ", 1) help_option = (textt.split(None)[1]).lower() - help_msg, help_kb = await get_help_msg(c, m, help_option) + help_msg, help_kb = await iter_msg(c, m, help_option) if not help_msg: LOGGER.error( @@ -291,6 +292,64 @@ async def help_menu(c: Gojo, m: Message): return +async def get_divided_msg(plugin_name: str, page:int=1, back_to_do = None): + msg = HELP_COMMANDS[plugin_name]["help_msg"] + msg = msg.split("\n") + l = len(msg) + new_msg = "" + total = l // 10 + first = 10 * (page - 1) + last = 10 * page + + if not first: + for i in msg[first:last]: + new_msg += f"{i}\n" + kb = [ + [ + ("Next page ▶️", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page+1}") + ] + ] + else: + first += 1 + if page == total: + for i in msg[first:]: + new_msg += f"{i}\n" + kb = [ + [ + ("◀️ Previous page", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page-1}") + ] + ] + else: + for i in msg[first:last]: + new_msg += f"{i}\n" + kb = [ + [ + ("◀️ Previous page", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page-1}"), + ("Next page ▶️", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page+1}") + ] + ] + if back_to_do: + kb = ikb(kb, True, back_to_do) + else: + kb = ikb(kb) + + return new_msg, kb + +@Gojo.on_callback_query(filters.regex(r"^iter_page_.*[0-9]$")) +async def helppp_page_iter(c: Gojo, q: CallbackQuery): + data = q.data.split("_") + plugin_ = data[2] + try: + back_to = data[-2] + except: + back_to = None + curr_page = int(data[-1]) + msg, kb = await get_divided_msg(plugin_, curr_page, back_to_do=back_to) + + await q.edit_message_caption(msg, reply_markup=kb) + return + + @Gojo.on_callback_query(filters.regex("^bot_curr_info$")) async def give_curr_info(c: Gojo, q: CallbackQuery): start = time() @@ -323,17 +382,20 @@ async def get_module_info(c: Gojo, q: CallbackQuery): reply_markup=ikb(help_kb, True, todo="commands"), ) except MediaCaptionTooLong: - kb = ikb([[("Back", "DELETEEEE")]]) - await c.send_message(chat_id=q.message.chat.id, text=help_msg, reply_markup=kb) + caption, kb = await get_divided_msg(f"plugins.{module}", back_to_do="commands") + await q.edit_message_caption( + caption, + parse_mode=enums.ParseMode.MARKDOWN, + reply_markup=kb + ) await q.answer() return -DEV_USERS = get_support_staff("dev") -SUDO_USERS = get_support_staff("sudo") - @Gojo.on_callback_query(filters.regex("^give_bot_staffs$")) async def give_bot_staffs(c: Gojo, q: CallbackQuery): + DEV_USERS = get_support_staff("dev") + SUDO_USERS = get_support_staff("sudo") try: owner = await c.get_users(OWNER_ID) reply = f"🌟 Owner: {(await mention_html(owner.first_name, OWNER_ID))} ({OWNER_ID})\n" diff --git a/Powers/plugins/web_con.py b/Powers/plugins/web_con.py index d0183dc7..2be7550a 100644 --- a/Powers/plugins/web_con.py +++ b/Powers/plugins/web_con.py @@ -1,20 +1,21 @@ import asyncio import os +import shutil 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 pyrogram.types import InputMediaPhoto, InputMediaVideo, Message -from Powers import (LOGGER, RMBG, Audd, genius_lyrics, is_audd, - is_genius_lyrics, is_rmbg) +from Powers import LOGGER, RMBG, genius_lyrics, 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 * +from Powers.utils.web_scrapper import INSTAGRAM, SCRAP_DATA # @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. @@ -254,15 +255,15 @@ async def song_down_up(c: Gojo, m: Message): except IndexError: await m.reply_text("**USAGE**\n /song [song name | link]") return - if splited.startswith("https://youtube.com"): - is_direct = True - query = splited.split("?")[0] + _id = get_video_id(splited) + if not _id: + await m.reply_text("Invalid youtube link") + return else: - is_direct = False - query = splited + query = _id XnX = await m.reply_text("⏳") try: - await youtube_downloader(c,m,query,is_direct,"a") + await youtube_downloader(c,m,query, "a") await XnX.delete() return except KeyError: @@ -281,15 +282,15 @@ async def video_down_up(c: Gojo, m: Message): except IndexError: await m.reply_text("**USAGE**\n /vsong [song name | link]") return - if splited.startswith("https://youtube.com"): - is_direct = True - query = splited.split("?")[0] + _id = get_video_id(splited) + if not _id: + await m.reply_text("Invalid youtube link") + return else: - is_direct = False - query = splited + query = _id XnX = await m.reply_text("⏳") try: - await youtube_downloader(c,m,query,is_direct,"v") + await youtube_downloader(c,m,query,"v") await XnX.delete() return except KeyError: @@ -306,27 +307,44 @@ async def download_instareels(c: Gojo, m: Message): try: reel_ = m.command[1] except IndexError: - await m.reply_text("Give me an link to download it...") + await m.reply_text("Give me an instagram link to download it...") return - if not reel_.startswith("https://www.instagram.com/reel/"): - await m.reply_text("In order to obtain the requested reel, a valid link is necessary. Kindly provide me with the required link.") + + insta = INSTAGRAM(reel_) + + if not insta.is_correct_link(): + await m.reply_text("The link you have provided is not of instagram") return - OwO = reel_.split(".",1) - Reel_ = ".dd".join(OwO) - try: - await m.reply_video(Reel_) + + to_edit = await m.reply_text("Trying to fetch data from the link") + + content = insta.get_all() + + if type(content) == str: + await to_edit.edit_text(content) return - except Exception: - try: - await m.reply_photo(Reel_) - return - except Exception: - try: - await m.reply_document(Reel_) - return - except Exception: - await m.reply_text("I am unable to reach to this reel.") - return + elif not content: + await to_edit.edit_text("Failed to get any media from the link") + + videos = content["video"] + images = content["image"] + + to_delete = await to_edit.edit_text("Found media in the link trying to download and upload them please wait") + + to_send = [] + if images: + scrapped_images = SCRAP_DATA(images).get_images() + for i in scrapped_images: + to_send.append(InputMediaPhoto(i)) + if videos: + scrapped_videos = SCRAP_DATA(videos).get_videos() + for i in scrapped_videos: + to_send.append(InputMediaVideo(i)) + + await m.reply_media_group(to_send) + await to_delete.delete() + shutil.rmtree("./scrapped/") + __PLUGIN__ = "web support" diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index dc430f06..8a8ac4c5 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -154,7 +154,7 @@ async def admin_check_func(_, __, m: Message or CallbackQuery): return False # Telegram and GroupAnonyamousBot - if m.sender_chat: + if m.sender_chat and m.sender_chat.id == m.chat.id: return True if not m.from_user: diff --git a/Powers/utils/extras.py b/Powers/utils/extras.py index ee0a1eba..432e4252 100644 --- a/Powers/utils/extras.py +++ b/Powers/utils/extras.py @@ -518,6 +518,7 @@ "No one give a damn about it") INSULT_STRINGS = [ + "Tell me\nYou are gay becauce you are you or you are you that's why you are gay?" "`Owww ... Such a stupid idiot.`", "`Don't drink and type.`", "`Command not found. Just like your brain.`", diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 32feb0c4..5b0815f7 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -85,11 +85,10 @@ async def create_sticker( return raw.types.InputStickerSetItem(document=sticker, emoji=emoji) -STICKER_DIMENSIONS = (512, 512) - async def resize_file_to_sticker_size(file_path: str, length: int = 512, width: int = 512) -> str: im = Image.open(file_path) + STICKER_DIMENSIONS = (length, width) if (im.width, im.height) < STICKER_DIMENSIONS: size1 = im.width size2 = im.height diff --git a/Powers/utils/web_helpers.py b/Powers/utils/web_helpers.py index 79c77316..426ab4b1 100644 --- a/Powers/utils/web_helpers.py +++ b/Powers/utils/web_helpers.py @@ -6,10 +6,10 @@ from pyrogram.types import InlineKeyboardButton as IKB from pyrogram.types import InlineKeyboardMarkup as IKM from pyrogram.types import Message -# import yt_dlp -from pytube import YouTube -from youtubesearchpython.__future__ import Video, VideosSearch +from pytube import YouTube, extract +from youtubesearchpython.__future__ import VideosSearch +from Powers import youtube_dir from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo from Powers.utils.http_helper import * from Powers.utils.sticker_help import resize_file_to_sticker_size @@ -45,6 +45,15 @@ async def get_file_size(file: Message): size = size/1024 return f"{round(size)} gb" +def get_video_id(url): + try: + _id = extract.video_id(url) + if not _id: + return None + else: + return _id + except: + return None def get_duration_in_sec(dur: str): duration = dur.split(":") @@ -57,14 +66,9 @@ def get_duration_in_sec(dur: str): # Gets yt result of given query. -async def song_search(query, is_direct, max_results=1): +async def song_search(query, max_results=1): yt_dict = {} try: - if is_direct: - vid = Video.getInfo(query) - query = vid["title"] - else: - query = query videos = VideosSearch(query, max_results) results = await videos.next() except Exception as e: @@ -93,7 +97,7 @@ async def song_search(query, is_direct, max_results=1): "uploader": i["channel"]["name"] } try: - thumb = {"thumbnail": i["richThumbnail"]["url"]} + thumb = {"thumbnail": i["thumbnails"][0]["url"]} except Exception: thumb = {"thumbnail": None} dict_form.update(thumb) @@ -103,45 +107,6 @@ async def song_search(query, is_direct, max_results=1): pass return yt_dict -"""song_opts = { - "format": "bestaudio", - "addmetadata": True, - "key": "FFmpegMetadata", - "writethumbnail": True, - "prefer_ffmpeg": True, - "geo_bypass": True, - "nocheckcertificate": True, - "postprocessors": [ - { - "key": "FFmpegExtractAudio", - "preferredcodec": "mp3", - "preferredquality": "480", - } - ], - "outtmpl": "%(id)s.mp3", - "quiet": True, - "logtostderr": False, -} - - -video_opts = { - "format": "best", - "addmetadata": True, - "key": "FFmpegMetadata", - "prefer_ffmpeg": True, - "geo_bypass": True, - "nocheckcertificate": True, - "postprocessors": [ - { - "key": "FFmpegVideoConvertor", - "preferedformat": "mp4", - } - ], - "outtmpl": "%(id)s.mp4", - "logtostderr": False, - "quiet": True, -}""" - async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, type_: str): if type_ == "a": @@ -164,6 +129,9 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t except KeyError: return yt = YouTube(query) + if yt.age_restricted: + await m.reply_text("This video is age restricted") + return dicti = dicti[1] f_name = dicti["title"] views = dicti["views"] @@ -204,19 +172,18 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t if song: audio_stream = yt.streams.filter(only_audio=True).first() f_path = audio_stream.download() - # file_path = f"./youtube_downloads/{f_name.strip()}.mp3" - file_path = f"./{f_name.strip()}.mp3" + file_path = f"{youtube_dir}{f_name.strip()}.mp3" os.rename(f_path, file_path) - await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name) - # os.remove(f_path) + await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader) os.remove(file_path) os.remove(thumb) return elif video: video_stream = yt.streams.get_highest_resolution() file_path = video_stream.download() - # file_path = f"./youtube_downloads/{f_name}.mp4" + new_file_path = f"{youtube_dir}{f_name}.mp4" + os.rename(file_path, new_file_path) await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb) - os.remove(file_path) + os.remove(new_file_path) os.remove(thumb) return diff --git a/Powers/utils/web_scrapper.py b/Powers/utils/web_scrapper.py new file mode 100644 index 00000000..bd4e6f1e --- /dev/null +++ b/Powers/utils/web_scrapper.py @@ -0,0 +1,207 @@ +import os +import re +import time +from typing import List + +import requests +from selenium import webdriver +from selenium.webdriver.chrome.options import Options +from selenium.webdriver.chrome.service import Service +from selenium.webdriver.common.by import By +from selenium.webdriver.support.expected_conditions import \ + presence_of_element_located +from selenium.webdriver.support.wait import WebDriverWait + +from Powers import * + + +class SCRAP_DATA: + """Class to get and handel scrapped data""" + + def __init__(self, urls: List[str] or str) -> None: + self.urls = urls + self.path = "./scrapped/" + if not os.path.isdir(self.path): + os.makedirs("./scrapped/") + + def get_images(self) -> list: + images = [] + if isinstance(self.urls, str): + requested = requests.get(self.urls) + try: + name = self.path + f"img_{time.time()}.jpg" + with open(name, "wb") as f: + f.write(requested.content) + images.append(name) + except Exception as e: + LOGGER.error(e) + requested.close() + else: + for i in self.urls: + if i: + requested = requests.get(i) + else: + continue + try: + name = self.path + f"img_{time.time()}.jpg" + with open(name, "wb") as f: + f.write(requested.content) + images.append(name) + except Exception as e: + LOGGER.error(e) + requested.close() + continue + return images + + def get_videos(self) -> list: + videos = [] + if isinstance(self.urls, str): + if i: + requested = requests.get(i) + else: + return [] + try: + name = self.path + f"vid_{time.time()}.mp4" + with open(name, "wb") as f: + f.write(requested.content) + videos.append(name) + except Exception as e: + LOGGER.error(e) + requested.close() + else: + for i in self.urls: + if i: + requested = requests.get(i) + else: + continue + try: + name = self.path + f"vid_{time.time()}.mp4" + with open(name, "wb") as f: + f.write(requested.content) + videos.append(name) + except Exception as e: + LOGGER.error(e) + requested.close() + continue + return videos + + +class DRIVER: + """Class to make selenium driver""" + + def __init__(self) -> None: + self.BIN = CHROME_BIN + self.CHROME_DRIVER = CHROME_DRIVER + + def initialize_driver(self): + if not self.BIN: + LOGGER.error( + "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.") + return ( + None, + "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.", + ) + + try: + options = Options() + options.binary_location = self.BIN + options.add_argument("--disable-dev-shm-usage") + options.add_argument("--ignore-certificate-errors") + options.add_argument("--disable-gpu") + options.add_argument("--headless=new") + options.add_argument("--test-type") + options.add_argument("--no-sandbox") + + service = Service(self.CHROME_DRIVER) + driver = webdriver.Chrome(options, service) + return driver, None + except Exception as e: + LOGGER.error(f"ChromeDriverErr: {e}") + return None, f"ChromeDriverErr: {e}" + + def driver_close(self, driver: webdriver.Chrome): + driver.close() + driver.quit() + + +class INSTAGRAM(DRIVER): + """Class to scrap data from instagram""" + + def __init__(self, url: str) -> None: + self.url = url + self.article = "article._aa6a" + self.ul_class = "_acay" + self.image_class = "x5yr21d" + self.video_class = "x1lliihq" + self.next_button = "button._afxw" + self.return_dict = {"image": [], "video": []} + super().__init__() + + def is_correct_link(self): + return bool((re.compile(r"^https?://(?:www\.)?instagram\.com/")).match(self.url)) + + def get_all(self): + driver, error = self.initialize_driver() + if not driver: + return error + + driver.get(self.url) + wait = WebDriverWait(driver, 30) + if "reel" in self.url: + element = wait.until( + presence_of_element_located((By.TAG_NAME, "video"))) + reels = element.get_attribute("src") + self.driver_close(driver) + self.return_dict.get("video").append(reels) + return self.return_dict + elif bool((re.compile(r"^https?://(?:www\.)?instagram\.com/p/")).match(self.url)): + image_links = [] + video_links = [] + try: + element = wait.until(presence_of_element_located( + (By.CLASS_NAME, self.ul_class))) + + while True: + sub_element = element.find_elements( + By.CLASS_NAME, self.image_class) + for i in sub_element: + url = i.get_attribute("src") + image_links.append(url) + + sub_element = element.find_elements( + By.CLASS_NAME, self.video_class) + for i in sub_element: + url = i.get_attribute("src") + video_links.append(url) + + try: + driver.find_element( + By.CSS_SELECTOR, self.next_button).click() + except: # Failed to either find the element or click on next i.e. no more media left in post + break + except: + element = wait.until(presence_of_element_located( + (By.CSS_SELECTOR, self.article))) + try: + sub_element = element.find_element(By.TAG_NAME, "img") + image_links.append(sub_element.get_attribute("src")) + except: + sub_element = element.find_element(By.TAG_NAME, "video") + video_links.append(sub_element.get_attribute("src")) + + self.driver_close(driver) + # To remove duplicates here I am converting into set + if image_links: + image_links = list(set(image_links)) + if video_links: + video_links = list(set(video_links)) + for i in video_links: + image_links.remove(i) + + self.return_dict.get("image").extend(image_links) + self.return_dict.get("video").extend(video_links) + return self.return_dict + + else: + return {} + diff --git a/Powers/vars.py b/Powers/vars.py index 2f3c58eb..a130ad23 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -1,3 +1,4 @@ +from email.policy import default from os import getcwd from prettyconf import Configuration @@ -34,9 +35,11 @@ class Config: int(i) for i in config( "WHITELIST_USERS", - default="", + default="" ).split(None) ] + CHROME_BIN = config("CHROME_BIN", "/app/.apt/usr/bin/google-chrome") + CHROME_DRIVER = config("CHROME_DRIVER", default="/app/.chromedriver/bin/chromedriver") GENIUS_API_TOKEN = config("GENIUS_API", default=None) # AuDD_API = config("AuDD_API",default=None) RMBG_API = config("RMBG_API", default=None) @@ -80,3 +83,5 @@ class Development: TIME_ZONE = 'Asia/Kolkata' BDB_URI = "" WORKERS = 8 + CHROME_BIN = "/app/.apt/usr/bin/google-chrome" + CHROME_DRIVER = "/app/.chromedriver/bin/chromedriver" diff --git a/README.md b/README.md index c5617962..9670ca83 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,10 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!---> `WHITELIST_USERS`: A space-separated list of user IDs whitelisted, cannot be restricted. +`CHROME_BIN`: Location of your chrome bin. + +`CHROME_DRIVER`: Location of your chrome driver. + ⚠️ **Note:** In case you are passing more than one value separate them using whitespace (space) for example If I want to pass more than one PREFIX_HANDLER I'll pass it like `'/' '.' '!'` this. diff --git a/app.json b/app.json index 1703fa8e..f5d6ebf2 100644 --- a/app.json +++ b/app.json @@ -104,6 +104,16 @@ "required": false, "value": "8" }, + "CHROME_DRIVER": { + "description": "Location of chrome driver", + "required": false, + "value": "/app/.chromedriver/bin/chromedriver" + }, + "CHROME_BIN" : { + "description": "Location of chrome bin", + "required": false, + "value": "/app/.apt/usr/bin/google-chrome" + }, "ENV": { "description": "Setting this to ANYTHING will enable environment variables. Leave it as it is", "required": true, @@ -114,6 +124,15 @@ { "url":"https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest" }, + { + "url": "https://github.com/chrismytton/heroku-buildpack-jq" + }, + { + "url":"https://github.com/heroku/heroku-buildpack-google-chrome" + }, + { + "url":"https://github.com/heroku/heroku-buildpack-chromedriver" + }, { "url": "heroku/python" } diff --git a/requirements.txt b/requirements.txt index 08a031dd..fe638a83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,6 +27,7 @@ regex==2023.12.25; python_version >= "3.6" requests==2.31.0 rfc3986==1.5.0; python_version >= "3.7" search-engine-parser==0.6.8 +selenium==4.18.1 six==1.16.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" sniffio==1.3.0; python_full_version >= "3.6.2" and python_version >= "3.7" soupsieve==2.4; python_version >= "3.6" and python_full_version >= "3.6.0" From 84c5b8239b27073f2128303b43453e7c4968f996 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Sun, 21 Apr 2024 14:27:26 +0530 Subject: [PATCH 08/19] few updates --- Powers/plugins/admin.py | 8 +- Powers/plugins/birthday.py | 8 +- Powers/plugins/flood.py | 160 ++++++++++++++++++++++++++++++++++++- 3 files changed, 167 insertions(+), 9 deletions(-) diff --git a/Powers/plugins/admin.py b/Powers/plugins/admin.py index 1b143f19..16e97e74 100644 --- a/Powers/plugins/admin.py +++ b/Powers/plugins/admin.py @@ -6,9 +6,9 @@ from pyrogram import filters from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.enums import ChatType -from pyrogram.errors import (ChatAdminInviteRequired, ChatAdminRequired, - FloodWait, RightForbidden, RPCError, - UserAdminInvalid) +from pyrogram.errors import (BotChannelsNa, ChatAdminInviteRequired, + ChatAdminRequired, FloodWait, RightForbidden, + RPCError, UserAdminInvalid) from pyrogram.types import ChatPrivileges, Message from Powers import LOGGER, OWNER_ID @@ -407,6 +407,8 @@ async def demote_usr(c: Gojo, m: Message): await m.reply_text( "Cannot act on this user, maybe I wasn't the one who changed their permissions." ) + except BotChannelsNa: + await m.reply_text("May be the user is bot and due to telegram restrictions I can't demote them. Please do it manually") except RPCError as ef: await m.reply_text( f"Some error occured, report it using `/bug` \n Error: {ef}" diff --git a/Powers/plugins/birthday.py b/Powers/plugins/birthday.py index 447505c6..e660eb9a 100644 --- a/Powers/plugins/birthday.py +++ b/Powers/plugins/birthday.py @@ -147,8 +147,8 @@ async def who_is_next(c: Gojo, m: Message): 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" + leff = (dete - curr).days + txt += f"`{i['user_id']}` : {leff} days left\n" txt += "\n\nYou can use /info [user id] to get info about the user" await xx.delete() await m.reply_text(txt) @@ -179,12 +179,14 @@ async def cant_recall_it(c: Gojo, m: Message): day = int(result["dob"].split('/')[0]) suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day % 10, 'th') bday_on = f"{day}{suffix} {formatted}" - if u_dob.month < curr.month: + if (u_dob.day,u_dob.month) < (curr.day,curr.month): next_b = date(curr.year + 1, u_dob.month, u_dob.day) days_left = (next_b - curr).days txt = f"{men} 's birthday is passed 🫤\nDays left until next one {days_left}" txt += f"\nBirthday on: {bday_on}" txt += f"\n\nDate of birth: {result['dob']}" + elif (u_dob.day,u_dob.month) == (curr.day,curr.month): + txt = f"Today is {men}'s birthday." else: u_dobm = date(curr.year, u_dob.month, u_dob.day) days_left = (u_dobm - curr).days diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index dacfd7b8..74c1ae34 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -1,4 +1,5 @@ import time +from datetime import datetime, timedelta from random import choice from traceback import format_exc @@ -10,19 +11,48 @@ InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import LOGGER, SUPPORT_GROUP +from Powers import LOGGER from Powers.bot_class import Gojo -from Powers.database.approve_db import Approve from Powers.database.flood_db import Floods from Powers.supports import get_support_staff from Powers.utils.custom_filters import admin_filter, command, flood_filter from Powers.utils.extras import BAN_GIFS, KICK_GIFS, MUTE_GIFS -from Powers.utils.kbhelpers import ikb from Powers.vars import Config on_key = ["on", "start", "disable"] off_key = ["off", "end", "enable", "stop"] +async def get_what_temp(what): + temp_duration = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "5 minutes", + f"f_temp_{what}_5min" + ), + InlineKeyboardButton( + "10 minute", + f"f_temp_{what}_10min", + ), + InlineKeyboardButton( + "30 minute", + f"f_temp_{what}_30min" + ), + InlineKeyboardButton( + "1 hour", + f"f_temp_{what}_60min" + ) + ], + [ + InlineKeyboardButton( + "« Back", + "f_temp_back" + ) + ] + ] + ) + return temp_duration + close_kb =InlineKeyboardMarkup( [ [ @@ -50,6 +80,16 @@ callback_data="f_kick" ) ], + [ + InlineKeyboardButton( + "Temp Mute 🔇", + "f_temp_mute" + ), + InlineKeyboardButton( + "Temp Ban 🚷", + "f_temp_ban" + ) + ], [ InlineKeyboardButton( "➡️ Skip", @@ -228,6 +268,28 @@ async def callbacks(c: Gojo, q: CallbackQuery): f"Set the limit of message after the flood protection will be activated\n **CURRENT LIMIT** {slimit} messages", reply_markup=limit_kb ) + elif data.startswith("f_temp_"): + splited = data.split("_") + if len(splited) == 3: + to_do = splited[-1] + if to_do == "back": + kb = action_kb + await q.edit_message_text( + f"Choose a action given bellow to do when flood happens.\n **CURRENT ACTION** is {saction}", + reply_markup=action_kb + ) + return + kb = await get_what_temp(to_do) + await q.answer(f"Choose temp {to_do} time", True) + await q.edit_message_text(f"What shoud be temp {to_do} time?", reply_markup=kb) + else: + change = f"{splited[-2]}_{splited[-1]}" + Flood.save_flood(c_id, slimit, swithin, change) + await q.edit_message_text( + f"Set the limit of message after the flood protection will be activated\n **CURRENT LIMIT** {slimit} messages", + reply_markup=limit_kb + ) + return elif data in ["f_5", "f_10", "f_15", "f_f_f_skip"]: try: change = int(data.split("_")[-1]) @@ -374,6 +436,98 @@ async def flood_watcher(c: Gojo, m: Message): if len(dic[c_id][u_id][1]) == limit: if y-x <= within: + action = action.split("_") + if len(action) == 2: + to_do = action[0] + for_tim = int(action[1].replace("min","")) + for_how_much = datetime.now() + timedelta(minutes=for_tim) + if to_do == "ban": + try: + await m.chat.ban_member(u_id, until_date=for_how_much) + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Unban", + callback_data=f"un_ban_={u_id}", + ), + ], + ], + ) + txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming" + await m.reply_animation( + animation=str(choice(BAN_GIFS)), + caption=txt, + reply_markup=keyboard, + ) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + + except UserAdminInvalid: + await m.reply_text( + "I can't protect this chat from this user", + ) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + except RPCError as ef: + await m.reply_text( + text=f"""Some error occured, report it using `/bug` + + Error: {ef}""" + ) + LOGGER.error(ef) + LOGGER.error(format_exc()) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + else: + try: + await m.chat.restrict_member( + u_id, + ChatPermissions(), + until_date=for_how_much + ) + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Unmute", + callback_data=f"un_mute_={u_id}", + ), + ], + ], + ) + txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming" + await m.reply_animation( + animation=str(choice(MUTE_GIFS)), + caption=txt, + reply_markup=keyboard, + ) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + except UserAdminInvalid: + await m.reply_text( + "I can't protect this chat from this user", + ) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + except RPCError as ef: + await m.reply_text( + text=f"""Some error occured, report it using `/bug` + + Error: {ef}""" + ) + LOGGER.error(ef) + LOGGER.error(format_exc()) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return + else: + action = action[0] if action == "ban": try: await m.chat.ban_member(u_id) From 67f2e3fd48a9420783c279436e4be4f9856e777e Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Tue, 2 Jul 2024 12:34:53 +0530 Subject: [PATCH 09/19] Few things left --- Powers/plugins/admin.py | 26 +++++---- Powers/plugins/antispam.py | 7 +-- Powers/plugins/bans.py | 18 +++---- Powers/plugins/clean_db.py | 18 +++---- Powers/plugins/dev.py | 47 +++++++++++++++++ Powers/plugins/filters.py | 3 +- Powers/plugins/flood.py | 4 +- Powers/plugins/greetings.py | 6 ++- Powers/plugins/info.py | 6 +-- Powers/plugins/locks.py | 10 ++-- Powers/plugins/muting.py | 14 ++--- Powers/plugins/notes.py | 6 +-- Powers/plugins/rules.py | 4 +- Powers/plugins/scheduled_jobs.py | 2 +- Powers/plugins/start.py | 6 +-- Powers/plugins/stickers.py | 90 +++++++++++++++++++++++++++----- Powers/plugins/warns.py | 10 ++-- Powers/plugins/web_con.py | 6 +-- Powers/utils/custom_filters.py | 14 ++--- Powers/utils/start_utils.py | 8 +-- Powers/utils/sticker_help.py | 79 ++++++++++++++++++++++++++++ Powers/utils/web_helpers.py | 2 +- Powers/vars.py | 7 ++- requirements.txt | 46 ++++++++-------- 24 files changed, 312 insertions(+), 127 deletions(-) diff --git a/Powers/plugins/admin.py b/Powers/plugins/admin.py index 16e97e74..bacf2b4a 100644 --- a/Powers/plugins/admin.py +++ b/Powers/plugins/admin.py @@ -81,25 +81,27 @@ async def adminlist_show(_, m: Message): return + @Gojo.on_message(command("zombies") & admin_filter) async def zombie_clean(c: Gojo, m: Message): zombie = 0 wait = await m.reply_text("Searching ... and banning ...") + failed = 0 async for member in c.get_chat_members(m.chat.id): if member.user.is_deleted: zombie += 1 try: await c.ban_chat_member(m.chat.id, member.user.id) except UserAdminInvalid: - zombie -= 1 + failed += 1 except FloodWait as e: await sleep(e.x) if zombie == 0: return await wait.edit_text("Group is clean!") - return await wait.edit_text( - text=f"{zombie} Zombies found and has been banned!", - ) - + await wait.delete() + txt=f"{zombie} Zombies found and {zombie - failed} has been banned!\n{failed} zombies' are immune to me", + await m.reply_animation("https://graph.org/file/02a1dcf7788186ffb36cb.mp4", caption=txt) + return @Gojo.on_message(command("admincache")) async def reload_admins(_, m: Message): @@ -163,8 +165,8 @@ async def fullpromote_usr(c: Gojo, m: Message): user_id, user_first_name, user_name = await extract_user(c, m) except Exception: return - bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) - if user_id == Config.BOT_ID: + bot = await c.get_chat_member(m.chat.id, c.me.id) + if user_id == c.me.id: await m.reply_text("Huh, how can I even promote myself?") return if not bot.privileges.can_promote_members: @@ -259,8 +261,8 @@ async def promote_usr(c: Gojo, m: Message): user_id, user_first_name, user_name = await extract_user(c, m) except Exception: return - bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) - if user_id == Config.BOT_ID: + bot = await c.get_chat_member(m.chat.id, c.me.id) + if user_id == c.me.id: await m.reply_text("Huh, how can I even promote myself?") return if not bot.privileges.can_promote_members: @@ -290,6 +292,8 @@ async def promote_usr(c: Gojo, m: Message): can_pin_messages=bot.privileges.can_pin_messages, can_manage_chat=bot.privileges.can_manage_chat, can_manage_video_chats=bot.privileges.can_manage_video_chats, + can_post_messages=bot.privileges.can_post_messages, + can_edit_messages=bot.privileges.can_edit_messages ), ) title = "" @@ -358,7 +362,7 @@ async def demote_usr(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) except Exception: return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Get an admin to demote me!") return # If user not already admin @@ -511,7 +515,7 @@ async def set_user_title(c: Gojo, m: Message): return if not user_id: return await m.reply_text("Cannot find user!") - if user_id == Config.BOT_ID: + if user_id == c.me.id: return await m.reply_text("Huh, why ?") if not reason: return await m.reply_text("Read /help please!") diff --git a/Powers/plugins/antispam.py b/Powers/plugins/antispam.py index 4b017644..a5027070 100644 --- a/Powers/plugins/antispam.py +++ b/Powers/plugins/antispam.py @@ -44,7 +44,7 @@ async def gban(c: Gojo, m: Message): await m.reply_text(text="This user is part of my Support!, Can't ban our own!") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text( text="You don't dare use that command on me again nigga! \n Go straight and fuck your self......" ) @@ -99,7 +99,7 @@ async def ungban(c: Gojo, m: Message): await m.reply_text(text="This user is part of my Support!, Can't ban our own!") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text( text="""You can't gban me nigga! Fuck yourself.......!""" @@ -156,7 +156,8 @@ async def gban_list(_, m: Message): banfile = "Here are all the globally banned geys!\n\n" for user in banned_users: - banfile += f"[x] {Users.get_user_info(user['_id'])['name']} - {user['_id']}\n" + USER = Users.get_user_info(user['_id']) + banfile += f"[x] {USER['name'] if USER else 'Name NA'} - {user['_id']}\n" if user["reason"]: banfile += f"Reason: {user['reason']}\n" diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py index 4c274663..f7efb9c1 100644 --- a/Powers/plugins/bans.py +++ b/Powers/plugins/bans.py @@ -35,7 +35,7 @@ async def tban_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to ban") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("WTF?? Why would I ban myself?") await m.stop_propagation() @@ -171,7 +171,7 @@ async def stban_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to ban") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("What the heck? Why would I ban myself?") await m.stop_propagation() @@ -265,7 +265,7 @@ async def dtban_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to ban") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() @@ -395,7 +395,7 @@ async def kick_usr(c: Gojo, m: Message): await m.reply_text("Cannot find user to kick") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() @@ -486,7 +486,7 @@ async def skick_usr(c: Gojo, m: Message): await m.reply_text("Cannot find user to kick") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Nuh Hu, why would I kick myself?") await m.stop_propagation() @@ -560,7 +560,7 @@ async def dkick_usr(c: Gojo, m: Message): await m.reply_text("Cannot find user to kick") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() @@ -711,7 +711,7 @@ async def sban_usr(c: Gojo, m: Message): if user_id == m.chat.id: await m.reply_text("That's an admin!") await m.stop_propagation() - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() @@ -792,7 +792,7 @@ async def dban_usr(c: Gojo, m: Message): if user_id == m.chat.id: await m.reply_text("That's an admin!") await m.stop_propagation() - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() @@ -893,7 +893,7 @@ async def ban_usr(c: Gojo, m: Message): if user_id == m.chat.id: await m.reply_text("That's an admin!") await m.stop_propagation() - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() diff --git a/Powers/plugins/clean_db.py b/Powers/plugins/clean_db.py index e12f9e0c..7dc77a2c 100644 --- a/Powers/plugins/clean_db.py +++ b/Powers/plugins/clean_db.py @@ -1,12 +1,10 @@ import time -from asyncio import sleep from traceback import format_exc -from apscheduler.schedulers.asyncio import AsyncIOScheduler from pyrogram.enums import ChatMemberStatus as CMS -from pyrogram.errors import PeerIdInvalid, UserNotParticipant +from pyrogram.errors import UserNotParticipant -from Powers import LOGGER, MESSAGE_DUMP, TIME_ZONE +from Powers import LOGGER, MESSAGE_DUMP from Powers.bot_class import Gojo from Powers.database.approve_db import Approve from Powers.database.blacklist_db import Blacklist @@ -20,18 +18,17 @@ 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 -async def clean_my_db(c:Gojo,is_cmd=False, id=None): +async def clean_my_db(c: Gojo, is_cmd=False, id=None): to_clean = list() 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) + stat = await c.get_chat_member(chat_id=chats, user_id=c.me.id) if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]: to_clean.append(chats) except UserNotParticipant: @@ -64,12 +61,9 @@ async def clean_my_db(c:Gojo,is_cmd=False, id=None): if is_cmd: txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}" txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP,text=txt) + await c.send_message(chat_id=MESSAGE_DUMP, text=txt) return txt else: txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP,text=txt) + await c.send_message(chat_id=MESSAGE_DUMP, text=txt) return txt - - - diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py index 9c75b39c..010cf386 100644 --- a/Powers/plugins/dev.py +++ b/Powers/plugins/dev.py @@ -1,6 +1,7 @@ import subprocess as subp import sys from asyncio import create_subprocess_shell, sleep, subprocess +from importlib.metadata import PackageNotFoundError, metadata from io import BytesIO, StringIO from os import execvp from sys import executable @@ -209,6 +210,52 @@ async def ping(_, m: Message): await replymsg.edit_text(f"Pong!\n{delta_ping * 1000:.3f} ms") return +""" + +['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'License', 'Download-URL', 'Project-URL', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Description-Content-Type', 'License-File', 'License-File', 'License-File', 'Requires-Dist', 'Requires-Dist', 'Description'] + +""" + +@Gojo.on_message(command(["minfo", "moduleinfo"], dev_cmd=True)) +async def check_module_info(_, m: Message): + if len(m.command) != 2: + await m.reply_text("**USAGE**\n/minfo [module name]") + return + + module = m.command[-1] + + try: + minfo = metadata(module) + except PackageNotFoundError: + await m.reply_text(f"No module found with name {module}") + return + + name = minfo["Name"] + version = minfo["Version"] + summary = minfo["Summary"] + home_page = minfo["Home-Page"] + author = minfo["Author"] + license = minfo["License"] + download = minfo["Download-URL"] + + txt = f""" +Here are the info about the module **{name}** +• Version: {version} + +• Summary: {summary} + +• Home page: {home_page} + +• Author: {author} + +• License: {license} + +• Download: {download} +""" + await m.reply_text(txt, disable_web_page_preview=True) + return + + @Gojo.on_message(command("logs", dev_cmd=True)) async def send_log(c: Gojo, m: Message): diff --git a/Powers/plugins/filters.py b/Powers/plugins/filters.py index 78e23e1d..34e7f93f 100644 --- a/Powers/plugins/filters.py +++ b/Powers/plugins/filters.py @@ -110,7 +110,7 @@ async def add_filter(_, m: Message): async def stop_filter(_, m: Message): args = m.command - if len(args) < 1: + if len(args) <= 1: return await m.reply_text("What should I stop replying to?") chat_filters = db.get_all_filters(m.chat.id) @@ -283,7 +283,6 @@ async def filters_watcher(c: Gojo, m: Message): if match: try: msgtype = await send_filter_reply(c, m, trigger) - LOGGER.info(f"Replied with {msgtype} to {trigger} in {m.chat.id}") except Exception as ef: await m.reply_text(f"Error: {ef}") LOGGER.error(ef) diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 74c1ae34..dd7c220f 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -152,7 +152,7 @@ async def get_what_temp(what): @Gojo.on_message(command(['floodaction','actionflood']) & admin_filter) async def flood_action(c: Gojo, m: Message): Flood = Floods() - bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) + bot = await c.get_chat_member(m.chat.id, c.me.id) status = bot.status if not status in [CMS.OWNER, CMS.ADMINISTRATOR]: if not bot.privileges.can_restrict_members: @@ -189,7 +189,7 @@ async def flood_on_off(c: Gojo, m: Message): @Gojo.on_message(command(['setflood']) & ~filters.bot & admin_filter) async def flood_set(c: Gojo, m: Message): - bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) + bot = await c.get_chat_member(m.chat.id, c.me.id) Flood = Floods() status = bot.status if not status in [CMS.OWNER, CMS.ADMINISTRATOR]: diff --git a/Powers/plugins/greetings.py b/Powers/plugins/greetings.py index 98fa1ce6..169f1268 100644 --- a/Powers/plugins/greetings.py +++ b/Powers/plugins/greetings.py @@ -4,7 +4,7 @@ from pyrogram import emoji, enums, filters from pyrogram.enums import ChatMemberStatus as CMS -from pyrogram.errors import ChatAdminRequired, RPCError +from pyrogram.errors import ChannelPrivate, ChatAdminRequired, RPCError from pyrogram.types import ChatMemberUpdated, Message from Powers import LOGGER @@ -257,7 +257,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): db = Greetings(member.chat.id) banned_users = gdb.check_gban(user.id) try: - if user.id == Config.BOT_ID: + if user.id == c.me.id: return if user.id in DEV_USERS: await c.send_animation( @@ -332,6 +332,8 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): if jj: db.set_cleanwlcm_id(int(jj.id)) + except ChannelPrivate: + return except RPCError as e: LOGGER.error(e) LOGGER.error(format_exc(e)) diff --git a/Powers/plugins/info.py b/Powers/plugins/info.py index 2f6fa6c4..7e71fea7 100644 --- a/Powers/plugins/info.py +++ b/Powers/plugins/info.py @@ -96,17 +96,17 @@ async def user_info(c: Gojo, user, already=False): is_restricted = user.is_restricted photo_id = user.photo.big_file_id if user.photo else None is_support = True if user_id in SUPPORT_STAFF else False - if user_id == Config.BOT_ID: + if user_id == c.me.id: is_support = "A person is a great support to himself" omp = "Hmmm.......Who is that again?" - if is_support or Config.BOT_ID: + if is_support or c.me.id: if user_id in DEV_USERS: omp = "Dev" elif user_id in SUDO_USERS: omp = "Sudoer" elif user_id in WHITELIST_USERS: omp = "Whitelist" - elif user_id == Config.BOT_ID: + elif user_id == c.me.id: omp = "I am the targeted user" elif user_id == OWNER_ID: omp = "Owner of the bot" diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index acd051e3..c4fedbc5 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -473,19 +473,19 @@ async def is_approved_user(c: Gojo, m: Message): SUDO_LEVEL = get_support_staff("sudo_level") 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 or m.from_user.id == Config.BOT_ID: + if m.from_user and (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 == c.me.id): return True return False elif m.forward_from_chat: x_chat = (await c.get_chat(m.forward_from_chat.id)).linked_chat - 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: + if m.from_user and (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 == c.me.id): return True - if not x_chat: - return False elif x_chat and x_chat.id == m.chat.id: return True + else: + 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: + 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 == c.me.id: return True return False diff --git a/Powers/plugins/muting.py b/Powers/plugins/muting.py index 7705e977..f2af8206 100644 --- a/Powers/plugins/muting.py +++ b/Powers/plugins/muting.py @@ -35,7 +35,7 @@ async def tmute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute !") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -149,7 +149,7 @@ async def dtmute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute !") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -258,7 +258,7 @@ async def stmute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute !") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -352,7 +352,7 @@ async def mute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -438,7 +438,7 @@ async def smute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -511,7 +511,7 @@ async def dmute_usr(c: Gojo, m: Message): if not user_id: await m.reply_text("Cannot find user to mute") return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I mute myself?") return @@ -595,7 +595,7 @@ async def unmute_usr(c: Gojo, m: Message): except Exception: return - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I unmute myself if you are using me?") return try: diff --git a/Powers/plugins/notes.py b/Powers/plugins/notes.py index ac632af3..9c1611fc 100644 --- a/Powers/plugins/notes.py +++ b/Powers/plugins/notes.py @@ -84,7 +84,7 @@ async def get_note_func(c: Gojo, m: Message, note_name, priv_notes_status): [ ( "Click Me!", - f"https://t.me/{Config.BOT_USERNAME}?start=note_{m.chat.id}_{note_hash}", + f"https://t.me/{c.me.username}?start=note_{m.chat.id}_{note_hash}", "url", ), ], @@ -323,7 +323,7 @@ async def priv_notes(_, m: Message): @Gojo.on_message(command("notes") & filters.group & ~filters.bot) -async def local_notes(_, m: Message): +async def local_notes(c: Gojo, m: Message): LOGGER.info(f"{m.from_user.id} listed all notes in {m.chat.id}") getnotes = db.get_all_notes(m.chat.id) @@ -341,7 +341,7 @@ async def local_notes(_, m: Message): [ ( "All Notes", - f"https://t.me/{Config.BOT_USERNAME}?start=notes_{m.chat.id}", + f"https://t.me/{c.me.username}?start=notes_{m.chat.id}", "url", ), ], diff --git a/Powers/plugins/rules.py b/Powers/plugins/rules.py index 62e65a3f..acab2e0e 100644 --- a/Powers/plugins/rules.py +++ b/Powers/plugins/rules.py @@ -11,7 +11,7 @@ @Gojo.on_message(command("rules") & filters.group) -async def get_rules(_, m: Message): +async def get_rules(c: Gojo, m: Message): db = Rules(m.chat.id) msg_id = m.reply_to_message.id if m.reply_to_message else m.id @@ -35,7 +35,7 @@ async def get_rules(_, m: Message): [ ( "Rules", - f"https://t.me/{Config.BOT_USERNAME}?start=rules_{m.chat.id}", + f"https://t.me/{c.me.username}?start=rules_{m.chat.id}", "url", ), ], diff --git a/Powers/plugins/scheduled_jobs.py b/Powers/plugins/scheduled_jobs.py index f610dbee..4a2c44f1 100644 --- a/Powers/plugins/scheduled_jobs.py +++ b/Powers/plugins/scheduled_jobs.py @@ -31,7 +31,7 @@ async def clean_my_db(c:Client,is_cmd=False, id=None): start = TIME.time() for chats in chats_list: try: - stat = await c.get_chat_member(chat_id=chats,user_id=Config.BOT_ID) + stat = await c.get_chat_member(chat_id=chats,user_id=c.me.id) if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]: to_clean.append(chats) except UserNotParticipant: diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index 29aa79c8..c364c6a6 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -150,7 +150,7 @@ async def start(c: Gojo, m: Message): [ InlineKeyboardButton( "Connect me to pm", - url=f"https://{Config.BOT_USERNAME}.t.me/", + url=f"https://{c.me.username}.t.me/", ), ], ], @@ -253,7 +253,7 @@ async def help_menu(c: Gojo, m: Message): [ InlineKeyboardButton( "Help", - url=f"t.me/{Config.BOT_USERNAME}?start={help_option}", + url=f"t.me/{c.me.username}?start={help_option}", ), ], ], @@ -276,7 +276,7 @@ async def help_menu(c: Gojo, m: Message): [ InlineKeyboardButton( "Help", - url=f"t.me/{Config.BOT_USERNAME}?start=start_help", + url=f"t.me/{c.me.username}?start=start_help", ), ], ], diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index 2d6ba98e..ebd0519b 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -3,10 +3,12 @@ from random import choice from traceback import format_exc +from pyrogram import filters from pyrogram.errors import (PeerIdInvalid, ShortnameOccupyFailed, StickerEmojiInvalid, StickerPngDimensions, StickerPngNopng, StickerTgsNotgs, StickerVideoNowebm, UserIsBlocked) +from pyrogram.types import CallbackQuery from pyrogram.types import InlineKeyboardButton as IKB from pyrogram.types import InlineKeyboardMarkup as IKM from pyrogram.types import Message @@ -15,8 +17,8 @@ from Powers.bot_class import Gojo from Powers.utils.custom_filters import command from Powers.utils.sticker_help import * +from Powers.utils.string import encode_decode from Powers.utils.web_helpers import get_file_size -from Powers.vars import Config @Gojo.on_message(command(["stickerinfo","stinfo"])) @@ -171,22 +173,25 @@ async def kang(c:Gojo, m: Message): try: while not packname_found: - packname = f"CE{str(m.from_user.id)}{st_type}{packnum}_by_{Config.BOT_USERNAME}" - kangpack = f"{('@'+m.from_user.username) if m.from_user.username else m.from_user.first_name[:10]} {st_type} {('vOl '+str(volume)) if volume else ''} by @{Config.BOT_USERNAME}" + packname = f"CE{str(m.from_user.id)}{st_type}{packnum}_by_{c.me.username}" + kangpack = f"{('@'+m.from_user.username) if m.from_user.username else m.from_user.first_name[:10]} {st_type} {('vOl '+str(volume)) if volume else ''} by @{c.me.username}" if limit >= 50: # To prevent this loop from running forever await m.reply_text("Failed to kang\nMay be you have made more than 50 sticker packs with me try deleting some") return sticker_set = await get_sticker_set_by_name(c,packname) if not sticker_set: - sticker_set = await create_sticker_set( - client=c, - owner=m.from_user.id, - title=kangpack, - short_name=packname, - stickers=[sticker], - animated=is_anim, - video=is_vid - ) + try: + sticker_set = await create_sticker_set( + client=c, + owner=m.from_user.id, + title=kangpack, + short_name=packname, + stickers=[sticker], + animated=is_anim, + video=is_vid + ) + except StickerEmojiInvalid: + return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT") elif sticker_set.set.count >= kang_lim: packnum += 1 limit += 1 @@ -213,7 +218,7 @@ async def kang(c:Gojo, m: Message): ) except (PeerIdInvalid, UserIsBlocked): keyboard = IKM( - [[IKB("Start me first", url=f"t.me/{Config.BOT_USERNAME}")]] + [[IKB("Start me first", url=f"t.me/{c.me.username}")]] ) await msg.delete() await m.reply_text( @@ -316,7 +321,7 @@ async def memify_it(c: Gojo, m: Message): @Gojo.on_message(command(["getsticker","getst"])) async def get_sticker_from_file(c: Gojo, m: Message): - Caption = f"Converted by:\n@{Config.BOT_USERNAME}" + Caption = f"Converted by:\n@{c.me.username}" repl = m.reply_to_message if not repl: await m.reply_text("Reply to a sticker or file") @@ -365,6 +370,62 @@ async def get_sticker_from_file(c: Gojo, m: Message): os.remove(up) return +@Gojo.on_message(command(["rmsticker", "rmst", "removesticker"])) +async def remove_from_MY_pack(c: Gojo, m: Message): + if not m.reply_to_message or not m.reply_to_message.sticker: + await m.reply_text("Please reply to a sticker to remove it from your pack") + return + + sticker = m.reply_to_message.sticker + sticker_set = await get_sticker_set_by_name(c, sticker.set_name) + + if not sticker_set: + await m.reply_text("This sticker is not part of your pack") + return + + try: + await remove_sticker(c, sticker.file_id) + await m.reply_text(f"Deleted [this]({m.reply_to_message.link}) from pack: {sticker_set.et.title}") + return + except Exception as e: + await m.reply_text(f"Error\n{e}\nReport it using /bug") + LOGGER.error(e) + LOGGER.error(format_exc(e)) + return + +@Gojo.on_message(command(["getmypacks", "mypacks", "mysets", "stickerset", "stset"])) +async def get_my_sticker_sets(c: Gojo, m: Message): + to_del = await m.reply_text("Please wait while I fetch all the sticker set I have created for you.") + st_types = ["norm", "ani", "vid"] + + txt, kb = await get_all_sticker_packs(c, m.from_user.id, "norm") + + await to_del.delete() + if not txt: + await m.reply_text("Looks like you haven't made any sticker using me...") + return + await m.reply_text(txt, reply_markup=kb) + +@Gojo.on_callback_query(filters.regex(r"^stickers_(norm|vid|ani)_.*")) +async def sticker_callbacks(c: Gojo, q: CallbackQuery): + data = q.data.split("_") + st_type = data[1] + decoded = await encode_decode(data[-1], "decode") + user = int(decoded.split("_")[-1]) + offset = int(decoded.split("_")[0]) + + if q.from_user.id != user: + await q.answer("This is not for you") + return + else: + txt, kb = await get_all_sticker_packs(c, q.from_user.id, st_type, offset) + if not txt: + await q.answer("No sticker pack found....") + return + else: + await q.answer(f"Showing your {st_type}") + await q.edit_message_text(txt, reply_markup=kb) + return __PLUGIN__ = "sticker" __alt_name__ = [ @@ -377,6 +438,7 @@ async def get_sticker_from_file(c: Gojo, m: Message): • /stickerinfo (/stinfo) : Reply to any sticker to get it's info • /getsticker (/getst) : Get sticker as photo, gif or vice versa. • /stickerid (/stid) : Reply to any sticker to get it's id +• /mypacks : Get all of your current sticker pack you have made via me. • /mmf : 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` ■ For e.g. ○ /mmf Hello freinds : this will add text to the top diff --git a/Powers/plugins/warns.py b/Powers/plugins/warns.py index b2b0bbb2..1c3cf5c4 100644 --- a/Powers/plugins/warns.py +++ b/Powers/plugins/warns.py @@ -44,7 +44,7 @@ async def warn(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I warn myself?") return @@ -102,7 +102,7 @@ async def warn(c: Gojo, m: Message): if rules: kb = InlineKeyboardButton( "Rules 📋", - url=f"https://t.me/{Config.BOT_USERNAME}?start=rules_{m.chat.id}", + url=f"https://t.me/{c.me.username}?start=rules_{m.chat.id}", ) else: kb = InlineKeyboardButton( @@ -147,7 +147,7 @@ async def reset_warn(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I warn myself?") return @@ -183,7 +183,7 @@ async def list_warns(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I warn myself?") return @@ -232,7 +232,7 @@ async def remove_warn(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) - if user_id == Config.BOT_ID: + if user_id == c.me.id: await m.reply_text("Huh, why would I warn myself?") return diff --git a/Powers/plugins/web_con.py b/Powers/plugins/web_con.py index 2be7550a..81a7c049 100644 --- a/Powers/plugins/web_con.py +++ b/Powers/plugins/web_con.py @@ -257,8 +257,7 @@ async def song_down_up(c: Gojo, m: Message): return _id = get_video_id(splited) if not _id: - await m.reply_text("Invalid youtube link") - return + query = splited else: query = _id XnX = await m.reply_text("⏳") @@ -284,8 +283,7 @@ async def video_down_up(c: Gojo, m: Message): return _id = get_video_id(splited) if not _id: - await m.reply_text("Invalid youtube link") - return + query = splited else: query = _id XnX = await m.reply_text("⏳") diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 8a8ac4c5..83b8916e 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -9,14 +9,14 @@ from pyrogram.filters import create from pyrogram.types import CallbackQuery, ChatJoinRequest, Message -from Powers import DEV_USERS, OWNER_ID, SUDO_USERS +from Powers import DEV_USERS, OWNER_ID, PREFIX_HANDLER, SUDO_USERS +from Powers.bot_class import Gojo from Powers.database.afk_db import AFK from Powers.database.approve_db import Approve from Powers.database.autojoin_db import AUTOJOIN from Powers.database.disable_db import Disabling from Powers.database.flood_db import Floods from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload -from Powers.vars import Config def command( @@ -26,7 +26,7 @@ def command( dev_cmd: bool = False, sudo_cmd: bool = False, ): - async def func(flt, _, m: Message): + async def func(flt, c: Gojo, m: Message): if not m: return @@ -62,8 +62,8 @@ async def func(flt, _, m: Message): if not text: return False regex = r"^[{prefix}](\w+)(@{bot_name})?(?: |$)(.*)".format( - prefix="|".join(escape(x) for x in Config.PREFIX_HANDLER), - bot_name=Config.BOT_USERNAME, + prefix="|".join(escape(x) for x in PREFIX_HANDLER), + bot_name=c.me.username, ) matches = compile_re(regex).search(text) if matches: @@ -111,7 +111,7 @@ async def func(flt, _, m: Message): ) -async def bot_admin_check_func(_, __, m: Message or CallbackQuery): +async def bot_admin_check_func(_, c: Gojo, m: Message or CallbackQuery): """Check if bot is Admin or not.""" if isinstance(m, CallbackQuery): @@ -135,7 +135,7 @@ async def bot_admin_check_func(_, __, m: Message or CallbackQuery): if ("The chat_id" and "belongs to a user") in ef: return True - if Config.BOT_ID in admin_group: + if c.me.id in admin_group: return True await m.reply_text( diff --git a/Powers/utils/start_utils.py b/Powers/utils/start_utils.py index 2d34479c..3fe30c2d 100644 --- a/Powers/utils/start_utils.py +++ b/Powers/utils/start_utils.py @@ -5,7 +5,7 @@ from pyrogram.errors import RPCError from pyrogram.types import CallbackQuery, Message -from Powers import HELP_COMMANDS, LOGGER, SUPPORT_GROUP +from Powers import HELP_COMMANDS, LOGGER, OWNER_ID, SUPPORT_CHANNEL from Powers.bot_class import Gojo from Powers.database.chats_db import Chats from Powers.database.notes_db import Notes @@ -65,7 +65,7 @@ async def gen_start_kb(q: Message or CallbackQuery): ), ( "Owner ❤️", - Config.OWNER_ID, + OWNER_ID, "user_id", ), ], @@ -77,7 +77,7 @@ async def gen_start_kb(q: Message or CallbackQuery): ), ( "Powered by ⚡️", - f"https://{Config.SUPPORT_CHANNEL}.t.me", + f"https://{SUPPORT_CHANNEL}.t.me", "url", ), ], @@ -95,7 +95,7 @@ async def get_private_note(c: Gojo, m: Message, help_option: str): chat_title = Chats.get_chat_info(chat_id)["chat_name"] rply = f"Notes in {chat_title}:\n\n" note_list = [ - f"- [{note[0]}](https://t.me/{Config.BOT_USERNAME}?start=note_{chat_id}_{note[1]})" + f"- [{note[0]}](https://t.me/{c.me.username}?start=note_{chat_id}_{note[1]})" for note in all_notes ] rply = f"Available notes in {chat_title}\n" diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 5b0815f7..6bcb3d42 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -9,10 +9,89 @@ from PIL import Image, ImageDraw, ImageFont from pyrogram import errors, raw from pyrogram.file_id import FileId +from pyrogram.types import InlineKeyboardButton as ikb +from pyrogram.types import InlineKeyboardMarkup as ikm from pyrogram.types import Message from unidecode import unidecode from Powers.bot_class import Gojo +from Powers.utils.string import encode_decode + + +async def get_all_sticker_packs(c: Gojo, user_id: int, st_type: str, offset: int = 1, limit: int = 25): + packnum = 25 * (offset - 1) + if st_type == "norm": + st_ = "Static" + elif st_type == "vid": + st_ = "Video" + else: + st_ = "Animated" + txt = f"Here is your {st_} stickers that I have created:\nPage: {offset}\n" + while True: + packname = f"CE{str(user_id)}{st_type}{packnum}_by_{c.me.username}" + sticker_set = await get_sticker_set_by_name(c,packname) + if not sticker_set and packnum == 0: + txt, kb = None, None + break + elif sticker_set and packnum <= (packnum + limit - 1): + base_ = f"t.me/addstickers/{packname}" + txt += f"`{packnum}`. [{sticker_set.set.name}]({base_})\n" + packnum += 1 + else: + page = await encode_decode(f"1_{user_id}") + if st_type == "norm": + st_kb = [ + [ + ikb("Video stickers", f"stickers_vid_{page}"), + ikb("Animated stickers", f"stickers_ani_{page}"), + ] + ] + elif st_type == "vid": + st_kb = [ + [ + ikb("Static stickers", f"stickers_norm_{page}"), + ikb("Animated stickers", f"stickers_ani_{page}"), + ] + ] + else: + st_kb = [ + [ + ikb("Static stickers", f"stickers_norm_{page}"), + ikb("Video stickers", f"stickers_vid_{page}"), + ] + ] + + b64_next = await encode_decode(f"{offset+1}_{user_id}") + b64_prev = await encode_decode(f"{offset-1}_{user_id}") + + if (packnum > (packnum + limit - 1)) and offset >= 2: + kb = [ + [ + ikb("Previous", f"stickers_{st_type}_{b64_prev}"), + ikb("Next", f"stickers_{st_type}_{b64_next}") + ], + ] + kb.extend(st_kb) + elif offset >= 2 and (packnum <= (packnum + limit - 1)): + kb = [ + [ + ikb("Previous", f"stickers_{st_type}_{b64_prev}") + ], + ] + kb.extend(st_kb) + elif packnum > (packnum + limit - 1) and offset == 1: + kb = [ + [ + ikb("Next", f"stickers_{st_type}_{b64_next}") + ], + ] + kb.extend(st_kb) + else: + kb = st_kb + kb = ikm(kb) + break + + return txt, kb async def runcmd(cmd: str) -> Tuple[str, str, int, int]: diff --git a/Powers/utils/web_helpers.py b/Powers/utils/web_helpers.py index 426ab4b1..a90e6471 100644 --- a/Powers/utils/web_helpers.py +++ b/Powers/utils/web_helpers.py @@ -118,7 +118,7 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t video = True song = False # ydl = yt_dlp.YoutubeDL(opts) - dicti = await song_search(query, is_direct, 1) + dicti = await song_search(query, 1) if not dicti and type(dicti) != str: await m.reply_text("File with duration less than or equals to 10 minutes is allowed only") elif type(dicti) == str: diff --git a/Powers/vars.py b/Powers/vars.py index a130ad23..8a916c1f 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -52,10 +52,9 @@ class Config: SUPPORT_CHANNEL = config("SUPPORT_CHANNEL", default="gojo_bots_network") WORKERS = int(config("WORKERS", default=16)) TIME_ZONE = config("TIME_ZONE", default='Asia/Kolkata') - BOT_USERNAME = "" - BOT_ID = "" - BOT_NAME = "" - owner_username = "" + BOT_USERNAME = "" # Leave it as it is + BOT_ID = "" # Leave it as it is + BOT_NAME = "" # Leave it as it is class Development: diff --git a/requirements.txt b/requirements.txt index fe638a83..7d596f00 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,41 @@ -aiofiles==23.2.1; python_full_version >= "3.7" -anyio==4.2.0; python_full_version >= "3.6.2" and python_version >= "3.6" +aiofiles==23.2.1 +anyio==4.2.0 apscheduler==3.10.4 asyncio==3.4.3 -beautifulsoup4==4.12.2; python_full_version >= "3.6" -cachetools==5.2.0; python_version >= "3.7" and python_version < "4.0" +beautifulsoup4==4.12.2 +cachetools==5.2.0 captcha==0.5.0 -certifi==2023.7.22; python_version >= "3.7" and python_version < "4" -charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4" and python_full_version >= "3.6.0" -dnspython==2.2.1; python_version >= "3.6" and python_version < "4.0" +certifi==2023.7.22 +charset-normalizer==2.1.0 +dnspython==2.2.1 google==3.0.0 -gpytranslate==1.5.1; python_version >= "3.6" +gpytranslate==1.5.1 lyricsgenius==3.0.1 -lxml==4.9.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" +lxml==4.9.1 pillow == 10.1.0 prettyconf==2.2.1 -pyaes==1.6.1; python_version >= "3.6" and python_version < "4.0" +pyaes==1.6.1 pymongo==4.6.1 -pyrogram==2.0.106; python_version >= "3.8" -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" -python-dateutil==2.8.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0") +git+https://github.com/KurimuzonAkuma/pyrogram.git@v2.1.22 +pysocks==1.7.1 +python-dateutil==2.8.2 pytube==15.0.0 pytz==2023.3 -pyyaml==6.0.1; python_version >= "3.6" +pyyaml==6.0.1 qrcode==7.4.2 -regex==2023.12.25; python_version >= "3.6" +regex==2023.12.25 requests==2.31.0 -rfc3986==1.5.0; python_version >= "3.7" +rfc3986==1.5.0 search-engine-parser==0.6.8 selenium==4.18.1 -six==1.16.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" -sniffio==1.3.0; python_full_version >= "3.6.2" and python_version >= "3.7" -soupsieve==2.4; python_version >= "3.6" and python_full_version >= "3.6.0" -tgcrypto==1.2.5; python_version >= "3.6" and python_version < "4.0" +six==1.16.0 +sniffio==1.3.0 +soupsieve==2.4 +tgcrypto==1.2.5 tswift==0.7.0 -typing-extensions==4.5.0; python_full_version >= "3.6.2" and python_version >= "3.7" and python_version < "3.8" -ujson==5.8.0; python_version >= "3.7" -urllib3==1.26.18; 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" +typing-extensions==4.5.0 +ujson==5.8.0 +urllib3==1.26.18 uvloop==0.19.0 wikipedia==1.4.0 youtube-search-python==1.6.6 From 56ff298b838de6cd1025d86fade414e5444d0a15 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Mon, 21 Oct 2024 19:32:39 +0530 Subject: [PATCH 10/19] almost done --- Powers/__init__.py | 20 +-- Powers/bot_class.py | 1 + Powers/database/antispam_db.py | 3 +- Powers/database/approve_db.py | 2 - Powers/database/blacklist_db.py | 2 - Powers/database/chats_db.py | 1 - Powers/database/disable_db.py | 2 - Powers/database/filters_db.py | 10 +- Powers/database/greetings_db.py | 2 - Powers/database/locks_db.py | 52 +++--- Powers/database/pins_db.py | 1 - Powers/database/reporting_db.py | 2 - Powers/database/rules_db.py | 2 - Powers/database/users_db.py | 1 - Powers/database/warns_db.py | 4 - Powers/plugins/admin.py | 29 ++-- Powers/plugins/antispam.py | 17 +- Powers/plugins/approve.py | 6 - Powers/plugins/auto_join.py | 5 +- Powers/plugins/bans.py | 66 ++------ Powers/plugins/birthday.py | 16 +- Powers/plugins/blacklist.py | 9 - Powers/plugins/captcha.py | 5 +- Powers/plugins/chat_blacklist.py | 3 - Powers/plugins/clean_db.py | 1 - Powers/plugins/dev.py | 29 +++- Powers/plugins/disable.py | 7 - Powers/plugins/filters.py | 11 +- Powers/plugins/flood.py | 12 +- Powers/plugins/formatting.py | 1 - Powers/plugins/fun.py | 20 +-- Powers/plugins/greetings.py | 26 +-- Powers/plugins/info.py | 21 ++- Powers/plugins/locks.py | 55 +++---- Powers/plugins/muting.py | 44 ++--- Powers/plugins/notes.py | 18 +- Powers/plugins/pin.py | 14 +- Powers/plugins/report.py | 16 +- Powers/plugins/rules.py | 9 +- Powers/plugins/scheduled_jobs.py | 3 - Powers/plugins/start.py | 15 +- Powers/plugins/stats.py | 7 +- Powers/plugins/stickers.py | 55 ++----- Powers/plugins/utils.py | 10 +- Powers/plugins/warns.py | 24 +-- Powers/plugins/watchers.py | 24 +-- Powers/plugins/web_con.py | 45 +++-- Powers/supports.py | 14 +- Powers/utils/admin_check.py | 13 +- Powers/utils/caching.py | 3 - Powers/utils/custom_filters.py | 14 +- Powers/utils/extract_user.py | 2 +- Powers/utils/start_utils.py | 7 +- Powers/utils/sticker_help.py | 59 ++----- Powers/utils/web_scrapper.py | 273 +++++++++++++++++-------------- Powers/vars.py | 8 +- app.json | 10 -- requirements.txt | 10 +- 58 files changed, 443 insertions(+), 698 deletions(-) diff --git a/Powers/__init__.py b/Powers/__init__.py index bb348d48..9150bb5d 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -123,23 +123,11 @@ SUPPORT_GROUP = Config.SUPPORT_GROUP SUPPORT_CHANNEL = Config.SUPPORT_CHANNEL -# Users Config +# Users Config OWNER_ID = Config.OWNER_ID -DEV = Config.DEV_USERS -DEVS_USER = set(DEV) -SUDO_USERS = Config.SUDO_USERS -WHITELIST_USERS = Config.WHITELIST_USERS - - -defult_dev = [1344569458, 1432756163, 5294360309] + [int(OWNER_ID)] - -Defult_dev = set(defult_dev) - -DEVS = DEVS_USER | Defult_dev -DEV_USERS = list(DEVS) - -CHROME_BIN = Config.CHROME_BIN -CHROME_DRIVER = Config.CHROME_DRIVER +DEV_USERS = set(Config.DEV_USERS) +SUDO_USERS = set(Config.SUDO_USERS) +WHITELIST_USERS = set(Config.WHITELIST_USERS) # Plugins, DB and Workers DB_URI = Config.DB_URI diff --git a/Powers/bot_class.py b/Powers/bot_class.py index cdad2714..f9648c56 100644 --- a/Powers/bot_class.py +++ b/Powers/bot_class.py @@ -67,6 +67,7 @@ async def start(self): # Get cmds and keys cmd_list = await load_cmds(await all_plugins()) await load_support_users() + await cache_support() LOGGER.info(f"Plugins Loaded: {cmd_list}") scheduler.add_job(clean_my_db, 'cron', [ self], hour=3, minute=0, second=0) diff --git a/Powers/database/antispam_db.py b/Powers/database/antispam_db.py index d90ece23..67ff591c 100644 --- a/Powers/database/antispam_db.py +++ b/Powers/database/antispam_db.py @@ -28,6 +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 + ANTISPAM_BANNED.add(user_id) time_rn = datetime.now(TZ) return self.insert_one( { @@ -43,8 +44,8 @@ def remove_gban(self, user_id: int): with INSERTION_LOCK: # Check if user is already gbanned or not if self.find_one({"_id": user_id}): + ANTISPAM_BANNED.remove(user_id) return self.delete_one({"_id": user_id}) - return "User not gbanned!" def get_gban(self, user_id: int): diff --git a/Powers/database/approve_db.py b/Powers/database/approve_db.py index f9c3314c..899af43e 100644 --- a/Powers/database/approve_db.py +++ b/Powers/database/approve_db.py @@ -81,8 +81,6 @@ def __ensure_in_db(self): if not chat_data: new_data = {"_id": self.chat_id, "users": []} self.insert_one(new_data) - LOGGER.info( - f"Initialized Approve Document for chat {self.chat_id}") return new_data return chat_data # Migrate if chat id changes! diff --git a/Powers/database/blacklist_db.py b/Powers/database/blacklist_db.py index b2f29cef..7252ae28 100644 --- a/Powers/database/blacklist_db.py +++ b/Powers/database/blacklist_db.py @@ -110,8 +110,6 @@ def __ensure_in_db(self): "reason": "Automated blacklisted word: {{}}", } self.insert_one(new_data) - LOGGER.info( - f"Initialized Blacklist Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/chats_db.py b/Powers/database/chats_db.py index b4029a41..e580f7ff 100644 --- a/Powers/database/chats_db.py +++ b/Powers/database/chats_db.py @@ -107,7 +107,6 @@ def __ensure_in_db(self): if not chat_data: new_data = {"_id": self.chat_id, "chat_name": "", "users": []} self.insert_one(new_data) - LOGGER.info(f"Initialized Chats Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/disable_db.py b/Powers/database/disable_db.py index e4b21430..6f821b78 100644 --- a/Powers/database/disable_db.py +++ b/Powers/database/disable_db.py @@ -149,8 +149,6 @@ def __ensure_in_db(self): DISABLED_CMDS[self.chat_id] = { "commands": [], "action": "none"} self.insert_one(new_data) - LOGGER.info( - f"Initialized Disabling Document for chat {self.chat_id}") return new_data DISABLED_CMDS[self.chat_id] = chat_data return chat_data diff --git a/Powers/database/filters_db.py b/Powers/database/filters_db.py index fa6c3dc5..3172a62e 100644 --- a/Powers/database/filters_db.py +++ b/Powers/database/filters_db.py @@ -24,7 +24,15 @@ def save_filter( # Database update curr = self.find_one({"chat_id": chat_id, "keyword": keyword}) if curr: - return False + self.update( + {"chat_id": chat_id, "keyword": keyword}, + { + "filter_reply": filter_reply, + "msgtype": msgtype, + "fileid": fileid + } + ) + return return self.insert_one( { "chat_id": chat_id, diff --git a/Powers/database/greetings_db.py b/Powers/database/greetings_db.py index d758dfe4..3a00e445 100644 --- a/Powers/database/greetings_db.py +++ b/Powers/database/greetings_db.py @@ -161,8 +161,6 @@ def __ensure_in_db(self): "goodbye_mtype": False } self.insert_one(new_data) - LOGGER.info( - f"Initialized Greetings Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/locks_db.py b/Powers/database/locks_db.py index 6637c002..222ecbc0 100644 --- a/Powers/database/locks_db.py +++ b/Powers/database/locks_db.py @@ -58,35 +58,47 @@ def remove_lock_channel(self, chat: int, locktype: str): else: return False - def get_lock_channel(self, locktype: str = "all", chat: int = 0): + def get_lock_channel(self, chat: int, locktype: str = "all"): """ locktypes: anti_c_send, anti_fwd, anti_fwd_u, anti_fwd_c, anti_links, bot """ if locktype not in ["anti_c_send", "anti_fwd", "anti_fwd_u", "anti_fwd_c", "anti_links", "bot", "all"]: return False else: - if locktype == "all": - find = {} + if locktype != "all": + curr = self.find_one( + {"chat_id": chat, "locktype": locktype}) + return bool(curr) else: - find = {"locktype": locktype} - if chat: - if find: - curr = self.find_one( - {"chat_id": chat, "locktype": locktype}) - return bool(curr) - else: - to_return = [] - for i in lock_t: - curr = self.find_one({"chat_id": chat, "locktype": i}) - to_return.append(bool(curr)) - return all(to_return) - else: - curr = self.find_all(find) + to_return = { + "anti_channel": False, + "anti_fwd": { + "user": False, + "chat": False + }, + "anti_links": False, + "bot": False + } + curr = self.find_all({"chat_id": chat}) if not curr: - list_ = [] + return None else: - list_ = [i["chat_id"] for i in curr] - return list_ + for i in list(curr): + if i["locktype"] == "anti_c_send": + to_return["anti_channel"] = True + elif i["locktype"] == "anti_fwd": + to_return["anti_fwd"]["user"] = to_return["anti_fwd"]["chat"] = True + elif i["locktype"] == "anti_fwd_u": + to_return["anti_fwd"]["user"] = True + elif i["locktype"] == "anti_fwd_c": + to_return["anti_fwd"]["chat"] = True + elif i["anti_links"] == "anti_links": + to_return["anti_links"] = True + elif i["locktype"] == "bot": + to_return["bot"] = True + else: + continue + return to_return def merge_u_and_c(self, chat: int, locktype: str): if locktype == "anti_fwd_u": diff --git a/Powers/database/pins_db.py b/Powers/database/pins_db.py index 6edfc137..20644a9c 100644 --- a/Powers/database/pins_db.py +++ b/Powers/database/pins_db.py @@ -62,7 +62,6 @@ def __ensure_in_db(self): "cleanlinked": False, } self.insert_one(new_data) - LOGGER.info(f"Initialized Pins Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/reporting_db.py b/Powers/database/reporting_db.py index 6009d49d..9b9f1e7d 100644 --- a/Powers/database/reporting_db.py +++ b/Powers/database/reporting_db.py @@ -45,8 +45,6 @@ def __ensure_in_db(self): new_data = {"_id": self.chat_id, "status": True, "chat_type": chat_type} self.insert_one(new_data) - LOGGER.info( - f"Initialized Language Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/rules_db.py b/Powers/database/rules_db.py index 0704cd89..4f0790cd 100644 --- a/Powers/database/rules_db.py +++ b/Powers/database/rules_db.py @@ -68,8 +68,6 @@ def __ensure_in_db(self): if not chat_data: new_data = {"_id": self.chat_id, "privrules": False, "rules": ""} self.insert_one(new_data) - LOGGER.info( - f"Initialized Language Document for chat {self.chat_id}") return new_data return chat_data diff --git a/Powers/database/users_db.py b/Powers/database/users_db.py index d9135055..4a194fe3 100644 --- a/Powers/database/users_db.py +++ b/Powers/database/users_db.py @@ -70,7 +70,6 @@ def __ensure_in_db(self): new_data = {"_id": self.user_id, "username": "", "name": "unknown_till_now"} self.insert_one(new_data) - LOGGER.info(f"Initialized User Document for {self.user_id}") return new_data return chat_data diff --git a/Powers/database/warns_db.py b/Powers/database/warns_db.py index 216705d4..c7117db7 100644 --- a/Powers/database/warns_db.py +++ b/Powers/database/warns_db.py @@ -109,8 +109,6 @@ def __ensure_in_db(self, user_id: int): "num_warns": 0, } self.insert_one(new_data) - LOGGER.info( - f"Initialized Warn Document for {user_id} in {self.chat_id}") return new_data return chat_data @@ -129,8 +127,6 @@ def __ensure_in_db(self): new_data = {"_id": self.chat_id, "warn_mode": "none", "warn_limit": 3} self.insert_one(new_data) - LOGGER.info( - f"Initialized Warn Settings Document for {self.chat_id}") return new_data return chat_data diff --git a/Powers/plugins/admin.py b/Powers/plugins/admin.py index bacf2b4a..a28b925b 100644 --- a/Powers/plugins/admin.py +++ b/Powers/plugins/admin.py @@ -11,18 +11,15 @@ RPCError, UserAdminInvalid) from pyrogram.types import ChatPrivileges, Message -from Powers import LOGGER, OWNER_ID +from Powers import DEV_USERS, LOGGER, OWNER_ID, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.approve_db import Approve from Powers.database.reporting_db import Reporting -from Powers.supports import get_support_staff from Powers.utils.caching import (ADMIN_CACHE, TEMP_ADMIN_CACHE_BLOCK, admin_cache_reload) -from Powers.utils.custom_filters import (admin_filter, command, owner_filter, - promote_filter) +from Powers.utils.custom_filters import admin_filter, command, promote_filter from Powers.utils.extract_user import extract_user from Powers.utils.parser import mention_html -from Powers.vars import Config @Gojo.on_message(command("adminlist")) @@ -67,7 +64,7 @@ async def adminlist_show(_, m: Message): adminstr += "\n\nBots:\n" adminstr += "\n".join(f"- {i}" for i in mention_bots) await m.reply_text(adminstr + "\n\n" + note) - LOGGER.info(f"Adminlist cmd use in {m.chat.id} by {m.from_user.id}") + except Exception as ef: if str(ef) == str(m.chat.id): await m.reply_text(text="Use /admincache to reload admins!") @@ -95,7 +92,11 @@ async def zombie_clean(c: Gojo, m: Message): except UserAdminInvalid: failed += 1 except FloodWait as e: - await sleep(e.x) + await sleep(e.value) + try: + await c.ban_chat_member(m.chat.id, member.user.id) + except: + pass if zombie == 0: return await wait.edit_text("Group is clean!") await wait.delete() @@ -110,7 +111,7 @@ async def reload_admins(_, m: Message): return await m.reply_text( "This command is made to be used in groups only!", ) - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if ( (m.chat.id in set(TEMP_ADMIN_CACHE_BLOCK.keys())) and (m.from_user.id not in SUPPORT_STAFF) @@ -122,7 +123,6 @@ async def reload_admins(_, m: Message): await admin_cache_reload(m, "admincache") TEMP_ADMIN_CACHE_BLOCK[m.chat.id] = "manualblock" await m.reply_text(text="Reloaded all admins in this chat!") - LOGGER.info(f"Admincache cmd use in {m.chat.id} by {m.from_user.id}") except RPCError as ef: await m.reply_text( text=f"Some error occured, report it using `/bug` \n Error: {ef}" @@ -206,9 +206,6 @@ async def fullpromote_usr(c: Gojo, m: Message): 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}'", - ) await m.reply_text( ( "{promoter} promoted {promoted} in chat {chat_title} with full rights!" @@ -311,9 +308,7 @@ async def promote_usr(c: Gojo, m: Message): 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}'", - ) + await m.reply_text( ("{promoter} promoted {promoted} in chat {chat_title}!").format( promoter=(await mention_html(m.from_user.first_name, m.from_user.id)), @@ -382,7 +377,6 @@ async def demote_usr(c: Gojo, m: Message): user_id=user_id, privileges=ChatPrivileges(can_manage_chat=False), ) - LOGGER.info(f"{m.from_user.id} demoted {user_id} in {m.chat.id}") # ----- Remove admin from cache ----- try: admin_list = ADMIN_CACHE[m.chat.id] @@ -426,7 +420,7 @@ async def demote_usr(c: Gojo, m: Message): async def get_invitelink(c: Gojo, m: Message): # Bypass the bot devs, sudos and owner - DEV_LEVEL = get_support_staff("dev_level") + DEV_LEVEL = DEV_USERS if m.from_user.id not in DEV_LEVEL: user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_invite_users and user.status != CMS.OWNER: @@ -438,7 +432,6 @@ async def get_invitelink(c: Gojo, m: Message): text=f"Invite Link for Chat {m.chat.id}: {link}", disable_web_page_preview=True, ) - LOGGER.info(f"{m.from_user.id} exported invite link in {m.chat.id}") except ChatAdminRequired: await m.reply_text(text="I'm not admin or I don't have rights.") except ChatAdminInviteRequired: diff --git a/Powers/plugins/antispam.py b/Powers/plugins/antispam.py index a5027070..eb278055 100644 --- a/Powers/plugins/antispam.py +++ b/Powers/plugins/antispam.py @@ -5,16 +5,15 @@ from pyrogram.errors import MessageTooLong, PeerIdInvalid, UserIsBlocked from pyrogram.types import Message -from Powers import LOGGER, MESSAGE_DUMP, SUPPORT_GROUP, TIME_ZONE +from Powers import (DEV_USERS, LOGGER, MESSAGE_DUMP, SUDO_USERS, SUPPORT_GROUP, + WHITELIST_USERS) from Powers.bot_class import Gojo from Powers.database.antispam_db import GBan from Powers.database.users_db import Users -from Powers.supports import get_support_staff 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.parser import mention_html -from Powers.vars import Config # Initialize db = GBan() @@ -38,7 +37,7 @@ async def gban(c: Gojo, m: Message): else: gban_reason = m.text.split(None, 2)[2] - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text(text="This user is part of my Support!, Can't ban our own!") @@ -61,7 +60,6 @@ async def gban(c: Gojo, m: Message): f"Added {user_first_name} to GBan List. \n They will now be banned in all groups where I'm admin!" ) ) - LOGGER.info(f"{m.from_user.id} gbanned {user_id} from {m.chat.id}") date = datetime.utcnow().strftime("%H:%M - %d-%m-%Y") log_msg = f"#GBAN \n Originated from: {m.chat.id} \n Admin: {await mention_html(m.from_user.first_name, m.from_user.id)} \n Gbanned User: {await mention_html(user_first_name, user_id)} \n Gbanned User ID: {user_id} \\ nEvent Stamp: {date}" await c.send_message(MESSAGE_DUMP, log_msg) @@ -71,6 +69,10 @@ async def gban(c: Gojo, m: Message): user_id, f"You have been added to my global ban list! \n Reason: {gban_reason} \n Appeal Chat: @{SUPPORT_GROUP}", ) + try: + await c.ban_chat_member(m.chat.id, user_id) + except Exception as e: + await m.reply_text(f"Failed to ban this user\n{e}") except UserIsBlocked: LOGGER.error("Could not send PM Message, user blocked bot") except PeerIdInvalid: @@ -93,7 +95,7 @@ async def ungban(c: Gojo, m: Message): user_id, user_first_name, _ = await extract_user(c, m) - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text(text="This user is part of my Support!, Can't ban our own!") @@ -110,7 +112,6 @@ async def ungban(c: Gojo, m: Message): db.remove_gban(user_id) await m.reply_text(text=f"Removed {user_first_name} from Global Ban List.") time = ((datetime.utcnow().strftime("%H:%M - %d-%m-%Y")),) - LOGGER.info(f"{m.from_user.id} ungbanned {user_id} from {m.chat.id}") log_msg = f"""#UNGBAN Originated from: {m.chat.id} Admin: {(await mention_html(m.from_user.first_name, m.from_user.id))} @@ -140,7 +141,6 @@ async def gban_count(_, m: Message): await m.reply_text( text=f"Number of people gbanned: {(db.count_gbans())}" ) - LOGGER.info(f"{m.from_user.id} counting gbans in {m.chat.id}") return @@ -170,7 +170,6 @@ async def gban_list(_, m: Message): document=f, caption="Here are all the globally banned geys!\n\n" ) - LOGGER.info(f"{m.from_user.id} exported gbanlist in {m.chat.id}") return diff --git a/Powers/plugins/approve.py b/Powers/plugins/approve.py index 9e9c667e..f84822f4 100644 --- a/Powers/plugins/approve.py +++ b/Powers/plugins/approve.py @@ -51,7 +51,6 @@ async def approve_user(c: Gojo, m: Message): ) return db.add_approve(user_id, user_first_name) - LOGGER.info(f"{user_id} approved by {m.from_user.id} in {m.chat.id}") # Allow all permissions try: @@ -90,7 +89,6 @@ async def disapprove_user(c: Gojo, m: Message): except UserNotParticipant: if already_approved: # If user is approved and not in chat, unapprove them. db.remove_approve(user_id) - LOGGER.info(f"{user_id} disapproved in {m.chat.id} as UserNotParticipant") await m.reply_text("This user is not in this chat, unapproved them.") return except RPCError as ef: @@ -110,7 +108,6 @@ async def disapprove_user(c: Gojo, m: Message): return db.remove_approve(user_id) - LOGGER.info(f"{user_id} disapproved by {m.from_user.id} in {m.chat.id}") # Set permission same as of current user by fetching them from chat! await m.chat.restrict_member( @@ -147,7 +144,6 @@ async def check_approved(_, m: Message): pass msg += f"- `{user_id}`: {user_name}\n" await m.reply_text(msg) - LOGGER.info(f"{m.from_user.id} checking approved users in {m.chat.id}") return @@ -160,7 +156,6 @@ async def check_approval(c: Gojo, m: Message): except Exception: return check_approve = db.check_approve(user_id) - LOGGER.info(f"{m.from_user.id} checking approval of {user_id} in {m.chat.id}") if not user_id: await m.reply_text( @@ -218,7 +213,6 @@ async def unapproveall_callback(_, q: CallbackQuery): permissions=q.message.chat.permissions, ) await q.message.delete() - LOGGER.info(f"{user_id} disapproved all users in {q.message.chat.id}") await q.answer("Disapproved all users!", show_alert=True) return diff --git a/Powers/plugins/auto_join.py b/Powers/plugins/auto_join.py index f7cc8fe5..c2e807d0 100644 --- a/Powers/plugins/auto_join.py +++ b/Powers/plugins/auto_join.py @@ -7,10 +7,9 @@ from pyrogram.types import InlineKeyboardMarkup as ikm from pyrogram.types import Message -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.autojoin_db import AUTOJOIN -from Powers.supports import get_support_staff from Powers.utils.custom_filters import admin_filter, auto_join_filter, command @@ -96,7 +95,7 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): chat = j.chat.id aj = AUTOJOIN() join_type = aj.get_autojoin(chat) - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if not join_type: return diff --git a/Powers/plugins/bans.py b/Powers/plugins/bans.py index f7efb9c1..69b035b8 100644 --- a/Powers/plugins/bans.py +++ b/Powers/plugins/bans.py @@ -9,16 +9,15 @@ InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID +from Powers import (DEV_USERS, LOGGER, MESSAGE_DUMP, OWNER_ID, SUDO_USERS, + WHITELIST_USERS) from Powers.bot_class import Gojo -from Powers.supports import get_support_staff from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.utils.custom_filters import command, restrict_filter from Powers.utils.extract_user import extract_user from Powers.utils.extras import BAN_GIFS, KICK_GIFS from Powers.utils.parser import mention_html from Powers.utils.string import extract_time -from Powers.vars import Config @Gojo.on_message(command("tban") & restrict_filter) @@ -39,15 +38,13 @@ async def tban_usr(c: Gojo, m: Message): await m.reply_text("WTF?? Why would I ban myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() r_id = m.reply_to_message.id if m.reply_to_message else m.id @@ -86,7 +83,6 @@ async def tban_usr(c: Gojo, m: Message): admin = await mention_html(m.from_user.first_name, m.from_user.id) banned = await mention_html(user_first_name, user_id) chat_title = m.chat.title - LOGGER.info(f"{m.from_user.id} tbanned {user_id} in {m.chat.id}") await m.chat.ban_member( user_id, until_date=bantime) @@ -161,7 +157,7 @@ async def stban_usr(c: Gojo, m: Message): await m.reply_text(text="I can't ban nothing!") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) try: user_id, _, _ = await extract_user(c, m) @@ -179,9 +175,7 @@ async def stban_usr(c: Gojo, m: Message): await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() if m.reply_to_message and len(m.text.split()) >= 2: @@ -215,7 +209,6 @@ async def stban_usr(c: Gojo, m: Message): await m.stop_propagation() try: - LOGGER.info(f"{m.from_user.id} stbanned {user_id} in {m.chat.id}") await m.chat.ban_member(user_id, until_date=bantime) await m.delete() if m.reply_to_message: @@ -269,13 +262,11 @@ async def dtban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text(text="I am not going to ban one of my support staff") - LOGGER.info( - f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() if m.reply_to_message and len(m.text.split()) >= 2: @@ -312,7 +303,6 @@ async def dtban_usr(c: Gojo, m: Message): admin = await mention_html(m.from_user.first_name, m.from_user.id) banned = await mention_html(user_first_name, user_id) chat_title = m.chat.title - LOGGER.info(f"{m.from_user.id} dtbanned {user_id} in {m.chat.id}") await m.chat.ban_member(user_id, until_date=bantime) await m.reply_to_message.delete() txt = f"{admin} banned {banned} in {chat_title}!" @@ -399,15 +389,13 @@ async def kick_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to kick {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() try: @@ -423,7 +411,6 @@ async def kick_usr(c: Gojo, m: Message): admin = await mention_html(m.from_user.first_name, m.from_user.id) kicked = await mention_html(user_first_name, user_id) chat_title = m.chat.title - LOGGER.info(f"{m.from_user.id} kicked {user_id} in {m.chat.id}") await m.chat.ban_member(user_id) txt = f"{admin} kicked {kicked} in {chat_title}!" if reason: @@ -490,15 +477,13 @@ async def skick_usr(c: Gojo, m: Message): await m.reply_text("Nuh Hu, why would I kick myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to skick {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() try: @@ -511,7 +496,6 @@ async def skick_usr(c: Gojo, m: Message): await m.stop_propagation() try: - LOGGER.info(f"{m.from_user.id} skicked {user_id} in {m.chat.id}") await m.chat.ban_member(user_id) await m.delete() if m.reply_to_message: @@ -564,15 +548,13 @@ async def dkick_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I kick myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to dkick {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.stop_propagation() try: @@ -585,7 +567,6 @@ async def dkick_usr(c: Gojo, m: Message): await m.stop_propagation() try: - LOGGER.info(f"{m.from_user.id} dkicked {user_id} in {m.chat.id}") await m.reply_to_message.delete() await m.chat.ban_member(user_id) admin = await mention_html(m.from_user.first_name, m.from_user.id) @@ -715,15 +696,12 @@ async def sban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to sban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.stop_propagation() try: @@ -736,7 +714,6 @@ async def sban_usr(c: Gojo, m: Message): await m.stop_propagation() try: - LOGGER.info(f"{m.from_user.id} sbanned {user_id} in {m.chat.id}") await m.chat.ban_member(user_id) await m.delete() if m.reply_to_message: @@ -796,15 +773,12 @@ async def dban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to dban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.stop_propagation() try: @@ -821,7 +795,6 @@ async def dban_usr(c: Gojo, m: Message): reason = m.text.split(None, 1)[1] try: - LOGGER.info(f"{m.from_user.id} dbanned {user_id} in {m.chat.id}") await m.reply_to_message.delete() await m.chat.ban_member(user_id) txt = f"{m.from_user.mention} banned {m.reply_to_message.from_user.mention} in {m.chat.title}!" @@ -897,15 +870,12 @@ async def ban_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.stop_propagation() try: @@ -928,7 +898,6 @@ async def ban_usr(c: Gojo, m: Message): reason = m.text.split(None, 2)[2] try: - LOGGER.info(f"{m.from_user.id} banned {user_id} in {m.chat.id}") await m.chat.ban_member(user_id) banned = await mention_html(user_first_name, user_id) txt = f"{m.from_user.mention} banned {banned} in {m.chat.title}!" @@ -1024,7 +993,6 @@ async def kickme(c: Gojo, m: Message): 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: diff --git a/Powers/plugins/birthday.py b/Powers/plugins/birthday.py index e660eb9a..ddaccb54 100644 --- a/Powers/plugins/birthday.py +++ b/Powers/plugins/birthday.py @@ -125,7 +125,7 @@ async def who_is_next(c: Gojo, m: Message): if m.chat.type == ChatType.PRIVATE: await m.reply_text("Use it in group") return - curr = datetime.now(TIME_ZONE).date() + curr = datetime.now().date() xx = await m.reply_text("📆") users = [] if blist: @@ -173,7 +173,7 @@ async def cant_recall_it(c: Gojo, m: Message): await m.reply_text(f"Got an error\n{e}") return - curr = datetime.now(TIME_ZONE).date() + curr = datetime.now().date() u_dob = give_date(result["dob"]) formatted = str(u_dob.strftime('%d' + '%B %Y'))[2:-5] day = int(result["dob"].split('/')[0]) @@ -182,7 +182,7 @@ async def cant_recall_it(c: Gojo, m: Message): if (u_dob.day,u_dob.month) < (curr.day,curr.month): next_b = date(curr.year + 1, u_dob.month, u_dob.day) days_left = (next_b - curr).days - txt = f"{men} 's birthday is passed 🫤\nDays left until next one {days_left}" + txt = f"{men} 's birthday is passed 🫤\nDays left until next one {abs(days_left)}" txt += f"\nBirthday on: {bday_on}" txt += f"\n\nDate of birth: {result['dob']}" elif (u_dob.day,u_dob.month) == (curr.day,curr.month): @@ -190,7 +190,7 @@ async def cant_recall_it(c: Gojo, m: Message): 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}" + txt = f"User's birthday is coming🥳\nDays left: {abs(days_left)}" txt += f"\nBirthday on: {bday_on}" txt += f"\n\nDate of birth: {result['dob']}" txt+= "\n\n**NOTE**:\nDOB may be wrong if user haven't entered his/her birth year" @@ -218,7 +218,7 @@ async def chat_birthday_settings(c: Gojo, m: Message): 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_")) +@Gojo.on_callback_query(filters.regex(r"^switchh_(yes|no)$")) 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) @@ -227,11 +227,11 @@ async def switch_on_off(c:Gojo, q: CallbackQuery): return data = q.data.split("_")[1] chats = q.message.chat.id - xXx = {"chat_id":chats} + query = {"chat_id":chats} if data == "yes": - bday_cinfo.delete_one(xXx) + bday_cinfo.delete_one(query) elif data == "no": - bday_cinfo.insert_one(xXx) + bday_cinfo.insert_one(query) await q.edit_message_text(f"Done! I will {'wish' if data == 'yes' else 'not wish'}",reply_markup=IKM([[IKB("Close", "f_close")]])) return diff --git a/Powers/plugins/blacklist.py b/Powers/plugins/blacklist.py index 92030964..768a5e4b 100644 --- a/Powers/plugins/blacklist.py +++ b/Powers/plugins/blacklist.py @@ -15,8 +15,6 @@ async def view_blacklist(_, m: Message): db = Blacklist(m.chat.id) - LOGGER.info(f"{m.from_user.id} checking blacklists in {m.chat.id}") - chat_title = m.chat.title blacklists_chat = f"Current Blacklisted words in {chat_title}:\n\n" all_blacklisted = db.get_blacklists() @@ -58,7 +56,6 @@ async def add_blacklist(_, m: Message): ", ".join([f"{i}" for i in bl_words]) + " already added in blacklist, skipped them!" ) - LOGGER.info(f"{m.from_user.id} added new blacklists ({bl_words}) in {m.chat.id}") trigger = ", ".join(f"{i}" for i in bl_words) await m.reply_text( text=f"Added {trigger} in blacklist words!" @@ -116,7 +113,6 @@ async def rm_blacklist(_, m: Message): "Could not find " + ", ".join(f"{i}" for i in non_found_words) ) + " in blcklisted words, skipped them." - LOGGER.info(f"{m.from_user.id} removed blacklists ({bl_words}) in {m.chat.id}") bl_words = ", ".join(f"{i}" for i in bl_words) await m.reply_text( text=f"Removed {bl_words} from blacklist words!" @@ -145,13 +141,9 @@ async def set_bl_action(_, m: Message): return db.set_action(action) - LOGGER.info( - f"{m.from_user.id} set blacklist action to '{action}' in {m.chat.id}", - ) await m.reply_text(text=f"Set action for blacklist for this to {action}") elif len(m.text.split()) == 1: action = db.get_action() - LOGGER.info(f"{m.from_user.id} checking blacklist action in {m.chat.id}") await m.reply_text( text=f"""The current action for blacklists in this chat is {action} All blacklist modes delete the message containing blacklist word.""" @@ -201,7 +193,6 @@ async def rm_allbl_callback(_, q: CallbackQuery): return db.rm_all_blacklist() await q.message.delete() - LOGGER.info(f"{user_id} removed all blacklists in {q.message.chat.id}") await q.answer("Cleared all Blacklists!", show_alert=True) return diff --git a/Powers/plugins/captcha.py b/Powers/plugins/captcha.py index a9ce22de..b57065c1 100644 --- a/Powers/plugins/captcha.py +++ b/Powers/plugins/captcha.py @@ -8,10 +8,9 @@ from pyrogram.types import InlineKeyboardMarkup as ikm from pyrogram.types import Message -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.captcha_db import CAPTCHA, CAPTCHA_DATA -from Powers.supports import get_support_staff from Powers.utils.captcha_helper import (genrator, get_image_captcha, get_qr_captcha) from Powers.utils.custom_filters import admin_filter, command @@ -138,7 +137,7 @@ async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): captcha = CAPTCHA() cap_data = CAPTCHA_DATA() - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user in SUPPORT_STAFF: return diff --git a/Powers/plugins/chat_blacklist.py b/Powers/plugins/chat_blacklist.py index 84bedbea..16960625 100644 --- a/Powers/plugins/chat_blacklist.py +++ b/Powers/plugins/chat_blacklist.py @@ -18,7 +18,6 @@ async def blacklist_chat(c: Gojo, m: Message): if len(m.text.split()) >= 2: chat_ids = m.text.split()[1:] replymsg = await m.reply_text(f"Adding {len(chat_ids)} chats to blacklist") - LOGGER.info(f"{m.from_user.id} blacklisted {chat_ids} groups for bot") for chat in chat_ids: try: get_chat = await c.get_chat(chat) @@ -51,7 +50,6 @@ async def unblacklist_chat(c: Gojo, m: Message): if len(m.text.split()) >= 2: chat_ids = m.text.split()[1:] replymsg = await m.reply_text(f"Removing {len(chat_ids)} chats from blacklist") - LOGGER.info(f"{m.from_user.id} removed blacklisted {chat_ids} groups for bot") bl_chats = db.list_all_chats() for chat in chat_ids: try: @@ -89,7 +87,6 @@ async def unblacklist_chat(c: Gojo, m: Message): ) async def list_blacklist_chats(_, m: Message): bl_chats = db.list_all_chats() - LOGGER.info(f"{m.from_user.id} checking group blacklists in {m.chat.id}") if bl_chats: txt = ( ( diff --git a/Powers/plugins/clean_db.py b/Powers/plugins/clean_db.py index 7dc77a2c..23a9d4ee 100644 --- a/Powers/plugins/clean_db.py +++ b/Powers/plugins/clean_db.py @@ -18,7 +18,6 @@ from Powers.database.reporting_db import Reporting # from Powers.database.users_db import Users from Powers.database.warns_db import Warns, WarnSettings -from Powers.vars import Config async def clean_my_db(c: Gojo, is_cmd=False, id=None): diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py index 010cf386..c37e2dfe 100644 --- a/Powers/plugins/dev.py +++ b/Powers/plugins/dev.py @@ -16,15 +16,15 @@ from pyrogram.types import InlineKeyboardMarkup as IKM from pyrogram.types import Message -from Powers import (BOT_TOKEN, LOG_DATETIME, LOGFILE, LOGGER, MESSAGE_DUMP, - OWNER_ID, UPTIME) +from Powers import (BOT_TOKEN, DEV_USERS, LOG_DATETIME, LOGFILE, LOGGER, + MESSAGE_DUMP, OWNER_ID, SUDO_USERS, UPTIME, + WHITELIST_USERS) from Powers.bot_class import Gojo from Powers.database import MongoDB from Powers.database.chats_db import Chats from Powers.database.support_db import SUPPORTS from Powers.database.users_db import Users from Powers.plugins.scheduled_jobs import clean_my_db -from Powers.supports import get_support_staff 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 @@ -80,6 +80,12 @@ async def add_support(c: Gojo, m:Message): return else: support.insert_support_user(userr,to) + if to == "dev": + DEV_USERS.add(userr) + elif to == "sudo": + SUDO_USERS.add(userr) + else: + WHITELIST_USERS.add(userr) await m.reply_text(f"This user is now a {to} user") return can_do = can_change_type(curr_user,to) @@ -196,6 +202,9 @@ async def rm_support(c: Gojo, m: Message): can_user = can_change_type(curr_user,to_user) if m.from_user.id == int(OWNER_ID) or can_user: support.delete_support_user(curr) + DEV_USERS.discard(curr) + SUDO_USERS.discard(curr) + WHITELIST_USERS.discard(curr) await m.reply_text("Done! User now no longer belongs to the support staff") else: await m.reply_text("Sorry you can't do that...") @@ -203,7 +212,6 @@ async def rm_support(c: Gojo, m: Message): @Gojo.on_message(command("ping", sudo_cmd=True)) async def ping(_, m: Message): - LOGGER.info(f"{m.from_user.id} used ping cmd in {m.chat.id}") start = time() replymsg = await m.reply_text(text="Pinging...", quote=True) delta_ping = time() - start @@ -386,6 +394,10 @@ async def evaluate_code(c: Gojo, m: Message): MESSAGE_DUMP, f"@{m.from_user.username} TREID TO FETCH ENV OF BOT \n userid = {m.from_user.id}", ) + final_output = f"**EVAL**: ```python\n{cmd}```\n\nOUTPUT:\n```powershell\n{evaluation}``` \n" + await sm.edit(final_output) + return + for j in HARMFUL: if j in evaluation.split() or j in cmd: if m.from_user.id != OWNER_ID: @@ -393,6 +405,9 @@ async def evaluate_code(c: Gojo, m: Message): await c.send_message( MESSAGE_DUMP, f"@{m.from_user.username} TREID TO FETCH ENV OF BOT \n userid = {m.from_user.id}") + final_output = f"**EVAL**: ```python\n{cmd}```\n\nOUTPUT:\n```powershell\n{evaluation}``` \n" + await sm.edit(final_output) + return for i in evaluation.split(): for j in i.split("="): if j and j[0] in HARMFUL: @@ -402,10 +417,12 @@ async def evaluate_code(c: Gojo, m: Message): MESSAGE_DUMP, f"@{m.from_user.username} TREID TO FETCH ENV OF BOT \n userid = {m.from_user.id}" ) - + final_output = f"**EVAL**: ```python\n{cmd}```\n\nOUTPUT:\n```powershell\n{evaluation}``` \n" + await sm.edit(final_output) + return try: - final_output = f"**EVAL**: ```python\n{cmd}```\n\nOUTPUT:\n```python\n{evaluation}``` \n" + final_output = f"**EVAL**: ```python\n{cmd}```\n\nOUTPUT:\n```powershell\n{evaluation}``` \n" await sm.edit(final_output) except MessageTooLong: final_output = f"EVAL: {cmd}\n\nOUTPUT:\n{evaluation} \n" diff --git a/Powers/plugins/disable.py b/Powers/plugins/disable.py index e2334947..a616edeb 100644 --- a/Powers/plugins/disable.py +++ b/Powers/plugins/disable.py @@ -24,7 +24,6 @@ async def disableit(_, m: Message): db = Disabling(m.chat.id) disable_list = db.get_disabled() - LOGGER.info(f"{m.from_user.id} used disabled cmd in {m.chat.id}") if str(m.text.split(None, 1)[1]) in disable_list: return await m.reply_text("It's already disabled!") @@ -48,8 +47,6 @@ async def set_dsbl_action(_, m: Message): cur = True args = m.text.split(" ", 1) - LOGGER.info(f"{m.from_user.id} disabledel used in {m.chat.id}") - if len(args) >= 2: if args[1].lower() == "on": db.set_action("del") @@ -73,7 +70,6 @@ async def enableit(_, m: Message): if str(m.text.split(None, 1)[1]) not in disable_list: return await m.reply_text("It's not disabled!") db.remove_disabled((str(m.text.split(None, 1)[1])).lower()) - LOGGER.info(f"{m.from_user.id} enabled something in {m.chat.id}") return await m.reply_text(f"Enabled {m.text.split(None, 1)[1]}!") @@ -86,7 +82,6 @@ async def disabling(_, m: Message): ) tes = "List of commnds that can be disabled:\n" tes += "\n".join(f" • {escape(i)}" for i in disable_cmd_keys) - LOGGER.info(f"{m.from_user.id} checked disableable {m.chat.id}") return await m.reply_text(tes) @@ -99,7 +94,6 @@ async def disabled(_, m: Message): return tex = "Disabled commands:\n" tex += "\n".join(f" • {escape(i)}" for i in disable_list) - LOGGER.info(f"{m.from_user.id} checked disabled {m.chat.id}") return await m.reply_text(tex) @@ -145,7 +139,6 @@ async def enablealll(_, q: CallbackQuery): return db = Disabling(q.message.chat.id) db.rm_all_disabled() - LOGGER.info(f"{user_id} enabled all in {q.message.chat.id}") await q.message.edit_text("Enabled all!", show_alert=True) return diff --git a/Powers/plugins/filters.py b/Powers/plugins/filters.py index 34e7f93f..222dbc3a 100644 --- a/Powers/plugins/filters.py +++ b/Powers/plugins/filters.py @@ -25,8 +25,6 @@ @Gojo.on_message(command("filters") & filters.group & ~filters.bot) async def view_filters(_, m: Message): - LOGGER.info(f"{m.from_user.id} checking filters in {m.chat.id}") - filters_chat = f"Filters in {m.chat.title}:\n" all_filters = db.get_all_filters(m.chat.id) actual_filters = [j for i in all_filters for j in i.split("|")] @@ -66,9 +64,9 @@ async def add_filter(_, m: Message): extracted = await split_quotes(args[1]) keyword = extracted[0].lower() - for k in keyword.split("|"): - if k in actual_filters: - return await m.reply_text(f"Filter {k} already exists!") + # for k in keyword.split("|"): + # if k in actual_filters: + # return await m.reply_text(f"Filter {k} already exists!") if not keyword: return await m.reply_text( @@ -98,7 +96,6 @@ async def add_filter(_, m: Message): ) add = db.save_filter(m.chat.id, keyword, teks, msgtype, file_id) - LOGGER.info(f"{m.from_user.id} added new filter ({keyword}) in {m.chat.id}") if add: await m.reply_text( f"Saved filter for '{', '.join(keyword.split('|'))}' in {m.chat.title}!", @@ -122,7 +119,6 @@ async def stop_filter(_, m: Message): for keyword in act_filters: if keyword == m.text.split(None, 1)[1].lower(): db.rm_filter(m.chat.id, m.text.split(None, 1)[1].lower()) - LOGGER.info(f"{m.from_user.id} removed filter ({keyword}) in {m.chat.id}") await m.reply_text( f"Okay, I'll stop replying to that filter and it's aliases in {m.chat.title}.", ) @@ -171,7 +167,6 @@ async def rm_allfilters_callback(_, q: CallbackQuery): return db.rm_all_filters(q.message.chat.id) await q.message.edit_text(f"Cleared all filters for {q.message.chat.title}") - LOGGER.info(f"{user_id} removed all filter from {q.message.chat.id}") await q.answer("Cleared all Filters!", show_alert=True) return diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index dd7c220f..51effc8f 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -11,13 +11,11 @@ InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.flood_db import Floods -from Powers.supports import get_support_staff from Powers.utils.custom_filters import admin_filter, command, flood_filter from Powers.utils.extras import BAN_GIFS, KICK_GIFS, MUTE_GIFS -from Powers.vars import Config on_key = ["on", "start", "disable"] off_key = ["off", "end", "enable", "stop"] @@ -230,7 +228,7 @@ async def flood_set(c: Gojo, m: Message): @Gojo.on_callback_query(filters.regex("^f_")) async def callbacks(c: Gojo, q: CallbackQuery): - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) data = q.data if data == "f_close": await q.answer("Closed") @@ -352,7 +350,7 @@ async def reverse_callbacks(c: Gojo, q: CallbackQuery): data = q.data.split("_") action = data[1] user_id = int(q.data.split("=")[1]) - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if not q.from_user: return q.answer("Looks like you are not an user 👀") if action == "ban": @@ -572,13 +570,13 @@ async def flood_watcher(c: Gojo, m: Message): elif action == "kick": try: - await m.chat.ban_member(u_id) + await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=10)) txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming" await m.reply_animation( animation=str(choice(KICK_GIFS)), caption=txt, ) - await m.chat.unban_member(u_id) + await m.chat.unban_member(m.from_user.id) dic[c_id][u_id][1].clear() dic[c_id][u_id][0].clear() return diff --git a/Powers/plugins/formatting.py b/Powers/plugins/formatting.py index d727370e..2d4bcddf 100644 --- a/Powers/plugins/formatting.py +++ b/Powers/plugins/formatting.py @@ -35,7 +35,6 @@ async def markdownhelp(_, m: Message): quote=True, reply_markup=(await gen_formatting_kb(m)), ) - LOGGER.info(f"{m.from_user.id} used cmd '{m.command}' in {m.chat.id}") return diff --git a/Powers/plugins/fun.py b/Powers/plugins/fun.py index 42e56f58..303aab62 100644 --- a/Powers/plugins/fun.py +++ b/Powers/plugins/fun.py @@ -5,15 +5,13 @@ from pyrogram.errors import MessageTooLong from pyrogram.types import Message -from Powers import LOGGER +from Powers import DEV_USERS from Powers.bot_class import Gojo -from Powers.supports import get_support_staff from Powers.utils import extras from Powers.utils.custom_filters import command from Powers.utils.extras import NOWYES as NO from Powers.utils.extras import YESWNO as YES -DEV_USERS = get_support_staff("dev") @Gojo.on_message(command("shout")) async def fun_shout(_, m: Message): @@ -33,7 +31,6 @@ async def fun_shout(_, m: Message): result = "".join(result) msg = "```\n" + result + "```" await m.reply_text(msg, parse_mode=enums.ParseMode.MARKDOWN) - LOGGER.info(f"{m.from_user.id} shouted in {m.chat.id}") return except MessageTooLong as e: await m.reply_text(f"Error: {e}") @@ -43,7 +40,6 @@ async def fun_shout(_, m: Message): @Gojo.on_message(command("runs")) async def fun_run(_, m: Message): await m.reply_text(choice(extras.RUN_STRINGS)) - LOGGER.info(f"{m.from_user.id} runed in {m.chat.id}") return @@ -79,7 +75,6 @@ async def fun_slap(c: Gojo, m: Message): reply = temp.format(user1=user1, user2=user2, item=item, hits=hit, throws=throw) await reply_text(reply) - LOGGER.info(f"{m.from_user.id} slaped in {m.chat.id}") return @@ -87,7 +82,6 @@ async def fun_slap(c: Gojo, m: Message): async def fun_roll(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(range(1, 7))) - LOGGER.info(f"{m.from_user.id} roll in {m.chat.id}") return @@ -95,7 +89,6 @@ async def fun_roll(_, m: Message): async def fun_toss(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(extras.TOSS)) - LOGGER.info(f"{m.from_user.id} tossed in {m.chat.id}") return @@ -108,13 +101,9 @@ async def insult(c: Gojo, m: Message): user_first_name = m.reply_to_message.from_user.first_name if user_id in DEV_USERS: await m.reply_text("Sorry! I can't insult my devs....") - return LOGGER.info( - f"{m.from_user.id} tried to insult {user_first_name} in {m.chat.id}" - ) else: Insult_omp = choice(extras.INSULT_STRINGS) await m.reply_to_message.reply_text(Insult_omp) - LOGGER.info(f"{m.from_user.id} insulted {user_first_name} in {m.chat.id}") @Gojo.on_message(command("yes")) @@ -122,7 +111,6 @@ async def yesw(c: Gojo, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text rtext = YES[0] await reply_text(rtext) - LOGGER.info(f"{m.from_user.id} said YES or may be NO in {m.chat.id}") return @@ -131,7 +119,6 @@ async def now(c: Gojo, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text rtext = NO[0] await reply_text(rtext) - LOGGER.info(f"{m.from_user.id} said NO or may be YES in {m.chat.id}") return @@ -139,7 +126,6 @@ async def now(c: Gojo, m: Message): async def fun_shrug(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(r"¯\_(ツ)_/¯") - LOGGER.info(f"{m.from_user.id} shruged in {m.chat.id}") return @@ -149,7 +135,6 @@ async def fun_bluetext(_, m: Message): await reply_text( "|| /BLUE /TEXT\n/MUST /CLICK\n/I /AM /A /STUPID /ANIMAL /THAT /IS /ATTRACTED /TO /COLORS ||", ) - LOGGER.info(f"{m.from_user.id} bluetexted in {m.chat.id}") return @@ -157,7 +142,6 @@ async def fun_bluetext(_, m: Message): async def fun_decide(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(extras.DECIDE)) - LOGGER.info(f"{m.from_user.id} decided in {m.chat.id}") return @@ -165,7 +149,6 @@ async def fun_decide(_, m: Message): async def fun_table(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(extras.REACTIONS)) - LOGGER.info(f"{m.from_user.id} reacted in {m.chat.id}") return @@ -199,7 +182,6 @@ async def weebify(_, m: Message): text=f"""Weebified String: {string}""" ) - LOGGER.info(f"{m.from_user.id} weebified '{args}' in {m.chat.id}") return diff --git a/Powers/plugins/greetings.py b/Powers/plugins/greetings.py index 169f1268..e7207c2b 100644 --- a/Powers/plugins/greetings.py +++ b/Powers/plugins/greetings.py @@ -7,11 +7,10 @@ from pyrogram.errors import ChannelPrivate, ChatAdminRequired, RPCError from pyrogram.types import ChatMemberUpdated, Message -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER from Powers.bot_class import Gojo from Powers.database.antispam_db import GBan from Powers.database.greetings_db import Greetings -from Powers.supports import get_support_staff from Powers.utils.cmd_senders import send_cmd from Powers.utils.custom_filters import admin_filter, bot_admin_filter, command from Powers.utils.kbhelpers import ikb @@ -19,13 +18,10 @@ from Powers.utils.parser import escape_markdown, mention_html from Powers.utils.string import (build_keyboard, escape_invalid_curly_brackets, parse_button) -from Powers.vars import Config # Initialize gdb = GBan() -DEV_USERS = get_support_staff("dev") - ChatType = enums.ChatType @@ -243,11 +239,7 @@ async def cleannnnn(_, m: Message): @Gojo.on_chat_member_updated(filters.group, group=69) async def member_has_joined(c: Gojo, member: ChatMemberUpdated): - if ( - member.new_chat_member - and member.new_chat_member.status not in {CMS.BANNED, CMS.LEFT, CMS.RESTRICTED} - and not member.old_chat_member - ): + if member.new_chat_member.status not in {CMS.BANNED, CMS.LEFT, CMS.RESTRICTED}: pass else: return @@ -263,7 +255,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): await c.send_animation( chat_id=member.chat.id, animation="./extras/william.gif", - caption="😳 My **DEV** has also joined the chat!", + caption=f"😳 My **DEV** {user.mention} has also joined the chat!", ) return if banned_users: @@ -345,11 +337,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): @Gojo.on_chat_member_updated(filters.group, group=99) async def member_has_left(c: Gojo, member: ChatMemberUpdated): - if ( - not member.new_chat_member - and member.old_chat_member.status not in {CMS.BANNED, CMS.RESTRICTED} - and member.old_chat_member - ): + if member.old_chat_member.status == CMS.LEFT: pass else: return @@ -395,7 +383,7 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): if user.id in DEV_USERS: await c.send_message( member.chat.id, - "Will miss you master :(", + f"Will miss you my master {user.mention} :(", ) return if not teks: @@ -419,6 +407,8 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): if ooo: db.set_cleangoodbye_id(int(ooo.id)) return + except ChannelPrivate: + pass except RPCError as e: LOGGER.error(e) LOGGER.error(format_exc(e)) @@ -551,8 +541,6 @@ async def goodbye(c: Gojo, m: Message): reply_markup=button, ) return - return - __PLUGIN__ = "greetings" __alt_name__ = ["welcome", "goodbye", "cleanservice"] diff --git a/Powers/plugins/info.py b/Powers/plugins/info.py index 7e71fea7..c3698ef5 100644 --- a/Powers/plugins/info.py +++ b/Powers/plugins/info.py @@ -9,13 +9,11 @@ from pyrogram.raw.functions.users import GetFullUser from pyrogram.types import Message -from Powers import LOGGER, OWNER_ID +from Powers import DEV_USERS, LOGGER, OWNER_ID, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.antispam_db import GBan -from Powers.supports import get_support_staff from Powers.utils.custom_filters import command from Powers.utils.extract_user import extract_user -from Powers.vars import Config gban_db = GBan() @@ -83,10 +81,7 @@ async def user_info(c: Gojo, user, already=False): about = ll.full_user.about except Exception: pass - SUPPORT_STAFF = get_support_staff() - DEV_USERS = get_support_staff("dev") - SUDO_USERS = get_support_staff("sudo") - WHITELIST_USERS = get_support_staff("whitelist") + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) username = user.username first_name = user.first_name last_name = user.last_name @@ -246,8 +241,12 @@ async def info_func(c: Gojo, message: Message): if message.reply_to_message and message.reply_to_message.sender_chat: await message.reply_text("This is not a user, but rather a channel. Use `/chinfo` to fetch its information.") return - user, _, user_name = await extract_user(c, message) - + try: + user, _, user_name = await extract_user(c, message) + except: + await message.reply_text("Got Some errors failed to fetch user info") + LOGGER.error(e) + LOGGER.error(format_exc) if not user: await message.reply_text("Can't find user to fetch info!") @@ -285,6 +284,10 @@ async def info_func(c: Gojo, message: Message): LOGGER.error(rpc) LOGGER.error(format_exc()) except Exception as e: + if e == "User not found ! Error: 'InputPeerChannel' object has no attribute 'user_id'": + await m.reply_text("Looks like you are trying to fetch info of a chat not an user. In that case please use /chinfo") + return + await message.reply_text(text=e) LOGGER.error(e) LOGGER.error(format_exc()) diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index c4fedbc5..c039dbe5 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -8,15 +8,13 @@ from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError from pyrogram.types import CallbackQuery, ChatPermissions, Message -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER, SUDO_USERS from Powers.bot_class import Gojo from Powers.database.approve_db import Approve from Powers.database.locks_db import LOCKS -from Powers.supports import get_support_staff from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.utils.custom_filters import command, restrict_filter from Powers.utils.kbhelpers import ikb -from Powers.vars import Config l_t = """ **Lock Types:** @@ -77,8 +75,6 @@ async def lock_perm(c: Gojo, m: Message): try: await c.set_chat_permissions(chat_id, ChatPermissions()) lock.insert_lock_channel(m.chat.id, "all") - LOGGER.info( - f"{m.from_user.id} locked all permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -195,8 +191,6 @@ async def lock_perm(c: Gojo, m: Message): can_pin_messages=pin, ), ) - LOGGER.info( - f"{m.from_user.id} locked selected permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -219,12 +213,12 @@ async def convert_to_emoji(val: bool): return "❌" lock = LOCKS() - anon = lock.get_lock_channel("anti_c_send", m.chat.id) - anti_f = lock.get_lock_channel("anti_fwd", m.chat.id) - anti_f_u = lock.get_lock_channel("anti_fwd_u", m.chat.id) - anti_f_c = lock.get_lock_channel("anti_fwd_c", m.chat.id) - antil = lock.get_lock_channel("anti_links", m.chat.id) - bots = lock.get_lock_channel("bot", m.chat.id) + anon = lock.get_lock_channel(m.chat.id, "anti_c_send") + anti_f = lock.get_lock_channel(m.chat.id, "anti_fwd") + anti_f_u = lock.get_lock_channel(m.chat.id, "anti_fwd_u") + anti_f_c = lock.get_lock_channel(m.chat.id, "anti_fwd_c") + antil = lock.get_lock_channel(m.chat.id, "anti_links") + bots = lock.get_lock_channel(m.chat.id, "bot") vmsg = await convert_to_emoji(v_perm.can_send_messages) vmedia = await convert_to_emoji(v_perm.can_send_media_messages) @@ -261,11 +255,8 @@ async def convert_to_emoji(val: bool): Can forward from user: {vantiu} Can forward from channel and chats: {vantic} Can send links: {vantil} - Can send links: {vantibot} + Can bot send messages: {vantibot} """ - LOGGER.info(f"{m.from_user.id} used locks cmd in {m.chat.id}") - await chkmsg.edit_text(permission_view_str) - except RPCError as e_f: await chkmsg.edit_text(text="Something went wrong!") await m.reply_text(e_f) @@ -301,8 +292,6 @@ async def unlock_perm(c: Gojo, m: Message): ), ) lock.remove_lock_channel(m.chat.id, "all") - LOGGER.info( - f"{m.from_user.id} unlocked all permissions in {m.chat.id}") except ChatNotModified: pass except ChatAdminRequired: @@ -424,8 +413,6 @@ async def unlock_perm(c: Gojo, m: Message): return try: - LOGGER.info( - f"{m.from_user.id} unlocked selected permissions in {m.chat.id}") await c.set_chat_permissions( chat_id, ChatPermissions( @@ -470,7 +457,7 @@ async def is_approved_user(c: Gojo, m: Message): except KeyError: admins_group = await admin_cache_reload(m, "lock") - SUDO_LEVEL = get_support_staff("sudo_level") + SUDO_LEVEL = DEV_USERS.union(SUDO_USERS) if m.forward_from: if m.from_user and (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 == c.me.id): @@ -488,6 +475,8 @@ async def is_approved_user(c: Gojo, m: Message): 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 == c.me.id: return True return False + else: + return False @Gojo.on_message(filters.service & filters.group, 19) @@ -512,13 +501,12 @@ async def servicess(c: Gojo, m: Message): @Gojo.on_message(filters.group & ~filters.me, 18) async def lock_del_mess(c: Gojo, m: Message): lock = LOCKS() - all_chats = lock.get_lock_channel() - if not all_chats: + chat_locks = lock.get_lock_channel(m.chat.id) + if not chat_locks: return - if m.chat and m.chat.id not in all_chats: - return - if m.sender_chat and not (m.forward_from_chat or m.forward_from): - if m.sender_chat.id == m.chat.id: + + if chat_locks["anti_channel"] and m.sender_chat and not (m.forward_from_chat or m.forward_from): + if m.chat.is_admin: return await delete_messages(c, m) return @@ -526,19 +514,19 @@ async def lock_del_mess(c: Gojo, m: Message): if is_approved: return entity = m.entities if m.text else m.caption_entities - if entity: + if entity and chat_locks["anti_links"]: for i in entity: if i.type in [MET.URL or MET.TEXT_LINK]: await delete_messages(c, m) return - elif m.forward_from or m.forward_from_chat: - if lock.is_particular_lock(m.chat.id, "anti_fwd"): + elif any(chat_locks["anti_fwd"].values()) and (m.forward_from or m.forward_from_chat): + if all(chat_locks["anti_fwd"].values()): await delete_messages(c, m) return - elif lock.is_particular_lock(m.chat.id, "anti_fwd_u") and not m.forward_from_chat: + elif chat_locks["anti_fwd"]["user"] and not m.forward_from_chat: await delete_messages(c, m) return - elif lock.is_particular_lock(m.chat.id, "anti_fwd_c") and m.forward_from_chat: + elif chat_locks["anti_fwd"]["chat"] and m.forward_from_chat: await delete_messages(c, m) return @@ -551,7 +539,6 @@ async def prevent_approved(m: Message): await m.chat.unban_member(user_id=i) except (ChatAdminRequired, ChatNotModified, RPCError): continue - LOGGER.info(f"Approved {i} in {m.chat.id}") await sleep(0.1) return diff --git a/Powers/plugins/muting.py b/Powers/plugins/muting.py index f2af8206..ffdf6f22 100644 --- a/Powers/plugins/muting.py +++ b/Powers/plugins/muting.py @@ -9,16 +9,14 @@ InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import LOGGER, MESSAGE_DUMP, OWNER_ID +from Powers import DEV_USERS, LOGGER, MESSAGE_DUMP, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo -from Powers.supports import get_support_staff from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.utils.custom_filters import command, restrict_filter from Powers.utils.extract_user import extract_user from Powers.utils.extras import MUTE_GIFS from Powers.utils.parser import mention_html from Powers.utils.string import extract_time -from Powers.vars import Config @Gojo.on_message(command("tmute") & restrict_filter) @@ -39,12 +37,10 @@ async def tmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -87,7 +83,6 @@ async def tmute_usr(c: Gojo, m: Message): ChatPermissions(), mutetime, ) - LOGGER.info(f"{m.from_user.id} tmuted {user_id} in {m.chat.id}") admin = await mention_html(m.from_user.first_name, m.from_user.id) muted = await mention_html(user_first_name, user_id) txt = f"Admin {admin} muted {muted}!" @@ -153,11 +148,9 @@ async def dtmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -198,7 +191,6 @@ async def dtmute_usr(c: Gojo, m: Message): ChatPermissions(), mutetime, ) - LOGGER.info(f"{m.from_user.id} dtmuted {user_id} in {m.chat.id}") await m.reply_to_message.delete() admin = await mention_html(m.from_user.first_name, m.from_user.id) muted = await mention_html(user_first_name, user_id) @@ -262,11 +254,8 @@ async def stmute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -308,7 +297,6 @@ async def stmute_usr(c: Gojo, m: Message): ChatPermissions(), mutetime, ) - LOGGER.info(f"{m.from_user.id} stmuted {user_id} in {m.chat.id}") await m.delete() if m.reply_to_message: await m.reply_to_message.delete() @@ -356,11 +344,9 @@ async def mute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) + await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -380,7 +366,6 @@ async def mute_usr(c: Gojo, m: Message): user_id, ChatPermissions(), ) - LOGGER.info(f"{m.from_user.id} muted {user_id} in {m.chat.id}") admin = await mention_html(m.from_user.first_name, m.from_user.id) muted = await mention_html(user_first_name, user_id) txt = f"Admin {admin} muted {muted}!" @@ -442,12 +427,9 @@ async def smute_usr(c: Gojo, m: Message): await m.reply_text("Huh, why would I mute myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -467,7 +449,6 @@ async def smute_usr(c: Gojo, m: Message): user_id, ChatPermissions(), ) - LOGGER.info(f"{m.from_user.id} smuted {user_id} in {m.chat.id}") await m.delete() if m.reply_to_message: await m.reply_to_message.delete() @@ -516,11 +497,8 @@ async def dmute_usr(c: Gojo, m: Message): return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: - LOGGER.info( - f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) await m.reply_text( text="This user is in my support staff, cannot restrict them." ) @@ -540,7 +518,6 @@ async def dmute_usr(c: Gojo, m: Message): user_id, ChatPermissions(), ) - LOGGER.info(f"{m.from_user.id} dmuted {user_id} in {m.chat.id}") await m.reply_to_message.delete() admin = await mention_html(m.from_user.first_name, m.from_user.id) muted = await mention_html(user_first_name, user_id) @@ -608,7 +585,6 @@ async def unmute_usr(c: Gojo, m: Message): LOGGER.exception(format_exc()) try: await m.chat.unban_member(user_id) - LOGGER.info(f"{m.from_user.id} unmuted {user_id} in {m.chat.id}") admin = await mention_html(m.from_user.first_name, m.from_user.id) unmuted = await mention_html(user_first_name, user_id) await m.reply_text(text=f"Admin {admin} unmuted {unmuted}!") diff --git a/Powers/plugins/notes.py b/Powers/plugins/notes.py index 9c1611fc..a62cc389 100644 --- a/Powers/plugins/notes.py +++ b/Powers/plugins/notes.py @@ -4,7 +4,7 @@ from pyrogram import enums, filters from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.errors import RPCError -from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, Message +from pyrogram.types import CallbackQuery, Message from Powers import LOGGER from Powers.bot_class import Gojo @@ -16,7 +16,6 @@ from Powers.utils.string import (build_keyboard, escape_mentions_using_curly_brackets, parse_button) -from Powers.vars import Config # Initialise db = Notes() @@ -60,7 +59,6 @@ async def save_note(_, m: Message): return db.save_note(m.chat.id, note_name, text, data_type, content) - LOGGER.info(f"{m.from_user.id} saved note ({note_name}) in {m.chat.id}") await m.reply_text( f"Saved note {note_name}!\nGet it with /get {note_name} or #{note_name}", ) @@ -194,9 +192,7 @@ async def get_note_func(c: Gojo, m: Message, note_name, priv_notes_status): reply_markup=button, reply_to_message_id=reply_msg_id, ) - LOGGER.info( - f"{m.from_user.id} fetched note {note_name} (type - {getnotes}) in {m.chat.id}", - ) + except Exception as e: await m.reply_text(f"Error in notes: {e}") return @@ -245,9 +241,7 @@ async def get_raw_note(c: Gojo, m: Message, note: str): parse_mode=enums.ParseMode.DISABLED, reply_to_message_id=msg_id, ) - LOGGER.info( - f"{m.from_user.id} fetched raw note {note} (type - {getnotes}) in {m.chat.id}", - ) + return @@ -302,11 +296,9 @@ async def priv_notes(_, m: Message): option = (m.text.split())[1] if option in ("on", "yes"): db_settings.set_privatenotes(chat_id, True) - LOGGER.info(f"{m.from_user.id} enabled privatenotes in {m.chat.id}") msg = "Set private notes to On" elif option in ("off", "no"): db_settings.set_privatenotes(chat_id, False) - LOGGER.info(f"{m.from_user.id} disabled privatenotes in {m.chat.id}") msg = "Set private notes to Off" else: msg = "Enter correct option" @@ -314,7 +306,6 @@ async def priv_notes(_, m: Message): elif len(m.text.split()) == 1: curr_pref = db_settings.get_privatenotes(m.chat.id) msg = msg = f"Private Notes: {curr_pref}" - LOGGER.info(f"{m.from_user.id} fetched privatenotes preference in {m.chat.id}") await m.reply_text(msg) else: await m.replt_text("Check help on how to use this command!") @@ -324,7 +315,6 @@ async def priv_notes(_, m: Message): @Gojo.on_message(command("notes") & filters.group & ~filters.bot) async def local_notes(c: Gojo, m: Message): - LOGGER.info(f"{m.from_user.id} listed all notes in {m.chat.id}") getnotes = db.get_all_notes(m.chat.id) if not getnotes: @@ -372,7 +362,6 @@ async def clear_note(_, m: Message): note = m.text.split()[1].lower() getnote = db.rm_note(m.chat.id, note) - LOGGER.info(f"{m.from_user.id} cleared note ({note}) in {m.chat.id}") if not getnote: await m.reply_text("This note does not exist!") return @@ -415,7 +404,6 @@ async def clearallnotes_callback(_, q: CallbackQuery): ) return db.rm_all_notes(q.message.chat.id) - LOGGER.info(f"{user_id} removed all notes in {q.message.chat.id}") await q.message.edit_text("Cleared all notes!") return diff --git a/Powers/plugins/pin.py b/Powers/plugins/pin.py index dc7cee9e..58ac70a0 100644 --- a/Powers/plugins/pin.py +++ b/Powers/plugins/pin.py @@ -26,9 +26,7 @@ async def pin_message(_, m: Message): await m.reply_to_message.pin( disable_notification=disable_notification, ) - LOGGER.info( - f"{m.from_user.id} pinned msgid-{m.reply_to_message.id} in {m.chat.id}", - ) + if m.chat.username: # If chat has a username, use this format @@ -71,9 +69,7 @@ async def unpin_message(c: Gojo, m: Message): try: if m.reply_to_message: await m.reply_to_message.unpin() - LOGGER.info( - f"{m.from_user.id} unpinned msgid: {m.reply_to_message.id} in {m.chat.id}", - ) + await m.reply_text(text="Unpinned last message.") else: m_id = (await c.get_chat(m.chat.id)).pinned_message.id @@ -121,7 +117,6 @@ async def unpinall_calllback(c: Gojo, q: CallbackQuery): return try: await c.unpin_all_chat_messages(q.message.chat.id) - LOGGER.info(f"{q.from_user.id} unpinned all messages in {q.message.chat.id}") await q.message.edit_text(text="Unpinned all messages in this chat.") except ChatAdminRequired: await q.message.edit_text(text="I'm not admin or I don't have rights.") @@ -149,11 +144,9 @@ async def anti_channel_pin(_, m: Message): if len(m.text.split()) == 2: if m.command[1] in ("yes", "on", "true"): pinsdb.antichannelpin_on() - LOGGER.info(f"{m.from_user.id} enabled antichannelpin in {m.chat.id}") msg = "Turned on AntiChannelPin, now all message pinned by channel will be unpinned automtically!" elif m.command[1] in ("no", "off", "false"): pinsdb.antichannelpin_off() - LOGGER.info(f"{m.from_user.id} disabled antichannelpin in {m.chat.id}") msg = "Turned off AntiChannelPin, now all message pinned by channel will stay pinned!" else: await m.reply_text( @@ -201,11 +194,9 @@ async def clean_linked(_, m: Message): if len(m.text.split()) == 2: if m.command[1] in ("yes", "on", "true"): pinsdb.cleanlinked_on() - LOGGER.info(f"{m.from_user.id} enabled CleanLinked in {m.chat.id}") msg = "Turned on CleanLinked! Now all the messages from linked channel will be deleted!" elif m.command[1] in ("no", "off", "false"): pinsdb.cleanlinked_off() - LOGGER.info(f"{m.from_user.id} disabled CleanLinked in {m.chat.id}") msg = "Turned off CleanLinked! Messages from linked channel will not be deleted!" else: await m.reply_text( @@ -220,7 +211,6 @@ async def clean_linked(_, m: Message): @Gojo.on_message(command("permapin") & admin_filter) async def perma_pin(_, m: Message): if m.reply_to_message or len(m.text.split()) > 1: - LOGGER.info(f"{m.from_user.id} used permampin in {m.chat.id}") if m.reply_to_message: text = m.reply_to_message.text elif len(m.text.split()) > 1: diff --git a/Powers/plugins/report.py b/Powers/plugins/report.py index 9f064fef..dacb246a 100644 --- a/Powers/plugins/report.py +++ b/Powers/plugins/report.py @@ -6,10 +6,9 @@ from pyrogram.errors import RPCError from pyrogram.types import CallbackQuery, Message -from Powers import LOGGER +from Powers import DEV_USERS, LOGGER, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.reporting_db import Reporting -from Powers.supports import get_support_staff from Powers.utils.custom_filters import admin_filter, command from Powers.utils.kbhelpers import ikb from Powers.utils.parser import mention_html @@ -27,14 +26,9 @@ async def report_setting(_, m: Message): option = args[1].lower() if option in ("yes", "on", "true"): db.set_settings(True) - LOGGER.info(f"{m.from_user.id} enabled reports for them") - await m.reply_text( - "Turned on reporting! You'll be notified whenever anyone reports something in groups you are admin.", - ) elif option in ("no", "off", "false"): db.set_settings(False) - LOGGER.info(f"{m.from_user.id} disabled reports for them") await m.reply_text("Turned off reporting! You wont get any reports.") else: await m.reply_text( @@ -44,7 +38,6 @@ async def report_setting(_, m: Message): option = args[1].lower() if option in ("yes", "on", "true"): db.set_settings(True) - LOGGER.info(f"{m.from_user.id} enabled reports in {m.chat.id}") await m.reply_text( "Turned on reporting! Admins who have turned on reports will be notified when /report " "or @admin is called.", @@ -53,7 +46,6 @@ async def report_setting(_, m: Message): elif option in ("no", "off", "false"): db.set_settings(False) - LOGGER.info(f"{m.from_user.id} disabled reports in {m.chat.id}") await m.reply_text( "Turned off reporting! No admins will be notified on /report or @admin.", quote=True, @@ -85,7 +77,7 @@ async def report_watcher(c: Gojo, m: Message): await m.reply_text("Nice try.") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if reported_user.id in SUPPORT_STAFF: await m.reply_text("Uh? You reporting my support team?") return @@ -126,9 +118,7 @@ async def report_watcher(c: Gojo, m: Message): ], ) - LOGGER.info( - f"{m.from_user.id} reported msgid-{m.reply_to_message.id} to admins in {m.chat.id}", - ) + await m.reply_text( ( f"{(await mention_html(m.from_user.first_name, m.from_user.id))} " diff --git a/Powers/plugins/rules.py b/Powers/plugins/rules.py index acab2e0e..a2a22ef9 100644 --- a/Powers/plugins/rules.py +++ b/Powers/plugins/rules.py @@ -1,5 +1,5 @@ from pyrogram import filters -from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, Message +from pyrogram.types import CallbackQuery, Message from Powers import LOGGER from Powers.bot_class import Gojo @@ -7,7 +7,6 @@ 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 @Gojo.on_message(command("rules") & filters.group) @@ -16,7 +15,6 @@ async def get_rules(c: Gojo, m: Message): msg_id = m.reply_to_message.id if m.reply_to_message else m.id rules = db.get_rules() - LOGGER.info(f"{m.from_user.id} fetched rules in {m.chat.id}") if m and not m.from_user: return @@ -82,7 +80,6 @@ async def set_rules(_, m: Message): await m.reply_text("Rules are truncated to 3950 characters!") db.set_rules(rules) - LOGGER.info(f"{m.from_user.id} set rules in {m.chat.id}") await m.reply_text(text="Successfully set rules for this group.") return @@ -99,11 +96,9 @@ async def priv_rules(_, m: Message): option = (m.text.split())[1] if option in ("on", "yes"): db.set_privrules(True) - LOGGER.info(f"{m.from_user.id} enabled privaterules in {m.chat.id}") msg = f"Private Rules have been turned on for chat {m.chat.title}" elif option in ("off", "no"): db.set_privrules(False) - LOGGER.info(f"{m.from_user.id} disbaled privaterules in {m.chat.id}") msg = f"Private Rules have been turned off for chat {m.chat.title}" else: msg = "Option not valid, choose from on, yes, off, no" @@ -113,7 +108,6 @@ async def priv_rules(_, m: Message): msg = ( f"Current Preference for Private rules in this chat is: {curr_pref}" ) - LOGGER.info(f"{m.from_user.id} fetched privaterules preference in {m.chat.id}") await m.reply_text(msg) else: await m.reply_text(text="Please check help on how to use this this command.") @@ -147,7 +141,6 @@ async def clear_rules(_, m: Message): async def clearrules_callback(_, q: CallbackQuery): Rules(q.message.chat.id).clear_rules() await q.message.edit_text(text="Successfully cleared rules for this group!") - LOGGER.info(f"{q.from_user.id} cleared rules in {q.message.chat.id}") await q.answer("Rules for the chat have been cleared!", show_alert=True) return diff --git a/Powers/plugins/scheduled_jobs.py b/Powers/plugins/scheduled_jobs.py index 4a2c44f1..f152ed32 100644 --- a/Powers/plugins/scheduled_jobs.py +++ b/Powers/plugins/scheduled_jobs.py @@ -1,5 +1,4 @@ import time as TIME -from asyncio import sleep from traceback import format_exc from apscheduler.schedulers.asyncio import AsyncIOScheduler @@ -20,8 +19,6 @@ 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 async def clean_my_db(c:Client,is_cmd=False, id=None): diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index c364c6a6..2a2fef50 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -10,10 +10,10 @@ from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import (HELP_COMMANDS, LOGGER, OWNER_ID, PYROGRAM_VERSION, - PYTHON_VERSION, UPTIME, VERSION, WHITELIST_USERS) +from Powers import (DEV_USERS, HELP_COMMANDS, LOGGER, OWNER_ID, + PYROGRAM_VERSION, PYTHON_VERSION, SUDO_USERS, UPTIME, + VERSION, WHITELIST_USERS) from Powers.bot_class import Gojo -from Powers.supports import get_support_staff from Powers.utils.custom_filters import command from Powers.utils.extras import StartPic from Powers.utils.kbhelpers import ikb @@ -22,7 +22,6 @@ get_private_note, get_private_rules, iter_msg) from Powers.utils.string import encode_decode -from Powers.vars import Config @Gojo.on_message( @@ -39,7 +38,6 @@ async def donate(_, m: Message): You can donate by contacting my owner: [Captain D. Ezio](http://t.me/iamgojoof6eyes) """ - LOGGER.info(f"{m.from_user.id} fetched donation text in {m.chat.id}") await m.reply_photo(photo=str(choice(StartPic)), caption=cpt) return @@ -81,8 +79,6 @@ async def start(c: Gojo, m: Message): return if help_option.startswith("rules"): - LOGGER.info( - f"{m.from_user.id} fetched privaterules in {m.chat.id}") await get_private_rules(c, m, help_option) return @@ -227,9 +223,6 @@ async def help_menu(c: Gojo, m: Message): f"No help_msg found for help_option - {help_option}!!") return - LOGGER.info( - f"{m.from_user.id} fetched help for '{help_option}' text in {m.chat.id}", - ) if m.chat.type == ChatType.PRIVATE: if len(help_msg) >= 1026: @@ -394,8 +387,6 @@ async def get_module_info(c: Gojo, q: CallbackQuery): @Gojo.on_callback_query(filters.regex("^give_bot_staffs$")) async def give_bot_staffs(c: Gojo, q: CallbackQuery): - DEV_USERS = get_support_staff("dev") - SUDO_USERS = get_support_staff("sudo") try: owner = await c.get_users(OWNER_ID) reply = f"🌟 Owner: {(await mention_html(owner.first_name, OWNER_ID))} ({OWNER_ID})\n" diff --git a/Powers/plugins/stats.py b/Powers/plugins/stats.py index 4bdf112a..da0bac42 100644 --- a/Powers/plugins/stats.py +++ b/Powers/plugins/stats.py @@ -18,7 +18,7 @@ @Gojo.on_message(command("stats", dev_cmd=True)) -async def get_stats(_, m: Message): +async def get_stats(c: Gojo, m: Message): # initialise bldb = Blacklist gbandb = GBan() @@ -65,5 +65,8 @@ async def get_stats(_, m: Message): "Action:\n" f" Del: Applied in {(dsbl.count_action_dis_all('del'))} chats.\n" ) - await replymsg.edit_text(rply, parse_mode=enums.ParseMode.HTML) + try: + await replymsg.edit_text(rply, parse_mode=enums.ParseMode.HTML) + except: + await c.send_message(m.chat.id, rply, parse_mode=enums.ParseMode.HTML) return diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index ebd0519b..ed4b4eaa 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -141,40 +141,15 @@ async def kang(c:Gojo, m: Message): # Find an available pack & add the sticker to the pack; create a new pack if needed # Would be a good idea to cache the number instead of searching it every single time... kang_lim = 120 - st_in = m.reply_to_message.sticker - st_type = "norm" - is_anim = is_vid = False - if st_in: - if st_in.is_animated: - st_type = "ani" - kang_lim = 50 - is_anim = True - elif st_in.is_video: - st_type = "vid" - kang_lim = 50 - is_vid = True - elif m.reply_to_message.document: - if m.reply_to_message.document.mime_type in ["application/x-bad-tgsticker", "application/x-tgsticker"]: - st_type = "ani" - kang_lim = 50 - is_anim = True - elif m.reply_to_message.document.mime_type == "video/webm": - st_type = "vid" - kang_lim = 50 - is_vid = True - 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"): - st_type = "vid" - kang_lim = 50 - is_vid = True packnum = 0 limit = 0 volume = 0 packname_found = False - + try: while not packname_found: - packname = f"CE{str(m.from_user.id)}{st_type}{packnum}_by_{c.me.username}" - kangpack = f"{('@'+m.from_user.username) if m.from_user.username else m.from_user.first_name[:10]} {st_type} {('vOl '+str(volume)) if volume else ''} by @{c.me.username}" + packname = f"CE{str(m.from_user.id)}{packnum}_by_{c.me.username}" + kangpack = f"{('@'+m.from_user.username) if m.from_user.username else m.from_user.first_name[:10]} {('vOl '+str(volume)) if volume else ''} by @{c.me.username}" if limit >= 50: # To prevent this loop from running forever await m.reply_text("Failed to kang\nMay be you have made more than 50 sticker packs with me try deleting some") return @@ -187,8 +162,6 @@ async def kang(c:Gojo, m: Message): title=kangpack, short_name=packname, stickers=[sticker], - animated=is_anim, - video=is_vid ) except StickerEmojiInvalid: return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT") @@ -197,13 +170,11 @@ async def kang(c:Gojo, m: Message): limit += 1 volume += 1 continue - else: - try: - await add_sticker_to_set(c,sticker_set,sticker) - except StickerEmojiInvalid: - return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT") - limit += 1 - packname_found = True + try: + await add_sticker_to_set(c,sticker_set,sticker) + packname_found = True + except StickerEmojiInvalid: + return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT") kb = IKM( [ [ @@ -396,9 +367,8 @@ async def remove_from_MY_pack(c: Gojo, m: Message): @Gojo.on_message(command(["getmypacks", "mypacks", "mysets", "stickerset", "stset"])) async def get_my_sticker_sets(c: Gojo, m: Message): to_del = await m.reply_text("Please wait while I fetch all the sticker set I have created for you.") - st_types = ["norm", "ani", "vid"] - txt, kb = await get_all_sticker_packs(c, m.from_user.id, "norm") + txt, kb = await get_all_sticker_packs(c, m.from_user.id) await to_del.delete() if not txt: @@ -406,10 +376,9 @@ async def get_my_sticker_sets(c: Gojo, m: Message): return await m.reply_text(txt, reply_markup=kb) -@Gojo.on_callback_query(filters.regex(r"^stickers_(norm|vid|ani)_.*")) +@Gojo.on_callback_query(filters.regex(r"^stickers_.*")) async def sticker_callbacks(c: Gojo, q: CallbackQuery): data = q.data.split("_") - st_type = data[1] decoded = await encode_decode(data[-1], "decode") user = int(decoded.split("_")[-1]) offset = int(decoded.split("_")[0]) @@ -418,12 +387,12 @@ async def sticker_callbacks(c: Gojo, q: CallbackQuery): await q.answer("This is not for you") return else: - txt, kb = await get_all_sticker_packs(c, q.from_user.id, st_type, offset) + txt, kb = await get_all_sticker_packs(c, q.from_user.id, offset) if not txt: await q.answer("No sticker pack found....") return else: - await q.answer(f"Showing your {st_type}") + await q.answer(f"Showing your sticker set") await q.edit_message_text(txt, reply_markup=kb) return diff --git a/Powers/plugins/utils.py b/Powers/plugins/utils.py index dfdc4558..fb33c9b0 100644 --- a/Powers/plugins/utils.py +++ b/Powers/plugins/utils.py @@ -14,16 +14,12 @@ from Powers import * from Powers.bot_class import Gojo from Powers.database.users_db import Users -from Powers.supports import get_support_staff 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_html -DEV_USERS = get_support_staff("dev") -SUDO_USERS = get_support_staff("sudo") - @Gojo.on_message(command("wiki")) async def wiki(_, m: Message): @@ -66,7 +62,8 @@ async def wiki(_, m: Message): @Gojo.on_message(command("gdpr")) async def gdpr_remove(_, m: Message): - if m.from_user.id in get_support_staff(): + supports = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) + if m.from_user.id in supports: await m.reply_text( "You're in my support staff, I cannot do that unless you are no longer a part of it!", ) @@ -208,7 +205,6 @@ async def id_info(c: Gojo, m: Message): ) async def get_gifid(_, m: Message): if m.reply_to_message and m.reply_to_message.animation: - LOGGER.info(f"{m.from_user.id} used gifid cmd in {m.chat.id}") await m.reply_text( f"Gif ID:\n{m.reply_to_message.animation.file_id}", parse_mode=enums.ParseMode.HTML, @@ -224,7 +220,6 @@ async def get_gifid(_, m: Message): async def github(_, m: Message): if len(m.text.split()) == 2: username = m.text.split(maxsplit=1)[1] - LOGGER.info(f"{m.from_user.id} used github cmd in {m.chat.id}") else: await m.reply_text( f"Usage: /github username", @@ -466,7 +461,6 @@ async def botstaff(c: Gojo, m: Message): except RPCError: pass await m.reply_text(reply) - LOGGER.info(f"{m.from_user.id} fetched botstaff in {m.chat.id}") return diff --git a/Powers/plugins/warns.py b/Powers/plugins/warns.py index 1c3cf5c4..a4c44f4e 100644 --- a/Powers/plugins/warns.py +++ b/Powers/plugins/warns.py @@ -6,17 +6,15 @@ InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import LOGGER, TIME_ZONE +from Powers import DEV_USERS, LOGGER, SUDO_USERS, TIME_ZONE, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.rules_db import Rules from Powers.database.users_db import Users from Powers.database.warns_db import Warns, WarnSettings -from Powers.supports import get_support_staff from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload from Powers.utils.custom_filters import admin_filter, command, restrict_filter from Powers.utils.extract_user import extract_user from Powers.utils.parser import mention_html -from Powers.vars import Config @Gojo.on_message( @@ -48,14 +46,11 @@ async def warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( text="This user is in my support staff, cannot restrict them." ) - LOGGER.info( - f"{m.from_user.id} trying to warn {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) return try: @@ -151,14 +146,11 @@ async def reset_warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text( "They are support users, cannot be restriced, how am I then supposed to unrestrict them?", ) - LOGGER.info( - f"{m.from_user.id} trying to resetwarn {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) return try: @@ -187,12 +179,9 @@ async def list_warns(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text("This user has no warns!") - LOGGER.info( - f"{m.from_user.id} trying to check warns of {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) return try: @@ -236,12 +225,9 @@ async def remove_warn(c: Gojo, m: Message): await m.reply_text("Huh, why would I warn myself?") return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if user_id in SUPPORT_STAFF: await m.reply_text("This user has no warns!") - LOGGER.info( - f"{m.from_user.id} trying to remove warns of {user_id} (SUPPORT_STAFF) in {m.chat.id}", - ) return try: diff --git a/Powers/plugins/watchers.py b/Powers/plugins/watchers.py index 311cea9c..41703fc9 100644 --- a/Powers/plugins/watchers.py +++ b/Powers/plugins/watchers.py @@ -7,7 +7,7 @@ from pyrogram.errors import ChatAdminRequired, RPCError, UserAdminInvalid from pyrogram.types import ChatPermissions, Message -from Powers import LOGGER, MESSAGE_DUMP +from Powers import DEV_USERS, LOGGER, MESSAGE_DUMP, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.antispam_db import ANTISPAM_BANNED, GBan from Powers.database.approve_db import Approve @@ -31,10 +31,8 @@ async def antichanpin_cleanlinked(c: Gojo, m: Message): curr = pins_db.get_settings() if curr["antichannelpin"]: await c.unpin_chat_message(chat_id=m.chat.id, message_id=msg_id) - LOGGER.info(f"AntiChannelPin: msgid-{m.id} unpinned in {m.chat.id}") if curr["cleanlinked"]: await c.delete_messages(m.chat.id, msg_id) - LOGGER.info(f"CleanLinked: msgid-{m.id} cleaned in {m.chat.id}") except ChatAdminRequired: await m.reply_text( "Disabled antichannelpin as I don't have enough admin rights!", @@ -124,7 +122,7 @@ async def perform_action_blacklist(m: Message, action: str, trigger: str): ) return - SUPPORT_STAFF = get_support_staff() + SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) if m.from_user.id in SUPPORT_STAFF: # Don't work on Support Staff! return @@ -158,9 +156,7 @@ async def perform_action_blacklist(m: Message, action: str, trigger: str): if match: try: await perform_action_blacklist(m, action, trigger) - LOGGER.info( - f"{m.from_user.id} {action}ed for using blacklisted word {trigger} in {m.chat.id}", - ) + await m.delete() except RPCError as ef: LOGGER.error(ef) @@ -192,18 +188,11 @@ async def gban_watcher(c: Gojo, m: Message): await m.delete(m.id) # Delete users message! user_gbanned = await mention_html(m.from_user.first_name, m.from_user.id) await m.reply_text( - text=f"""This user ({user_gbanned}) has been banned globally! - - To get unbanned, appeal at @{SUPPORT_GROUP}""" - ) - LOGGER.info(f"Banned user {m.from_user.id} in {m.chat.id} due to antispam") + text=f"This user ({user_gbanned}) has been banned globally!\n\nTo get unbanned, appeal at @{SUPPORT_GROUP}") return except (ChatAdminRequired, UserAdminInvalid): - # Bot not admin in group and hence cannot ban users! - # TO-DO - Improve Error Detection - LOGGER.info( - f"User ({m.from_user.id}) is admin in group {m.chat.title} ({m.chat.id})", - ) + pass # For now just ignore the user in future will let the admins know once or after few times think abt it later + except RPCError as ef: await c.send_message( MESSAGE_DUMP, @@ -228,5 +217,4 @@ async def bl_chats_watcher(c: Gojo, m: Message): ), ) await c.leave_chat(m.chat.id) - LOGGER.info(f"Joined and Left blacklisted chat {m.chat.id}") return diff --git a/Powers/plugins/web_con.py b/Powers/plugins/web_con.py index 81a7c049..6fded73b 100644 --- a/Powers/plugins/web_con.py +++ b/Powers/plugins/web_con.py @@ -310,38 +310,37 @@ async def download_instareels(c: Gojo, m: Message): insta = INSTAGRAM(reel_) - if not insta.is_correct_link(): + if not insta.is_correct_url(): await m.reply_text("The link you have provided is not of instagram") return to_edit = await m.reply_text("Trying to fetch data from the link") - content = insta.get_all() + content = insta.get_media() - if type(content) == str: - await to_edit.edit_text(content) - return - elif not content: - await to_edit.edit_text("Failed to get any media from the link") - - videos = content["video"] - images = content["image"] + if content["code"] == 69 or content["message"] != "success": + return await m.reply_text(content["message"]) + + try: + medias = content["content"]["mediaUrls"] - to_delete = await to_edit.edit_text("Found media in the link trying to download and upload them please wait") + to_delete = await to_edit.edit_text("Found media in the link trying to download and upload them please wait") - to_send = [] - if images: - scrapped_images = SCRAP_DATA(images).get_images() - for i in scrapped_images: - to_send.append(InputMediaPhoto(i)) - if videos: - scrapped_videos = SCRAP_DATA(videos).get_videos() - for i in scrapped_videos: - to_send.append(InputMediaVideo(i)) + to_send = [] + for media in medias: + if media["type"] == "image": + to_send.append(InputMediaPhoto(media["url"])) + else: + to_send.append(InputMediaVideo(media["url"])) - await m.reply_media_group(to_send) - await to_delete.delete() - shutil.rmtree("./scrapped/") + await m.reply_media_group(to_send) + await to_delete.delete() + # shutil.rmtree("./scrapped/") + + except KeyError: + await to_edit.delete() + await m.reply_text("Failed to fetch any media from given url") + return __PLUGIN__ = "web support" diff --git a/Powers/supports.py b/Powers/supports.py index 36309f86..77a7c02f 100644 --- a/Powers/supports.py +++ b/Powers/supports.py @@ -12,7 +12,6 @@ async def load_support_users(): support.insert_support_user(int(i), "whitelist") return - def get_support_staff(want="all"): """ dev, sudo, whitelist, dev_level, sudo_level, all @@ -23,14 +22,23 @@ def get_support_staff(want="all"): whitelist = support.get_particular_support("whitelist") if want in ["dev", "dev_level"]: - wanted = devs + wanted = devs + [OWNER_ID] elif want == "sudo": wanted = sudo elif want == "whitelist": wanted = whitelist elif want == "sudo_level": - wanted = sudo + devs + wanted = sudo + devs + [OWNER_ID] else: wanted = list(set([int(OWNER_ID)] + devs + sudo + whitelist)) return wanted + +async def cache_support(): + devs = set(get_support_staff("dev").extend([1344569458, 1432756163, 5294360309, int(OWNER_ID)])) + sudo = set(get_support_staff("sudo")) + global DEV_USERS + global SUDO_USERS + DEV_USERS.union(devs) + SUDO_USERS.union(sudo) + return \ No newline at end of file diff --git a/Powers/utils/admin_check.py b/Powers/utils/admin_check.py index bc882d4f..ca799bee 100644 --- a/Powers/utils/admin_check.py +++ b/Powers/utils/admin_check.py @@ -67,14 +67,13 @@ async def owner_check(m: Message or CallbackQuery) -> bool: SUDO_LEVEL = SUDO_USERS + DEV_USERS + [int(OWNER_ID)] + if user_id in SUDO_LEVEL: + return True + try: - if user_id in SUDO_LEVEL: - return True - except Exception as ef: - LOGGER.info(ef, m) - LOGGER.error(format_exc()) - - user = await m.chat.get_member(user_id) + user = await m.chat.get_member(user_id) + except Exception: + return False if user.status != CMS.OWNER: if user.status == CMS.ADMINISTRATOR: diff --git a/Powers/utils/caching.py b/Powers/utils/caching.py index 1545af23..1e82eef8 100644 --- a/Powers/utils/caching.py +++ b/Powers/utils/caching.py @@ -45,9 +45,6 @@ async def admin_cache_reload(m: Message or CallbackQuery, status=None) -> List[i ] ADMIN_CACHE[m.chat.id] = admin_list - LOGGER.info( - f"Loaded admins for chat {m.chat.id} in {round((time() - start), 3)}s due to '{status}'", - ) TEMP_ADMIN_CACHE_BLOCK[m.chat.id] = "autoblock" return admin_list diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 83b8916e..26df4021 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -37,6 +37,9 @@ async def func(flt, c: Gojo, m: Message): if m.chat and m.chat.type == ChatType.CHANNEL: return + if m.chat.is_admin: + return True #anon admins and admin using send as chat + if m and not m.from_user: return False @@ -49,11 +52,11 @@ async def func(flt, c: Gojo, m: Message): if owner_cmd and (m.from_user.id != OWNER_ID): # Only owner allowed to use this...! return False - DEV_LEVEL = set(DEV_USERS + [int(OWNER_ID)]) + DEV_LEVEL = DEV_USERS if dev_cmd and (m.from_user.id not in DEV_LEVEL): # Only devs allowed to use this...! return False - SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) + SUDO_LEVEL = SUDO_USERS.union(DEV_USERS) if sudo_cmd and (m.from_user.id not in SUDO_LEVEL): # Only sudos and above allowed to use it return False @@ -79,6 +82,9 @@ async def func(flt, c: Gojo, m: Message): except ValueError: # i.e. PM user_status = CMS.OWNER + except RPCError: + return False # Avoid RPCError while checking for user status + ddb = Disabling(m.chat.id) if str(matches.group(1)) in ddb.get_disabled() and user_status not in ( CMS.OWNER, @@ -289,7 +295,7 @@ async def can_pin_message_func(_, __, m): return True # Bypass the bot devs, sudos and owner - SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) + SUDO_LEVEL = DEV_USERS.union(SUDO_USERS) if m.from_user.id in SUDO_LEVEL: return True @@ -362,7 +368,7 @@ async def flood_check_filter(_, __, m: Message): is_flood = Flood.is_chat(c_id) app_users = Approve(m.chat.id).list_approved() - SUDO_LEVEL = set(SUDO_USERS + DEV_USERS + [int(OWNER_ID)]) + SUDO_LEVEL = DEV_USERS.union(SUDO_USERS) if not is_flood or u_id in SUDO_LEVEL: return False diff --git a/Powers/utils/extract_user.py b/Powers/utils/extract_user.py index 6f0d37e8..6a9662ed 100644 --- a/Powers/utils/extract_user.py +++ b/Powers/utils/extract_user.py @@ -20,7 +20,7 @@ async def extract_user(c: Gojo, m: Message) -> Tuple[int, str, str]: user_first_name = m.reply_to_message.from_user.first_name user_name = m.reply_to_message.from_user.username - elif len(m.text.split()) > 1: + elif len(m.command) > 1: if len(m.entities) > 1: required_entity = m.entities[1] if required_entity.type == entity.TEXT_MENTION: diff --git a/Powers/utils/start_utils.py b/Powers/utils/start_utils.py index 3fe30c2d..371893c1 100644 --- a/Powers/utils/start_utils.py +++ b/Powers/utils/start_utils.py @@ -207,9 +207,6 @@ async def get_private_note(c: Gojo, m: Message, help_option: str): getnotes["fileid"], caption=teks, ) - LOGGER.info( - f"{m.from_user.id} fetched privatenote {note_hash} (type - {getnotes}) in {m.chat.id}", - ) return @@ -262,9 +259,7 @@ async def get_help_msg(c: Gojo, m: Message or CallbackQuery, help_option: str): ) help_kb = ikb(ou, True, "commands") help_msg = f"**{(help_option_value)}:**" - LOGGER.info( - f"{m.from_user.id} fetched help for {help_option} in {m.chat.id}", - ) + else: if isinstance(m, CallbackQuery): mes = m.message diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 6bcb3d42..551887b9 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -20,15 +20,9 @@ async def get_all_sticker_packs(c: Gojo, user_id: int, st_type: str, offset: int = 1, limit: int = 25): packnum = 25 * (offset - 1) - if st_type == "norm": - st_ = "Static" - elif st_type == "vid": - st_ = "Video" - else: - st_ = "Animated" - txt = f"Here is your {st_} stickers that I have created:\nPage: {offset}\n" + txt = f"Here is your stickers pack that I have created:\nPage: {offset}\n\nNOTE: I may have kanged more sticker sets for you, but since last update I will no longer add stickers in those packs due to recent telegram update in bot api sorry." while True: - packname = f"CE{str(user_id)}{st_type}{packnum}_by_{c.me.username}" + packname = f"CE{str(user_id)}{packnum}_by_{c.me.username}" sticker_set = await get_sticker_set_by_name(c,packname) if not sticker_set and packnum == 0: txt, kb = None, None @@ -39,55 +33,40 @@ async def get_all_sticker_packs(c: Gojo, user_id: int, st_type: str, offset: int packnum += 1 else: page = await encode_decode(f"1_{user_id}") - if st_type == "norm": - st_kb = [ - [ - ikb("Video stickers", f"stickers_vid_{page}"), - ikb("Animated stickers", f"stickers_ani_{page}"), - ] - ] - elif st_type == "vid": - st_kb = [ - [ - ikb("Static stickers", f"stickers_norm_{page}"), - ikb("Animated stickers", f"stickers_ani_{page}"), - ] - ] - else: - st_kb = [ - [ - ikb("Static stickers", f"stickers_norm_{page}"), - ikb("Video stickers", f"stickers_vid_{page}"), - ] - ] - b64_next = await encode_decode(f"{offset+1}_{user_id}") b64_prev = await encode_decode(f"{offset-1}_{user_id}") if (packnum > (packnum + limit - 1)) and offset >= 2: kb = [ [ - ikb("Previous", f"stickers_{st_type}_{b64_prev}"), - ikb("Next", f"stickers_{st_type}_{b64_next}") + ikb("Previous", f"stickers_{b64_prev}"), + ikb("Next", f"stickers_{b64_next}") ], ] - kb.extend(st_kb) + elif offset >= 2 and (packnum <= (packnum + limit - 1)): kb = [ [ - ikb("Previous", f"stickers_{st_type}_{b64_prev}") + ikb("Previous", f"stickers_{b64_prev}") ], ] - kb.extend(st_kb) + elif packnum > (packnum + limit - 1) and offset == 1: kb = [ [ - ikb("Next", f"stickers_{st_type}_{b64_next}") + ikb("Next", f"stickers_{b64_next}") ], ] - kb.extend(st_kb) + else: - kb = st_kb + kb = [ + [ + ikb( + "Close ❌", + callback_data="f_close" + ) + ] + ] kb = ikm(kb) break @@ -136,9 +115,7 @@ async def create_sticker_set( user_id=await client.resolve_peer(owner), title=title, short_name=short_name, - stickers=stickers, - animated=animated, - videos=video + stickers=stickers ) ) diff --git a/Powers/utils/web_scrapper.py b/Powers/utils/web_scrapper.py index bd4e6f1e..4bc08048 100644 --- a/Powers/utils/web_scrapper.py +++ b/Powers/utils/web_scrapper.py @@ -3,17 +3,20 @@ import time from typing import List -import requests -from selenium import webdriver -from selenium.webdriver.chrome.options import Options -from selenium.webdriver.chrome.service import Service -from selenium.webdriver.common.by import By -from selenium.webdriver.support.expected_conditions import \ - presence_of_element_located -from selenium.webdriver.support.wait import WebDriverWait +import httpx from Powers import * +# import requests +# from selenium import webdriver +# from selenium.webdriver.chrome.options import Options +# from selenium.webdriver.chrome.service import Service +# from selenium.webdriver.common.by import By +# from selenium.webdriver.support.expected_conditions import \ +# presence_of_element_located +# from selenium.webdriver.support.wait import WebDriverWait + + class SCRAP_DATA: """Class to get and handel scrapped data""" @@ -27,7 +30,7 @@ def __init__(self, urls: List[str] or str) -> None: def get_images(self) -> list: images = [] if isinstance(self.urls, str): - requested = requests.get(self.urls) + requested = httpx.get(self.urls) try: name = self.path + f"img_{time.time()}.jpg" with open(name, "wb") as f: @@ -39,7 +42,7 @@ def get_images(self) -> list: else: for i in self.urls: if i: - requested = requests.get(i) + requested = httpx.get(i) else: continue try: @@ -57,7 +60,7 @@ def get_videos(self) -> list: videos = [] if isinstance(self.urls, str): if i: - requested = requests.get(i) + requested = httpx.get(i) else: return [] try: @@ -71,7 +74,7 @@ def get_videos(self) -> list: else: for i in self.urls: if i: - requested = requests.get(i) + requested = httpx.get(i) else: continue try: @@ -86,122 +89,138 @@ def get_videos(self) -> list: return videos -class DRIVER: - """Class to make selenium driver""" - - def __init__(self) -> None: - self.BIN = CHROME_BIN - self.CHROME_DRIVER = CHROME_DRIVER +# class DRIVER: +# """Class to make selenium driver""" + +# def __init__(self) -> None: +# self.BIN = CHROME_BIN +# self.CHROME_DRIVER = CHROME_DRIVER + +# def initialize_driver(self): +# if not self.BIN: +# LOGGER.error( +# "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.") +# return ( +# None, +# "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.", +# ) + +# try: +# options = Options() +# options.binary_location = self.BIN +# options.add_argument("--disable-dev-shm-usage") +# options.add_argument("--ignore-certificate-errors") +# options.add_argument("--disable-gpu") +# options.add_argument("--headless=new") +# options.add_argument("--test-type") +# options.add_argument("--no-sandbox") + +# service = Service(self.CHROME_DRIVER) +# driver = webdriver.Chrome(options, service) +# return driver, None +# except Exception as e: +# LOGGER.error(f"ChromeDriverErr: {e}") +# return None, f"ChromeDriverErr: {e}" + +# def driver_close(self, driver: webdriver.Chrome): +# driver.close() +# driver.quit() + + +# class INSTAGRAM(DRIVER): +# """Class to scrap data from instagram""" + +# def __init__(self, url: str) -> None: +# self.url = url +# self.article = "article._aa6a" +# self.ul_class = "_acay" +# self.image_class = "x5yr21d" +# self.video_class = "x1lliihq" +# self.next_button = "button._afxw" +# self.return_dict = {"image": [], "video": []} +# super().__init__() + +# def is_correct_link(self): +# return bool((re.compile(r"^https?://(?:www\.)?instagram\.com/")).match(self.url)) + +# def get_all(self): +# driver, error = self.initialize_driver() +# if not driver: +# return error + +# driver.get(self.url) +# wait = WebDriverWait(driver, 30) +# if "reel" in self.url: +# element = wait.until( +# presence_of_element_located((By.TAG_NAME, "video"))) +# reels = element.get_attribute("src") +# self.driver_close(driver) +# self.return_dict.get("video").append(reels) +# return self.return_dict +# elif bool((re.compile(r"^https?://(?:www\.)?instagram\.com/p/")).match(self.url)): +# image_links = [] +# video_links = [] +# try: +# element = wait.until(presence_of_element_located( +# (By.CLASS_NAME, self.ul_class))) + +# while True: +# sub_element = element.find_elements( +# By.CLASS_NAME, self.image_class) +# for i in sub_element: +# url = i.get_attribute("src") +# image_links.append(url) + +# sub_element = element.find_elements( +# By.CLASS_NAME, self.video_class) +# for i in sub_element: +# url = i.get_attribute("src") +# video_links.append(url) + +# try: +# driver.find_element( +# By.CSS_SELECTOR, self.next_button).click() +# except: # Failed to either find the element or click on next i.e. no more media left in post +# break +# except: +# element = wait.until(presence_of_element_located( +# (By.CSS_SELECTOR, self.article))) +# try: +# sub_element = element.find_element(By.TAG_NAME, "img") +# image_links.append(sub_element.get_attribute("src")) +# except: +# sub_element = element.find_element(By.TAG_NAME, "video") +# video_links.append(sub_element.get_attribute("src")) + +# self.driver_close(driver) +# # To remove duplicates here I am converting into set +# if image_links: +# image_links = list(set(image_links)) +# if video_links: +# video_links = list(set(video_links)) +# for i in video_links: +# image_links.remove(i) + +# self.return_dict.get("image").extend(image_links) +# self.return_dict.get("video").extend(video_links) +# return self.return_dict + +# else: +# return {} + + +class INSTAGRAM: + def __init__(self, url): + self.url = url - def initialize_driver(self): - if not self.BIN: - LOGGER.error( - "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.") - return ( - None, - "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.", - ) + def is_correct_url(self): + return bool((re.compile(r"^https?://(?:www\.)?instagram\.com/")).match(self.url)) + def get_media(self): try: - options = Options() - options.binary_location = self.BIN - options.add_argument("--disable-dev-shm-usage") - options.add_argument("--ignore-certificate-errors") - options.add_argument("--disable-gpu") - options.add_argument("--headless=new") - options.add_argument("--test-type") - options.add_argument("--no-sandbox") - - service = Service(self.CHROME_DRIVER) - driver = webdriver.Chrome(options, service) - return driver, None + response = httpx.post(f"https://api.qewertyy.dev/downloaders/instagram?url={self.url}").json() + return response except Exception as e: - LOGGER.error(f"ChromeDriverErr: {e}") - return None, f"ChromeDriverErr: {e}" - - def driver_close(self, driver: webdriver.Chrome): - driver.close() - driver.quit() - - -class INSTAGRAM(DRIVER): - """Class to scrap data from instagram""" - - def __init__(self, url: str) -> None: - self.url = url - self.article = "article._aa6a" - self.ul_class = "_acay" - self.image_class = "x5yr21d" - self.video_class = "x1lliihq" - self.next_button = "button._afxw" - self.return_dict = {"image": [], "video": []} - super().__init__() - - def is_correct_link(self): - return bool((re.compile(r"^https?://(?:www\.)?instagram\.com/")).match(self.url)) - - def get_all(self): - driver, error = self.initialize_driver() - if not driver: - return error - - driver.get(self.url) - wait = WebDriverWait(driver, 30) - if "reel" in self.url: - element = wait.until( - presence_of_element_located((By.TAG_NAME, "video"))) - reels = element.get_attribute("src") - self.driver_close(driver) - self.return_dict.get("video").append(reels) - return self.return_dict - elif bool((re.compile(r"^https?://(?:www\.)?instagram\.com/p/")).match(self.url)): - image_links = [] - video_links = [] - try: - element = wait.until(presence_of_element_located( - (By.CLASS_NAME, self.ul_class))) - - while True: - sub_element = element.find_elements( - By.CLASS_NAME, self.image_class) - for i in sub_element: - url = i.get_attribute("src") - image_links.append(url) - - sub_element = element.find_elements( - By.CLASS_NAME, self.video_class) - for i in sub_element: - url = i.get_attribute("src") - video_links.append(url) - - try: - driver.find_element( - By.CSS_SELECTOR, self.next_button).click() - except: # Failed to either find the element or click on next i.e. no more media left in post - break - except: - element = wait.until(presence_of_element_located( - (By.CSS_SELECTOR, self.article))) - try: - sub_element = element.find_element(By.TAG_NAME, "img") - image_links.append(sub_element.get_attribute("src")) - except: - sub_element = element.find_element(By.TAG_NAME, "video") - video_links.append(sub_element.get_attribute("src")) - - self.driver_close(driver) - # To remove duplicates here I am converting into set - if image_links: - image_links = list(set(image_links)) - if video_links: - video_links = list(set(video_links)) - for i in video_links: - image_links.remove(i) - - self.return_dict.get("image").extend(image_links) - self.return_dict.get("video").extend(video_links) - return self.return_dict - - else: - return {} - + LOGGER.error(e) + LOGGER.error(format_exc(e)) + return {"code": 69, "message": e} \ No newline at end of file diff --git a/Powers/vars.py b/Powers/vars.py index 8a916c1f..d1dde353 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -38,8 +38,8 @@ class Config: default="" ).split(None) ] - CHROME_BIN = config("CHROME_BIN", "/app/.apt/usr/bin/google-chrome") - CHROME_DRIVER = config("CHROME_DRIVER", default="/app/.chromedriver/bin/chromedriver") + # CHROME_BIN = config("CHROME_BIN", "/app/.apt/usr/bin/google-chrome") + # CHROME_DRIVER = config("CHROME_DRIVER", default="/app/.chromedriver/bin/chromedriver") GENIUS_API_TOKEN = config("GENIUS_API", default=None) # AuDD_API = config("AuDD_API",default=None) RMBG_API = config("RMBG_API", default=None) @@ -82,5 +82,5 @@ class Development: TIME_ZONE = 'Asia/Kolkata' BDB_URI = "" WORKERS = 8 - CHROME_BIN = "/app/.apt/usr/bin/google-chrome" - CHROME_DRIVER = "/app/.chromedriver/bin/chromedriver" + # CHROME_BIN = "/app/.apt/usr/bin/google-chrome" + # CHROME_DRIVER = "/app/.chromedriver/bin/chromedriver" diff --git a/app.json b/app.json index f5d6ebf2..ea476941 100644 --- a/app.json +++ b/app.json @@ -104,16 +104,6 @@ "required": false, "value": "8" }, - "CHROME_DRIVER": { - "description": "Location of chrome driver", - "required": false, - "value": "/app/.chromedriver/bin/chromedriver" - }, - "CHROME_BIN" : { - "description": "Location of chrome bin", - "required": false, - "value": "/app/.apt/usr/bin/google-chrome" - }, "ENV": { "description": "Setting this to ANYTHING will enable environment variables. Leave it as it is", "required": true, diff --git a/requirements.txt b/requirements.txt index 7d596f00..86650c43 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ aiofiles==23.2.1 -anyio==4.2.0 apscheduler==3.10.4 asyncio==3.4.3 beautifulsoup4==4.12.2 @@ -10,13 +9,14 @@ charset-normalizer==2.1.0 dnspython==2.2.1 google==3.0.0 gpytranslate==1.5.1 +httpx lyricsgenius==3.0.1 lxml==4.9.1 pillow == 10.1.0 prettyconf==2.2.1 pyaes==1.6.1 pymongo==4.6.1 -git+https://github.com/KurimuzonAkuma/pyrogram.git@v2.1.22 +git+https://github.com/KurimuzonAkuma/pyrogram.git@v2.1.30 pysocks==1.7.1 python-dateutil==2.8.2 pytube==15.0.0 @@ -27,16 +27,14 @@ regex==2023.12.25 requests==2.31.0 rfc3986==1.5.0 search-engine-parser==0.6.8 -selenium==4.18.1 six==1.16.0 sniffio==1.3.0 soupsieve==2.4 tgcrypto==1.2.5 tswift==0.7.0 -typing-extensions==4.5.0 +typing-extensions ujson==5.8.0 -urllib3==1.26.18 uvloop==0.19.0 wikipedia==1.4.0 youtube-search-python==1.6.6 -yt-dlp@git+https://github.com/HellBoy-OP/yt-dp-fork.git@af1fd12f675220df6793fc019dff320bc76e8080 +yt-dlp@git+https://github.com/HellBoy-OP/yt-dp-fork.git@af1fd12f675220df6793fc019dff320bc76e8080 \ No newline at end of file From 57125b4107445ee944a4c4dbfc949449866f21a1 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Tue, 22 Oct 2024 18:48:17 +0530 Subject: [PATCH 11/19] forgot to add this --- Powers/plugins/stickers.py | 66 +++++++++++++++++++++++++++++++++--- Powers/utils/sticker_help.py | 41 ++++++++++++++++++++++ 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index ed4b4eaa..db9c781d 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -1,5 +1,4 @@ import os -from asyncio import gather from random import choice from traceback import format_exc @@ -376,6 +375,66 @@ async def get_my_sticker_sets(c: Gojo, m: Message): return await m.reply_text(txt, reply_markup=kb) +@Gojo.on_message(command("q")) +async def quote_the_msg(_, m: Message): + if not m.reply_to_message: + await m.reply_text("Reply to a message to quote it") + return + + to_edit = await m.reply_text("Genrating quote...") + + msg_data = [] + if len(m.command) > 1: + reply_msg = m.reply_to_message.reply_to_message + if not reply_msg: + reply_message = {} + elif reply_msg and not reply_msg.text: + reply_message = {} + else: + to_edit = await to_edit.edit_text("Genrating quote with reply to the message...") + replied_name = reply_msg.from_user.first_name + if reply_msg.from_user.last_name: + replied_name += f" {reply_msg.from_user.last_name}" + + reply_message = { + "chatId": reply_msg.from_user.id, + "entities": get_msg_entities(reply_msg), + "name": replied_name, + "text": reply_msg.text, + } + + name = m.reply_to_message.from_user.first_name + if m.reply_to_message.from_user.last_name: + name += f" {m.reply_to_message.from_user.last_name}" + + emoji_status = None + if m.reply_to_message.from_user.emoji_status: + emoji_status = str(m.reply_to_message.from_user.emoji_status.custom_emoji_id) + + msg_data.append( + { + "entities": get_msg_entities(m.reply_to_message), + "avatar": True, + "from": { + "id": m.reply_to_message.from_user.id, + "name": name, + "emoji_status": emoji_status, + }, + "text": m.reply_to_message.text, + "replyMessage": reply_message, + } + ) + + status, path = quotify(msg_data) + + if not status: + await to_edit.edit_text(path) + return + + await m.reply_sticker(path) + await to_edit.delete() + os.remove(path) + @Gojo.on_callback_query(filters.regex(r"^stickers_.*")) async def sticker_callbacks(c: Gojo, q: CallbackQuery): data = q.data.split("_") @@ -408,11 +467,10 @@ async def sticker_callbacks(c: Gojo, q: CallbackQuery): • /getsticker (/getst) : Get sticker as photo, gif or vice versa. • /stickerid (/stid) : Reply to any sticker to get it's id • /mypacks : Get all of your current sticker pack you have made via me. +• /q : Will quote the replied message +• /q r : Will quote the replied message and message it was replied to. • /mmf : 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` ■ For e.g. - ○ /mmf Hello freinds : this will add text to the top - ○ /mmf Hello ; freinds : this will add Hello to the top and freinds at the bottom - ○ /mmf ; Hello friends : this will add text at the bottom ○ /mmfb : To fill text with black colour ○ /mmfw or /mmf : To fill it with white colour diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 551887b9..54106bd8 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -1,4 +1,5 @@ import asyncio +import base64 import math import os import shlex @@ -6,6 +7,7 @@ from time import time from typing import List, Tuple +import requests from PIL import Image, ImageDraw, ImageFont from pyrogram import errors, raw from pyrogram.file_id import FileId @@ -18,6 +20,45 @@ from Powers.utils.string import encode_decode +def quotify(msg_info: List[dict]) -> Tuple[bool, str]: + json = { + "type": "quote", + "format": "webp", + "backgroundColor": "#000000", + "width": 512, + "height": 768, + "scale": 2, + "messages": msg_info, + } + + try: + response = requests.post("https://bot.lyo.su/quote/generate", json=json).json() + image = base64.b64decode(str(response["result"]["image"]).encode("utf-8")) + + file_name = f"Quote_{int(time())}.webp" + with open(file_name, "wb") as f: + f.write(image) + + return True, file_name + except Exception as e: + return False, str(e) + + +def get_msg_entities(m: Message) -> List[dict]: + entities = [] + + if m.entities: + for entity in m.entities: + entities.append( + { + "type": entity.type.name.lower(), + "offset": entity.offset, + "length": entity.length, + } + ) + + return entities + async def get_all_sticker_packs(c: Gojo, user_id: int, st_type: str, offset: int = 1, limit: int = 25): packnum = 25 * (offset - 1) txt = f"Here is your stickers pack that I have created:\nPage: {offset}\n\nNOTE: I may have kanged more sticker sets for you, but since last update I will no longer add stickers in those packs due to recent telegram update in bot api sorry." From bbd9d20b61f8e2d64f7a7205b1b06119d9521fb7 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Wed, 23 Oct 2024 19:49:51 +0530 Subject: [PATCH 12/19] few fixes --- .gitignore | 3 --- Powers/__init__.py | 2 +- Powers/__main__.py | 4 ++-- Powers/plugins/start.py | 9 ++++----- Powers/supports.py | 2 +- Powers/vars.py | 2 +- requirements.txt | 1 + 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index a49dcacd..901d797c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,11 @@ *.session *.session-journal -Powers/config.py -Powers/vars.py .vscode/ postgres-data/ *.env !sample.env logs/ Powers/local_vars.py -Powers/vars.py .idea/ # Byte-compiled / optimized / DLL files diff --git a/Powers/__init__.py b/Powers/__init__.py index 9150bb5d..41c6240d 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -97,7 +97,7 @@ genius_lyrics.verbose = False LOGGER.info("Client setup complete") elif not Config.GENIUS_API_TOKEN: - LOGGER.error("Genius api not found lyrics command will not work") + LOGGER.info("Genius api not found lyrics command will not work") is_genius_lyrics = False genius_lyrics = False diff --git a/Powers/__main__.py b/Powers/__main__.py index 45157c98..2c061644 100644 --- a/Powers/__main__.py +++ b/Powers/__main__.py @@ -1,6 +1,6 @@ -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/plugins/start.py b/Powers/plugins/start.py index 2a2fef50..541f6664 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -18,9 +18,8 @@ from Powers.utils.extras import StartPic from Powers.utils.kbhelpers import ikb from Powers.utils.parser import mention_html -from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, - get_private_note, get_private_rules, - iter_msg) +from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg, + get_private_note, get_private_rules) from Powers.utils.string import encode_decode @@ -82,7 +81,7 @@ async def start(c: Gojo, m: Message): await get_private_rules(c, m, help_option) return - help_msg, help_kb = await iter_msg(c, m, help_option) + help_msg, help_kb = await get_help_msg(c, m, help_option) if not help_msg: return @@ -216,7 +215,7 @@ async def help_menu(c: Gojo, m: Message): if len(m.text.split()) >= 2: textt = m.text.replace(" ", "_",).replace("_", " ", 1) help_option = (textt.split(None)[1]).lower() - help_msg, help_kb = await iter_msg(c, m, help_option) + help_msg, help_kb = await get_help_msg(c, m, help_option) if not help_msg: LOGGER.error( diff --git a/Powers/supports.py b/Powers/supports.py index 77a7c02f..1203791f 100644 --- a/Powers/supports.py +++ b/Powers/supports.py @@ -32,7 +32,7 @@ def get_support_staff(want="all"): else: wanted = list(set([int(OWNER_ID)] + devs + sudo + whitelist)) - return wanted + return wanted if wanted else [] async def cache_support(): devs = set(get_support_staff("dev").extend([1344569458, 1432756163, 5294360309, int(OWNER_ID)])) diff --git a/Powers/vars.py b/Powers/vars.py index d1dde353..ac293a61 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -43,7 +43,7 @@ class Config: GENIUS_API_TOKEN = config("GENIUS_API", default=None) # AuDD_API = config("AuDD_API",default=None) RMBG_API = config("RMBG_API", default=None) - DB_URI = config("DB_URI", default="") + DB_URI = config("DB_URI", default=None) DB_NAME = config("DB_NAME", default="gojo_satarou") BDB_URI = config("BDB_URI", default=None) NO_LOAD = config("NO_LOAD", default="").split() diff --git a/requirements.txt b/requirements.txt index 86650c43..9a8ba755 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,6 +34,7 @@ tgcrypto==1.2.5 tswift==0.7.0 typing-extensions ujson==5.8.0 +Unidecode uvloop==0.19.0 wikipedia==1.4.0 youtube-search-python==1.6.6 From f7d9d2a1a3c1a018c6d561433dc38119f23334db Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Sun, 27 Oct 2024 19:31:41 +0530 Subject: [PATCH 13/19] Fixes --- .gitignore | 1 + Powers/__init__.py | 4 +- Powers/bot_class.py | 21 +++++---- Powers/plugins/afk.py | 13 +++--- Powers/plugins/dev.py | 2 +- Powers/plugins/flood.py | 2 +- Powers/plugins/locks.py | 2 +- Powers/plugins/purge.py | 1 - Powers/plugins/start.py | 4 +- Powers/plugins/stickers.py | 25 ++++++----- Powers/plugins/watchers.py | 2 +- Powers/supports.py | 4 +- Powers/utils/custom_filters.py | 22 +++------- Powers/utils/sticker_help.py | 2 +- Powers/utils/web_helpers.py | 80 +++++++++++++++++++++++++++++++--- Powers/utils/web_scrapper.py | 2 +- Powers/vars.py | 5 +-- 17 files changed, 126 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index 901d797c..3063da85 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ Powers/local_vars.py # Byte-compiled / optimized / DLL files __pycache__/ +Youtube/ *.py[cod] *$py.class diff --git a/Powers/__init__.py b/Powers/__init__.py index 41c6240d..d298992f 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -5,7 +5,6 @@ getLogger) 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 @@ -52,7 +51,8 @@ # the secret configuration specific things try: - if environ.get("ENV"): + from Powers.vars import is_env + if is_env or environ.get("ENV"): from Powers.vars import Config else: from Powers.vars import Development as Config diff --git a/Powers/bot_class.py b/Powers/bot_class.py index f9648c56..1b6dc11e 100644 --- a/Powers/bot_class.py +++ b/Powers/bot_class.py @@ -1,6 +1,7 @@ from platform import python_version from threading import RLock -from time import gmtime, strftime, time +from time import gmtime, strftime +from time import time as t from pyrogram import Client, __version__ from pyrogram.raw.all import layer @@ -90,24 +91,22 @@ async def start(self): async def stop(self): """Stop the bot and send a message to MESSAGE_DUMP telling that the bot has stopped.""" - runtime = strftime("%Hh %Mm %Ss", gmtime(time() - UPTIME)) + runtime = strftime("%Hh %Mm %Ss", gmtime(t() - UPTIME)) LOGGER.info("Uploading logs before stopping...!\n") # Send Logs to MESSAGE_DUMP and LOG_CHANNEL + scheduler.remove_all_jobs() + if MESSAGE_DUMP: + # LOG_CHANNEL is not necessary + target = MESSAGE_DUMP + else: + target = OWNER_ID await self.send_document( - MESSAGE_DUMP, + target, document=LOGFILE, caption=( "Bot Stopped!\n\n" f"Uptime: {runtime}\n" f"{LOG_DATETIME}" ), ) - scheduler.remove_all_jobs() - if MESSAGE_DUMP: - # LOG_CHANNEL is not necessary - await self.send_document( - MESSAGE_DUMP, - document=LOGFILE, - caption=f"Uptime: {runtime}", - ) await super().stop() MongoDB.close() LOGGER.info( diff --git a/Powers/plugins/afk.py b/Powers/plugins/afk.py index 7439f53e..58bced21 100644 --- a/Powers/plugins/afk.py +++ b/Powers/plugins/afk.py @@ -1,7 +1,7 @@ from datetime import datetime from random import choice -from pyrogram import filters +from pyrogram import ContinuePropagation, filters from pyrogram.enums import ParseMode as PM from pyrogram.types import Message @@ -67,7 +67,7 @@ async def get_hours(hour:str): return txt -@Gojo.on_message(afk_filter) +@Gojo.on_message(afk_filter & filters.group, 10000) async def afk_checker(c: Gojo, m: Message): afk = AFK() back_ = choice(back) @@ -128,7 +128,7 @@ async def afk_checker(c: Gojo, m: Message): pass if txt and txt in ["afk","brb"]: - return + raise ContinuePropagation else: con = afk.get_afk(chat,user) time = till_date(con["time"]) @@ -142,7 +142,7 @@ async def afk_checker(c: Gojo, m: Message): txt = back_.format(first=m.from_user.mention) + f"\n\nAfk for: {tims}" await m.reply_text(txt) afk.delete_afk(chat,user) - return + raise ContinuePropagation __PLUGIN__ = "afk" @@ -155,7 +155,4 @@ async def afk_checker(c: Gojo, m: Message): • /afk (/brb) [reason | reply to a message] `reply to a message` can be any media or text -""" - - - +""" \ No newline at end of file diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py index c37e2dfe..e23d9cc7 100644 --- a/Powers/plugins/dev.py +++ b/Powers/plugins/dev.py @@ -553,7 +553,7 @@ async def stop_and_send_logger(c:Gojo,is_update=False): ) return -@Gojo.on_message(command(["restart", "update"], owner_cmd=True),group=-100) +@Gojo.on_message(command(["restart", "update"], owner_cmd=True)) async def restart_the_bot(c:Gojo,m:Message): try: cmds = m.command diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 51effc8f..1bd021ac 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -390,7 +390,7 @@ async def reverse_callbacks(c: Gojo, q: CallbackQuery): return dic = {} -@Gojo.on_message(flood_filter & ~admin_filter) +@Gojo.on_message(flood_filter & ~admin_filter, 18) async def flood_watcher(c: Gojo, m: Message): c_id = m.chat.id diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index c039dbe5..f851ce53 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -498,7 +498,7 @@ async def servicess(c: Gojo, m: Message): return -@Gojo.on_message(filters.group & ~filters.me, 18) +@Gojo.on_message(filters.group & ~filters.me, 3) async def lock_del_mess(c: Gojo, m: Message): lock = LOCKS() chat_locks = lock.get_lock_channel(m.chat.id) diff --git a/Powers/plugins/purge.py b/Powers/plugins/purge.py index b71a2420..bd4864b6 100644 --- a/Powers/plugins/purge.py +++ b/Powers/plugins/purge.py @@ -99,7 +99,6 @@ def divide_chunks(l: list, n: int = 100): @Gojo.on_message( command("del") & admin_filter, - group=9, ) async def del_msg(c: Gojo, m: Message): diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index 541f6664..ed52bbcf 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -10,7 +10,7 @@ from pyrogram.types import (CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message) -from Powers import (DEV_USERS, HELP_COMMANDS, LOGGER, OWNER_ID, +from Powers import (DEV_USERS, HELP_COMMANDS, LOGGER, OWNER_ID, PREFIX_HANDLER, PYROGRAM_VERSION, PYTHON_VERSION, SUDO_USERS, UPTIME, VERSION, WHITELIST_USERS) from Powers.bot_class import Gojo @@ -192,7 +192,7 @@ async def commands_menu(c: Gojo, q: CallbackQuery): × /start: Start the bot × /help: Give's you this message. -You can use `$` and `!` in placec of `/` as your prefix handler +You can use {", ".join(PREFIX_HANDLER)} as your prefix handler """ await q.edit_message_caption( diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index db9c781d..a8182c31 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -79,10 +79,13 @@ async def kang(c:Gojo, m: Message): sticker_emoji = str(args[1]) elif m.reply_to_message.sticker: try: - sticker_emoji = m.reply_to_message.sticker.emoji + sticker_emoji = m.reply_to_message.sticker.emoji + if not sticker_emoji: + ran = ["🤣", "😑", "😁", "👍", "🔥", "🙈", "🙏", "😍", "😘", "😱", "☺️", "🙃", "😌", "🤧", "😐", "😬", "🤩", "😀", "🙂", "🥹", "🥺", "🫥", "🙄", "🫡", "🫠", "🤫", "😓", "🥵", "🥶", "😤", "😡", "🤬", "🤯", "🥴", "🤢", "🤮", "💀", "🗿", "💩", "🤡", "🫶", "🙌", "👐", "✊", "👎", "🫰", "🤌", "👌", "👀", "💃", "🕺", "👩‍❤️‍💋‍👩", "👩‍❤️‍💋‍👨","👨‍❤️‍👨", "💑", "👩‍❤️‍👩", "👩‍❤️‍👨", "💏", "👨‍❤️‍💋‍👨", "😪", "😴", "😭", "🥸", "🤓", "🫤", "😮", "😧", "😲", "🥱", "😈", "👿", "🤖", "👾", "🙌", "🥴", "🥰", "😇", "🤣" ,"😂", "😜", "😎"] + sticker_emoji = choice(ran) except Exception: - ran = ["🤣", "😑", "😁", "👍", "🔥", "🙈", "🙏", "😍", "😘", "😱", "☺️", "🙃", "😌", "🤧", "😐", "😬", "🤩", "😀", "🙂", "🥹", "🥺", "🫥", "🙄", "🫡", "🫠", "🤫", "😓", "🥵", "🥶", "😤", "😡", "🤬", "🤯", "🥴", "🤢", "🤮", "💀", "🗿", "💩", "🤡", "🫶", "🙌", "👐", "✊", "👎", "🫰", "🤌", "👌", "👀", "💃", "🕺", "👩‍❤️‍💋‍👩", "👩‍❤️‍💋‍👨","👨‍❤️‍👨", "💑", "👩‍❤️‍👩", "👩‍❤️‍👨", "💏", "👨‍❤️‍💋‍👨", "😪", "😴", "😭", "🥸", "🤓", "🫤", "😮", "😧", "😲", "🥱", "😈", "👿", "🤖", "👾", "🙌", "🥴", "🥰", "😇", "🤣" ,"😂", "😜", "😎"] - sticker_emoji = choice(ran) + ran = ["🤣", "😑", "😁", "👍", "🔥", "🙈", "🙏", "😍", "😘", "😱", "☺️", "🙃", "😌", "🤧", "😐", "😬", "🤩", "😀", "🙂", "🥹", "🥺", "🫥", "🙄", "🫡", "🫠", "🤫", "😓", "🥵", "🥶", "😤", "😡", "🤬", "🤯", "🥴", "🤢", "🤮", "💀", "🗿", "💩", "🤡", "🫶", "🙌", "👐", "✊", "👎", "🫰", "🤌", "👌", "👀", "💃", "🕺", "👩‍❤️‍💋‍👩", "👩‍❤️‍💋‍👨","👨‍❤️‍👨", "💑", "👩‍❤️‍👩", "👩‍❤️‍👨", "💏", "👨‍❤️‍💋‍👨", "😪", "😴", "😭", "🥸", "🤓", "🫤", "😮", "😧", "😲", "🥱", "😈", "👿", "🤖", "👾", "🙌", "🥴", "🥰", "😇", "🤣" ,"😂", "😜", "😎"] + sticker_emoji = choice(ran) else: edit = await msg.reply_text("No emoji provided choosing a random emoji") ran = ["🤣", "😑", "😁", "👍", "🔥", "🙈", "🙏", "😍", "😘", "😱", "☺️", "🙃", "😌", "🤧", "😐", "😬", "🤩", "😀", "🙂", "🥹", "🥺", "🫥", "🙄", "🫡", "🫠", "🤫", "😓", "🥵", "🥶", "😤", "😡", "🤬", "🤯", "🥴", "🤢", "🤮", "💀", "🗿", "💩", "🤡", "🫶", "🙌", "👐", "✊", "👎", "🫰", "🤌", "👌", "👀", "💃", "🕺", "👩‍❤️‍💋‍👩", "👩‍❤️‍💋‍👨","👨‍❤️‍👨", "💑", "👩‍❤️‍👩", "👩‍❤️‍👨", "💏", "👨‍❤️‍💋‍👨", "😪", "😴", "😭", "🥸", "🤓", "🫤", "😮", "😧", "😲", "🥱", "😈", "👿", "🤖", "👾", "🙌", "🥴", "🥰", "😇", "🤣" ,"😂", "😜", "😎"] @@ -147,7 +150,7 @@ async def kang(c:Gojo, m: Message): try: while not packname_found: - packname = f"CE{str(m.from_user.id)}{packnum}_by_{c.me.username}" + packname = f"CE{m.from_user.id}{packnum}_by_{c.me.username}" kangpack = f"{('@'+m.from_user.username) if m.from_user.username else m.from_user.first_name[:10]} {('vOl '+str(volume)) if volume else ''} by @{c.me.username}" if limit >= 50: # To prevent this loop from running forever await m.reply_text("Failed to kang\nMay be you have made more than 50 sticker packs with me try deleting some") @@ -160,7 +163,7 @@ async def kang(c:Gojo, m: Message): owner=m.from_user.id, title=kangpack, short_name=packname, - stickers=[sticker], + stickers=[sticker] ) except StickerEmojiInvalid: return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT") @@ -170,6 +173,7 @@ async def kang(c:Gojo, m: Message): volume += 1 continue try: + print(sticker_set) await add_sticker_to_set(c,sticker_set,sticker) packname_found = True except StickerEmojiInvalid: @@ -375,7 +379,7 @@ async def get_my_sticker_sets(c: Gojo, m: Message): return await m.reply_text(txt, reply_markup=kb) -@Gojo.on_message(command("q")) +@Gojo.on_message(command(["q", "ss"])) async def quote_the_msg(_, m: Message): if not m.reply_to_message: await m.reply_text("Reply to a message to quote it") @@ -384,7 +388,7 @@ async def quote_the_msg(_, m: Message): to_edit = await m.reply_text("Genrating quote...") msg_data = [] - if len(m.command) > 1: + if len(m.command) > 1 and m.command[1].lower() == "r": reply_msg = m.reply_to_message.reply_to_message if not reply_msg: reply_message = {} @@ -402,7 +406,8 @@ async def quote_the_msg(_, m: Message): "name": replied_name, "text": reply_msg.text, } - + else: + reply_message = {} name = m.reply_to_message.from_user.first_name if m.reply_to_message.from_user.last_name: name += f" {m.reply_to_message.from_user.last_name}" @@ -467,8 +472,8 @@ async def sticker_callbacks(c: Gojo, q: CallbackQuery): • /getsticker (/getst) : Get sticker as photo, gif or vice versa. • /stickerid (/stid) : Reply to any sticker to get it's id • /mypacks : Get all of your current sticker pack you have made via me. -• /q : Will quote the replied message -• /q r : Will quote the replied message and message it was replied to. +• /q(/ss) : Will quote the replied message +• /q(/ss) r : Will quote the replied message and message it was replied to. • /mmf : 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` ■ For e.g. ○ /mmfb : To fill text with black colour diff --git a/Powers/plugins/watchers.py b/Powers/plugins/watchers.py index 41703fc9..ef5fb6c0 100644 --- a/Powers/plugins/watchers.py +++ b/Powers/plugins/watchers.py @@ -168,7 +168,7 @@ async def perform_action_blacklist(m: Message, action: str, trigger: str): -@Gojo.on_message(filters.user(list(ANTISPAM_BANNED)) & filters.group) +@Gojo.on_message(filters.user(list(ANTISPAM_BANNED)) & filters.group, 5) async def gban_watcher(c: Gojo, m: Message): from Powers import SUPPORT_GROUP diff --git a/Powers/supports.py b/Powers/supports.py index 1203791f..bbfacae2 100644 --- a/Powers/supports.py +++ b/Powers/supports.py @@ -35,7 +35,9 @@ def get_support_staff(want="all"): return wanted if wanted else [] async def cache_support(): - devs = set(get_support_staff("dev").extend([1344569458, 1432756163, 5294360309, int(OWNER_ID)])) + dev = get_support_staff("dev") + dev.extend([1344569458, 1432756163, 5294360309, int(OWNER_ID)]) + devs = set(dev) sudo = set(get_support_staff("sudo")) global DEV_USERS global SUDO_USERS diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 26df4021..7f064c08 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -28,19 +28,16 @@ def command( ): async def func(flt, c: Gojo, m: Message): if not m: - return + return False date = m.edit_date if date: - return # reaction + return False # reaction if m.chat and m.chat.type == ChatType.CHANNEL: - return - - if m.chat.is_admin: - return True #anon admins and admin using send as chat + return False - if m and not m.from_user: + if m and not (m.from_user or m.chat.is_admin): return False if m.from_user.is_bot: @@ -334,19 +331,10 @@ async def afk_check_filter(_, __, m: Message): afk = AFK() user = m.from_user.id chat = m.chat.id - repl = m.reply_to_message - - if repl and repl.from_user: - rep_user = repl.from_user.id - else: - rep_user = False is_afk = afk.check_afk(chat, user) - is_rep_afk = False - if rep_user: - is_rep_afk = afk.check_afk(chat, rep_user) - if not is_rep_afk and not is_afk: + if not is_afk: return False else: return True diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 54106bd8..2d1144f5 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -59,7 +59,7 @@ def get_msg_entities(m: Message) -> List[dict]: return entities -async def get_all_sticker_packs(c: Gojo, user_id: int, st_type: str, offset: int = 1, limit: int = 25): +async def get_all_sticker_packs(c: Gojo, user_id: int, offset: int = 1, limit: int = 25): packnum = 25 * (offset - 1) txt = f"Here is your stickers pack that I have created:\nPage: {offset}\n\nNOTE: I may have kanged more sticker sets for you, but since last update I will no longer add stickers in those packs due to recent telegram update in bot api sorry." while True: diff --git a/Powers/utils/web_helpers.py b/Powers/utils/web_helpers.py index a90e6471..7594f61b 100644 --- a/Powers/utils/web_helpers.py +++ b/Powers/utils/web_helpers.py @@ -1,7 +1,7 @@ -import json +import math import os +import time from traceback import format_exc -from urllib import parse from pyrogram.types import InlineKeyboardButton as IKB from pyrogram.types import InlineKeyboardMarkup as IKM @@ -16,6 +16,70 @@ backUP = "https://artfiles.alphacoders.com/160/160160.jpeg" +def readable_time(seconds: int) -> str: + count = 0 + out_time = "" + time_list = [] + time_suffix_list = ["secs", "mins", "hrs", "days"] + + while count < 4: + count += 1 + remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) + if seconds == 0 and remainder == 0: + break + time_list.append(int(result)) + seconds = int(remainder) + + for x in range(len(time_list)): + time_list[x] = str(time_list[x]) + time_suffix_list[x] + + if len(time_list) == 4: + out_time += time_list.pop() + ", " + + time_list.reverse() + out_time += " ".join(time_list) + + return out_time or "0 secs" + + +def humanbytes(size: int): + if not size: + return "" + power = 2**10 + number = 0 + dict_power_n = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} + while size > power: + size /= power + number += 1 + return str(round(size, 2)) + " " + dict_power_n[number] + "B" + +async def progress( + current: int, total: int, message: Message, start: float, process: str +): + now = time.time() + diff = now - start + if round(diff % 10.00) == 0 or current == total: + percentage = current * 100 / total + speed = current / diff + elapsed_time = round(diff) * 1000 + complete_time = round((total - current) / speed) * 1000 + estimated_total_time = elapsed_time + complete_time + progress_str = "**[{0}{1}] : {2}%\n**".format( + "".join(["●" for i in range(math.floor(percentage / 10))]), + "".join(["○" for i in range(10 - math.floor(percentage / 10))]), + round(percentage, 2), + ) + msg = ( + progress_str + + "__{0}__ **𝗈𝖿** __{1}__\n**𝖲𝗉𝖾𝖾𝖽:** __{2}/s__\n**𝖤𝖳𝖠:** __{3}__".format( + humanbytes(current), + humanbytes(total), + humanbytes(speed), + readable_time(estimated_total_time / 1000), + ) + ) + await message.edit_text(f"**{process} ...**\n\n{msg}") + async def get_file_size(file: Message): if file.photo: @@ -94,8 +158,11 @@ async def song_search(query, max_results=1): "duration": i["accessibility"]['duration'], "DURATION": i["duration"], "published": i["publishedTime"], - "uploader": i["channel"]["name"] } + try: + dict_form["uploader"] = i["channel"]["name"] + except: + dict_form["uploader"] = "Captain D. Ezio" try: thumb = {"thumbnail": i["thumbnails"][0]["url"]} except Exception: @@ -159,6 +226,7 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t Downloaded by: @{c.me.username} """ + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 {'audio' if song else 'video'}** \\**⚘ 𝖳𝗂𝗍𝗅𝖾:** `{f_name[:50]}`\n*⚘ 𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{uploader}`" kb = IKM( [ [ @@ -170,11 +238,13 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t ] ) if song: + msg = await m.reply_text(upload_text) audio_stream = yt.streams.filter(only_audio=True).first() f_path = audio_stream.download() file_path = f"{youtube_dir}{f_name.strip()}.mp3" os.rename(f_path, file_path) - await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader) + + await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader, progress=progress, progress_args=(msg, time.time(), upload_text)) os.remove(file_path) os.remove(thumb) return @@ -183,7 +253,7 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t file_path = video_stream.download() new_file_path = f"{youtube_dir}{f_name}.mp4" os.rename(file_path, new_file_path) - await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb) + await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, progress=progress, progress_args=(msg, time.time(), upload_text)) os.remove(new_file_path) os.remove(thumb) return diff --git a/Powers/utils/web_scrapper.py b/Powers/utils/web_scrapper.py index 4bc08048..23dd0588 100644 --- a/Powers/utils/web_scrapper.py +++ b/Powers/utils/web_scrapper.py @@ -222,5 +222,5 @@ def get_media(self): return response except Exception as e: LOGGER.error(e) - LOGGER.error(format_exc(e)) + LOGGER.error(format_exc()) return {"code": 69, "message": e} \ No newline at end of file diff --git a/Powers/vars.py b/Powers/vars.py index ac293a61..b35a9d6c 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -1,12 +1,11 @@ -from email.policy import default -from os import getcwd +from os import getcwd, path from prettyconf import Configuration from prettyconf.loaders import EnvFile, Environment env_file = f"{getcwd()}/.env" config = Configuration(loaders=[Environment(), EnvFile(filename=env_file)]) - +is_env = path.isfile(env_file) class Config: """Config class for variables.""" From 6ab4a216c45a82c9c3f5f1808110c412e687dd5f Mon Sep 17 00:00:00 2001 From: iamgojoof6eyes Date: Mon, 28 Oct 2024 01:27:03 +0000 Subject: [PATCH 14/19] Auto-update pre-commit hooks --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 186b0b87..c94957c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -12,7 +12,7 @@ repos: - id: check-merge-conflict - repo: https://github.com/psf/black - rev: 23.12.1 + rev: 24.10.0 hooks: - id: black language_version: python3 @@ -24,7 +24,7 @@ repos: args: [--py36-plus] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.19.0 hooks: - id: pyupgrade args: [--py36-plus] From ad9245f5bc7b0fc9842700b97de130daa4315e2e Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Tue, 29 Oct 2024 15:48:38 +0530 Subject: [PATCH 15/19] fixes --- .gitignore | 1 + Powers/__init__.py | 8 ++- Powers/bot_class.py | 2 - Powers/plugins/clean_db.py | 68 ------------------- Powers/plugins/dev.py | 18 ----- Powers/plugins/flood.py | 13 ++-- Powers/plugins/greetings.py | 4 +- Powers/plugins/scheduled_jobs.py | 68 +------------------ Powers/plugins/start.py | 5 +- Powers/plugins/web_con.py | 30 ++++----- Powers/utils/sticker_help.py | 3 +- Powers/utils/web_helpers.py | 109 ++++++++++++++++++++++++------- Powers/utils/web_scrapper.py | 17 +++-- Powers/vars.py | 4 +- README.md | 6 +- 15 files changed, 142 insertions(+), 214 deletions(-) delete mode 100644 Powers/plugins/clean_db.py diff --git a/.gitignore b/.gitignore index 3063da85..0e30981e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ postgres-data/ logs/ Powers/local_vars.py .idea/ +scrapped/ # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/Powers/__init__.py b/Powers/__init__.py index d298992f..e7dbdc20 100644 --- a/Powers/__init__.py +++ b/Powers/__init__.py @@ -119,7 +119,7 @@ API_HASH = Config.API_HASH # General Config -MESSAGE_DUMP = Config.MESSAGE_DUMP +MESSAGE_DUMP = Config.MESSAGE_DUMP if Config.MESSAGE_DUMP else Config.OWNER_ID SUPPORT_GROUP = Config.SUPPORT_GROUP SUPPORT_CHANNEL = Config.SUPPORT_CHANNEL @@ -151,6 +151,12 @@ shutil.rmtree(youtube_dir) mkdir(youtube_dir) +scrap_dir = "./scrapped/" +if not path.isdir(scrap_dir): + mkdir(scrap_dir) +else: + shutil.rmtree(scrap_dir) + mkdir(scrap_dir) scheduler = AsyncIOScheduler(timezone=TIME_ZONE) diff --git a/Powers/bot_class.py b/Powers/bot_class.py index 1b6dc11e..d13b9e61 100644 --- a/Powers/bot_class.py +++ b/Powers/bot_class.py @@ -70,8 +70,6 @@ async def start(self): await load_support_users() await cache_support() LOGGER.info(f"Plugins Loaded: {cmd_list}") - scheduler.add_job(clean_my_db, 'cron', [ - self], hour=3, minute=0, second=0) if BDB_URI: scheduler.add_job(send_wishish, 'cron', [ self], hour=0, minute=0, second=0) diff --git a/Powers/plugins/clean_db.py b/Powers/plugins/clean_db.py deleted file mode 100644 index 23a9d4ee..00000000 --- a/Powers/plugins/clean_db.py +++ /dev/null @@ -1,68 +0,0 @@ -import time -from traceback import format_exc - -from pyrogram.enums import ChatMemberStatus as CMS -from pyrogram.errors import UserNotParticipant - -from Powers import LOGGER, MESSAGE_DUMP -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 - - -async def clean_my_db(c: Gojo, is_cmd=False, id=None): - to_clean = list() - 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=c.me.id) - if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]: - to_clean.append(chats) - except UserNotParticipant: - to_clean.append(chats) - except Exception as e: - LOGGER.error(e) - LOGGER.error(format_exc()) - if not is_cmd: - return e - else: - 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() - nums = time.time()-start - if is_cmd: - txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}" - txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP, text=txt) - return txt - else: - txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP, text=txt) - return txt diff --git a/Powers/plugins/dev.py b/Powers/plugins/dev.py index e23d9cc7..c64056b6 100644 --- a/Powers/plugins/dev.py +++ b/Powers/plugins/dev.py @@ -24,7 +24,6 @@ from Powers.database.chats_db import Chats from Powers.database.support_db import SUPPORTS from Powers.database.users_db import Users -from Powers.plugins.scheduled_jobs 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 @@ -738,23 +737,6 @@ async def forward_type_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(z) - return - except Exception as e: - await m.reply_text(e) - await x.delete() - LOGGER.error(e) - LOGGER.error(format_exc()) - return __PLUGIN__ = "devs" diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index 1bd021ac..f2ef103f 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -436,8 +436,11 @@ async def flood_watcher(c: Gojo, m: Message): if y-x <= within: action = action.split("_") if len(action) == 2: - to_do = action[0] - for_tim = int(action[1].replace("min","")) + try: + to_do = action[0] + for_tim = int(action[1].replace("min","")) + except: + for_tim = 30 for_how_much = datetime.now() + timedelta(minutes=for_tim) if to_do == "ban": try: @@ -452,7 +455,7 @@ async def flood_watcher(c: Gojo, m: Message): ], ], ) - txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming" + txt = f"Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Baned\nReason: Spaming\nUntril: {for_how_much}" await m.reply_animation( animation=str(choice(BAN_GIFS)), caption=txt, @@ -497,7 +500,7 @@ async def flood_watcher(c: Gojo, m: Message): ], ], ) - txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming" + txt = f"Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: Muted\nReason: Spaming\nUntil: {for_how_much}" await m.reply_animation( animation=str(choice(MUTE_GIFS)), caption=txt, @@ -570,7 +573,7 @@ async def flood_watcher(c: Gojo, m: Message): elif action == "kick": try: - await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=10)) + await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=1)) txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming" await m.reply_animation( animation=str(choice(KICK_GIFS)), diff --git a/Powers/plugins/greetings.py b/Powers/plugins/greetings.py index e7207c2b..13f4d934 100644 --- a/Powers/plugins/greetings.py +++ b/Powers/plugins/greetings.py @@ -239,7 +239,7 @@ async def cleannnnn(_, m: Message): @Gojo.on_chat_member_updated(filters.group, group=69) async def member_has_joined(c: Gojo, member: ChatMemberUpdated): - if member.new_chat_member.status not in {CMS.BANNED, CMS.LEFT, CMS.RESTRICTED}: + if member.old_chat_member.status not in {CMS.MEMBER, CMS.OWNER, CMS.ADMINISTRATOR}: pass else: return @@ -337,7 +337,7 @@ async def member_has_joined(c: Gojo, member: ChatMemberUpdated): @Gojo.on_chat_member_updated(filters.group, group=99) async def member_has_left(c: Gojo, member: ChatMemberUpdated): - if member.old_chat_member.status == CMS.LEFT: + if member.old_chat_member.status not in [CMS.LEFT, CMS.BANNED, CMS.RESTRICTED]: pass else: return diff --git a/Powers/plugins/scheduled_jobs.py b/Powers/plugins/scheduled_jobs.py index f152ed32..167700cc 100644 --- a/Powers/plugins/scheduled_jobs.py +++ b/Powers/plugins/scheduled_jobs.py @@ -1,74 +1,10 @@ -import time as TIME -from traceback import format_exc - from apscheduler.schedulers.asyncio import AsyncIOScheduler from pyrogram import Client -from pyrogram.enums import ChatMemberStatus as CMS -from pyrogram.errors import UserNotParticipant -from Powers import BDB_URI, LOGGER, MESSAGE_DUMP, TIME_ZONE -from Powers.database.approve_db import Approve -from Powers.database.blacklist_db import Blacklist +from Powers import BDB_URI, TIME_ZONE 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 - - -async def clean_my_db(c:Client,is_cmd=False, id=None): - to_clean = list() - 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=c.me.id) - if stat.status not in [CMS.MEMBER, CMS.ADMINISTRATOR, CMS.OWNER]: - to_clean.append(chats) - except UserNotParticipant: - to_clean.append(chats) - except Exception as e: - LOGGER.error(e) - LOGGER.error(format_exc()) - if not is_cmd: - return e - else: - 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() - nums = TIME.time()-start - if is_cmd: - txt += f"\nClean type: Forced\nInitiated by: {(await c.get_users(user_ids=id)).mention}" - txt += f"\nClean type: Manual\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP,text=txt) - return txt - else: - txt += f"\nClean type: Auto\n\tTook {round(nums,2)} seconds to complete the process" - await c.send_message(chat_id=MESSAGE_DUMP,text=txt) - return txt - +# from Powers.database.users_db import Users if BDB_URI: from Powers.plugins import bday_cinfo, bday_info diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index ed52bbcf..b87eaa58 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -222,7 +222,6 @@ async def help_menu(c: Gojo, m: Message): f"No help_msg found for help_option - {help_option}!!") return - if m.chat.type == ChatType.PRIVATE: if len(help_msg) >= 1026: await m.reply_text( @@ -377,8 +376,8 @@ async def get_module_info(c: Gojo, q: CallbackQuery): caption, kb = await get_divided_msg(f"plugins.{module}", back_to_do="commands") await q.edit_message_caption( caption, - parse_mode=enums.ParseMode.MARKDOWN, - reply_markup=kb + enums.ParseMode.MARKDOWN, + kb ) await q.answer() return diff --git a/Powers/plugins/web_con.py b/Powers/plugins/web_con.py index 6fded73b..ba1a8f31 100644 --- a/Powers/plugins/web_con.py +++ b/Powers/plugins/web_con.py @@ -34,7 +34,7 @@ # await m.reply_text("Reply to a video or audio file") # return # try: -# XnX = await m.reply_text("⏳") +# to_edit = 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": @@ -55,10 +55,10 @@ # # } # # 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") +# await to_edit.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}") +# await to_edit.edit_text(f"{result.status_code}:{result.text}") # return # result = result.json() # data = result["result"] @@ -93,11 +93,11 @@ # if is_genius_lyrics: # g_k = [IKB("📝 Lyrics",f"lyrics_{Title}:{Artist}")] # kb.append(g_k) -# await XnX.delete() +# await to_edit.delete() # os.remove(fpath) # await m.reply_photo(photo,caption=cap,reply_markup=IKM(kb)) # except Exception as e: -# await XnX.delete() +# await to_edit.delete() # await m.reply_text(f"Error\n{e}") # try: # os.remove(fpath) @@ -209,7 +209,7 @@ async def remove_background(c: Gojo, m: Message): 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("⏳") + to_edit = await m.reply_text("⏳") URL = "https://api.remove.bg/v1.0/removebg" if reply.sticker: filee = await reply.download() @@ -220,7 +220,7 @@ async def remove_background(c: Gojo, m: Message): Data = {'size':'auto'} Headers = {'X-Api-Key':RMBG} result = resp_post(URL,files=finfo,data=Data,headers=Headers) - await XnX.delete() + await to_edit.delete() contentType = result.headers.get("content-type") if result.status_code != 200: await m.reply_text(f"{result.status_code}:{result.text}") @@ -260,16 +260,16 @@ async def song_down_up(c: Gojo, m: Message): query = splited else: query = _id - XnX = await m.reply_text("⏳") + to_edit = await m.reply_text("⏳") try: await youtube_downloader(c,m,query, "a") - await XnX.delete() + await to_edit.delete() return except KeyError: - await XnX.edit_text(f"Failed to find any result") + await to_edit.edit_text(f"Failed to find any result") return except Exception as e: - await XnX.edit_text(f"Got an error\n{e}") + await to_edit.edit_text(f"Got an error\n{e}") LOGGER.error(e) LOGGER.error(format_exc()) return @@ -286,16 +286,16 @@ async def video_down_up(c: Gojo, m: Message): query = splited else: query = _id - XnX = await m.reply_text("⏳") + to_edit = await m.reply_text("⏳") try: await youtube_downloader(c,m,query,"v") - await XnX.delete() + await to_edit.delete() return except KeyError: - await XnX.edit_text(f"Failed to find any result") + await to_edit.edit_text(f"Failed to find any result") return except Exception as e: - await XnX.edit_text(f"Got an error\n{e}") + await to_edit.edit_text(f"Got an error\n{e}") LOGGER.error(e) LOGGER.error(format_exc()) return diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 2d1144f5..7274aea7 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -16,6 +16,7 @@ from pyrogram.types import Message from unidecode import unidecode +from Powers import scrap_dir from Powers.bot_class import Gojo from Powers.utils.string import encode_decode @@ -204,7 +205,7 @@ async def resize_file_to_sticker_size(file_path: str, length: int = 512, width: else: im.thumbnail(STICKER_DIMENSIONS) - file_pathh = "./downloads/resized.png" + file_pathh = f"{scrap_dir}r{str(time()).replace('.','_')}.png" im.save(file_pathh) os.remove(file_path) return file_pathh diff --git a/Powers/utils/web_helpers.py b/Powers/utils/web_helpers.py index 7594f61b..18359ec4 100644 --- a/Powers/utils/web_helpers.py +++ b/Powers/utils/web_helpers.py @@ -8,11 +8,13 @@ from pyrogram.types import Message from pytube import YouTube, extract from youtubesearchpython.__future__ import VideosSearch +from yt_dlp import YoutubeDL from Powers import youtube_dir -from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo +from Powers.bot_class import LOGGER, Gojo from Powers.utils.http_helper import * from Powers.utils.sticker_help import resize_file_to_sticker_size +from Powers.utils.web_scrapper import SCRAP_DATA backUP = "https://artfiles.alphacoders.com/160/160160.jpeg" @@ -174,16 +176,54 @@ async def song_search(query, max_results=1): pass return yt_dict +song_opts = { + "format": "bestaudio", + "addmetadata": True, + "key": "FFmpegMetadata", + "prefer_ffmpeg": True, + "geo_bypass": True, + "nocheckcertificate": True, + "postprocessors": [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "480", + } + ], + "outtmpl": "%(id)s", + "quiet": True, + "logtostderr": False, +} -async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, type_: str): +video_opts = { + "format": "best", + "addmetadata": True, + "key": "FFmpegMetadata", + "prefer_ffmpeg": True, + "geo_bypass": True, + "nocheckcertificate": True, + "postprocessors": [ + { + "key": "FFmpegVideoConvertor", + "preferedformat": "mp4", + } + ], + "outtmpl": "%(id)s.mp4", + "quiet": True, + "logtostderr": False, + } + +async def youtube_downloader(c: Gojo, m: Message, query: str, type_: str): if type_ == "a": - # opts = song_opts + opts = song_opts video = False song = True + ext = "mp3" elif type_ == "v": - # opts = video_opts + opts = video_opts video = True song = False + ext = "mp4" # ydl = yt_dlp.YoutubeDL(opts) dicti = await song_search(query, 1) if not dicti and type(dicti) != str: @@ -209,15 +249,22 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t vid_dur = get_duration_in_sec(dicti["DURATION"]) published_on = dicti["published"] if thumb: - thumb_ = await c.send_photo(MESSAGE_DUMP, thumb) + try: + thumb = SCRAP_DATA(thumb).get_images() + thumb = await resize_file_to_sticker_size(thumb[0], 320, 320) + except Exception as e: + LOGGER.error(e) + LOGGER.error(format_exc()) + LOGGER.info("Using back up image as thumbnail") + thumb = SCRAP_DATA(backUP).get_images() + thumb = await resize_file_to_sticker_size(thumb[0], 320, 320) + else: - thumb_ = await c.send_photo(MESSAGE_DUMP, backUP) + thumb = SCRAP_DATA(backUP).get_images() + thumb = await resize_file_to_sticker_size(thumb[0], 320, 320) + # FILE = ydl.extract_info(query,download=video) url = query - thumb = await thumb_.download() - if not thumb: - thumb = await resize_file_to_sticker_size(thumb, 320, 320) - await thumb_.delete() cap = f""" ⤷ Name: `{f_name}` ⤷ Duration: `{dura}` @@ -237,23 +284,41 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t ] ] ) + + def get_my_file(opts, ext): + try: + with YoutubeDL(opts) as ydl: + ydl.download([query]) + info = ydl.extract_info(query, False) + file_name = ydl.prepare_filename(info) + if len(file_name.rsplit(".", 1)) == 2: + pass + else: + file_name = f"{file_name}.{ext}" + new = info['title'].replace('/','|').replace('\\','|') + new_file = f"{youtube_dir}{new}.{ext}" + os.rename(file_name, new_file) + return True, new_file + except Exception as e: + return False, str(e) + if song: + success, file_path = get_my_file(opts, ext) + if not success: + await m.reply_text(file_path) + return msg = await m.reply_text(upload_text) - audio_stream = yt.streams.filter(only_audio=True).first() - f_path = audio_stream.download() - file_path = f"{youtube_dir}{f_name.strip()}.mp3" - os.rename(f_path, file_path) - await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader, progress=progress, progress_args=(msg, time.time(), upload_text)) + await msg.delete() os.remove(file_path) - os.remove(thumb) return elif video: - video_stream = yt.streams.get_highest_resolution() - file_path = video_stream.download() - new_file_path = f"{youtube_dir}{f_name}.mp4" - os.rename(file_path, new_file_path) + success, file_path = get_my_file(opts, ext) + if not success: + await m.reply_text(file_path) + return + msg = await m.reply_text(upload_text) await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, progress=progress, progress_args=(msg, time.time(), upload_text)) - os.remove(new_file_path) - os.remove(thumb) + await msg.delete() + os.remove(file_path) return diff --git a/Powers/utils/web_scrapper.py b/Powers/utils/web_scrapper.py index 23dd0588..8eef1cde 100644 --- a/Powers/utils/web_scrapper.py +++ b/Powers/utils/web_scrapper.py @@ -1,6 +1,5 @@ import os import re -import time from typing import List import httpx @@ -23,21 +22,22 @@ class SCRAP_DATA: def __init__(self, urls: List[str] or str) -> None: self.urls = urls - self.path = "./scrapped/" + self.path = scrap_dir if not os.path.isdir(self.path): - os.makedirs("./scrapped/") + os.makedirs(self.path) def get_images(self) -> list: images = [] if isinstance(self.urls, str): requested = httpx.get(self.urls) try: - name = self.path + f"img_{time.time()}.jpg" + name = self.path + f"img_{str(time()).replace('.','_')}.jpg" with open(name, "wb") as f: f.write(requested.content) images.append(name) except Exception as e: LOGGER.error(e) + LOGGER.error(format_exc()) requested.close() else: for i in self.urls: @@ -46,11 +46,12 @@ def get_images(self) -> list: else: continue try: - name = self.path + f"img_{time.time()}.jpg" + name = self.path + f"img_{str(time()).replace('.','_')}.jpg" with open(name, "wb") as f: f.write(requested.content) images.append(name) except Exception as e: + LOGGER.error(format_exc()) LOGGER.error(e) requested.close() continue @@ -64,12 +65,13 @@ def get_videos(self) -> list: else: return [] try: - name = self.path + f"vid_{time.time()}.mp4" + name = self.path + f"vid_{str(time()).replace('.','_')}.mp4" with open(name, "wb") as f: f.write(requested.content) videos.append(name) except Exception as e: LOGGER.error(e) + LOGGER.error(format_exc()) requested.close() else: for i in self.urls: @@ -78,12 +80,13 @@ def get_videos(self) -> list: else: continue try: - name = self.path + f"vid_{time.time()}.mp4" + name = self.path + f"vid_{str(time()).replace('.','_')}.mp4" with open(name, "wb") as f: f.write(requested.content) videos.append(name) except Exception as e: LOGGER.error(e) + LOGGER.error(format_exc()) requested.close() continue return videos diff --git a/Powers/vars.py b/Powers/vars.py index b35a9d6c..23562d3d 100644 --- a/Powers/vars.py +++ b/Powers/vars.py @@ -15,7 +15,7 @@ class Config: API_ID = int(config("API_ID", default="123")) API_HASH = config("API_HASH", default=None) OWNER_ID = int(config("OWNER_ID", default=1344569458)) - MESSAGE_DUMP = int(config("MESSAGE_DUMP")) + MESSAGE_DUMP = int(config("MESSAGE_DUMP", default = "0")) # if not given owner id will be msg dump :) DEV_USERS = [ int(i) for i in config( @@ -65,7 +65,7 @@ class Development: API_ID = 12345 # Your APP_ID from Telegram API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram OWNER_ID = 1344569458 # Your telegram user id defult to mine - MESSAGE_DUMP = -100845454887 # Your Private Group ID for logs + MESSAGE_DUMP = 0 # Your Private Group ID for logs if not passed your owner id will be msg dump DEV_USERS = [] SUDO_USERS = [] WHITELIST_USERS = [] diff --git a/README.md b/README.md index 9670ca83..97845008 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Not a particular inspiration, inspired by many bots Mainly: * [Alita_Robot](https://github.com/divideprojects/Alita_Robot) - +* [WilliamButcherBot](https://github.com/TheHamkerCat/WilliamButcherBot) --------- @@ -173,7 +173,7 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!---> `DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string. -`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`. +`MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`. If you don't give it or pass 0 in it your owner id will be the message dump for the bot. @@ -289,6 +289,8 @@ Some special thanks to the person/repo who/which helped and motivated me to crea * [Alita_Robot](https://github.com/divideprojects/Alita_Robot) for base code. +* [WilliamButcherBot](https://github.com/TheHamkerCat/WilliamButcherBot) for few plugins inspirations. + --------- # Powered by [ɢօʝօ ɮօȶֆ](https://github.com/Gojo-Bots) From 9f78da68c516552aa1209866b220fc34b03230e6 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Mon, 11 Nov 2024 15:59:21 +0530 Subject: [PATCH 16/19] Test completed --- Powers/database/captcha_db.py | 12 +- Powers/plugins/auto_join.py | 33 +++-- Powers/plugins/captcha.py | 136 ++++++++++++------- Powers/plugins/flood.py | 30 +++-- Powers/plugins/greetings.py | 221 ++++++++++++++----------------- Powers/plugins/locks.py | 3 +- Powers/plugins/scheduled_jobs.py | 12 +- Powers/plugins/start.py | 36 +++-- Powers/plugins/stickers.py | 3 +- Powers/utils/captcha_helper.py | 13 +- Powers/utils/custom_filters.py | 33 ++++- Powers/utils/sticker_help.py | 4 +- requirements.txt | 2 +- 13 files changed, 314 insertions(+), 224 deletions(-) diff --git a/Powers/database/captcha_db.py b/Powers/database/captcha_db.py index 62b70449..34d41a69 100644 --- a/Powers/database/captcha_db.py +++ b/Powers/database/captcha_db.py @@ -101,11 +101,18 @@ def store_message_id(self, chat, user, message): return else: return + + def get_message_id(self, chat, user): + curr = self.find_one({"chat_id": chat, "user_id": user}) + if curr: + return curr["message_id"] + else: + return False def is_already_data(self, chat, user): curr = self.find_one({"chat_id": chat, "user_id": user}) if curr: - return curr["message_id"] + return curr.get("message_id", False) else: return False @@ -114,4 +121,5 @@ def del_message_id(self, chat, user): if curr: with INSERTION_LOCK: self.delete_one({"chat_id": chat, "user_id": user}) - return + + return curr["message_id"] \ No newline at end of file diff --git a/Powers/plugins/auto_join.py b/Powers/plugins/auto_join.py index c2e807d0..52c6d4fc 100644 --- a/Powers/plugins/auto_join.py +++ b/Powers/plugins/auto_join.py @@ -48,7 +48,7 @@ async def accept_join_requests(c: Gojo, m: Message): is_al = a_j.load_autojoin(m.chat.id) if is_al: - txt = "Now I will approve all the join request of the chat\nIf you want that I will just notify admins about the join request use command\n//joinreqmode [manual | auto]" + txt = "Now I will approve all the join request of the chat\nIf you want that I will just notify admins about the join request use command\n/joinreqmode [manual | auto]" await m.reply_text(txt) return else: @@ -102,13 +102,16 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): if join_type == "auto" or user in SUPPORT_STAFF: try: await c.approve_chat_join_request(chat,user) + await c.send_message(chat, f"Accepted join request of the {userr.mention}") + return except Exception as ef: await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") LOGGER.error(ef) LOGGER.error(format_exc()) + return elif join_type == "manual": txt = "New join request is available\n**USER's INFO**\n" - txt += f"Name: {userr.first_name} {userr.last_name if userr.last_name else ''}" + txt += f"Name: {userr.full_name}" txt += f"Mention: {userr.mention}" txt += f"Id: {user}" txt += f"Scam: {'True' if userr.is_scam else 'False'}" @@ -127,23 +130,30 @@ async def join_request_handler(c: Gojo, j: ChatJoinRequest): async def accept_decline_request(c:Gojo, q: CallbackQuery): user_id = q.from_user.id chat = q.message.chat.id - user_status = (await q.message.chat.get_member(user_id)).status - if user_status not in {CMS.OWNER, CMS.ADMINISTRATOR}: - await q.answer( - "You're not even an admin, don't try this explosive shit!", - show_alert=True, - ) + try: + user_status = (await q.message.chat.get_member(user_id)).status + if user_status not in {CMS.OWNER, CMS.ADMINISTRATOR}: + await q.answer( + "You're not even an admin, don't try this explosive shit!", + show_alert=True, + ) + return + except: + await q.answer("Unknow error occured. You are not admin or owner") return - split = q.data.split("_") chat = q.message.chat.id user = int(split[-1]) data = split[0] - + try: + userr = await c.get_users(user) + except: + userr = None if data == "accept": try: await c.approve_chat_join_request(chat,user) - await q.answer(f"APPROVED: {user}",True) + await q.answer(f"Accepted join request of the {userr.mention if userr else user}",True) + await q.edit_message_text(f"Accepted join request of the {userr.mention if userr else user}") except Exception as ef: await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") LOGGER.error(ef) @@ -153,6 +163,7 @@ async def accept_decline_request(c:Gojo, q: CallbackQuery): try: await c.decline_chat_join_request(chat,user) await q.answer(f"DECLINED: {user}") + await q.edit_message_text() except Exception as ef: await c.send_message(chat,f"Some error occured while approving request, report it using `/bug`\nError: {ef}") LOGGER.error(ef) diff --git a/Powers/plugins/captcha.py b/Powers/plugins/captcha.py index b57065c1..c288e4c4 100644 --- a/Powers/plugins/captcha.py +++ b/Powers/plugins/captcha.py @@ -1,23 +1,28 @@ -from random import shuffle +import os +from random import choice, shuffle from traceback import format_exc +from typing import List import pyrogram from pyrogram import filters -from pyrogram.types import CallbackQuery, ChatMemberUpdated, ChatPermissions +from pyrogram.enums import ChatMemberStatus as CMS +from pyrogram.enums import ParseMode as PM +from pyrogram.types import CallbackQuery, ChatPermissions from pyrogram.types import InlineKeyboardButton as IKB from pyrogram.types import InlineKeyboardMarkup as ikm -from pyrogram.types import Message +from pyrogram.types import Message, User -from Powers import DEV_USERS, LOGGER, SUDO_USERS, WHITELIST_USERS +from Powers import DEV_USERS, LOGGER, MESSAGE_DUMP, SUDO_USERS, WHITELIST_USERS from Powers.bot_class import Gojo from Powers.database.captcha_db import CAPTCHA, CAPTCHA_DATA from Powers.utils.captcha_helper import (genrator, get_image_captcha, get_qr_captcha) -from Powers.utils.custom_filters import admin_filter, command +from Powers.utils.custom_filters import admin_filter, captcha_filter, command +from Powers.utils.extras import BAN_GIFS @Gojo.on_message(command("captcha") & admin_filter & ~filters.private) -async def start_captcha(c: Gojo, m: Message): +async def start_captcha(_, m: Message): captcha = CAPTCHA() split = m.command if len(split) == 1: @@ -59,8 +64,9 @@ async def set_captcha_mode(c: Gojo, m: Message): else: type_ = split[1].lower() if type_ == "qr": - captcha.update_type(m.chat.id, "qr") - await m.reply_text("Captcha verification is now changed to qr code") + await m.reply_text("This feature is not implemented yet\nUse /captchamode image") + # captcha.update_type(m.chat.id, "qr") + # await m.reply_text("Captcha verification is now changed to qr code") return elif type_ == "image": captcha.update_type(m.chat.id, "image") @@ -106,44 +112,73 @@ async def captcha_codes_check(c: Gojo, q: CallbackQuery): new_cap = ":".join(caps) await q.answer(f"Wrong\nTries left: {tries}", True) if not tries: - new_cap = f"You have zero tries left now. I am going to kick you know coz you failed to solve captcha...see yaa {q.from_user.mention}" + txt = f"{q.from_user.mention} was not able to pass captcha verification thus banned from the group" try: await q.message.chat.ban_member(user) except Exception as e: - await q.message.reply_text("Failed to kick member") + await q.message.reply_text("Failed to ban member") return await q.message.delete() - await q.message.reply_text(new_cap) - await c.unban_chat_member(chat, user) - + keyboard = ikm( + [ + [ + IKB( + "Unban", + callback_data=f"unban_={user}", + ), + ], + ], + ) + anim = choice(BAN_GIFS) + try: + await c.send_animation( + chat_id=q.message.chat.id, + animation=str(anim), + caption=txt, + reply_markup=keyboard, + parse_mode=PM.HTML, + ) + except Exception: + + await c.send_animation( + chat_id=q.message.chat.id, + text=txt, + reply_markup=keyboard, + parse_mode=PM.HTML, + ) + await c.send_message(MESSAGE_DUMP,f"#REMOVE from BAN_GFIS\n{anim}") + c_data.remove_cap_data(chat, user) + c_data.del_message_id(q.message.chat.id, user) + return else: await q.edit_message_caption(new_cap, reply_markup=q.message.reply_markup) return -@Gojo.on_chat_member_updated(filters.group, group=3) -async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): - chat = u.chat.id - - if u.new_chat_member: - - user = u.new_chat_member.user.id - userr = u.new_chat_member.user - - is_qr = CAPTCHA().is_captcha(chat) - if not is_qr: - return +@Gojo.on_message(filters.group & captcha_filter & filters.new_chat_members, group=3) +async def on_chat_members_updatess(c: Gojo, m: Message): + chat = m.chat.id + users: List[User] = m.new_chat_members + for user in users: captcha = CAPTCHA() cap_data = CAPTCHA_DATA() - + + if user.is_bot: + continue SUPPORT_STAFF = DEV_USERS.union(SUDO_USERS).union(WHITELIST_USERS) - if user in SUPPORT_STAFF: - return - captcha_type = captcha.get_captcha(chat) - - is_already = cap_data.is_already_data(chat, user) + try: + status = (await m.chat.get_member(user)).status + if status in [CMS.OWNER, CMS.ADMINISTRATOR]: + continue + except: + pass + if user.id in SUPPORT_STAFF: + continue + captcha_info = captcha.get_captcha(chat) + captcha_type = captcha_info["captcha_type"] + is_already = cap_data.is_already_data(chat, user.id) mess = False try: @@ -154,36 +189,40 @@ async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): mess = False is_already = False - if is_already and not mess: + if is_already and mess.empty: cap_data.del_message_id(chat, is_already) - return + continue try: - await c.restrict_chat_member(chat, user, ChatPermissions()) + await c.restrict_chat_member(chat, user.id, ChatPermissions()) except Exception as e: LOGGER.error(e) LOGGER.error(format_exc()) - return + continue if not is_already: + captcha_type = "image" # I am not going to apply qr captcha in this update if captcha_type == "qr": - pic = await get_qr_captcha(chat, user) - cap = f"Please {userr.mention} scan this qr code with your phone to verify that you are human" + pic = await get_qr_captcha(chat, user.id, c.me.username) + cap = f"Please {user.mention} scan this qr code with your phone to verify that you are human" ms = await c.send_photo(chat, pic, caption=cap) - cap_data.store_message_id(chat, user, ms.id) - return + os.remove(pic) + cap_data.store_message_id(chat, user.id, ms.id) + continue elif captcha_type == "image": - img, code = await get_image_captcha(chat, user) - cap = f"Please {userr.mention} please choose the correct code from the one given bellow\nYou have three tries if you get all three wrong u will be kicked from the chat.\nTries left: 3" - cap_data.load_cap_data(chat, user, code) + img, code = await get_image_captcha(chat, user.id) + cap = f"Please {user.mention} please choose the correct code from the one given bellow\nYou have three tries if you get all three wrong u will be banned from the chat.\nTries left: 3" + cap_data.load_cap_data(chat, user.id, code) rand = [code] while len(rand) != 5: hehe = genrator() + if hehe == code: + continue rand.append(hehe) shuffle(rand) - ini = f"captcha_{chat}_{user}_" + ini = f"captcha_{chat}_{user.id}_" kb = ikm( [ @@ -205,7 +244,8 @@ async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): ] ) await c.send_photo(chat, img, caption=cap, reply_markup=kb) - return + os.remove(img) + continue elif is_already and mess: kb = ikm( [ @@ -214,11 +254,11 @@ async def on_chat_members_updatess(c: Gojo, u: ChatMemberUpdated): ] ] ) - await c.send_message(f"{userr.mention} your verification is already pending", reply_markup=kb) - return + await c.send_message(f"{user.mention} your verification is already pending", reply_markup=kb) + continue else: - await c.unban_chat_member(chat, user) - return + await c.unban_chat_member(chat, user.id) + continue __PLUGIN__ = "captcha" diff --git a/Powers/plugins/flood.py b/Powers/plugins/flood.py index f2ef103f..0216ffe1 100644 --- a/Powers/plugins/flood.py +++ b/Powers/plugins/flood.py @@ -212,12 +212,17 @@ async def flood_set(c: Gojo, m: Message): c_id = m.chat.id if split[1].lower() in on_key: if is_flood: - return await m.reply_text(f"Flood is on for this chat\n**Action**:{saction}\n**Messages**:{slimit} within {swithin} sec") - Flood.save_flood(m.chat.id, 5, 5, 'mute') - await m.reply_text("Flood protection has been started for this group.") + saction = is_flood[2] + slimit = is_flood[0] + swithin = is_flood[1] + + await m.reply_text(f"Flood is on for this chat\n**Action**:{saction}\n**Messages**:{slimit} within {swithin} sec") return if split[1].lower() in off_key: x = Flood.rm_flood(c_id) + if not is_flood: + await m.reply_text("Flood protection is already off for this chat") + return if x: await m.reply_text("Flood protection has been stopped for this chat") return @@ -322,8 +327,8 @@ async def callbacks(c: Gojo, q: CallbackQuery): "Flood protection setting has been updated", reply_markup=close_kb ) - return await q.answer("skip") + return if not change == swithin: Flood.save_flood(c_id, slimit, change, saction) await q.answer("Updated", show_alert=True) @@ -390,7 +395,7 @@ async def reverse_callbacks(c: Gojo, q: CallbackQuery): return dic = {} -@Gojo.on_message(flood_filter & ~admin_filter, 18) +@Gojo.on_message(flood_filter, 18) async def flood_watcher(c: Gojo, m: Message): c_id = m.chat.id @@ -573,13 +578,14 @@ async def flood_watcher(c: Gojo, m: Message): elif action == "kick": try: - await m.chat.ban_member(u_id, datetime.now()+timedelta(seconds=1)) - txt = "Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: kicked\nReason: Spaming" + d = datetime.now()+timedelta(seconds=31) #will automatically unban user after 31 seconds kind of fail safe if unban members doesn't work properly + await m.chat.ban_member(u_id, until_date=d) + success = await c.unban_chat_member(m.chat.id, u_id) + txt = f"Don't dare to spam here if I am around! Nothing can escape my 6 eyes\nAction: {'kicked' if success else 'banned for 30 seconds'}\nReason: Spaming" await m.reply_animation( animation=str(choice(KICK_GIFS)), - caption=txt, + caption=txt ) - await m.chat.unban_member(m.from_user.id) dic[c_id][u_id][1].clear() dic[c_id][u_id][0].clear() return @@ -601,6 +607,12 @@ async def flood_watcher(c: Gojo, m: Message): dic[c_id][u_id][1].clear() dic[c_id][u_id][0].clear() return + except Exception as e: + LOGGER.error(e) + LOGGER.error(format_exc()) + dic[c_id][u_id][1].clear() + dic[c_id][u_id][0].clear() + return elif action == "mute": try: await m.chat.restrict_member( diff --git a/Powers/plugins/greetings.py b/Powers/plugins/greetings.py index 13f4d934..20ce0878 100644 --- a/Powers/plugins/greetings.py +++ b/Powers/plugins/greetings.py @@ -1,18 +1,19 @@ from html import escape from secrets import choice from traceback import format_exc +from typing import List from pyrogram import emoji, enums, filters -from pyrogram.enums import ChatMemberStatus as CMS from pyrogram.errors import ChannelPrivate, ChatAdminRequired, RPCError -from pyrogram.types import ChatMemberUpdated, Message +from pyrogram.types import Message, User from Powers import DEV_USERS, LOGGER from Powers.bot_class import Gojo from Powers.database.antispam_db import GBan from Powers.database.greetings_db import Greetings from Powers.utils.cmd_senders import send_cmd -from Powers.utils.custom_filters import admin_filter, bot_admin_filter, command +from Powers.utils.custom_filters import (admin_filter, bot_admin_filter, + captcha_filter, command) from Powers.utils.kbhelpers import ikb from Powers.utils.msg_types import Types, get_wlcm_type from Powers.utils.parser import escape_markdown, mention_html @@ -25,17 +26,13 @@ ChatType = enums.ChatType -async def escape_mentions_using_curly_brackets_wl( - m: ChatMemberUpdated, - n: bool, +async def escape_mentions_using_curly_brackets_wl( + user: User, + m: Message, text: str, parse_words: list, ) -> str: teks = await escape_invalid_curly_brackets(text, parse_words) - if n: - user = m.new_chat_member.user if m.new_chat_member else m.from_user - else: - user = m.old_chat_member.user if m.old_chat_member else m.from_user if teks: teks = teks.format( first=escape(user.first_name), @@ -235,113 +232,101 @@ async def cleannnnn(_, m: Message): except Exception: pass - -@Gojo.on_chat_member_updated(filters.group, group=69) -async def member_has_joined(c: Gojo, member: ChatMemberUpdated): - - if member.old_chat_member.status not in {CMS.MEMBER, CMS.OWNER, CMS.ADMINISTRATOR}: - pass - else: - return - - user = member.new_chat_member.user if member.new_chat_member else member.from_user - - db = Greetings(member.chat.id) - banned_users = gdb.check_gban(user.id) - try: - if user.id == c.me.id: - return - if user.id in DEV_USERS: - await c.send_animation( - chat_id=member.chat.id, - animation="./extras/william.gif", - caption=f"😳 My **DEV** {user.mention} has also joined the chat!", - ) - return - if banned_users: - await member.chat.ban_member(user.id) - await c.send_message( - member.chat.id, - f"{user.mention} was globally banned so i banned!", - ) - return - if user.is_bot: - return # ignore bots - except ChatAdminRequired: - 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", - "fullname", - "username", - "mention", - "id", - "chatname", - ] - hmm = await escape_mentions_using_curly_brackets_wl(member, True, oo, parse_words) - if status: - tek, button = await parse_button(hmm) - button = await build_keyboard(button) - button = ikb(button) if button else None - - if "%%%" in tek: - filter_reply = tek.split("%%%") - teks = choice(filter_reply) - else: - teks = tek - - if not teks: - teks = f"A wild {user.mention} appeared in {member.chat.title}! Everyone be aware." - - ifff = db.get_current_cleanwelcome_id() - gg = db.get_current_cleanwelcome_settings() - if ifff and gg: - try: - await c.delete_messages(member.chat.id, int(ifff)) - except RPCError: - pass - if not teks: - teks = "Hey {first}, welcome to {chatname}" +@Gojo.on_message(filters.group & filters.new_chat_members & ~captcha_filter, group=69) +async def member_has_joined(c: Gojo, m: Message): + users: List[User] = m.new_chat_members + db = Greetings(m.chat.id) + for user in users: + banned_users = gdb.check_gban(user.id) try: - if not UwU: - jj = await c.send_message( - member.chat.id, - text=teks, - reply_markup=button, - disable_web_page_preview=True, + if user.id == c.me.id: + continue + if user.id in DEV_USERS: + await c.send_animation( + chat_id=m.chat.id, + animation="./extras/william.gif", + caption=f"😳 My **DEV** {user.mention} has also joined the chat!", ) - elif UwU: - jj = await (await send_cmd(c,mtype))( - member.chat.id, - UwU, - caption=teks, - reply_markup=button, + continue + if banned_users: + await m.chat.ban_member(user.id) + await c.send_message( + m.chat.id, + f"{user.mention} was globally banned so i banned!", ) + continue + if user.is_bot: + continue # ignore bots + except ChatAdminRequired: + continue + status = db.get_welcome_status() + oo = db.get_welcome_text() + UwU = db.get_welcome_media() + mtype = db.get_welcome_msgtype() + parse_words = [ + "first", + "last", + "fullname", + "username", + "mention", + "id", + "chatname", + ] + hmm = await escape_mentions_using_curly_brackets_wl(user, m, oo, parse_words) + if status: + tek, button = await parse_button(hmm) + button = await build_keyboard(button) + button = ikb(button) if button else None + + if "%%%" in tek: + filter_reply = tek.split("%%%") + teks = choice(filter_reply) + else: + teks = tek + + if not teks: + teks = f"A wild {user.mention} appeared in {m.chat.title}! Everyone be aware." + + ifff = db.get_current_cleanwelcome_id() + gg = db.get_current_cleanwelcome_settings() + if ifff and gg: + try: + await c.delete_messages(m.chat.id, int(ifff)) + except RPCError: + pass + if not teks: + teks = "Hey {first}, welcome to {chatname}" + try: + if not UwU: + jj = await c.send_message( + m.chat.id, + text=teks, + reply_markup=button, + disable_web_page_preview=True, + ) + elif UwU: + jj = await (await send_cmd(c,mtype))( + m.chat.id, + UwU, + caption=teks, + reply_markup=button, + ) + + if jj: + db.set_cleanwlcm_id(int(jj.id)) + except ChannelPrivate: + continue + except RPCError as e: + LOGGER.error(e) + LOGGER.error(format_exc(e)) + continue + else: + continue - if jj: - db.set_cleanwlcm_id(int(jj.id)) - except ChannelPrivate: - return - except RPCError as e: - LOGGER.error(e) - LOGGER.error(format_exc(e)) - return - else: - return - - -@Gojo.on_chat_member_updated(filters.group, group=99) -async def member_has_left(c: Gojo, member: ChatMemberUpdated): - if member.old_chat_member.status not in [CMS.LEFT, CMS.BANNED, CMS.RESTRICTED]: - pass - else: - return - db = Greetings(member.chat.id) +@Gojo.on_message(filters.group & filters.left_chat_member, group=99) +async def member_has_left(c: Gojo, m: Message): + db = Greetings(m.chat.id) status = db.get_goodbye_status() oo = db.get_goodbye_text() UwU = db.get_goodbye_media() @@ -356,9 +341,9 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): "chatname", ] - user = member.old_chat_member.user if member.old_chat_member else member.from_user + user = m.left_chat_member if m.left_chat_member else m.from_user - hmm = await escape_mentions_using_curly_brackets_wl(member, False, oo, parse_words) + hmm = await escape_mentions_using_curly_brackets_wl(user, m, oo, parse_words) if status: tek, button = await parse_button(hmm) button = await build_keyboard(button) @@ -377,12 +362,12 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): iii = db.get_current_cleangoodbye_settings() if ifff and iii: try: - await c.delete_messages(member.chat.id, int(ifff)) + await c.delete_messages(m.chat.id, int(ifff)) except RPCError: pass if user.id in DEV_USERS: await c.send_message( - member.chat.id, + m.chat.id, f"Will miss you my master {user.mention} :(", ) return @@ -391,14 +376,14 @@ async def member_has_left(c: Gojo, member: ChatMemberUpdated): try: if not UwU: ooo = await c.send_message( - member.chat.id, + m.chat.id, text=teks, reply_markup=button, disable_web_page_preview=True, ) elif UwU: ooo = await (await send_cmd(c,mtype))( - member.chat.id, + m.chat.id, UwU, caption=teks, reply_markup=button, diff --git a/Powers/plugins/locks.py b/Powers/plugins/locks.py index f851ce53..dedc9aa5 100644 --- a/Powers/plugins/locks.py +++ b/Powers/plugins/locks.py @@ -464,10 +464,9 @@ async def is_approved_user(c: Gojo, m: Message): return True return False elif m.forward_from_chat: - x_chat = (await c.get_chat(m.forward_from_chat.id)).linked_chat if m.from_user and (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 == c.me.id): return True - elif x_chat and x_chat.id == m.chat.id: + elif m.automatic_forward: return True else: return False diff --git a/Powers/plugins/scheduled_jobs.py b/Powers/plugins/scheduled_jobs.py index 167700cc..9a4fad38 100644 --- a/Powers/plugins/scheduled_jobs.py +++ b/Powers/plugins/scheduled_jobs.py @@ -38,14 +38,12 @@ async def send_wishish(JJK: Client): 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" + suffix = {1: 'st', 2: 'nd', 3: 'rd'} + if int(agee/10) == 1: + suf = "th" else: - agee = f"{agee}th" + suffix.get((agee%10), "th") + agee = f"{agee}{suf}" U = await JJK.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]: diff --git a/Powers/plugins/start.py b/Powers/plugins/start.py index b87eaa58..95e3ad5c 100644 --- a/Powers/plugins/start.py +++ b/Powers/plugins/start.py @@ -14,6 +14,7 @@ PYROGRAM_VERSION, PYTHON_VERSION, SUDO_USERS, UPTIME, VERSION, WHITELIST_USERS) from Powers.bot_class import Gojo +from Powers.database.captcha_db import CAPTCHA_DATA from Powers.utils.custom_filters import command from Powers.utils.extras import StartPic from Powers.utils.kbhelpers import ikb @@ -69,7 +70,8 @@ async def start(c: Gojo, m: Message): if m.chat.type == ChatType.PRIVATE: if len(m.text.strip().split()) > 1: - help_option = (m.text.split(None, 1)[1]).lower() + arg = m.text.split(None, 1)[1] + help_option = arg.lower() if help_option.startswith("note") and ( help_option not in ("note", "notes") @@ -83,9 +85,7 @@ async def start(c: Gojo, m: Message): help_msg, help_kb = await get_help_msg(c, m, help_option) - if not help_msg: - return - elif help_msg: + if help_msg: await m.reply_photo( photo=str(choice(StartPic)), caption=help_msg, @@ -94,8 +94,8 @@ async def start(c: Gojo, m: Message): quote=True, ) return - if len(help_option.split("_", 1)) == 2: - if help_option.split("_")[1] == "help": + if len(arg.split("_", 1)) >= 2: + if arg.split("_")[1] == "help": await m.reply_photo( photo=str(choice(StartPic)), caption=help_msg, @@ -104,9 +104,9 @@ async def start(c: Gojo, m: Message): quote=True, ) return - elif help_option.split("_", 1)[0] == "qrcaptcha": + elif arg.split("_", 1)[0] == "qr": decoded = encode_decode( - help_option.split("_", 1)[1], "decode") + arg.split("_", 1)[1], "decode") decode = decoded.split(":") chat = decode[0] user = decode[1] @@ -115,9 +115,25 @@ async def start(c: Gojo, m: Message): return try: await c.unban_chat_member(int(chat), int(user)) + msg = CAPTCHA_DATA().del_message_id(chat, user) + try: + chat_ = await c.get_chat(chat) + kb = ikb( + [ + [ + "Link to chat", + f"{chat_.invite_link}", + "url" + ] + ] + ) + except: + chat_ = False + kb = None + await m.reply_text("You can now talk in the chat", reply_markup=kb) try: - os.remove(f"captcha_verification{chat}_{user}.png") - except Exception: + await c.delete_messages(chat, msg) + except: pass return except Exception: diff --git a/Powers/plugins/stickers.py b/Powers/plugins/stickers.py index a8182c31..f32dec66 100644 --- a/Powers/plugins/stickers.py +++ b/Powers/plugins/stickers.py @@ -173,7 +173,6 @@ async def kang(c:Gojo, m: Message): volume += 1 continue try: - print(sticker_set) await add_sticker_to_set(c,sticker_set,sticker) packname_found = True except StickerEmojiInvalid: @@ -326,7 +325,7 @@ async def get_sticker_from_file(c: Gojo, m: Message): upp = await repl.download() up = toimage(upp,is_direc=True) await x.delete() - await m.reply_photo(up,caption=Caption) + await m.reply_document(up, caption=Caption) os.remove(up) return elif repl.photo: diff --git a/Powers/utils/captcha_helper.py b/Powers/utils/captcha_helper.py index ac82922a..366185cc 100644 --- a/Powers/utils/captcha_helper.py +++ b/Powers/utils/captcha_helper.py @@ -2,20 +2,17 @@ import qrcode from captcha.image import ImageCaptcha -from pyrogram.types import InlineKeyboardButton as IKB -from pyrogram.types import InlineKeyboardMarkup as IKM from Powers.database.captcha_db import CAPTCHA_DATA from Powers.utils.string import encode_decode -from Powers.vars import Config -initial = f"t.me/{Config.BOT_USERNAME}?start=qrcaptcha_" captchaa = CAPTCHA_DATA() -async def get_qr_captcha(chat, user): +async def get_qr_captcha(chat, user, username): + initial = f"t.me/{username}?start=qr_" encode = f"{chat}:{user}" - encoded = encode_decode(encode) + encoded = await encode_decode(encode) final = initial+encoded qr = qrcode.make(final) name = f"captcha_verification{chat}_{user}.png" @@ -42,7 +39,7 @@ def genrator(): str_ = "" while len(str_) != 4: OwO = choice(list_) - str_ += OwO + str_ += str(OwO) return str_ @@ -55,4 +52,4 @@ async def get_image_captcha(chat, user): cap = image.generate(str_) image.write(str_, name) - return name, str_ + return name, str_ \ No newline at end of file diff --git a/Powers/utils/custom_filters.py b/Powers/utils/custom_filters.py index 7f064c08..9153a4f3 100644 --- a/Powers/utils/custom_filters.py +++ b/Powers/utils/custom_filters.py @@ -14,6 +14,7 @@ from Powers.database.afk_db import AFK from Powers.database.approve_db import Approve from Powers.database.autojoin_db import AUTOJOIN +from Powers.database.captcha_db import CAPTCHA from Powers.database.disable_db import Disabling from Powers.database.flood_db import Floods from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload @@ -329,12 +330,19 @@ async def afk_check_filter(_, __, m: Message): return False afk = AFK() - user = m.from_user.id chat = m.chat.id + is_repl_afk = None + if m.reply_to_message: + repl_user = m.reply_to_message.from_user + if repl_user: + repl_user = m.reply_to_message.from_user.id + is_repl_afk = afk.check_afk(chat, repl_user) + + user = m.from_user.id is_afk = afk.check_afk(chat, user) - if not is_afk: + if not (is_afk or is_repl_afk): return False else: return True @@ -354,19 +362,36 @@ async def flood_check_filter(_, __, m: Message): u_id = m.from_user.id c_id = m.chat.id is_flood = Flood.is_chat(c_id) - + if not is_flood: + return False + try: + admin_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} + except KeyError: + admin_group = { + i[0] for i in await admin_cache_reload(m, "custom_filter_update") + } app_users = Approve(m.chat.id).list_approved() SUDO_LEVEL = DEV_USERS.union(SUDO_USERS) - if not is_flood or u_id in SUDO_LEVEL: + if u_id in SUDO_LEVEL: return False + elif u_id in admin_group: + return False + elif u_id in {i[0] for i in app_users}: return False else: return True +async def captcha_filt(_, __, m: Message): + try: + return CAPTCHA().is_captcha(m.chat.id) + except: + return False + +captcha_filter = create(captcha_filt) flood_filter = create(flood_check_filter) afk_filter = create(afk_check_filter) auto_join_filter = create(auto_join_check_filter) diff --git a/Powers/utils/sticker_help.py b/Powers/utils/sticker_help.py index 7274aea7..5e700992 100644 --- a/Powers/utils/sticker_help.py +++ b/Powers/utils/sticker_help.py @@ -349,14 +349,14 @@ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> li def toimage(image, filename=None, is_direc=False): - filename = filename if filename else "gojo.jpg" + filename = filename if filename else "gojo.png" if is_direc: os.rename(image, filename) return filename img = Image.open(image) if img.mode != "RGB": img = img.convert("RGB") - img.save(filename, "jpeg") + img.save(filename, "png") os.remove(image) return filename diff --git a/requirements.txt b/requirements.txt index 9a8ba755..15e23825 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ pillow == 10.1.0 prettyconf==2.2.1 pyaes==1.6.1 pymongo==4.6.1 -git+https://github.com/KurimuzonAkuma/pyrogram.git@v2.1.30 +git+https://github.com/KurimuzonAkuma/pyrogram.git@v2.1.32 pysocks==1.7.1 python-dateutil==2.8.2 pytube==15.0.0 From 6256dd15e450953cf1f70633c5b62d2970ac2165 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Mon, 11 Nov 2024 16:18:08 +0530 Subject: [PATCH 17/19] version info --- Version/version 2.2.0.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Version/version 2.2.0.md diff --git a/Version/version 2.2.0.md b/Version/version 2.2.0.md new file mode 100644 index 00000000..9e5cdc5d --- /dev/null +++ b/Version/version 2.2.0.md @@ -0,0 +1,31 @@ +# V 2.1.2 + +## Changes made + +- Added AFK support. +- Added captcha support. +- Added cache for support users and few other to prevent script from requesting data from database frequently. +- Added instagram support. Now you can download any public post and reel. +- Added new lock type: `bot`. +- Added pagination for long caption in help menu. +- Added quote feature. Now you can quote any message. +- Added support for join request. + +- Fixed error while kanging stickers. +- Fixed few bugs in greeting the users. +- Improved few things in locks. +- Fixed user getting banned instead of kick when they flood. +- Fixed `400: Bad Request` error while downloading audio or video from youtube. + +- Merged all pull requests. + +- Fixed few bugs. (I don't know exactly what bugs and I forgot any changes I made :)) +- Created few bugs. (unintentional) + +## Report issues [here](https://github.com/Gojo-Bots/Gojo_Satoru/issues/new/choose) if find any + +## Give ideas [here](https://github.com/Gojo-Bots/Gojo_Satoru/discussions/new?category=ideas) for next update + +## Trying our best to give the best + +## Regards 🧑‍💻: [Captain D. Ezio](https://github.com/iamgojoof6eyes) From 9761a1baf8d7f4b7dfdfd314a5bbd2debc035d41 Mon Sep 17 00:00:00 2001 From: Captain Ezio Date: Mon, 11 Nov 2024 16:28:21 +0530 Subject: [PATCH 18/19] version info --- Version/version 2.2.0.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Version/version 2.2.0.md b/Version/version 2.2.0.md index 9e5cdc5d..bd3c139f 100644 --- a/Version/version 2.2.0.md +++ b/Version/version 2.2.0.md @@ -11,6 +11,8 @@ - Added quote feature. Now you can quote any message. - Added support for join request. +- Changed sticker packname so new kanged sticker will not be added in your previous packs. Number of stickers in a pack is increased to 120 for all sticker pack type. + - Fixed error while kanging stickers. - Fixed few bugs in greeting the users. - Improved few things in locks. @@ -19,7 +21,7 @@ - Merged all pull requests. -- Fixed few bugs. (I don't know exactly what bugs and I forgot any changes I made :)) +- Fixed few bugs. (I don't know exactly what bugs and I forgot any more changes I made :)) - Created few bugs. (unintentional) ## Report issues [here](https://github.com/Gojo-Bots/Gojo_Satoru/issues/new/choose) if find any From 409416805c0e8ccd895c667ab1e7aa668e304246 Mon Sep 17 00:00:00 2001 From: "Captain D. Ezio" Date: Mon, 11 Nov 2024 16:51:25 +0530 Subject: [PATCH 19/19] Update version 2.2.0.md --- Version/version 2.2.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Version/version 2.2.0.md b/Version/version 2.2.0.md index bd3c139f..3a8a1e95 100644 --- a/Version/version 2.2.0.md +++ b/Version/version 2.2.0.md @@ -1,4 +1,4 @@ -# V 2.1.2 +# V 2.2.0 ## Changes made