def cmd_list_rules(self, event): user_obj = Users.with_id(event.author.id) enabled_rules = user_obj.get_enabled() embed = MessageEmbed() embed.title = '{}\'s Uno Rules'.format(event.author) embed.description = 'Change a rule by typing `{prefix}uno <enable/disable> <rule #>`.\nExample: `{prefix}uno enable 2`'.format(prefix=event.db_guild.prefix) # embed.color = 0x11538982 embed.add_field( name='{}:one: Jump In'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.jump_in in enabled_rules else NO_EMOJI)), value='At any time, if you have the same card - color and number - as the card anyone plays, you can \"jump\" in by playing that card, and then the turn goes to the person after you.' ) embed.add_field( name='{}:two: Stacking Draws'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.stack_draws in enabled_rules else NO_EMOJI)), value='If someone plays a draw 2 on you, you can stack another draw 2 on it instead of drawing your cards and skipping your turn; the next person then has to draw 4 cards unless he or she also stacks. The same is true of Draw 4s - but you cannot mix and match Draw 4 and Draw 2 cards.' ) embed.add_field( name='{}:three: 7-Swap'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.seven_swap in enabled_rules else NO_EMOJI)), value='When playing a 7, you can choose to trade hands with another player.' ) embed.add_field( name='{}:four: 0-Super Swap'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.super_swap in enabled_rules else NO_EMOJI)), value='When playing a 0, all players must switch hands with the player a turn ahead of them.' ) embed.add_field( name='{}:five: Cancel Skip'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.cancel_skip in enabled_rules else NO_EMOJI)), value='If the player before you has plays a Skip, you can play another Skip and will skip the next player\'s turn.' ) embed.add_field( name='{}:six: Special Multiplay'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.special_multiplay in enabled_rules else NO_EMOJI)), value='You can place multiple Draw 2s, Draw 4s, Skips, and Reverses at one time and the effects will stack. For example, if you place 2 Skips down, it will skip 2 players. If you place 3 Draw 2s down, the next player will draw 6 cards.' ) embed.add_field( name='{}:seven: Trains'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.trains in enabled_rules else NO_EMOJI)), value='You can place multiple cards down if they are either one up, one down, or the same number as the previous card. For example, if you have the hand `Red1, Green2, Yellow3, Green4` and you place down the Yellow3, you can place down **in order** `Green2, Red1` or `Green4` on the same turn.' ) embed.add_field( name='{}:eight: Endless Draw'.format('<{}>'.format(YES_EMOJI if Users.UnoRules.endless_draw in enabled_rules else NO_EMOJI)), value='If you are unable to play any cards, you must keep drawing cards until you can play.' ) return event.msg.reply('', embed=embed)
def stars_stats(self, event, user=None): if user: try: given_stars = list( StarboardEntry.select(fn.COUNT('*'), ).join(Message).where( (~(StarboardEntry.star_message_id >> None)) & (StarboardEntry.stars.contains(user.id)) & (Message.guild_id == event.guild.id)).tuples())[0][0] recieved_stars_posts, recieved_stars_total = list( StarboardEntry.select( fn.COUNT('*'), fn.SUM(fn.array_length(StarboardEntry.stars, 1)), ).join(Message).where( (~(StarboardEntry.star_message_id >> None)) & (Message.author_id == user.id) & (Message.guild_id == event.guild.id)).tuples())[0] except: raise CommandFail('Failed to crunch the numbers on that user') embed = MessageEmbed() embed.color = 0xFEE75C embed.title = user.username embed.set_thumbnail(url=user.avatar_url) embed.add_field(name='Total Stars Given', value=str(given_stars), inline=True) embed.add_field(name='Total Posts w/ Stars', value=str(recieved_stars_posts), inline=True) embed.add_field(name='Total Stars Recieved', value=str(recieved_stars_total), inline=True) # embed.add_field(name='Star Rank', value='#{}'.format(recieved_stars_rank), inline=True) return event.msg.reply('', embed=embed) total_starred_posts, total_stars = list( StarboardEntry.select( fn.COUNT('*'), fn.SUM(fn.array_length(StarboardEntry.stars, 1)), ).join(Message).where( (~(StarboardEntry.star_message_id >> None)) & (StarboardEntry.blocked == 0) & (Message.guild_id == event.guild.id)).tuples())[0] top_users = list( StarboardEntry.select( fn.SUM(fn.array_length(StarboardEntry.stars, 1)), User.user_id).join(Message, ).join( User, on=(Message.author_id == User.user_id), ).where((~(StarboardEntry.star_message_id >> None)) & (fn.array_length(StarboardEntry.stars, 1) > 0) & (StarboardEntry.blocked == 0) & (Message.guild_id == event.guild.id)).group_by(User). order_by(fn.SUM(fn.array_length(StarboardEntry.stars, 1)).desc()).limit(5).tuples()) embed = MessageEmbed() embed.color = 0xFEE75C embed.title = 'Star Stats' embed.add_field(name='Total Stars Given', value=total_stars, inline=True) embed.add_field(name='Total Starred Posts', value=total_starred_posts, inline=True) embed.add_field(name='Top Star Recievers', value='\n'.join( '{}. <@{}> ({})'.format(idx + 1, row[1], row[0]) for idx, row in enumerate(top_users))) event.msg.reply('', embed=embed)
def on_weather(self, event, content): r = requests.get("http://api.openweathermap.org/data/2.5/weather", params={ "q": content, "appid": cfg.weather_key, "units": "metric" }).json() if r["cod"] == 401: event.msg.reply("nothing found") return name = r["name"] country = r["sys"]["country"] id = r["id"] humidity = r["main"]["humidity"] temp = r["main"]["temp"] temp_min = r["main"]["temp_min"] temp_max = r["main"]["temp_max"] weather = r["weather"][0]["main"] sunrise = r["sys"]["sunrise"] sunset = r["sys"]["sunset"] embed = MessageEmbed() embed.color = cfg.color embed.add_field( name=":earth_americas: Location", value="[{}, {}](https://openweathermap.org/city/{})".format( name, country, id), inline=True) embed.add_field(name=":sweat: Humidity", value="{}%".format(humidity), inline=True) embed.add_field(name=":cloud: Weather", value=weather, inline=True) embed.add_field(name=":thermometer: Temperature", value="{:.1f}°C / {:.1f}°F".format( temp, (temp * 9 / 5) + 32), inline=True) embed.add_field( name=":sunny: Min / Max", value="{:.1f}°C - {:.1f}°C\n{:.1f}°F - {:.1f}°F".format( temp_min, temp_max, (temp_min * 9 / 5) + 32, (temp_max * 9 / 5) + 32), inline=True) embed.add_field( name=":sunrise_over_mountains: Sunrise / Sunset", value="{:02.0f}:{:02.0f} UTC / {:02.0f}:{:02.0f} UTC".format( (sunrise / (60 * 60)) % 24, (sunrise / 60) % 60, (sunset / (60 * 60)) % 24, (sunset / 60) % 60), inline=True) event.msg.reply('', embed=embed)
def changelog_post_approval(plugin, entry, mod_user_id): description = entry.description if not description: description = '_None_' category_breadcrumbs = '#' + entry.category_channel_name if entry.genre_category_name: category_breadcrumbs = '#' + entry.genre_category_name + ' / ' + category_breadcrumbs embed = MessageEmbed() embed.title = '✅ Server has been approved!' embed.add_field(name='🏷 Name', value=entry.name, inline=True) embed.add_field(name='📖 Description', value=description, inline=True) embed.add_field(name='🗃 Category', value=category_breadcrumbs, inline=True) embed.add_field(name='🚩 Invite', value='https://discord.gg/{entry.invite_code}'.format(entry=entry), inline=True) embed.add_field(name='👤 Invitee', value='<@{entry.invitee_id}>'.format(entry=entry), inline=True) embed.add_field(name='📆 Submitted At', value='{entry.submitted_at}'.format(entry=entry), inline=True) embed.add_field(name='👮 Moderator', value='<@{mod_user_id}>'.format(mod_user_id=mod_user_id), inline=True) embed.set_footer(text='ID: {entry.id}'.format(entry=entry)) for channel_id in plugin.config.changelogChannelIDs: plugin.client.api.channels_messages_create(channel_id, embed=embed)
class RaidPlugin(Plugin): """Disco plugin holding all of the commands related to Destiny 2 raids""" raidtime = arrow.get() israidset = False killthreads = False raiders = [] timer15triggered = False @Plugin.command('show', group='event') def command_raid(self, event): """Show the current raid, if it is set""" if self.israidset: self.eventEmbed.fields[1].value = self.get_raiders_string(event) self.eventEmbed.fields[0].value = self.eventTime self.eventEmbed.set_footer( text="Total Members: {}".format(len(self.raiders))) # event.msg.reply("Current raid: {} ({})\nRaid members: {}" #.format(arrow.get(self.raidtime).humanize(), # self.raidtime.strftime("%a, %I:%M %p %Z"), # self.get_raiders_string(event))) event.msg.reply(embed=self.eventEmbed) else: event.msg.reply("No event set") @Plugin.command('new', '<rtime:str> <eventTitle:str...>', group='event') def command_new(self, event, rtime, eventTitle): """Set up a new raid, passing in time via argument to the bot""" # some stuff to do before we start guild = event.msg.guild # we now have a list of every emoji in the server, use str() to convert to format you can send via message self.guildEmojis = list(guild.emojis.values()) # print(self.guildEmojis) if self.israidset: event.msg.reply('There is already an event set!') return parsed = dateparser.parse(rtime, settings={ 'TIMEZONE': 'Europe/London', 'TO_TIMEZONE': 'Europe/London', 'RETURN_AS_TIMEZONE_AWARE': True }) if eventTitle is "": eventTitle = "New Event" eventDesc = "`@Destinybot event add` to add up" if not parsed: event.msg.reply('Could not detect the time, please try again') return timeNow = datetime.now(timezone.utc).astimezone( pytz.timezone('Europe/London')) if parsed < timeNow: parsed = parsed + timedelta(days=1) self.raidtime = arrow.get(parsed) self.israidset = True self.killthreads = False timer_now = Thread(target=self.raidtimer_now, args=(event, )) timer_15 = Thread(target=self.raidtimer_15, args=(event, )) timer_now.start() timer_15.start() # event.msg.reply('Event Created! {0}: '.format(eventTitle) + parsed.strftime("%A at %I:%M %p %Z")) self.eventEmbed = MessageEmbed(title=eventTitle, description=eventDesc, color=3447003) self.eventTime = parsed.strftime("%A at %I:%M %p %Z") self.eventTitle = eventTitle self.eventEmbed.add_field(name="Time", value=self.eventTime, inline=False) # save all this stuff as a attribute of the plugin so we can access it in 'show' and other functions self.eventEmbed.add_field(name="Members", value=self.get_raiders_string(event), inline=False) self.eventEmbed.set_footer( text="Total Members: {}".format(len(self.raiders))) # message = Message(embeds=list(embed)) event.msg.reply(embed=self.eventEmbed) @Plugin.command('edit', '<rtime:str...>', group='event') def command_edit(self, event, rtime): """Edit the existing raid, passing in via argument to the bot""" if not self.israidset: event.msg.reply('There is no event to edit!') return parsed = dateparser.parse(rtime, settings={ 'TIMEZONE': 'Europe/London', 'TO_TIMEZONE': 'Europe/London', 'RETURN_AS_TIMEZONE_AWARE': True }) if not parsed: event.msg.reply('Could not detect the time, please try again') return self.raidtime = arrow.get(parsed) self.eventTime = parsed.strftime("%A at %I:%M %p %Z") # if the 15 minute timer triggered, and there's more than 15 minutes left, restart it diff = self.raidtime - arrow.now(tz='Europe/London') if self.timer15triggered and diff.seconds / 60 > 15: timer_15 = Thread(target=self.raidtimer_15, args=(event, )) timer_15.start() self.timer15triggered = False event.msg.reply('Current event time changed to: ' + parsed.strftime("%A at %I:%M %p %Z")) @Plugin.command('clear', group='event') def command_clear(self, event): """Reset the current raid""" self.raid_clear(event) event.msg.reply('The current event has been cleared') @Plugin.command('add', group='event') def command_add(self, event): """Adds the user to the raid group""" if not self.israidset: event.msg.reply('There is currently no event set, ' + event.msg.author.username + '!') return if event.msg.author in self.raiders: event.msg.reply('You\'re already in the event, ' + event.msg.author.username + '!') return self.raiders.append(event.msg.author) event.msg.reply('You have joined the event, {}! ({} total)'.format( event.msg.author.username, len(self.raiders))) @Plugin.command('remove', group='event') def command_remove(self, event): """Removes the user from the raid group""" if not self.israidset: event.msg.reply('There is currently no event set, ' + event.msg.author.username + '!') return self.raiders.remove(event.msg.author) event.msg.reply('You have been removed from the event, ' + event.msg.author.username) def raidtimer_now(self, event): """When there's 30 seconds left, mention the raidgroup and reset the raid""" while True: if self.killthreads: break diff = self.raidtime - arrow.now(tz='Europe/London') if diff.seconds <= 30: raidgroup = "" for members in self.raiders: raidgroup += members.mention + ", " # raidstartEmbed = MessageEmbed(title=self.eventEmbed.title + "starting now!", description=raidgroup.rstrip(', ')) event.msg.reply('"{}" starting now! '.format( self.eventEmbed.title.rstrip(' ')) + raidgroup.rstrip(', ')) # event.msg.reply(embed=raidstartEmbed) self.raid_clear(event) break time.sleep(10) def raidtimer_15(self, event): """When there's 15 minutes left, mention the raidgroup""" while True: if self.killthreads: break diff = self.raidtime - arrow.now(tz='Europe/London') minutes = diff.seconds / 60 if minutes <= 15: raidgroup = "" for members in self.raiders: raidgroup += members.mention + ", " event.msg.reply('"{}" starting in 15 minutes! '.format( self.eventEmbed.title.rstrip(' ')) + raidgroup.rstrip(', ')) self.timer15triggered = True break time.sleep(30) def raid_clear(self, event): """Reset the state of raid""" self.raidtime = arrow.get() self.israidset = False self.killthreads = True self.timer15triggered = False self.raiders = [] def get_raiders_string(self, event): """Gets all raid member's usernames in a single string""" if len(self.raiders) <= 0: return "None" raidmembers = "" for member in self.raiders: # discord markdown for one line codeblock raidmembers += "`{}` ".format(member.username) return raidmembers.rstrip(' ') # def get_random_teams(self, event): # pass # def start_draft(self, event): # pass @Plugin.command('random', '[team1:str] [team2:str]', group='draft') def get_random_teams(self, event, team1="Team A", team2="Team B"): """Randomly drafts players added to the event in to two teams""" team_dict = {team1: [], team2: []} player_list = self.raiders print(player_list) random.shuffle(player_list) index = 0 for player in player_list: is_odd = index % 2 if is_odd: team_dict[team1].append(player.username) else: team_dict[team2].append(player.username) index += 1 self.teamEmbed = MessageEmbed( title="**Teams have been randomly assigned!**", description="", color=3447003) team1Str = "" team2Str = "" team1PlayerStr = "" team2PlayerStr = "" for count in range(0, len(self.guildEmojis)): if team1 in self.guildEmojis[count].name: # + " **VS**" #make it so the emoji prepends the team name team1Str = str(self.guildEmojis[count]) + " " + team1 if team1Str == "": team1Str = team1 for count in range(0, len(self.guildEmojis)): if team2 in self.guildEmojis[count].name: # + " " + #make it so the emoji is after the team name team2Str = str(self.guildEmojis[count]) + " " + team2 if team2Str == "": team2Str = team2 for each in team_dict[team1]: team1PlayerStr = team1PlayerStr + "`" + each + "`" + " " for each in team_dict[team2]: team2PlayerStr = team2PlayerStr + "`" + each + "`" + " " team1PlayerStr.rstrip(" ") team2PlayerStr.rstrip(" ") if not team1PlayerStr: team1PlayerStr = "None" if not team2PlayerStr: team2PlayerStr = "None" self.teamEmbed.add_field(name=team1Str, value=team1PlayerStr, inline=False) self.teamEmbed.add_field(name="\u2063", value="__**VS**__", inline=False) self.teamEmbed.add_field(name="\u2063", value="\u2063", inline=False) self.teamEmbed.add_field(name=team2Str, value=team2PlayerStr, inline=False) event.msg.reply(embed=self.teamEmbed) @Plugin.command('show', group='draft') def show_draft(self, event): """Show the last created draft""" temp_embed = self.teamEmbed temp_embed.title = "Current Teams" event.msg.reply(embed=temp_embed) @Plugin.command('clear', group='draft') def clear_draft(self, event): """Clears the last created draft""" temp_embed = self.teamEmbed temp_embed.title = "Current Teams" event.msg.reply(embed=temp_embed) def start_cm_draft(self, event, teams, captains): pass
def msgstats(self, event, user): # Query for the basic aggregate message statistics message_stats = Message.select( fn.Count('*'), fn.Sum(fn.char_length(Message.content)), fn.Sum(fn.array_length(Message.emojis, 1)), fn.Sum(fn.array_length(Message.mentions, 1)), fn.Sum(fn.array_length(Message.attachments, 1)), ).where((Message.author_id == user.id)).tuples(). async () reactions_given = Reaction.select( fn.Count('*'), Reaction.emoji_id, Reaction.emoji_name, ).join(Message, on=(Message.id == Reaction.message_id)).where( (Reaction.user_id == user.id)).group_by( Reaction.emoji_id, Reaction.emoji_name).order_by( fn.Count('*').desc()).tuples(). async () # Query for most used emoji emojis = Message.raw( ''' SELECT gm.emoji_id, gm.name, count(*) FROM ( SELECT unnest(emojis) as id FROM messages WHERE author_id=%s ) q JOIN guild_emojis gm ON gm.emoji_id=q.id GROUP BY 1, 2 ORDER BY 3 DESC LIMIT 1 ''', (user.id, )).tuples(). async () deleted = Message.select( fn.Count('*')).where((Message.author_id == user.id) & (Message.deleted == 1)).tuples(). async () wait_many(message_stats, reactions_given, emojis, deleted, timeout=15) # If we hit an exception executing the core query, throw an exception if message_stats.exception: message_stats.get() q = message_stats.value[0] embed = MessageEmbed() embed.fields.append( MessageEmbedField(name='Total Messages Sent', value=q[0] or '0', inline=True)) embed.fields.append( MessageEmbedField(name='Total Characters Sent', value=q[1] or '0', inline=True)) if deleted.value: embed.fields.append( MessageEmbedField(name='Total Deleted Messages', value=deleted.value[0][0], inline=True)) embed.fields.append( MessageEmbedField(name='Total Custom Emojis', value=q[2] or '0', inline=True)) embed.fields.append( MessageEmbedField(name='Total Mentions', value=q[3] or '0', inline=True)) embed.fields.append( MessageEmbedField(name='Total Attachments', value=q[4] or '0', inline=True)) if reactions_given.value: reactions_given = reactions_given.value embed.fields.append( MessageEmbedField(name='Total Reactions', value=sum(i[0] for i in reactions_given), inline=True)) emoji = (reactions_given[0][2] if not reactions_given[0][1] else '<:{}:{}>'.format( reactions_given[0][2], reactions_given[0][1])) embed.fields.append( MessageEmbedField(name='Most Used Reaction', value=u'{} (used {} times)'.format( emoji, reactions_given[0][0], ), inline=True)) if emojis.value: emojis = list(emojis.value) if emojis: embed.add_field( name='Most Used Emoji', value=u'<:{1}:{0}> (`{1}`, used {2} times)'.format( *emojis[0])) embed.thumbnail = MessageEmbedThumbnail(url=user.avatar_url) embed.color = get_dominant_colors_user(user) event.msg.reply('', embed=embed)
def server(self, event, guild_id=None): guild = self.state.guilds.get(guild_id) if guild_id else event.guild if not guild: raise CommandFail('invalid server') self.client.api.channels_typing(event.channel.id) embed = MessageEmbed() # Server Information content_server = [] created_at = to_datetime(guild.id) content_server.append(u'**Created:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - created_at), created_at.isoformat(), )) content_server.append(u'**Members:** {:,}'.format(len(guild.members))) content_server.append(u'**Features:** {}'.format( ', '.join(guild.features) or 'none')) content_server.append(u'**Voice region:** {}'.format(guild.region)) if not bool(guild.max_members): self.state.guilds[guild.id].inplace_update( self.client.api.guilds_get(guild.id), ignored=[ 'channels', 'members', 'voice_states', 'presences', ]) content_server.append(u'**Max presences:** {:,}'.format( self.state.guilds[guild.id].max_presences)) content_server.append(u'**Max members:** {:,}'.format( self.state.guilds[guild.id].max_members)) embed.add_field(name=u'\u276F Server Information', value='\n'.join(content_server), inline=False) # Counts content_counts = [] count = {} for c in guild.channels.values(): if not c.type: continue ctype = c.type.name.split('_')[1] count[ctype] = count.get(ctype, 0) + 1 content_counts.append(u'<{}> {} channel categories'.format( CHANNEL_CATEGORY_EMOJI, count.get('category', 0))) content_counts.append(u'<{}> {} text channels'.format( TEXT_CHANNEL_EMOJI, count.get('text', 0))) content_counts.append(u'<{}> {} voice channels'.format( VOICE_CHANNEL_EMOJI, count.get('voice', 0))) embed.add_field(name=u'\u276F Counts', value='\n'.join(content_counts), inline=True) content_counts2 = [] content_counts2.append(u'<{}> {} roles'.format(ROLE_EMOJI, len(guild.roles))) static_emojis = len( filter(lambda e: not guild.emojis.get(e).animated, guild.emojis)) animated_emojis = len( filter(lambda e: guild.emojis.get(e).animated, guild.emojis)) content_counts2.append(u'<{}> {}/{total} static emojis'.format( EMOJI_EMOJI, static_emojis, total=self.get_max_emoji_slots(guild))) content_counts2.append(u'<{}> {}/{total} animated emojis'.format( EMOJI_EMOJI, animated_emojis, total=self.get_max_emoji_slots(guild))) embed.add_field(name=u'\u200B', value='\n'.join(content_counts2), inline=True) # Members content_members = [] status_counts = defaultdict(int) for member in guild.members.values(): if not member.user.presence: status = Status.OFFLINE else: status = member.user.presence.status status_counts[status] += 1 for status, count in sorted(status_counts.items(), key=lambda i: Status[i[0]]): content_members.append(u'<{}> - {}'.format(STATUS_EMOJI[status], count)) embed.add_field(name=u'\u276F Members', value='\n'.join(content_members), inline=True) # Boosts content_boosts = [] content_boosts.append(u'<{}> Level {}'.format( PREMIUM_GUILD_TIER_EMOJI[guild.premium_tier], int(guild.premium_tier))) real_boost_count = len( filter(lambda y: guild.members.get(y).premium_since, guild.members)) content_boosts.append(u'<{}> {} boosts {}'.format( PREMIUM_GUILD_ICON_EMOJI, guild.premium_subscription_count, '({})'.format(real_boost_count) if real_boost_count < guild.premium_subscription_count else '')) embed.add_field(name=u'\u276F Server Boost', value='\n'.join(content_boosts), inline=True) if guild.icon: embed.set_thumbnail(url=guild.icon_url) embed.color = get_dominant_colors_guild(guild, guild.get_icon_url('png')) event.msg.reply('', embed=embed)
from datetime import datetime from disco.bot import Plugin from disco.types.message import MessageEmbed embed = MessageEmbed() embed.set_author(name='fiskenslakt#9545', icon_url='https://cdn.discordapp.com/avatars/170208380739256320/dcb3c939597392dc3208de3264ccfe58.png') embed.title = 'Bot for Retro' embed.description = 'This is a bot for Retro for various moderation tasks. There are also commands for purely entertainment purposes. If you have a feature in mind that you would like added, post it to #meta' embed.add_field(name='Made with:', value='Python', inline=True) embed.add_field(name='Library:', value='Disco', inline=True) embed.add_field(name='Made by:', value='Fiskenslakt', inline=False) embed.timestamp = datetime.utcnow().isoformat() embed.set_thumbnail(url='https://i.imgur.com/uddZWLw.png') embed.set_footer(text='Generaloberst Bot v0.13.0') embed.color = '10038562' class InfoPlugin(Plugin): @Plugin.command('info', aliases=['about']) def info_command(self, event): """= info = Displays information about bot usage :: !info aliases :: !about category :: Info """ event.msg.reply(embed=embed)
def handle_exception(event, bot, exception): # catch everything and extract all info we can from the func arguments so we see what exactly was going on print("Exception caught, extracting information") print("====EXCEPTION====") print(exception) print("====STACKTRACE====") print(traceback.format_exc()) print("====ORIGINAL MESSAGE====") print(event.msg.content) print("====SENDER====") print(event.msg.author) print("====Channel====") print("{} ({})".format(event.msg.channel.name, event.msg.channel.id)) embed = MessageEmbed() embed.title = "Exception caught" embed.add_field(name="Original message", value=Utils.trim_message(event.msg.content, 1024)) embed.add_field(name="Channel", value="{} ({})".format(event.msg.channel.name, event.msg.channel.id)) embed.add_field(name="Sender", value=str(event.msg.author)) embed.add_field(name="Exception", value=str(exception)) parts = Pages.paginate(str(traceback.format_exc()), max_chars=1024) if len(parts) > 4: embed.add_field( name="Stacktrace", value= "Something went incredibly wrong, stacktrace is over 4096 chars!") else: for part in parts: embed.add_field(name="Stacktrace", value=part) embed.timestamp = datetime.utcnow().isoformat() embed.color = int('ff0000', 16) log_to_bot_log(bot, embed=embed)