# <============================================== IMPORTS =========================================================> import ast import csv import json import os import re import time import uuid from io import BytesIO from telegram import ( ChatMember, InlineKeyboardButton, InlineKeyboardMarkup, MessageEntity, Update, ) from telegram.constants import ParseMode from telegram.error import BadRequest, Forbidden, TelegramError from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes from telegram.helpers import mention_html, mention_markdown import Database.sql.feds_sql as sql from Mikobot import ( DRAGONS, EVENT_LOGS, LOGGER, OWNER_ID, SUPPORT_CHAT, dispatcher, function, ) from Mikobot.plugins.disable import DisableAbleCommandHandler from Mikobot.plugins.helper_funcs.alternate import send_message from Mikobot.plugins.helper_funcs.chat_status import is_user_admin from Mikobot.plugins.helper_funcs.extraction import ( extract_unt_fedban, extract_user, extract_user_fban, ) from Mikobot.plugins.helper_funcs.string_handling import markdown_parser # <=======================================================================================================> FBAN_ERRORS = { "User is an administrator of the chat", "Chat not found", "Not enough rights to restrict/unrestrict chat member", "User_not_participant", "Peer_id_invalid", "Group chat was deactivated", "Need to be inviter of a user to kick it from a basic group", "Chat_admin_required", "Only the creator of a basic group can kick group administrators", "Channel_private", "Not in the chat", "Have no rights to send a message", } UNFBAN_ERRORS = { "User is an administrator of the chat", "Chat not found", "Not enough rights to restrict/unrestrict chat member", "User_not_participant", "Method is available for supergroup and channel chats only", "Not in the chat", "Channel_private", "Chat_admin_required", "Have no rights to send a message", } # <================================================ FUNCTION =======================================================> async def new_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): chat = update.effective_chat user = update.effective_user message = update.effective_message bot = context.bot if chat.type != "private": await update.effective_message.reply_text( "Federations can only be created by privately messaging me.", ) return if len(message.text) == 1: await send_message( update.effective_message, "Please write the name of the federation!", ) return fednam = message.text.split(None, 1)[1] if not fednam == "": fed_id = str(uuid.uuid4()) fed_name = fednam LOGGER.info(fed_id) x = sql.new_fed(user.id, fed_name, fed_id) if not x: await update.effective_message.reply_text( f"Can't federate! Please contact @{SUPPORT_CHAT} if the problem persist.", ) return await update.effective_message.reply_text( "*You have succeeded in creating a new federation!*" "\nName: `{}`" "\nID: `{}`" "\n\nUse the command below to join the federation:" "\n`/joinfed {}`".format(fed_name, fed_id, fed_id), parse_mode=ParseMode.MARKDOWN, ) try: await bot.send_message( EVENT_LOGS, "New Federation: {}\nID:
{}
".format(fed_name, fed_id), parse_mode=ParseMode.HTML, ) except: LOGGER.warning("Cannot send a message to EVENT_LOGS") else: await update.effective_message.reply_text( "Please write down the name of the federation", ) async def del_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type != "private": await update.effective_message.reply_text( "Federations can only be deleted by privately messaging me.", ) return if args: is_fed_id = args[0] getinfo = sql.get_fed_info(is_fed_id) if getinfo is False: await update.effective_message.reply_text("This federation does not exist.") return if int(getinfo["owner"]) == int(user.id) or int(user.id) == OWNER_ID: fed_id = is_fed_id else: await update.effective_message.reply_text( "Only federation owners can do this!" ) return else: await update.effective_message.reply_text("What should I delete?") return if is_user_fed_owner(fed_id, user.id) is False: await update.effective_message.reply_text("Only federation owners can do this!") return await update.effective_message.reply_text( "You sure you want to delete your federation? This cannot be reverted, you will lose your entire ban list, and '{}' will be permanently lost.".format( getinfo["fname"], ), reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton( text="⚠️ Delete Federation ⚠️", callback_data="rmfed_{}".format(fed_id), ), ], [InlineKeyboardButton(text="Cancel", callback_data="rmfed_cancel")], ], ), ) async def rename_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): user = update.effective_user msg = update.effective_message args = msg.text.split(None, 2) if len(args) < 3: return await msg.reply_text("usage: /renamefed ") fed_id, newname = args[1], args[2] verify_fed = sql.get_fed_info(fed_id) if not verify_fed: return await msg.reply_text("This fed not exist in my database!") if is_user_fed_owner(fed_id, user.id): sql.rename_fed(fed_id, user.id, newname) await msg.reply_text(f"Successfully renamed your fed name to {newname}!") else: await msg.reply_text("Only federation owner can do this!") async def fed_chat(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user fed_id = sql.get_fed_id(chat.id) user_id = update.effective_message.from_user.id if not await is_user_admin(update.effective_chat, user_id): await update.effective_message.reply_text( "You must be an admin to execute this command", ) return if not fed_id: await update.effective_message.reply_text( "This group is not in any federation!" ) return user = update.effective_user chat = update.effective_chat info = sql.get_fed_info(fed_id) text = "This group is part of the following federation:" text += "\n{} (ID: {})".format(info["fname"], fed_id) await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML) async def join_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return message = update.effective_message administrators = await chat.get_administrators() fed_id = sql.get_fed_id(chat.id) if user.id in DRAGONS: pass else: for admin in administrators: status = admin.status if status == "creator": if str(admin.user.id) == str(user.id): pass else: await update.effective_message.reply_text( "Only group creators can use this command!", ) return if fed_id: await message.reply_text("You cannot join two federations from one chat") return if len(args) >= 1: getfed = sql.search_fed_by_id(args[0]) if getfed is False: await message.reply_text("Please enter a valid federation ID") return x = sql.chat_join_fed(args[0], chat.title, chat.id) if not x: await message.reply_text( f"Failed to join federation! Please contact @{SUPPORT_CHAT} should this problem persist!", ) return get_fedlog = await sql.get_fed_log(args[0]) if get_fedlog: if ast.literal_eval(get_fedlog): await bot.send_message( get_fedlog, "Chat *{}* has joined the federation *{}*".format( chat.title, getfed["fname"], ), parse_mode="markdown", message_thread_id=( message.message_thread_id if chat.is_forum else None ), ) await message.reply_text( "This group has joined the federation: {}!".format(getfed["fname"]), ) async def leave_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our PM!", ) return fed_id = sql.get_fed_id(chat.id) fed_info = sql.get_fed_info(fed_id) # administrators = await chat.get_administrators().status getuser = await bot.get_chat_member(chat.id, user.id).status if getuser in "creator" or user.id in DRAGONS: if sql.chat_leave_fed(chat.id) is True: get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if ast.literal_eval(get_fedlog): await bot.send_message( get_fedlog, "Chat *{}* has left the federation *{}*".format( chat.title, fed_info["fname"], ), parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) await send_message( update.effective_message, "This group has left the federation {}!".format(fed_info["fname"]), ) else: await update.effective_message.reply_text( "How can you leave a federation that you never joined?!", ) else: await update.effective_message.reply_text( "Only group creators can use this command!" ) async def user_join_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if is_user_fed_owner(fed_id, user.id) or user.id in DRAGONS: user_id = await extract_user(msg, context, args) if user_id: user = await bot.get_chat(user_id) elif not msg.reply_to_message and not args: user = msg.from_user elif not msg.reply_to_message and ( not args or ( len(args) >= 1 and not args[0].startswith("@") and not args[0].isdigit() and not msg.parse_entities([MessageEntity.TEXT_MENTION]) ) ): await msg.reply_text("I cannot extract user from this message") return else: LOGGER.warning("error") getuser = sql.search_user_in_fed(fed_id, user_id) fed_id = sql.get_fed_id(chat.id) info = sql.get_fed_info(fed_id) get_owner = ast.literal_eval(info["fusers"])["owner"] get_owner = await bot.get_chat(get_owner) if isinstance(get_owner, ChatMember): if user_id == get_owner.id: await update.effective_message.reply_text( "You do know that the user is the federation owner, right? RIGHT?", ) return if getuser: await update.effective_message.reply_text( "I cannot promote users who are already federation admins! Can remove them if you want!", ) return if user_id == bot.id: await update.effective_message.reply_text( "I already am a federation admin in all federations!", ) return res = sql.user_join_fed(fed_id, user_id) if res: await update.effective_message.reply_text("Successfully Promoted!") else: await update.effective_message.reply_text("Failed to promote!") else: await update.effective_message.reply_text("Only federation owners can do this!") async def user_demote_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if is_user_fed_owner(fed_id, user.id): msg = update.effective_message user_id = await extract_user(msg, context, args) if user_id: user = await bot.get_chat(user_id) elif not msg.reply_to_message and not args: user = msg.from_user elif not msg.reply_to_message and ( not args or ( len(args) >= 1 and not args[0].startswith("@") and not args[0].isdigit() and not msg.parse_entities([MessageEntity.TEXT_MENTION]) ) ): await msg.reply_text("I cannot extract user from this message") return else: LOGGER.warning("error") if user_id == bot.id: await update.effective_message.reply_text( "The thing you are trying to demote me from will fail to work without me! Just saying.", ) return if sql.search_user_in_fed(fed_id, user_id) is False: await update.effective_message.reply_text( "I cannot demote people who are not federation admins!", ) return res = sql.user_demote_fed(fed_id, user_id) if res is True: await update.effective_message.reply_text("Demoted from a Fed Admin!") else: await update.effective_message.reply_text("Demotion failed!") else: await update.effective_message.reply_text("Only federation owners can do this!") return async def fed_info(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if args: fed_id = args[0] info = sql.get_fed_info(fed_id) else: if chat.type == "private": await send_message( update.effective_message, "You need to provide me a fedid to check fedinfo in my pm.", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await send_message( update.effective_message, "This group is not in any federation!", ) return info = sql.get_fed_info(fed_id) if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text( "Only a federation admin can do this!" ) return owner = await bot.get_chat(info["owner"]) try: owner_name = owner.first_name + " " + owner.last_name except: owner_name = owner.first_name FEDADMIN = sql.all_fed_users(fed_id) TotalAdminFed = len(FEDADMIN) user = update.effective_user chat = update.effective_chat info = sql.get_fed_info(fed_id) text = "ℹ️ Federation Information:" text += "\nFedID: {}".format(fed_id) text += "\nName: {}".format(info["fname"]) text += "\nCreator: {}".format(mention_html(owner.id, owner_name)) text += "\nAll Admins: {}".format(TotalAdminFed) getfban = sql.get_all_fban_users(fed_id) text += "\nTotal banned users: {}".format(len(getfban)) getfchat = sql.all_fed_chats(fed_id) text += "\nNumber of groups in this federation: {}".format( len(getfchat), ) await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML) async def fed_admin(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not in any federation!" ) return if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text("Only federation admins can do this!") return user = update.effective_user chat = update.effective_chat info = sql.get_fed_info(fed_id) text = "Federation Admin {}:\n\n".format(info["fname"]) text += "👑 Owner:\n" owner = await bot.get_chat(info["owner"]) try: owner_name = owner.first_name + " " + owner.last_name except: owner_name = owner.first_name text += " • {}\n".format(mention_html(owner.id, owner_name)) members = sql.all_fed_members(fed_id) if len(members) == 0: text += "\n🔱 There are no admins in this federation" else: text += "\n🔱 Admin:\n" for x in members: user = await bot.get_chat(x) text += " • {}\n".format(mention_html(user.id, user.first_name)) await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML) async def fed_ban(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return info = sql.get_fed_info(fed_id) getfednotif = sql.user_feds_report(info["owner"]) if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text("Only federation admins can do this!") return message = update.effective_message user_id, reason = extract_unt_fedban(message, context, args) fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user_id) if not user_id: await message.reply_text("You don't seem to be referring to a user") return if user_id == bot.id: await message.reply_text( "What is funnier than kicking the group creator? Self sacrifice.", ) return if is_user_fed_owner(fed_id, user_id) is True: await message.reply_text("Why did you try the federation fban?") return if is_user_fed_admin(fed_id, user_id) is True: await message.reply_text("He is a federation admin, I can't fban him.") return if user_id == OWNER_ID: await message.reply_text("Disaster level God cannot be fed banned!") return if int(user_id) in DRAGONS: await message.reply_text("Dragons cannot be fed banned!") return if user_id in [777000, 1087968824]: await message.reply_text("Fool! You can't attack Telegram's native tech!") return try: user_chat = await bot.get_chat(user_id) isvalid = True fban_user_id = user_chat.id fban_user_name = user_chat.first_name fban_user_lname = user_chat.last_name fban_user_uname = user_chat.username except BadRequest as excp: if not str(user_id).isdigit(): await send_message(update.effective_message, excp.message) return elif len(str(user_id)) != 9: await send_message(update.effective_message, "That's so not a user!") return isvalid = False fban_user_id = int(user_id) fban_user_name = "user({})".format(user_id) fban_user_lname = None fban_user_uname = None if isvalid and user_chat.type != "private": await send_message(update.effective_message, "That's so not a user!") return if isvalid: user_target = mention_html(fban_user_id, fban_user_name) else: user_target = fban_user_name if fban: fed_name = info["fname"] # https://t.me/OnePunchSupport/41606 // https://t.me/OnePunchSupport/41619 # starting = "The reason fban is replaced for {} in the Federation {}.".format(user_target, fed_name) # await send_message(update.effective_message, starting, parse_mode=ParseMode.HTML) # if reason == "": # reason = "No reason given." temp = sql.un_fban_user(fed_id, fban_user_id) if not temp: await message.reply_text("Failed to update the reason for fedban!") return x = sql.fban_user( fed_id, fban_user_id, fban_user_name, fban_user_lname, fban_user_uname, reason, int(time.time()), ) if not x: await message.reply_text( f"Failed to ban from the federation! If this problem continues, contact @{SUPPORT_CHAT}.", ) return fed_chats = sql.all_fed_chats(fed_id) # Will send to current chat await bot.send_message( chat.id, "FedBan reason updated" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) # Send message to owner if fednotif is enabled if getfednotif: await bot.send_message( info["owner"], "FedBan reason updated" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) # If fedlog is set, then send message, except fedlog is current chat get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if int(get_fedlog) != int(chat.id): await bot.send_message( get_fedlog, "FedBan reason updated" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) for fedschat in fed_chats: try: # Do not spam all fed chats """ bot.send_message(chat, "FedBan reason updated" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}" \ "\nReason: {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), parse_mode="HTML") """ await bot.ban_chat_member(fedschat, fban_user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: try: await dispatcher.bot.getChat(fedschat) except Forbidden: sql.chat_leave_fed(fedschat) LOGGER.info( "Chat {} has leave fed {} because I was kicked".format( fedschat, info["fname"], ), ) continue elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Could not fban on {} because: {}".format(chat, excp.message), ) except TelegramError: pass # Also do not spam all fed admins """ send_to_list(bot, FEDADMIN, "FedBan reason updated" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}" \ "\nReason: {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), html=True) """ # Fban for fed subscriber subscriber = list(sql.get_subscriber(fed_id)) if len(subscriber) != 0: for fedsid in subscriber: all_fedschat = sql.all_fed_chats(fedsid) for fedschat in all_fedschat: try: await bot.ban_chat_member(fedschat, fban_user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: try: await dispatcher.bot.getChat(fedschat) except Forbidden: targetfed_id = sql.get_fed_id(fedschat) sql.unsubs_fed(fed_id, targetfed_id) LOGGER.info( "Chat {} has unsub fed {} because I was kicked".format( fedschat, info["fname"], ), ) continue elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Unable to fban on {} because: {}".format( fedschat, excp.message, ), ) except TelegramError: pass # await send_message(update.effective_message, "Fedban Reason has been updated.") return fed_name = info["fname"] # starting = "Starting a federation ban for {} in the Federation {}.".format( # user_target, fed_name) # await update.effective_message.reply_text(starting, parse_mode=ParseMode.HTML) # if reason == "": # reason = "No reason given." x = sql.fban_user( fed_id, fban_user_id, fban_user_name, fban_user_lname, fban_user_uname, reason, int(time.time()), ) if not x: await message.reply_text( f"Failed to ban from the federation! If this problem continues, contact @{SUPPORT_CHAT}.", ) return fed_chats = sql.all_fed_chats(fed_id) # Will send to current chat await bot.send_message( chat.id, "New FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) # Send message to owner if fednotif is enabled if getfednotif: await bot.send_message( info["owner"], "New FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) # If fedlog is set, then send message, except fedlog is current chat get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if int(get_fedlog) != int(chat.id): await bot.send_message( get_fedlog, "New FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}" "\nReason: {}".format( fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason, ), parse_mode="HTML", ) chats_in_fed = 0 for fedschat in fed_chats: chats_in_fed += 1 try: # Do not spamming all fed chats """ bot.send_message(chat, "FedBan reason updated" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}" \ "\nReason: {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), parse_mode="HTML") """ await bot.ban_chat_member(fedschat, fban_user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: pass elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Could not fban on {} because: {}".format(chat, excp.message), ) except TelegramError: pass # Also do not spamming all fed admins """ send_to_list(bot, FEDADMIN, "FedBan reason updated" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}" \ "\nReason: {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), html=True) """ # Fban for fed subscriber subscriber = list(sql.get_subscriber(fed_id)) if len(subscriber) != 0: for fedsid in subscriber: all_fedschat = sql.all_fed_chats(fedsid) for fedschat in all_fedschat: try: await bot.ban_chat_member(fedschat, fban_user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: try: await dispatcher.bot.getChat(fedschat) except Forbidden: targetfed_id = sql.get_fed_id(fedschat) sql.unsubs_fed(fed_id, targetfed_id) LOGGER.info( "Chat {} has unsub fed {} because I was kicked".format( fedschat, info["fname"], ), ) continue elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Unable to fban on {} because: {}".format( fedschat, excp.message, ), ) except TelegramError: pass async def unfban(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user message = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return info = sql.get_fed_info(fed_id) getfednotif = sql.user_feds_report(info["owner"]) if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text("Only federation admins can do this!") return user_id = extract_user_fban(message, context, args) if not user_id: await message.reply_text("You do not seem to be referring to a user.") return try: user_chat = await bot.get_chat(user_id) isvalid = True fban_user_id = user_chat.id fban_user_name = user_chat.first_name fban_user_lname = user_chat.last_name fban_user_uname = user_chat.username except BadRequest as excp: if not str(user_id).isdigit(): await send_message(update.effective_message, excp.message) return elif len(str(user_id)) != 9: await send_message(update.effective_message, "That's so not a user!") return isvalid = False fban_user_id = int(user_id) fban_user_name = "user({})".format(user_id) fban_user_lname = None fban_user_uname = None if isvalid and user_chat.type != "private": await message.reply_text("That's so not a user!") return if isvalid: user_target = mention_html(fban_user_id, fban_user_name) else: user_target = fban_user_name fban, fbanreason, fbantime = sql.get_fban_user(fed_id, fban_user_id) if fban is False: await message.reply_text("This user is not fbanned!") return banner = update.effective_user chat_list = sql.all_fed_chats(fed_id) # Will send to current chat await bot.send_message( chat.id, "Un-FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}".format( info["fname"], mention_html(user.id, user.first_name), user_target, fban_user_id, ), parse_mode="HTML", ) # Send message to owner if fednotif is enabled if getfednotif: await bot.send_message( info["owner"], "Un-FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}".format( info["fname"], mention_html(user.id, user.first_name), user_target, fban_user_id, ), parse_mode="HTML", ) # If fedlog is set, then send message, except fedlog is current chat get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if int(get_fedlog) != int(chat.id): await bot.send_message( get_fedlog, "Un-FedBan" "\nFederation: {}" "\nFederation Admin: {}" "\nUser: {}" "\nUser ID: {}".format( info["fname"], mention_html(user.id, user.first_name), user_target, fban_user_id, ), parse_mode="HTML", ) unfbanned_in_chats = 0 for fedchats in chat_list: unfbanned_in_chats += 1 try: member = await bot.get_chat_member(fedchats, user_id) if member.status == "kicked": await bot.unban_chat_member(fedchats, user_id) # Do not spamming all fed chats """ bot.send_message(chat, "Un-FedBan" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}".format(info['fname'], mention_html(user.id, user.first_name), user_target, fban_user_id), parse_mode="HTML") """ except BadRequest as excp: if excp.message in UNFBAN_ERRORS: pass elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Could not fban on {} because: {}".format(chat, excp.message), ) except TelegramError: pass try: x = sql.un_fban_user(fed_id, user_id) if not x: await send_message( update.effective_message, "Un-fban failed, this user may already be un-fedbanned!", ) return except: pass # UnFban for fed subscriber subscriber = list(sql.get_subscriber(fed_id)) if len(subscriber) != 0: for fedsid in subscriber: all_fedschat = sql.all_fed_chats(fedsid) for fedschat in all_fedschat: try: await bot.unban_chat_member(fedchats, user_id) except BadRequest as excp: if excp.message in FBAN_ERRORS: try: await dispatcher.bot.getChat(fedschat) except Forbidden: targetfed_id = sql.get_fed_id(fedschat) sql.unsubs_fed(fed_id, targetfed_id) LOGGER.info( "Chat {} has unsub fed {} because I was kicked".format( fedschat, info["fname"], ), ) continue elif excp.message == "User_id_invalid": break else: LOGGER.warning( "Unable to fban on {} because: {}".format( fedschat, excp.message, ), ) except TelegramError: pass if unfbanned_in_chats == 0: await send_message( update.effective_message, "This person has been un-fbanned in 0 chats.", ) if unfbanned_in_chats > 0: await send_message( update.effective_message, "This person has been un-fbanned in {} chats.".format(unfbanned_in_chats), ) # Also do not spamming all fed admins """ FEDADMIN = sql.all_fed_users(fed_id) for x in FEDADMIN: getreport = sql.user_feds_report(x) if getreport is False: FEDADMIN.remove(x) send_to_list(bot, FEDADMIN, "Un-FedBan" \ "\nFederation: {}" \ "\nFederation Admin: {}" \ "\nUser: {}" \ "\nUser ID: {}".format(info['fname'], mention_html(user.id, user.first_name), mention_html(user_chat.id, user_chat.first_name), user_chat.id), html=True) """ async def set_frules(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not in any federation!" ) return if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text("Only fed admins can do this!") return if len(args) >= 1: msg = update.effective_message raw_text = msg.text args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args if len(args) == 2: txt = args[1] offset = len(txt) - len(raw_text) # set correct offset relative to command markdown_rules = markdown_parser( txt, entities=msg.parse_entities(), offset=offset, ) x = sql.set_frules(fed_id, markdown_rules) if not x: await update.effective_message.reply_text( f"Whoa! There was an error while setting federation rules! If you wondered why please ask it in @{SUPPORT_CHAT}!", ) return rules = sql.get_fed_info(fed_id)["frules"] getfed = sql.get_fed_info(fed_id) get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if ast.literal_eval(get_fedlog): await bot.send_message( get_fedlog, "*{}* has updated federation rules for fed *{}*".format( user.first_name, getfed["fname"], ), parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) await update.effective_message.reply_text( f"Rules have been changed to :\n{rules}!" ) else: await update.effective_message.reply_text("Please write rules to set this up!") async def get_frules(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not in any federation!" ) return rules = sql.get_frules(fed_id) text = "*Rules in this fed:*\n" text += rules await update.effective_message.reply_text(text, parse_mode=ParseMode.MARKDOWN) async def fed_broadcast(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args msg = update.effective_message user = update.effective_user chat = update.effective_chat if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return if args: chat = update.effective_chat fed_id = sql.get_fed_id(chat.id) fedinfo = sql.get_fed_info(fed_id) if is_user_fed_owner(fed_id, user.id) is False: await update.effective_message.reply_text( "Only federation owners can do this!" ) return # Parsing md raw_text = msg.text args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args txt = args[1] offset = len(txt) - len(raw_text) # set correct offset relative to command text_parser = markdown_parser(txt, entities=msg.parse_entities(), offset=offset) text = text_parser try: broadcaster = user.first_name except: broadcaster = user.first_name + " " + user.last_name text += "\n\n- {}".format(mention_markdown(user.id, broadcaster)) chat_list = sql.all_fed_chats(fed_id) failed = 0 for chat in chat_list: title = "*New broadcast from Fed {}*\n".format(fedinfo["fname"]) try: await bot.sendMessage( chat, title + text, parse_mode="markdown", message_thread_id=msg.message_thread_id if chat.is_forum else None, ) except TelegramError: try: await dispatcher.bot.getChat(chat) except Forbidden: failed += 1 sql.chat_leave_fed(chat) LOGGER.info( "Chat {} has left fed {} because I was kicked".format( chat, fedinfo["fname"], ), ) continue failed += 1 LOGGER.warning("Couldn't send broadcast to {}".format(str(chat))) send_text = "The federation broadcast is complete" if failed >= 1: send_text += "{} the group failed to receive the message, probably because it left the Federation.".format( failed, ) await update.effective_message.reply_text(send_text) async def fed_ban_list(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args, chat_data = context.bot, context.args, context.chat_data chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) info = sql.get_fed_info(fed_id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return if is_user_fed_owner(fed_id, user.id) is False: await update.effective_message.reply_text("Only Federation owners can do this!") return user = update.effective_user chat = update.effective_chat getfban = sql.get_all_fban_users(fed_id) if len(getfban) == 0: await update.effective_message.reply_text( "The federation ban list of {} is empty".format(info["fname"]), parse_mode=ParseMode.HTML, ) return if args: if args[0] == "json": jam = time.time() new_jam = jam + 1800 cek = get_chat(chat.id, chat_data) if cek.get("status"): if jam <= int(cek.get("value")): waktu = time.strftime( "%H:%M:%S %d/%m/%Y", time.localtime(cek.get("value")), ) await update.effective_message.reply_text( "You can backup your data once every 30 minutes!\nYou can back up data again at `{}`".format( waktu, ), parse_mode=ParseMode.MARKDOWN, ) return else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) backups = "" for users in getfban: getuserinfo = sql.get_all_fban_users_target(fed_id, users) json_parser = { "user_id": users, "first_name": getuserinfo["first_name"], "last_name": getuserinfo["last_name"], "user_name": getuserinfo["user_name"], "reason": getuserinfo["reason"], } backups += json.dumps(json_parser) backups += "\n" with BytesIO(str.encode(backups)) as output: output.name = "mikobot_fbanned_users.json" await update.effective_message.reply_document( document=output, filename="mikobot_fbanned_users.json", caption="Total {} User are blocked by the Federation {}.".format( len(getfban), info["fname"], ), ) return elif args[0] == "csv": jam = time.time() new_jam = jam + 1800 cek = get_chat(chat.id, chat_data) if cek.get("status"): if jam <= int(cek.get("value")): waktu = time.strftime( "%H:%M:%S %d/%m/%Y", time.localtime(cek.get("value")), ) await update.effective_message.reply_text( "You can back up data once every 30 minutes!\nYou can back up data again at `{}`".format( waktu, ), parse_mode=ParseMode.MARKDOWN, ) return else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) backups = "id,firstname,lastname,username,reason\n" for users in getfban: getuserinfo = sql.get_all_fban_users_target(fed_id, users) backups += ( "{user_id},{first_name},{last_name},{user_name},{reason}".format( user_id=users, first_name=getuserinfo["first_name"], last_name=getuserinfo["last_name"], user_name=getuserinfo["user_name"], reason=getuserinfo["reason"], ) ) backups += "\n" with BytesIO(str.encode(backups)) as output: output.name = "mikobot_fbanned_users.csv" await update.effective_message.reply_document( document=output, filename="mikobot_fbanned_users.csv", caption="Total {} User are blocked by Federation {}.".format( len(getfban), info["fname"], ), ) return text = "{} users have been banned from the federation {}:\n".format( len(getfban), info["fname"], ) for users in getfban: getuserinfo = sql.get_all_fban_users_target(fed_id, users) if getuserinfo is False: text = "There are no users banned from the federation {}".format( info["fname"], ) break user_name = getuserinfo["first_name"] if getuserinfo["last_name"]: user_name += " " + getuserinfo["last_name"] text += " • {} ({})\n".format( mention_html(users, user_name), users, ) try: await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML) except: jam = time.time() new_jam = jam + 1800 cek = get_chat(chat.id, chat_data) if cek.get("status"): if jam <= int(cek.get("value")): waktu = time.strftime( "%H:%M:%S %d/%m/%Y", time.localtime(cek.get("value")), ) await update.effective_message.reply_text( "You can back up data once every 30 minutes!\nYou can back up data again at `{}`".format( waktu, ), parse_mode=ParseMode.MARKDOWN, ) return else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) cleanr = re.compile("<.*?>") cleantext = re.sub(cleanr, "", text) with BytesIO(str.encode(cleantext)) as output: output.name = "fbanlist.txt" await update.effective_message.reply_document( document=output, filename="fbanlist.txt", caption="The following is a list of users who are currently fbanned in the Federation {}.".format( info["fname"], ), ) async def fed_notif(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message fed_id = sql.get_fed_id(chat.id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return if args: if args[0] in ("yes", "on"): sql.set_feds_setting(user.id, True) await msg.reply_text( "Reporting Federation back up! Every user who is fban / unfban you will be notified via PM.", ) elif args[0] in ("no", "off"): sql.set_feds_setting(user.id, False) await msg.reply_text( "Reporting Federation has stopped! Every user who is fban / unfban you will not be notified via PM.", ) else: await msg.reply_text("Please enter `on`/`off`", parse_mode="markdown") else: getreport = sql.user_feds_report(user.id) await msg.reply_text( "Your current Federation report preferences: `{}`".format(getreport), parse_mode="markdown", ) async def fed_chats(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) info = sql.get_fed_info(fed_id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return if is_user_fed_admin(fed_id, user.id) is False: await update.effective_message.reply_text("Only federation admins can do this!") return getlist = sql.all_fed_chats(fed_id) if len(getlist) == 0: await update.effective_message.reply_text( "No users are fbanned from the federation {}".format(info["fname"]), parse_mode=ParseMode.HTML, ) return text = "New chat joined the federation {}:\n".format(info["fname"]) for chats in getlist: try: chat_obj = await dispatcher.bot.getChat(chats) chat_name = chat_obj.title except Forbidden: sql.chat_leave_fed(chats) LOGGER.info( "Chat {} has leave fed {} because I was kicked".format( chats, info["fname"], ), ) continue text += " • {} ({})\n".format(chat_name, chats) try: await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML) except: cleanr = re.compile("<.*?>") cleantext = re.sub(cleanr, "", text) with BytesIO(str.encode(cleantext)) as output: output.name = "fedchats.txt" await update.effective_message.reply_document( document=output, filename="fedchats.txt", caption="Here is a list of all the chats that joined the federation {}.".format( info["fname"], ), ) async def fed_import_bans(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, chat_data = context.bot, context.chat_data chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) info = sql.get_fed_info(fed_id) getfed = sql.get_fed_info(fed_id) if not fed_id: await update.effective_message.reply_text( "This group is not a part of any federation!", ) return if is_user_fed_owner(fed_id, user.id) is False: await update.effective_message.reply_text("Only Federation owners can do this!") return if msg.reply_to_message and msg.reply_to_message.document: jam = time.time() new_jam = jam + 1800 cek = get_chat(chat.id, chat_data) if cek.get("status"): if jam <= int(cek.get("value")): waktu = time.strftime( "%H:%M:%S %d/%m/%Y", time.localtime(cek.get("value")), ) await update.effective_message.reply_text( "You can get your data once every 30 minutes!\nYou can get data again at `{}`".format( waktu, ), parse_mode=ParseMode.MARKDOWN, ) return else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) else: if user.id not in DRAGONS: put_chat(chat.id, new_jam, chat_data) # if int(int(msg.reply_to_message.document.file_size)/1024) >= 200: # msg.reply_text("This file is too big!") # return success = 0 failed = 0 try: file_info = await bot.get_file(msg.reply_to_message.document.file_id) except BadRequest: await msg.reply_text( "Try downloading and re-uploading the file, this one seems broken!", ) return fileformat = msg.reply_to_message.document.file_name.split(".")[-1] if fileformat == "json": multi_fed_id = [] multi_import_userid = [] multi_import_firstname = [] multi_import_lastname = [] multi_import_username = [] multi_import_reason = [] with BytesIO() as file: file_info.download_to_object(out=file) file.seek(0) reading = file.read().decode("UTF-8") splitting = reading.split("\n") for x in splitting: if x == "": continue try: data = json.loads(x) except json.decoder.JSONDecodeError as err: failed += 1 continue try: import_userid = int(data["user_id"]) # Make sure it int import_firstname = str(data["first_name"]) import_lastname = str(data["last_name"]) import_username = str(data["user_name"]) import_reason = str(data["reason"]) except ValueError: failed += 1 continue # Checking user if int(import_userid) == bot.id: failed += 1 continue if is_user_fed_owner(fed_id, import_userid) is True: failed += 1 continue if is_user_fed_admin(fed_id, import_userid) is True: failed += 1 continue if str(import_userid) == str(OWNER_ID): failed += 1 continue if int(import_userid) in DRAGONS: failed += 1 continue multi_fed_id.append(fed_id) multi_import_userid.append(str(import_userid)) multi_import_firstname.append(import_firstname) multi_import_lastname.append(import_lastname) multi_import_username.append(import_username) multi_import_reason.append(import_reason) success += 1 sql.multi_fban_user( multi_fed_id, multi_import_userid, multi_import_firstname, multi_import_lastname, multi_import_username, multi_import_reason, ) text = "Blocks were successfully imported. {} people are blocked.".format( success, ) if failed >= 1: text += " {} Failed to import.".format(failed) get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if ast.literal_eval(get_fedlog): teks = "Fed *{}* has successfully imported data. {} banned.".format( getfed["fname"], success, ) if failed >= 1: teks += " {} Failed to import.".format(failed) await bot.send_message( get_fedlog, teks, parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) elif fileformat == "csv": multi_fed_id = [] multi_import_userid = [] multi_import_firstname = [] multi_import_lastname = [] multi_import_username = [] multi_import_reason = [] file_info.download_to_drive( "fban_{}.csv".format(msg.reply_to_message.document.file_id), ) with open( "fban_{}.csv".format(msg.reply_to_message.document.file_id), "r", encoding="utf8", ) as csvFile: reader = csv.reader(csvFile) for data in reader: try: import_userid = int(data[0]) # Make sure it int import_firstname = str(data[1]) import_lastname = str(data[2]) import_username = str(data[3]) import_reason = str(data[4]) except ValueError: failed += 1 continue # Checking user if int(import_userid) == bot.id: failed += 1 continue if is_user_fed_owner(fed_id, import_userid) is True: failed += 1 continue if is_user_fed_admin(fed_id, import_userid) is True: failed += 1 continue if str(import_userid) == str(OWNER_ID): failed += 1 continue if int(import_userid) in DRAGONS: failed += 1 continue multi_fed_id.append(fed_id) multi_import_userid.append(str(import_userid)) multi_import_firstname.append(import_firstname) multi_import_lastname.append(import_lastname) multi_import_username.append(import_username) multi_import_reason.append(import_reason) success += 1 # t = ThreadWithReturnValue(target=sql.fban_user, args=(fed_id, str(import_userid), import_firstname, import_lastname, import_username, import_reason,)) # t.start() sql.multi_fban_user( multi_fed_id, multi_import_userid, multi_import_firstname, multi_import_lastname, multi_import_username, multi_import_reason, ) csvFile.close() os.remove("fban_{}.csv".format(msg.reply_to_message.document.file_id)) text = "Files were imported successfully. {} people banned.".format(success) if failed >= 1: text += " {} Failed to import.".format(failed) get_fedlog = await sql.get_fed_log(fed_id) if get_fedlog: if ast.literal_eval(get_fedlog): teks = "Fed *{}* has successfully imported data. {} banned.".format( getfed["fname"], success, ) if failed >= 1: teks += " {} Failed to import.".format(failed) await bot.send_message( get_fedlog, teks, parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) else: await send_message(update.effective_message, "This file is not supported.") return await send_message(update.effective_message, text) async def del_fed_button(update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query userid = query.message.chat.id fed_id = query.data.split("_")[1] if fed_id == "cancel": await query.message.edit_text("Federation deletion cancelled") return getfed = sql.get_fed_info(fed_id) if getfed: delete = sql.del_fed(fed_id) if delete: await query.message.edit_text( "You have removed your Federation! Now all the Groups that are connected with `{}` do not have a Federation.".format( getfed["fname"], ), parse_mode="markdown", ) async def fed_stat_user(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if args: if args[0].isdigit(): user_id = args[0] else: user_id = await extract_user(msg, context, args) else: user_id = await extract_user(msg, context, args) if user_id: if len(args) == 2 and args[0].isdigit(): fed_id = args[1] user_name, reason, fbantime = sql.get_user_fban(fed_id, str(user_id)) if fbantime: fbantime = time.strftime("%d/%m/%Y", time.localtime(fbantime)) else: fbantime = "Unavaiable" if user_name is False: await send_message( update.effective_message, "Fed {} not found!".format(fed_id), parse_mode="markdown", ) return if user_name == "" or user_name is None: user_name = "He/she" if not reason: await send_message( update.effective_message, "{} is not banned in this federation!".format(user_name), ) else: teks = "{} banned in this federation because:\n`{}`\n*Banned at:* `{}`".format( user_name, reason, fbantime, ) await send_message( update.effective_message, teks, parse_mode="markdown" ) return user_name, fbanlist = sql.get_user_fbanlist(str(user_id)) if user_name == "": try: user_first = await bot.get_chat(user_id) if isinstance(user_first, ChatMember): user_name = user_id.first_name except BadRequest: user_name = "He/she" if user_name == "" or user_name is None: user_name = "He/she" if len(fbanlist) == 0: await send_message( update.effective_message, "{} is not banned in any federation!".format(user_name), ) return else: teks = "{} has been banned in this federation:\n".format(user_name) for x in fbanlist: teks += "- `{}`: {}\n".format(x[0], x[1][:20]) teks += "\nIf you want to find out more about the reasons for Fedban specifically, use /fbanstat " await send_message(update.effective_message, teks, parse_mode="markdown") elif not msg.reply_to_message and not args: user_id = msg.from_user.id user_name, fbanlist = sql.get_user_fbanlist(user_id) if user_name == "": user_name = msg.from_user.first_name if len(fbanlist) == 0: await send_message( update.effective_message, "{} is not banned in any federation!".format(user_name), ) else: teks = "{} has been banned in this federation:\n".format(user_name) for x in fbanlist: teks += "- `{}`: {}\n".format(x[0], x[1][:20]) teks += "\nIf you want to find out more about the reasons for Fedban specifically, use /fbanstat " await send_message(update.effective_message, teks, parse_mode="markdown") else: fed_id = args[0] fedinfo = sql.get_fed_info(fed_id) if not fedinfo: await send_message( update.effective_message, "Fed {} not found!".format(fed_id) ) return name, reason, fbantime = sql.get_user_fban(fed_id, msg.from_user.id) if fbantime: fbantime = time.strftime("%d/%m/%Y", time.localtime(fbantime)) else: fbantime = "Unavaiable" if not name: name = msg.from_user.first_name if not reason: await send_message( update.effective_message, "{} is not banned in this federation".format(name), ) return await send_message( update.effective_message, "{} banned in this federation because:\n`{}`\n*Banned at:* `{}`".format( name, reason, fbantime, ), parse_mode="markdown", ) async def set_fed_log(update: Update, context: ContextTypes.DEFAULT_TYPE): args = context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return if args: fedinfo = sql.get_fed_info(args[0]) if not fedinfo: await send_message( update.effective_message, "This Federation does not exist!" ) return isowner = is_user_fed_owner(args[0], user.id) if not isowner: await send_message( update.effective_message, "Only federation creator can set federation logs.", ) return setlog = sql.set_fed_log(args[0], chat.id) if setlog: await send_message( update.effective_message, "Federation log `{}` has been set to {}".format( fedinfo["fname"], chat.title, ), parse_mode="markdown", ) else: await send_message( update.effective_message, "You have not provided your federated ID!", ) async def unset_fed_log(update: Update, context: ContextTypes.DEFAULT_TYPE): args = context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return if args: fedinfo = sql.get_fed_info(args[0]) if not fedinfo: await send_message( update.effective_message, "This Federation does not exist!" ) return isowner = is_user_fed_owner(args[0], user.id) if not isowner: await send_message( update.effective_message, "Only federation creator can set federation logs.", ) return setlog = sql.set_fed_log(args[0], None) if setlog: await send_message( update.effective_message, "Federation log `{}` has been revoked on {}".format( fedinfo["fname"], chat.title, ), parse_mode="markdown", ) else: await send_message( update.effective_message, "You have not provided your federated ID!", ) async def subs_feds(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) fedinfo = sql.get_fed_info(fed_id) if not fed_id: await send_message( update.effective_message, "This group is not in any federation!" ) return if is_user_fed_owner(fed_id, user.id) is False: await send_message(update.effective_message, "Only fed owner can do this!") return if args: getfed = sql.search_fed_by_id(args[0]) if getfed is False: await send_message( update.effective_message, "Please enter a valid federation id.", ) return subfed = sql.subs_fed(args[0], fed_id) if subfed: await send_message( update.effective_message, "Federation `{}` has subscribe the federation `{}`. Every time there is a Fedban from that federation, this federation will also banned that user.".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", ) get_fedlog = await sql.get_fed_log(args[0]) if get_fedlog: if int(get_fedlog) != int(chat.id): await bot.send_message( get_fedlog, "Federation `{}` has subscribe the federation `{}`".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) else: await send_message( update.effective_message, "Federation `{}` already subscribe the federation `{}`.".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", ) else: await send_message( update.effective_message, "You have not provided your federated ID!", ) async def unsubs_feds(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) fedinfo = sql.get_fed_info(fed_id) if not fed_id: await send_message( update.effective_message, "This group is not in any federation!" ) return if is_user_fed_owner(fed_id, user.id) is False: await send_message(update.effective_message, "Only fed owner can do this!") return if args: getfed = sql.search_fed_by_id(args[0]) if getfed is False: await send_message( update.effective_message, "Please enter a valid federation id.", ) return subfed = sql.unsubs_fed(args[0], fed_id) if subfed: await send_message( update.effective_message, "Federation `{}` now unsubscribe fed `{}`.".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", ) get_fedlog = await sql.get_fed_log(args[0]) if get_fedlog: if int(get_fedlog) != int(chat.id): await bot.send_message( get_fedlog, "Federation `{}` has unsubscribe fed `{}`.".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", message_thread_id=( update.effective_message.message_thread_id if chat.is_forum else None ), ) else: await send_message( update.effective_message, "Federation `{}` is not subscribing `{}`.".format( fedinfo["fname"], getfed["fname"], ), parse_mode="markdown", ) else: await send_message( update.effective_message, "You have not provided your federated ID!", ) async def get_myfedsubs(update: Update, context: ContextTypes.DEFAULT_TYPE): args = context.args chat = update.effective_chat user = update.effective_user msg = update.effective_message if chat.type == "private": await send_message( update.effective_message, "This command is specific to the group, not to our pm!", ) return fed_id = sql.get_fed_id(chat.id) fedinfo = sql.get_fed_info(fed_id) if not fed_id: await send_message( update.effective_message, "This group is not in any federation!" ) return if is_user_fed_owner(fed_id, user.id) is False: await send_message(update.effective_message, "Only fed owner can do this!") return try: getmy = sql.get_mysubs(fed_id) except: getmy = [] if len(getmy) == 0: await send_message( update.effective_message, "Federation `{}` is not subscribing any federation.".format( fedinfo["fname"], ), parse_mode="markdown", ) return else: listfed = "Federation `{}` is subscribing federation:\n".format( fedinfo["fname"], ) for x in getmy: listfed += "- `{}`\n".format(x) listfed += ( "\nTo get fed info `/fedinfo `. To unsubscribe `/unsubfed `." ) await send_message(update.effective_message, listfed, parse_mode="markdown") async def get_myfeds_list(update: Update, context: ContextTypes.DEFAULT_TYPE): chat = update.effective_chat user = update.effective_user msg = update.effective_message fedowner = sql.get_user_owner_fed_full(user.id) if fedowner: text = "*You are owner of feds:\n*" for f in fedowner: text += "- `{}`: *{}*\n".format(f["fed_id"], f["fed"]["fname"]) else: text = "*You are not have any feds!*" await send_message(update.effective_message, text, parse_mode="markdown") def is_user_fed_admin(fed_id, user_id): fed_admins = sql.all_fed_users(fed_id) if fed_admins is False: return False if int(user_id) in fed_admins or int(user_id) == OWNER_ID: return True else: return False def is_user_fed_owner(fed_id, user_id): getsql = sql.get_fed_info(fed_id) if getsql is False: return False getfedowner = ast.literal_eval(getsql["fusers"]) if getfedowner is None or getfedowner is False: return False getfedowner = getfedowner["owner"] if str(user_id) == getfedowner or int(user_id) == OWNER_ID: return True else: return False # There's no handler for this yet, but updating for v12 in case its used async def welcome_fed(update: Update, context: ContextTypes.DEFAULT_TYPE): bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user fed_id = sql.get_fed_id(chat.id) fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user.id) if fban: await update.effective_message.reply_text( "This user is banned in current federation! I will remove him.", ) await bot.ban_chat_member(chat.id, user.id) return True else: return False def __stats__(): all_fbanned = sql.get_all_fban_users_global() all_feds = sql.get_all_feds_users_global() return "• {} banned users across {} Federations".format( len(all_fbanned), len(all_feds), ) def __user_info__(user_id, chat_id): fed_id = sql.get_fed_id(chat_id) if fed_id: fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user_id) info = sql.get_fed_info(fed_id) infoname = info["fname"] if int(info["owner"]) == user_id: text = "Federation owner of: {}.".format(infoname) elif is_user_fed_admin(fed_id, user_id): text = "Federation admin of: {}.".format(infoname) elif fban: text = "Federation banned: Yes" text += "\nReason: {}".format(fbanreason) else: text = "Federation banned: No" else: text = "" return text # Temporary data def put_chat(chat_id, value, chat_data): # print(chat_data) if value is False: status = False else: status = True chat_data[chat_id] = {"federation": {"status": status, "value": value}} def get_chat(chat_id, chat_data): # print(chat_data) try: value = chat_data[chat_id]["federation"] return value except KeyError: return {"status": False, "value": False} async def fed_owner_help(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.effective_message.reply_text( """*👑 Fed Owner Only:* » `/newfed `*:* Creates a Federation, One allowed per user » `/renamefed `*:* Renames the fed id to a new name » `/delfed `*:* Delete a Federation, and any information related to it. Will not cancel blocked users » `/fpromote `*:* Assigns the user as a federation admin. Enables all commands for the user under `Fed Admins` » `/fdemote `*:* Drops the User from the admin Federation to a normal User » `/subfed `*:* Subscribes to a given fed ID, bans from that subscribed fed will also happen in your fed » `/unsubfed `*:* Unsubscribes to a given fed ID » `/setfedlog `*:* Sets the group as a fed log report base for the federation » `/unsetfedlog `*:* Removed the group as a fed log report base for the federation » `/fbroadcast `*:* Broadcasts a messages to all groups that have joined your fed » `/fedsubs`*:* Shows the feds your group is subscribed to `(broken rn)`""", parse_mode=ParseMode.MARKDOWN, ) async def fed_admin_help(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.effective_message.reply_text( """*🔱 Fed Admins:* » `/fban `*:* Fed bans a user » `/unfban `*:* Removes a user from a fed ban » `/fedinfo `*:* Information about the specified Federation » `/joinfed `*:* Join the current chat to the Federation. Only chat owners can do this. Every chat can only be in one Federation » `/leavefed `*:* Leave the Federation given. Only chat owners can do this » `/setfrules `*:* Arrange Federation rules » `/fedadmins`*:* Show Federation admin » `/fbanlist`*:* Displays all users who are victimized at the Federation at this time » `/fedchats`*:* Get all the chats that are connected in the Federation » `/chatfed `*:* See the Federation in the current chat\n""", parse_mode=ParseMode.MARKDOWN, ) async def fed_user_help(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.effective_message.reply_text( """*🎩 Any user:* » `/fbanstat`*:* Shows if you/or the user you are replying to or their username is fbanned somewhere or not » `/fednotif `*:* Federation settings not in PM when there are users who are fbaned/unfbanned » `/frules`*:* See Federation regulations\n""", parse_mode=ParseMode.MARKDOWN, ) # <=================================================== HELP ====================================================> __mod_name__ = "FEDS" __help__ = """ ➠ *Everything is fun, until a spammer starts entering your group, and you have to block it. Then you need to start banning more, and more, and it hurts*. *But then you have many groups, and you don't want this spammer to be in one of your groups - how can you deal? Do you have to manually block it, in all your groups*?\n *No longer!* *With Federation, you can make a ban in one chat overlap with all other chats*.\n *You can even designate federation admins, so your trusted admin can ban all the spammers from chats you want to protect*.\n ➠ *Commands:* ➠ Feds are now divided into 3 sections for your ease. » /fedownerhelp: Provides help for fed creation and owner only commands. » /fedadminhelp: Provides help for fed administration commands. » /feduserhelp: Provides help for commands anyone can use. """ # <================================================ HANDLER =======================================================> function(CommandHandler("newfed", new_fed, block=False)) function(CommandHandler("delfed", del_fed, block=False)) function(CommandHandler("renamefed", rename_fed, block=False)) function(CommandHandler("joinfed", join_fed, block=False)) function(CommandHandler("leavefed", leave_fed, block=False)) function(CommandHandler("fpromote", user_join_fed, block=False)) function(CommandHandler("fdemote", user_demote_fed, block=False)) function(CommandHandler("fedinfo", fed_info, block=False)) function(DisableAbleCommandHandler("fban", fed_ban, block=False)) function(CommandHandler("unfban", unfban, block=False)) function(CommandHandler("fbroadcast", fed_broadcast, block=False)) function(CommandHandler("setfrules", set_frules, block=False)) function(CommandHandler("frules", get_frules, block=False)) function(CommandHandler("chatfed", fed_chat, block=False)) function(CommandHandler("fedadmins", fed_admin, block=False)) function(CommandHandler("fbanlist", fed_ban_list, block=False)) function(CommandHandler("fednotif", fed_notif, block=False)) function(CommandHandler("fedchats", fed_chats, block=False)) function(CommandHandler("importfbans", fed_import_bans, block=False)) function(DisableAbleCommandHandler(["fedstat", "fbanstat"], fed_stat_user, block=False)) function(CommandHandler("setfedlog", set_fed_log, block=False)) function(CommandHandler("unsetfedlog", unset_fed_log, block=False)) function(CommandHandler("subfed", subs_feds, block=False)) function(CommandHandler("unsubfed", unsubs_feds, block=False)) function(CommandHandler("fedsubs", get_myfedsubs, block=False)) function(CommandHandler("myfeds", get_myfeds_list, block=False)) function(CallbackQueryHandler(del_fed_button, pattern=r"rmfed_", block=False)) function(CommandHandler("fedownerhelp", fed_owner_help, block=False)) function(CommandHandler("fedadminhelp", fed_admin_help, block=False)) function(CommandHandler("feduserhelp", fed_user_help, block=False)) # <================================================ END =======================================================>