def __list_all_modules(): from os.path import dirname, basename, isfile import glob # This generates a list of helper_funcs in this folder for the * in __main__ to work. mod_paths = glob.glob(dirname(__file__) + "/*.py") all_modules = [ basename(f)[:-3] for f in mod_paths if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") ] if LOAD or NO_LOAD: to_load = LOAD if to_load: if not all( any(mod == module_name for module_name in all_modules) for mod in to_load): LOGGER.error("Invalid loadorder names. Quitting.") sys.exit(1) else: to_load = all_modules if NO_LOAD: LOGGER.info("Not loading: {}".format(NO_LOAD)) return [item for item in to_load if item not in NO_LOAD] return to_load return all_modules
async def get_peer_id(entity: str or int) -> int: peer = None try: peer = await client.get_peer_id(entity) except Exception as e: LOGGER.debug(e) return peer
async def ban(event): if ((event.is_channel or event.is_group) and not (event.chat.creator or event.chat.admin_rights.ban_users)): await event.edit("`You do not have rights to ban users in here!`") return user, reason, exception = await get_entity_from_msg(event) if user: if exception: await event.edit(f"`Ban machine broke!\n{user}`") return try: await client.edit_permissions(entity=await event.get_input_chat(), user=user, view_messages=False) text = "`Successfully banned ``{}`` (``{}``)!`" if reason: text += f"\n`Reason:` `{reason}`" await event.edit(text.format(get_display_name(user), user.id)) except Exception as e: await event.edit("`An exception occured trying to ban. " " Make sure you have the correct rights! " "Check the logs for more information.`") LOGGER.exception(e)
async def promote(event): if ((event.is_channel or event.is_group) and not (event.chat.creator or event.chat.admin_rights.add_admins)): await event.edit("`You do not have rights to add admins in here!`") return user, extra, exception = await get_entity_from_msg(event) if user: if exception: await event.edit(f"`Promote machine broke!\n{user}`") return try: await client.edit_admin( entity=await event.get_input_chat(), post_messages=True if event.is_channel else False, edit_messages=True if event.is_channel else False, user=user, is_admin=True, title=extra) text = "`Successfully promoted ``{}`` (``{}``)!`" if extra: text += f"\n`Title:` `{extra}`" await event.edit(text.format(get_display_name(user), user.id)) except Exception as e: await event.edit("`An exception occured trying to promote. " " Make sure you have the correct rights! " "Check the logs for more information.`") LOGGER.exception(e)
async def _get_new_ub_pack( conv: custom.conversation.Conversation, packs: list, is_animated: bool ) -> Tuple[str, str, bool]: ub_packs = [] new_pack = False user = await client.get_me() tag = "@" + user.username if user.username else user.id for pack in packs: if "_kang_pack" in pack: if "_animated" in pack: if is_animated: ub_packs.append(pack) else: if not is_animated: ub_packs.append(pack) pack = sorted(ub_packs)[-1] # Fetch the last pack await conv.send_message(pack) r11 = await conv.get_response() LOGGER.debug("Stickers:" + r11.text) if "120 stickers" in r11.text: l_char = pack[-1:] # Check if the suffix is a digit if l_char.isdigit(): pack = pack[:-1] + str(int(l_char) + 1) # ++ the suffix else: pack = pack + "_2" # Append the suffix new_pack = True if is_animated: packnick = f"{tag}'s animated kang pack {pack[-1:]}" else: packnick = f"{tag}'s kang pack {pack[-1:]}" await client.send_read_acknowledge(conv.chat_id) return pack, packnick, new_pack
async def demote(event: NewMessage.Event) -> None: """Demote a user in a group or channel.""" if not event.is_private and not await get_rights(event, ban_users=True): await event.answer("`You do not have rights to remove admins in here!`" ) return elif event.is_private: await event.answer("`You can't demote users in private chats.`") return user, reason, exception = await get_entity_from_msg(event) if user: if exception: await event.answer(f"`Demote machine broke!\n{user}`") return else: await event.answer("`At least specifiy a user, maybe?`") return entity = await event.get_chat() try: await client.edit_admin(entity=entity, user=user, is_admin=False) text = "`Successfully demoted `{}` (``{}``)!`" if reason: text += f"\n`Reason:` `{reason}`" e1 = await get_chat_link(user) e2 = await get_chat_link(entity, event.id) log_msg = f"Successfully demoted {e1} in {e2}" if reason: log_msg += f"\nReason: {reason}" await event.answer(text.format(e1, user.id), log=("demote", log_msg)) except Exception as e: await event.answer(f"`{e}`") LOGGER.exception(e)
async def shutdown(event: NewMessage.Event) -> None: """Shutdown the userbot script.""" await event.answer("`Disconnecting the client and exiting. Ciao!`") client.reconnect = False print() LOGGER.info("Disconnecting the client and exiting the main script.") await client.disconnect()
async def unban(event): if ((event.is_channel or event.is_group) and not (event.chat.creator or event.chat.admin_rights.ban_users)): await event.edit("`You do not have rights to un-ban users in here!`") return user, reason, exception = await get_entity_from_msg(event) if user: if exception: await event.edit(f"`Un-ban machine broke!\n{user}`") return try: await client.edit_permissions(entity=await event.get_input_chat(), user=user, view_messages=True, send_messages=True, send_media=True, send_stickers=True, send_gifs=True, send_games=True, send_inline=True, send_polls=True) text = "`Successfully un-banned ``{}`` (``{}``)!`" if reason: text += f"\n`Reason:` `{reason}`" await event.edit(text.format(get_display_name(user), user.id)) except Exception as e: await event.edit(f"`{e}`") LOGGER.exception(e)
async def whois(event: NewMessage.Event) -> None: """Get your or a user's/chat's information.""" match = event.matches[0].group(1) entities = [] if match: entities, _ = await client.parse_arguments(match) if "this" in entities: entities.remove("this") entities.append(event.chat_id) elif event.reply_to_msg_id: if not entities: reply = await event.get_reply_message() user = reply.sender_id if reply.fwd_from: if reply.fwd_from.from_id: user = reply.fwd_from.from_id entities.append(user) else: entities.append("self") users = "" chats = "" channels = "" failed = [] for user in entities: try: input_entity = await client.get_input_entity(user) if isinstance(input_entity, types.InputPeerChat): full_chat = await client( functions.messages.GetFullChatRequest(input_entity)) string = await Parser.parse_full_chat(full_chat, event) chats += f"\n{chats}\n" elif isinstance(input_entity, types.InputPeerChannel): full_channel = await client( functions.channels.GetFullChannelRequest(input_entity)) string = await Parser.parse_full_chat(full_channel, event) channels += f"\n{string}\n" else: full_user = await client( functions.users.GetFullUserRequest(input_entity)) string = await Parser.parse_full_user(full_user, event) users += f"\n{string}\n" except Exception as e: LOGGER.debug(e) failed.append(user) if users: await event.answer("**USERS**" + users, reply=True) if chats: await event.answer("**CHATS**" + chats, reply=True) if channels: await event.answer("**CHANNELS**" + channels, reply=True) if failed: failedtext = "**Unable to fetch:**\n" failedtext += ", ".join(f'`{u}`' for u in failed) await event.answer(failedtext) elif not (users or chats or channels): await event.answer("__Something went wrong!__", self_destruct=2)
async def upload_progress(current, total): """ Logs the upload progress """ # Quite spammy, find a better way to log the progress percentage = round((current / total) * 100, 2) LOGGER.debug( f"Uploaded {current} of {total} bytes. Progress: {percentage}%" )
async def update_requirements(): reqs = os.path.join(basedir, "requirements.txt") try: await create_subprocess_shell(' '.join(sys.executable, "-m", "pip", "install", "-r", str(reqs))) except Exception as e: LOGGER.exception(e)
async def shutdown(update): await update.edit("`Shutting down...`") LOGGER.info("Bot shutting down...") try: await update.client.disconnect() except: pass
async def bio_filter(event: ChatAction.Event) -> None: """Filter incoming messages for blacklisting.""" text = None broadcast = getattr(event.chat, 'broadcast', False) if not redis or event.is_private or broadcast: return if event.user_added or event.user_joined: try: sender = await event.get_input_user() chat = await event.get_chat() sender_id = await client.get_peer_id(sender) chat_id = await client.get_peer_id(chat) localbl = localBlacklists.get(chat_id, False) except (ValueError, TypeError): return if chat_id in whitelistedChats or sender_id in whitelistedUsers: return if await is_admin(chat_id, sender_id): return user = await client(functions.users.GetFullUserRequest(id=sender)) if GlobalBlacklist.bio: for value in GlobalBlacklist.bio: bio = await escape_string(value) if re.search(bio, user.about, flags=re.I): text = ("**Banned due to globally blacklisted bio match: " f"{value}**") elif localbl and getattr(localbl, 'bio', False): for value in localBlacklists[chat_id].bio: bio = await escape_string(value) if re.search(bio, user.about, flags=re.I): text = f"**Banned due to blacklisted bio match: {value}**" if text: ban_right = getattr(chat.admin_rights, 'ban_users', False) if ban_right or chat.creator: pass else: return try: await client.edit_permissions(entity=chat, user=sender_id, view_messages=False) await event.reply(text) if client.logger: logger_group = client.config['userbot'].getint( 'logger_group_id', 'me') log_text = ("**USERBOT LOG** #blacklist\n" f'Banned {sender_id} from {chat_id}.\n{text}.') await client.send_message(logger_group, log_text) except Exception as e: await event.reply(f"**Couldn't ban user due to {e}**") LOGGER.exception(e)
async def tban(event: NewMessage.Event) -> None: """Temporary ban a user in a group or channel.""" if not event.is_private and not await get_rights(event, ban_users=True): await event.answer("`You do not have rights to t-ban users in here!`") return elif event.is_private: await event.answer("`You can't t-ban users in private chats.`") return user, extra, exception = await get_entity_from_msg(event) if user: if exception: await event.answer(f"`T-ban machine broke!\n{user}`") return else: await event.answer("`At least specifiy a user, maybe?`") return entity = await event.get_chat() try: time = None reason = None seconds = None text = "`Successfully t-banned `{}` (``{}``)!`" e1 = await get_chat_link(user) e2 = await get_chat_link(entity, event.id) log_msg = f"Successfully t-banned {e1} in {e2}" if extra: reason, seconds = await split_extra_string(extra) if reason: text += f"\n`Reason:` `{reason}`" log_msg += f"\nReason: {reason}" if seconds: time = timedelta(seconds=seconds) text += f"\n`Time:` `{await _humanfriendly_seconds(seconds)}`" log_msg += f"Time: {await _humanfriendly_seconds(seconds)}" if not seconds: await event.answer("`Provide the total time limit for t-ban!`") return await client.edit_permissions( entity=entity, user=user, until_date=time, view_messages=False ) await event.answer( text.format(e1, user.id), log=("tban", log_msg) ) except Exception as e: await event.answer(f"`{e}`") LOGGER.exception(e)
async def update_requirements(): try: process = await asyncio.create_subprocess_shell( f'{sys.executable} -m pip install --user -r requirements.txt', stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) await process.communicate() return process.returncode except Exception as e: LOGGER.exception(e) return await client.get_traceback(e)
async def update_requirements(): reqs = str(requirements_path) try: process = await asyncio.create_subprocess_shell( ' '.join([sys.executable, "-m", "pip", "install", "-r", reqs]), stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) await process.communicate() return process.returncode except Exception as e: LOGGER.exception(e) return repr(e)
async def git_repo(event: NewMessage.Event) -> None: """Get the repo url.""" try: repo = git.Repo('.') remote_url = repo.remote().url.replace(".git", '/') if remote_url[-1] != '/': remote_url = remote_url + '/' repo.__del__() except Exception as e: LOGGER.info("Couldnt fetch the repo link.") LOGGER.debug(e) remote_url = "https://github.com/kandnub/TG-UserBot/" await event.answer(f"[TG-UserBot]({remote_url})")
async def update_requirements(): args = ['-m', 'pip', 'install', '--user', '-r', 'requirements.txt'] try: process = await asyncio.create_subprocess_exec( sys.executable.replace(' ', '\\ '), *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) await process.communicate() return process.returncode except Exception as e: LOGGER.exception(e) return await client.get_traceback(e)
async def update_requirements(): reqs = ' '.join( [sys.executable, "-m", "pip", "install", "-r", 'requirements.txt']) try: process = await asyncio.create_subprocess_shell( reqs, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) await process.communicate() return process.returncode except Exception as e: LOGGER.exception(e) return await client.get_traceback(e)
async def git_repo(event: NewMessage.Event) -> None: """Get the repo url.""" try: repo = git.Repo('.') remote_url = repo.remote().url.replace(".git", '/') if remote_url[-1] != '/': remote_url = remote_url + '/' repo.__del__() except Exception as e: LOGGER.info("Couldnt fetch the repo link.") LOGGER.debug(e) remote_url = "https://github.com/AvinashReddy3108/PaperplaneRemix.git" await event.answer( f"Click [here]({remote_url}) to check out my userbot's source code.")
async def update_requirements(): args = ["-m", "pip", "install", "--user", "-r", "requirements.txt"] try: process = await asyncio.create_subprocess_exec( sys.executable.replace(" ", "\\ "), *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) await process.communicate() return process.returncode except Exception as e: LOGGER.exception(e) return await client.get_traceback(e)
async def download(update): global is_downloading path = "/tmp/{}".format(os.getpid()) if not os.path.exists(path): os.mkdir(path) args = get_args(update) if len(args) < 1: await update.edit("`Usage: .spotdl <link>`") return link = args[0] if not "track" in link: await update.edit("`Invalid link. Please note that playlist links won't work!`") return if is_downloading: await update.edit("`Already downloading a song, please wait.`") return else: is_downloading = True try: await update.edit("`Downloading song, please wait...`") LOGGER.info("Starting download of " + link + ".") fetch = await create_subprocess_exec( "spotdl", "--ignore-ffmpeg-version", # TODO: Change this - It is required in order to run on Leap 15.2 Arm link, "--output", path, stdout=PIPE, stderr=PIPE, ) stdout, stderr = await fetch.communicate() result = str(stdout.decode().strip()) \ + str(stderr.decode().strip()) directory = os.fsencode(path) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".mp3"): await update.edit("`Sucessfully downloaded " + filename.replace(".mp3", "") + "`") LOGGER.info("Serving " + filename.replace(".mp3", "") + "...") await update.client.send_file(update.chat_id, path + "/" + filename) LOGGER.info("Serving " + filename.replace(".mp3", "") + " - Done.") LOGGER.debug("Deleting old files...") os.remove(path + "/" + filename) LOGGER.debug("Done deleting old files.") except FileNotFoundError: await update.edit("`Spotify-downloader is not installed.`") is_downloading = False
async def unban(event: NewMessage.Event) -> None: """Un-ban a user in a group or channel.""" if not event.is_private and not await get_rights(event, ban_users=True): await event.answer("`You do not have rights to un-ban users in here!`") return elif event.is_private: await event.answer("`You can't un-ban users in private chats.`") return user, reason, exception = await get_entity_from_msg(event) if user: if exception: await event.answer(f"`Un-ban machine broke!\n{user}`") return else: await event.answer("`At least specifiy a user, maybe?`") return entity = await event.get_chat() try: await client.edit_permissions( entity=entity, user=user, view_messages=True, send_messages=True, send_media=True, send_stickers=True, send_gifs=True, send_games=True, send_inline=True, send_polls=True ) text = "`Successfully un-banned `{}` (``{}``)!`" if reason: text += f"\n`Reason:` `{reason}`" e1 = await get_chat_link(user) e2 = await get_chat_link(entity, event.id) log_msg = f"Successfully unbanned {e1} in {e2}" if reason: log_msg += f"\nReason: {reason}" await event.answer( text.format(e1, user.id), log=("unban", log_msg) ) except Exception as e: await event.answer(f"`{e}`") LOGGER.exception(e)
async def ban_user(event: NewMessage.Event or ChatAction.Event, text: str, bl_type: str = None, match: Union[str, int] = None, globally: bool = False) -> bool: if isinstance(event, NewMessage.Event): sender = await event.get_input_sender() else: sender = await event.get_input_user() temp_banlist.append(sender) chat = await event.get_chat() ban_right = getattr(chat.admin_rights, 'ban_users', False) delete_messages = getattr(chat.admin_rights, 'delete_messages', False) if not (ban_right or chat.creator): return False user_href = "[{0}](tg://user?id={0})".format(sender.user_id) try: await client.edit_permissions(entity=chat.id, user=sender, view_messages=False) if delete_messages: await event.delete() text = text.format(user_href, ' globally ' if globally else ' ') await event.respond(text) if client.logger: logger_group = client.config['userbot'].getint( 'logger_group_id', 'me') if chat.username: chat_href = (f"[{chat.title}]" f"(tg://resolve?domain={chat.username})") else: chat_href = f"[{chat.title}] `{chat.id}`" log_text = ("**USERBOT LOG** #blacklist\n" f"Banned {user_href} from {chat_href}.\n") if bl_type and match: log_text += f"Blacklist type: `{bl_type}`.\nMatch: `{match}`" await client.send_message(logger_group, log_text) if bl_type and match and sender.user_id not in blacklistedUsers: blacklistedUsers.update({sender.user_id: (bl_type, match)}) redis.set('blacklist:users', dill.dumps(blacklistedUsers)) return True except Exception as e: exc = await client.get_traceback(e) await event.respond(f"**Couldn't ban user. Exception:\n**```{exc}```") LOGGER.exception(e) return False finally: temp_banlist.remove(sender)
async def translateme(e): global langi translator=Translator() textx=await e.get_reply_message() message = e.text if textx: message = textx text = str(message.message) else: text = str(message[4:]) text = (deEmojify(text)) reply_text=translator.translate(text, dest=langi).text reply_text="`Source: `\n"+text+"`\n\nTranslation: `\n"+reply_text await client.send_message(e.chat_id,reply_text) await e.delete() LOGGER.debug("Translate query "+text+" was executed successfully")
async def ban_user(event: NewMessage.Event, text: str) -> bool: chat = await event.get_chat() ban_right = getattr(chat.admin_rights, 'ban_user', False) if not (chat.creator or ban_right): return False try: await client.edit_permissions(entity=event.chat_id, user=event.from_id, view_messages=False) await event.answer( text, log=('blacklist', f'Banned {event.from_id} from {event.chat_id}.\n{text}.')) return True except Exception as e: await event.answer(f"**Couldn't ban user due to {e}**", reply=True) LOGGER.exception(e) return False
async def whichid(event: NewMessage.Event) -> None: """ Get the ID of a chat/channel or user. `{prefix}id` or **{prefix}id user1 user2** """ match = event.matches[0].group(1) text = "" if not match and not event.reply_to_msg_id: attr = "first_name" if event.is_private else "title" text = f"{getattr(event.chat, attr)}: " text += f"`{get_peer_id(event.chat_id)}`" elif event.reply_to_msg_id: reply = await event.get_reply_message() user = reply.sender_id if reply.fwd_from: if reply.fwd_from.from_id: user = reply.fwd_from.from_id peer = get_peer_id(user) text = f"[{peer}](tg://user?id={peer}): `{peer}`" else: failed = [] strings = [] users, _ = await client.parse_arguments(match) for user in users: try: entity = await client.get_input_entity(user) peer = get_peer_id(entity) strings.append( f"[{user}](tg://user?id={peer}): `{peer}`" ) except Exception as e: failed.append(user) LOGGER.debug(e) if strings: text = ",\n".join(strings) if failed: ftext = "**Users which weren't resolved:**\n" ftext += ", ".join(f'`{f}`' for f in failed) await event.answer(ftext, reply=True) if text: await event.answer(text)
async def sed(e): sed_result = separate_sed(e.text) L = await e.get_reply_message() if sed_result: if L: to_fix = L.text else: await e.edit( "`Master, I don't have brains. Well you too don't I guess.`" ) return repl, repl_with, flags = sed_result if not repl: await e.edit( "`Master, I don't have brains. Well you too don't I guess.`" ) return try: check = re.match(repl, to_fix, flags=re.IGNORECASE) if check and check.group(0).lower() == to_fix.lower(): await e.edit( "`Boi!, that's a reply. Don't use sed`" ) return if "i" in flags and "g" in flags: text = re.sub(repl, repl_with, to_fix, flags=re.I).strip() elif "i" in flags: text = re.sub(repl, repl_with, to_fix, count=1, flags=re.I).strip() elif "g" in flags: text = re.sub(repl, repl_with, to_fix).strip() else: text = re.sub(repl, repl_with, to_fix, count=1).strip() except sre_constants.error: LOGGER.warning(e.text) LOGGER.exception("SRE constant error") await e.edit("B O I! [Learn Regex](https://regexone.com)") return if text: await e.edit("Did you mean? \n\n`" + text + "`")
async def promote(event: NewMessage.Event) -> None: """Promote a user in a group or channel.""" if not event.is_private and not await get_rights(event, add_admins=True): await event.answer("`You do not have rights to add admins in here!`") return elif event.is_private: await event.answer("`You can't promote users in private chats.`") return user, extra, exception = await get_entity_from_msg(event) if user: if exception: await event.answer(f"`Promote machine broke!\n{user}`") return else: await event.answer("`At least specifiy a user, maybe?`") return entity = await event.get_chat() try: await client.edit_admin( entity=entity, user=user, is_admin=True, title=extra ) text = "`Successfully promoted `{}` (``{}``)!`" if extra: text += f"\n`Title:` `{extra}`" e1 = await get_chat_link(user) e2 = await get_chat_link(entity, event.id) log_msg = f"Successfully promoted {e1} in {e2}" if extra: log_msg += f"\nTitle: {extra}" await event.answer( text.format(e1, user.id), log=("promote", log_msg) ) except Exception as e: await event.answer(f"`{e}`") LOGGER.exception(e)
async def tmute(event): if ((event.is_channel or event.is_group) and not (event.chat.creator or event.chat.ban_users)): await event.edit("`You do not have rights to mute users in here!`") return user, extra, exception = await get_entity_from_msg(event) if user: if exception: await event.edit(f"`T-mute machine broke!\n{user}`") return try: time = None reason = None seconds = None text = "`Successfully t-muted ``{}`` (``{}``)!`" if extra: reason, seconds = await split_extra_string(extra) if reason: text += f"\n`Reason:` `{reason}`" if seconds: time = timedelta(seconds=seconds) text += f"\n`Time:` `{time}`" if not seconds: await event.edit("`Provide the total time limit for t-mute!`") return await client.edit_permissions(entity=await event.get_input_chat(), user=user, until_date=time, send_messages=False) await event.edit(text.format(get_display_name(user), user.id)) except Exception as e: await event.edit("`An exception occured trying to t-mute. " " Make sure you have the correct rights! " "Check the logs for more information.`") LOGGER.exception(e)