async def findtype(self, ctx, id: discord.Object): bot = self.bot async def found_message(type_id): await ctx.embed(title="Type Finder", description=f"**ID**: `{id.id}`\n" f"**Type:** `{type_id.capitalize()}`\n" f"**Created:** `{id.created_at}`") async def find(w, t): try: method = getattr(bot, f"{w}_{t}") if result := await discord.utils.maybe_coroutine( method, id.id): return result is not None except discord.Forbidden: return ("fetch", "guild") != (w, t) except (discord.NotFound, AttributeError): pass m = await bot.http._HTTPClient__session.get( f"https://cdn.discordapp.com/emojis/{id.id}") if m.status == 200: return await found_message("emoji") if await try_call(commands.MessageConverter().convert, ctx, str(id.id)): return await found_message("message") for way, typeobj in itertools.product( ("get", "fetch"), ("channel", "user", "webhook", "guild")): if await find(way, typeobj): return await found_message(typeobj) await ctx.maybe_reply("idk")
async def delete_bot_msg(self, ctx, message_ids: commands.Greedy[int]): for m_id in message_ids: converter = commands.MessageConverter() m = await converter.convert(ctx, str(m_id)) if not m.author.bot: raise commands.CommandError( "I can only delete my own messages") await m.delete() await ctx.message.add_reaction(ctx.tick(True))
async def message(self, ctx, *args): try: converter = commands.MessageConverter() target_message = await converter.convert(ctx=ctx, argument=' '.join(args)) except commands.errors.BadArgument: await ctx.send( utils.fill_message("karma_message_format", user=ctx.author.id)) return await self.karma.message_karma(ctx, target_message)
async def add(self, ctx: commands.Context, message_url: str): try: converter = commands.MessageConverter() message: discord.Message = await converter.convert(ctx, message_url) self.repo.add_or_update_channel(str(message.channel.id), str(message.id)) if not message.pinned: await message.pin() await ctx.send(Messages.autopin_add_done) except commands.errors.BadArgument: await ctx.send(Messages.autopin_add_unknown_message) return
async def raw(self, ctx, message_id: str = None): """Decode the markdown of a message""" if message_id is None: async for m in ctx.channel.history(limit=2): if m.id == ctx.message.id: continue else: await ctx.safe_send( discord.utils.escape_markdown(m.content)) else: # await ctx.message.add_reaction('<a:loading:681628799376293912>') converter = commands.MessageConverter() m = await converter.convert(ctx, message_id) await ctx.safe_send(discord.utils.escape_markdown(m.content))
import inspect from discord import Embed, Message, TextChannel from discord.ext import commands, flags from bot.bot import TechStruckBot from bot.utils.embed_flag_input import ( allowed_mentions_input, dict_to_allowed_mentions, dict_to_embed, embed_input, process_message_mentions, webhook_input, ) flags._converters.CONVERTERS["Message"] = commands.MessageConverter().convert async def maybe_await(coro): if not coro: return return await coro class Utils(commands.Cog): """Utility commands""" def __init__(self, bot: TechStruckBot): self.bot = bot @embed_input(all=True) @allowed_mentions_input()
async def karma_message(self, ctx, link: str): """Get karma for given message""" converter = commands.MessageConverter() try: message = await converter.convert(ctx=ctx, argument=link) except Exception as error: return await self.output.error(ctx, "Message not found", error) embed = self.embed(ctx=ctx, description=f"{message.author}") # fmt: off count = True if message.channel.id in config.get("karma", "banned channels") \ or ( not config.get("karma", "count subjects") and repo_s.get(message.channel.name) is not None ): count = False for word in config.get("karma", "banned words"): if word in message.content: count = False break # fmt: on output = {"negative": [], "neutral": [], "positive": []} karma = 0 for reaction in message.reactions: emote = reaction.emoji value = repo_k.emoji_value_raw(emote) if value == 1: output["positive"].append(emote) karma += reaction.count async for user in reaction.users(): if user.id == message.author.id: karma -= 1 break elif value == -1: output["negative"].append(emote) karma -= reaction.count async for user in reaction.users(): if user.id == message.author.id: karma += 1 break else: output["neutral"].append(emote) embed.add_field(name="Link", value=message.jump_url, inline=False) if count: for key, value in output.items(): if len(value) == 0: continue emotes = " ".join(str(emote) for emote in value) embed.add_field(name=text.get("karma", "embed_" + key), value=emotes) # fmt: off embed.add_field( name=text.get("karma", "embed_total"), value=f"**{karma}**", inline=False, ) # fmt: on else: embed.add_field(name="\u200b", value=text.get("karma", "embed_disabled"), inline=False) await ctx.send(embed=embed) await utils.room_check(ctx)
def __init__(self, bot): self.bot = bot self.message_converter = commands.MessageConverter()
async def handle_reaction(self, ctx: ReactionContext): # grillbot emoji for removing message causes errors if ctx.emoji == "⏹️": return # handle karma vote elif ctx.message.content.startswith(messages.karma_vote_message_hack): if ctx.emoji not in ["✅", "❌", "0⃣"]: await ctx.message.remove_reaction(ctx.emoji, ctx.member) else: users = [] for reaction in ctx.message.reactions: users.append(await reaction.users().flatten()) # Flatten the final list users = [x for y in users for x in y] if users.count(ctx.member) > 1: await ctx.message.remove_reaction(ctx.emoji, ctx.member) # reeval karma message elif (ctx.message.embeds and ctx.message.embeds[0].title is not discord.Embed.Empty and ctx.message.embeds[0].title == "Karma zprávy"): async with ctx.channel.typing(): await ctx.message.remove_reaction(ctx.emoji, ctx.member) msg_converter = commands.MessageConverter() message = await msg_converter.convert( self, ctx.message.embeds[0].fields[0].value) embed = await self.karma.message_karma(ctx.member, message) await ctx.message.edit(embed=embed) # leaderboard pagination elif (ctx.message.embeds and ctx.message.embeds[0].title is not discord.Embed.Empty and re.match(r".* (LEADER|BAJKAR|ISHA|GIVING)BOARD .*", ctx.message.embeds[0].title) and ctx.emoji in ["◀", "▶", "⏪"]): embed = ctx.message.embeds[0] column, attribute, max_page = self.karma.get_db_from_title( embed.title) if column is None: return if embed.description is not discord.Embed.Empty: current_page = int(embed.description.split(" – ")[0]) else: current_page = max_page if ctx.emoji == "▶": next_page = current_page + 10 if next_page > max_page - 9: next_page = max_page - 9 elif ctx.emoji == "◀": next_page = current_page - 10 if next_page <= 0: next_page = 1 elif ctx.emoji == "⏪": next_page = 1 embed.description = self.karma.gen_leaderboard_content( attribute, next_page, column) embed.timestamp = datetime.datetime.now(tz=datetime.timezone.utc) if "LEADERBOARD" in embed.title: value_num = math.ceil(next_page / config.karma_grillbot_leaderboard_size) value = messages.karma_web if value_num == 1 else f"{messages.karma_web}{value_num}" embed.set_field_at(index=0, name=messages.karma_web_title, value=value) await ctx.message.edit(embed=embed) if ctx.message.guild: await ctx.message.remove_reaction(ctx.emoji, ctx.member) # handle karma elif (ctx.member.id != ctx.message.author.id and ctx.guild.id == config.guild_id and ctx.message.channel.id not in config.karma_banned_channels and config.karma_ban_role_id not in map(lambda x: x.id, ctx.member.roles)): if isinstance(ctx.emoji, str): karma_r.karma_emoji(ctx.message.author, ctx.member, ctx.emoji) else: karma_r.karma_emoji(ctx.message.author, ctx.member, ctx.emoji.id)
async def pick_karma_command(self, ctx, *args): karma = self.karma if len(args) == 0: await ctx.send(karma.karma_get(ctx.author)) await self.check.botroom_check(ctx.message) elif args[0] == "stalk": try: converter = commands.MemberConverter() target_member = await converter.convert(ctx=ctx, argument=' '.join( args[1:])) except commands.errors.BadArgument: await ctx.send( utils.fill_message("member_not_found", user=ctx.author.id)) return await ctx.send(karma.karma_get(ctx.author, target_member)) await self.check.botroom_check(ctx.message) elif args[0] == "get": if not await self.check.guild_check(ctx.message): await ctx.send(messages.server_warning) else: try: await karma.emoji_get_value(ctx.message) await self.check.botroom_check(ctx.message) except discord.errors.Forbidden: return elif args[0] == "revote": if not await self.check.guild_check(ctx.message): await ctx.send(messages.server_warning) else: if ctx.message.channel.id == config.vote_room or \ ctx.author.id == config.admin_id: try: await ctx.message.delete() await karma.emoji_revote_value(ctx.message) except discord.errors.Forbidden: return else: await ctx.send( utils.fill_message("vote_room_only", room=discord.utils.get( ctx.guild.channels, id=config.vote_room))) elif args[0] == "vote": if not await self.check.guild_check(ctx.message): await ctx.send(messages.server_warning) else: if ctx.message.channel.id == config.vote_room or \ ctx.author.id == config.admin_id: try: await ctx.message.delete() await karma.emoji_vote_value(ctx.message) except discord.errors.Forbidden: return else: await ctx.send( utils.fill_message("vote_room_only", room=discord.utils.get( ctx.guild.channels, id=config.vote_room))) elif args[0] == "give": if ctx.author.id == config.admin_id: await karma.karma_give(ctx.message) else: await ctx.send( utils.fill_message("insufficient_rights", user=ctx.author.id)) elif args[0] == "message": try: converter = commands.MessageConverter() target_message = await converter.convert(ctx=ctx, argument=' '.join( args[1:])) except commands.errors.BadArgument: await ctx.send( utils.fill_message("karma_message_format", user=ctx.author.id)) return await karma.message_karma(ctx, target_message) else: await ctx.send( utils.fill_message("karma_invalid_command", user=ctx.author.id))
return converter type_to_converter = { # Builtins bool: commands.core._convert_to_bool, int: built_in_converter(int), str: str, # Discord objects Role: commands.RoleConverter(), User: commands.UserConverter(), Member: commands.MemberConverter(), Color: commands.ColorConverter(), Invite: commands.InviteConverter(), Emoji: commands.EmojiConverter(), Message: commands.MessageConverter(), PartialEmoji: commands.PartialEmojiConverter(), TextChannel: commands.TextChannelConverter(), VoiceChannel: commands.VoiceChannelConverter(), CategoryChannel: commands.CategoryChannelConverter(), } _to_str = { Message: lambda m: f"Message with id {m.id} in {m.channel.mention}", } def to_str(argument: UserInputable) -> str: _type = type(argument) if issubclass(_type, Enum): return argument.name.capitalize().replace("_", " ")
def __init__(self): self.message_converter = commands.MessageConverter() super().__init__()
async def process_browse_reaction(self, ctx, payload, search_instead_of_browse): converter = commands.MessageConverter() msg_to_edit = await converter.convert(ctx=ctx, argument=str(payload.message_id)) try: await msg_to_edit.remove_reaction(member=payload.member, emoji=payload.emoji.name) except: raise CustomCommandError( "Hey, I need the Manage Messages permission to do that.") # prev page if payload.emoji.name == "⬅": await self.browse_emojis( ctx=ctx, category=browse_messages[int(payload.message_id)]["category"], page_count=browse_messages[int( payload.message_id)]["page no."] - 1, author=browse_messages[int(payload.message_id)]["user"], msg_to_edit=msg_to_edit, force=True, search_instead_of_browse=search_instead_of_browse) # install emoji elif payload.emoji.name == "✅": ctx.message.author = browse_messages[int( payload.message_id)]["user"] await self.install_emoji( ctx, browse_messages[int(payload.message_id)]["emoji"], author=browse_messages[int(payload.message_id)]["user"], success_message="Emoji added from browser") await self.browse_emojis( ctx=ctx, category=browse_messages[int(payload.message_id)]["category"], page_count=browse_messages[int( payload.message_id)]["page no."], author=browse_messages[int(payload.message_id)]["user"], msg_to_edit=msg_to_edit, force=True, search_instead_of_browse=search_instead_of_browse) # next page elif payload.emoji.name == "➡": await self.browse_emojis( ctx=ctx, category=browse_messages[int(payload.message_id)]["category"], page_count=browse_messages[int( payload.message_id)]["page no."] + 1, author=browse_messages[int(payload.message_id)]["user"], msg_to_edit=msg_to_edit, force=True, search_instead_of_browse=search_instead_of_browse) # shuffle elif payload.emoji.name == "🔀": await self.browse_emojis( ctx=ctx, category=browse_messages[int(payload.message_id)]["category"], page_count=browse_messages[int( payload.message_id)]["page no."] - 1, author=browse_messages[int(payload.message_id)]["user"], msg_to_edit=msg_to_edit, random_page=True, force=True, search_instead_of_browse=search_instead_of_browse)
async def browse_emojis(self, ctx, category=None, page_count=0, author=None, msg_to_edit: discord.Message = None, random_page=False, search_instead_of_browse=False, force=False, use_db=False): """An interactive browser to find and install emojis.""" au = ctx.message.author if author is None else author # print([info for info in browse_messages.values()]) # print(au) if search_instead_of_browse and force is False: # require vote if int(self.bot.user.id) == 719924856619139083: response = await self.verify_voter(ctx.message.author.id) if response == False: await send_error( ctx, "Please vote to use this command -- it's free, takes 30 seconds, and helps the bot keep" " going." "\n\n[Click here to vote!](https://top.gg/bot/719924856619139083/vote)\n\n" "**Important note:** votes can take a few minutes to register.", client=self.bot) return try: # remove user's active search(es) if au.id in [info["user"].id for info in browse_messages.values() ] and force is False: for key in browse_messages.copy(): if browse_messages[key]["user"] == au: conv = commands.MessageConverter() wipe_msg = await conv.convert(ctx=ctx, argument=str(key)) await self.wipe_browse_message( wipe_msg, custom_message= "👋 You started a new search, so I've shut down this one.", author=au) except: pass # create embed with author's name and avatar browse_embed = discord.Embed() browse_embed.colour = Colours.base browse_embed.set_author(name=ctx.message.author.display_name if author is None else author.display_name, icon_url=ctx.message.author.avatar_url if author is None else author.avatar_url) # if no category selected, display list of categories if category is None: browse_embed.title = "Choose a category to browse" browse_embed.description = "If this isn't your style, you can search over 100,000 emojis using `>search` instead." formatted_categories = " ".join( categories := [f"`{category}`" for category in emoji_categories.keys()]) browse_embed.add_field(name="Categories", value=formatted_categories) browse_embed.add_field( name="Usage", value= f"Browse a category: `>category {choice(categories)[1:-1]}` (for example)" ) await ctx.channel.send(embed=browse_embed) # if a category was selected, browse it else: # browsing NSFW requires NSFW channel try: if category.lower( ) == "nsfw" and ctx.channel.is_nsfw() is False: raise CustomCommandError( "Please do that in an NSFW channel!") except AttributeError: pass # a list of emojis in selected category if not search_instead_of_browse: try: emoji_list_filtered = [ json_item for json_item in emoji_list if json_item["category"] == emoji_categories[ category.capitalize()] ] except: raise Exception( f"{category} is not a valid category, or there are no emojis in it." ) else: emoji_list_filtered = [{ "image": emoji.url, "description": str(emoji.name), "title": str(emoji.name) } for emoji in self.bot.emojis if category.lower().rstrip() in str(emoji.name).lower().rstrip()] # raise error if no emojis found if len(emoji_list_filtered) == 0: raise Exception( f"{category} is not a valid category, or there are no emojis in it." ) # if there are some emojis in the category else: if random_page: page_count = randint(1, len(emoji_list_filtered)) elif page_count < 0: page_count = len(emoji_list_filtered) + page_count elif page_count > len(emoji_list_filtered) - 1: page_count = (len(emoji_list_filtered) - page_count) # emoji name browse_embed.add_field( name=f"Page {page_count + 1} / {len(emoji_list_filtered)}", value= f"{emoji_list_filtered[page_count]['description'].split()[0]}" ) # emoji preview browse_embed.set_thumbnail( url=emoji_list_filtered[page_count]["image"]) # if message needs to be edited if msg_to_edit is not None: await msg_to_edit.edit(embed=browse_embed) # add new embed browse_messages[msg_to_edit.id][ "page no."] += 1 # increment page number browse_messages[msg_to_edit.id] = { "category": category, "page no.": page_count, "emoji": emoji_list_filtered[page_count], "user": ctx.message.author if author is None else author, } # add new reactions await msg_to_edit.add_reaction("⬅") await msg_to_edit.add_reaction("✅") await msg_to_edit.add_reaction("➡") await msg_to_edit.add_reaction("🔀") msg_id = msg_to_edit.id wipe_msg = msg_to_edit # otherwise, post a new message else: # send msg embed_msg = await ctx.message.channel.send( embed=browse_embed) # save message data browse_messages[embed_msg.id] = { "category": category, "page no.": page_count, "emoji": emoji_list_filtered[page_count], "user": ctx.message.author if author is None else author, } # add control reactions await embed_msg.add_reaction("⬅") await embed_msg.add_reaction("✅") await embed_msg.add_reaction("➡") await embed_msg.add_reaction("🔀") msg_id = embed_msg.id wipe_msg = embed_msg def check(payload): return payload.member == au and payload.message_id == msg_id try: payload = await self.bot.wait_for("raw_reaction_add", timeout=30.0, check=check) await self.process_browse_reaction( ctx, payload, search_instead_of_browse) except ReactionTimeout: await self.wipe_browse_message(wipe_msg, author=ctx.message.author if author is None else author) except Exception as e: await self.wipe_browse_message( wipe_msg, custom_message= "Something went wrong; closing this search.", author=ctx.message.author if author is None else author) raise e