async def search_infractions_by_user(message: discord.Message, args: List[str], client: discord.Client, ctx: CommandCtx) -> Any: if not message.guild: return 1 tstart = time.monotonic() if not ctx.verbose: raise lib_sonnetcommands.CommandError( "ERROR: search-infractions only meant to be called directly") # Reparse args try: args = shlex.split(" ".join(args)) except ValueError: raise lib_sonnetcommands.CommandError( "ERROR: Shlex failed to parse arguments") # Parse flags parser = Parser("search-infractions") selected_chunk_f = parser.add_arg(["-p", "--page"], lambda s: int(s) - 1) responsible_mod_f = parser.add_arg(["-m", "--mod"], get_user_id) user_affected_f = parser.add_arg(["-u", "--user"], get_user_id) per_page_f = parser.add_arg(["-i", "--infractioncount"], int) infraction_type_f = parser.add_arg(["-t", "--type"], str) filtering_f = parser.add_arg(["-f", "--filter"], str) automod_f = lib_tparse.add_true_false_flag(parser, "automod") try: parser.parse(args, stderr=io.StringIO(), exit_on_fail=False, lazy=True) except lib_tparse.ParseFailureError: await message.channel.send("Failed to parse flags") return 1 selected_chunk = selected_chunk_f.get(0) per_page = per_page_f.get(20) user_affected = user_affected_f.get() # Default to user if no user/mod flags are supplied if None is responsible_mod_f.get() is user_affected: try: user_affected = get_user_id(args[0]) except (IndexError, ValueError): pass if not 5 <= per_page <= 40: # pytype: disable=unsupported-operands await message.channel.send( "ERROR: Cannot exeed range 5-40 infractions per page") return 1 refilter: "Optional[re.Pattern[str]]" if (f := filtering_f.get()) is not None: try: refilter = re.compile(f) except re.error: raise lib_sonnetcommands.CommandError( "ERROR: Filter regex is invalid")
async def initialise_poll(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: try: await message.add_reaction("👍") await message.add_reaction("👎") except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError( "ERROR: The bot does not have permissions to add a reaction here") except discord.errors.NotFound: raise lib_sonnetcommands.CommandError( "ERROR: Could not find the message [404]")
async def grab_guild_info(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: if not message.guild: return 1 guild = message.guild embed_col = load_embed_color(guild, embed_colors.primary, kwargs["ramfs"]) guild_embed = discord.Embed(title=f"Information on {guild}", color=embed_col) if guild.owner: guild_embed.add_field(name="Server Owner:", value=guild.owner.mention) guild_embed.add_field(name="# of Roles:", value=f"{len(guild.roles)} Roles") guild_embed.add_field(name="Top Role:", value=guild.roles[-1].mention) guild_embed.add_field(name="Member Count:", value=str(guild.member_count)) guild_embed.add_field(name="Creation Date:", value=parsedate(guild.created_at)) guild_embed.set_footer(text=f"gid: {guild.id}") guild_embed.set_thumbnail(url=cast(str, guild.icon_url)) try: await message.channel.send(embed=guild_embed) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError(constants.sonnet.error_embed)
async def parse_channel_message_noexcept( message: discord.Message, args: list[str], client: discord.Client) -> tuple[discord.Message, int]: """ Parse a channel message from a url, #channel messageid, or channelid-messageid field :returns: Tuple[discord.Message, int] -- The message and the amount of args the message grabbing took :raises: lib_sonnetcommands.CommandError -- The message did not exist or the function had invalid inputs """ if not message.guild: raise lib_sonnetcommands.CommandError("ERROR: Not a guild message") try: message_link = args[0].replace("-", "/").split("/") log_channel: Union[str, int] = message_link[-2] message_id = message_link[-1] nargs = 1 except IndexError: try: log_channel = args[0].strip("<#!>") message_id = args[1] nargs = 2 except IndexError: raise lib_sonnetcommands.CommandError( constants.sonnet.error_args.not_enough) try: log_channel = int(log_channel) except ValueError: raise lib_sonnetcommands.CommandError( constants.sonnet.error_channel.invalid) discord_channel = client.get_channel(log_channel) if not discord_channel: raise lib_sonnetcommands.CommandError( constants.sonnet.error_channel.invalid) if not isinstance(discord_channel, discord.TextChannel): raise lib_sonnetcommands.CommandError( constants.sonnet.error_channel.scope) if discord_channel.guild.id != message.guild.id: raise lib_sonnetcommands.CommandError( constants.sonnet.error_channel.scope) try: discord_message = await discord_channel.fetch_message(int(message_id)) except (ValueError, discord.errors.HTTPException): raise lib_sonnetcommands.CommandError( constants.sonnet.error_message.invalid) if not discord_message: raise lib_sonnetcommands.CommandError( constants.sonnet.error_message.invalid) return (discord_message, nargs)
async def parse_user_member_noexcept( message: discord.Message, args: List[str], client: discord.Client, argindex: int = 0, default_self: bool = False ) -> Tuple[UserInterface, Optional[discord.Member]]: """ Parse a user and member object from a potential user string Always returns a user, only returns member if the user is in the guild User returned might be a member, do not rely on this. :returns: Tuple[Union[discord.User, discord.Member], Optional[discord.Member]] -- A discord user and optional member :raises: lib_sonnetcommands.CommandError -- Could not find the user or input invalid """ if not message.guild or not isinstance(message.author, discord.Member): raise lib_sonnetcommands.CommandError("Not a guild message") try: uid = int(args[argindex].strip("<@!>")) except ValueError: raise lib_sonnetcommands.CommandError("Invalid UserID") except IndexError: if default_self: return message.author, message.author else: raise lib_sonnetcommands.CommandError("No user specified") member: Optional[discord.Member] user: Optional[discord.User | discord.Member] try: member = message.guild.get_member(uid) if not (user := client.get_user(uid)): user = await client.fetch_user(uid) except (discord.errors.NotFound, discord.errors.HTTPException): raise lib_sonnetcommands.CommandError("User does not exist") return user, member
async def full_help(self, page: int, per_page: int) -> discord.Embed: cmds = self.ctx.cmds cmds_dict = self.ctx.cmds_dict if page < 0 or page >= (len(self.ctx.cmds) + (per_page - 1)) // per_page: raise lib_sonnetcommands.CommandError( f"ERROR: No such page {page+1}") cmd_embed = discord.Embed( title= f"Category Listing (Page {page+1} / {(len(cmds) + (per_page-1))//per_page})", color=load_embed_color(self.guild, embed_colors.primary, self.ctx.ramfs)) cmd_embed.set_author(name=self.helpname) total = 0 # Total counting is seperate due to pagination not counting all modules for cmd in cmds_dict: if 'alias' not in cmds_dict[cmd]: total += 1 for module in sorted( cmds, key=lambda m: m.category_info['pretty_name'])[( page * per_page):(page * per_page) + per_page]: mnames = [ f"`{i}`" for i in module.commands if 'alias' not in module.commands[i] ] helptext = ', '.join( mnames) if mnames else module.category_info['description'] cmd_embed.add_field( name= f"{module.category_info['pretty_name']} ({module.category_info['name']})", value=helptext, inline=False) cmd_embed.set_footer( text=f"Total Commands: {total} | Total Endpoints: {len(cmds_dict)}" ) return cmd_embed
async def avatar_function(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: if not message.guild: return 1 user, _ = await parse_user_member_noexcept(message, args, client, default_self=True) embed = discord.Embed(description=f"{user.mention}'s Avatar", color=load_embed_color(message.guild, embed_colors.primary, kwargs["ramfs"])) embed.set_image(url=user_avatar_url(user)) embed.timestamp = datetime_now() try: await message.channel.send(embed=embed) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError(constants.sonnet.error_embed)
async def help_function(message: discord.Message, args: List[str], client: discord.Client, ctx: CommandCtx) -> Any: if not message.guild: return 1 helpname: str = f"{BOT_NAME} Help" per_page: int = 10 cmds = ctx.cmds cmds_dict = ctx.cmds_dict parser = Parser("help") pageP = parser.add_arg(["-p", "--page"], lambda s: int(s) - 1) commandonlyP = parser.add_arg("-c", lib_tparse.store_true, flag=True) try: parser.parse(args, stderr=io.StringIO(), exit_on_fail=False, lazy=True, consume=True) except lib_tparse.ParseFailureError: raise lib_sonnetcommands.CommandError("Could not parse pagecount") page = pageP.get(0) commandonly = commandonlyP.get() is True prefix = ctx.conf_cache["prefix"] help_helper = HelpHelper(message, message.guild, args, client, ctx, prefix, helpname) if args: modules = {mod.category_info["name"] for mod in cmds} # Per module help if (a := args[0].lower()) in modules and not commandonly: description, commands, curmod = await help_helper.category_help(a) pagecount = (len(commands) + (per_page - 1)) // per_page cmd_embed = discord.Embed( title= f"{curmod.category_info['pretty_name']} (Page {page+1} / {pagecount})", description=description, color=load_embed_color(message.guild, embed_colors.primary, ctx.ramfs)) cmd_embed.set_author(name=helpname) if not (0 <= page < pagecount): # pytype: disable=unsupported-operands raise lib_sonnetcommands.CommandError( f"ERROR: No such page {page+1}") for name, desc in commands[page * per_page:(page * per_page) + per_page]: cmd_embed.add_field(name=name, value=desc, inline=False) try: await message.channel.send(embed=cmd_embed) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError( constants.sonnet.error_embed) # Per command help elif a in cmds_dict: try: await message.channel.send( embed=await help_helper.single_command(a)) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError( constants.sonnet.error_embed) # Do not echo user input else: # lets check if they cant read documentation probably_tried_paging: bool try: probably_tried_paging = int( args[0]) <= ((len(cmds) + (per_page - 1)) // per_page) except ValueError: probably_tried_paging = False no_command_text: str = f"No command {'or command module '*(not commandonly)}with that name" if probably_tried_paging: raise lib_sonnetcommands.CommandError( f"{no_command_text} (did you mean `{prefix}help -p {int(args[0])}`?)" ) raise lib_sonnetcommands.CommandError(no_command_text)
async def profile_function(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: if not message.guild: return 1 user, member = await parse_user_member_noexcept(message, args, client, default_self=True) # Status hashmap status_map = { "online": "🟢 (online)", "offline": "⚫ (offline)", "idle": "🟡 (idle)", "dnd": "🔴 (dnd)", "do_not_disturb": "🔴 (dnd)", "invisible": "⚫ (offline)" } embed = discord.Embed(title="User Information", description=f"User information for {user.mention}:", color=load_embed_color(message.guild, embed_colors.primary, kwargs["ramfs"])) embed.set_thumbnail(url=user_avatar_url(user)) embed.add_field(name="Username", value=str(user), inline=True) embed.add_field(name="User ID", value=str(user.id), inline=True) if member: embed.add_field(name="Status", value=status_map[member.raw_status], inline=True) embed.add_field(name="Highest Rank", value=f"{member.top_role.mention}", inline=True) embed.add_field(name="Created", value=parsedate(user.created_at), inline=True) if member: embed.add_field(name="Joined", value=parsedate(member.joined_at), inline=True) # Parse adding infraction count with db_hlapi(message.guild.id) as db: viewinfs = parse_boolean( db.grab_config("member-view-infractions") or "0") moderator = await parse_permissions(message, kwargs["conf_cache"], "moderator", verbose=False) if moderator or (viewinfs and user.id == message.author.id): embed.add_field( name="Infractions", value=f"{db.grab_filter_infractions(user=user.id, count=True)}" ) embed.timestamp = datetime_now() try: await message.channel.send(embed=embed) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError(constants.sonnet.error_embed)
if probably_tried_paging: raise lib_sonnetcommands.CommandError( f"{no_command_text} (did you mean `{prefix}help -p {int(args[0])}`?)" ) raise lib_sonnetcommands.CommandError(no_command_text) # Total help else: try: await message.channel.send( embed=await help_helper.full_help(page, per_page)) except discord.errors.Forbidden: raise lib_sonnetcommands.CommandError(constants.sonnet.error_embed) async def grab_guild_info(message: discord.Message, args: List[str], client: discord.Client, **kwargs: Any) -> Any: if not message.guild: return 1 guild = message.guild embed_col = load_embed_color(guild, embed_colors.primary, kwargs["ramfs"]) guild_embed = discord.Embed(title=f"Information on {guild}", color=embed_col) if guild.owner: guild_embed.add_field(name="Server Owner:", value=guild.owner.mention)