def tempmute(self, event, user, duration=None, reason=None): if not duration and reason: duration = parse_duration(reason.split(' ')[0], safe=True) if duration: if ' ' in reason: reason = reason.split(' ', 1)[-1] else: reason = None elif duration: duration = parse_duration(duration) member = event.guild.get_member(user) if member: self.can_act_on(event, member.id) if not event.config.mute_role: raise CommandFail('mute is not setup on this server') if event.config.mute_role in member.roles: raise CommandFail(u'{} is already muted'.format(member.user)) # If we have a duration set, this is a tempmute if duration: # Create the infraction Infraction.tempmute(self, event, member, reason, duration) self.queue_infractions() self.confirm_action( event, maybe_string( reason, u':ok_hand: {u} is now muted for {t} (`{o}`)', u':ok_hand: {u} is now muted for {t}', u=member.user, t=humanize.naturaldelta(duration - datetime.utcnow()), )) if event.config.notify_action_on and event.config.notify_action_on.mutes: try: event.guild.get_member(user.id).user.open_dm( ).send_message( 'You have been **Muted** in the guild **{}** for `{}`' .format(event.guild.name, reason or 'no reason specified.')) except: pass else: pass else: existed = False # If the user is already muted check if we can take this from a temp # to perma mute. if event.config.mute_role in member.roles: existed = Infraction.clear_active( event, member.id, [Infraction.Types.TEMPMUTE]) # The user is 100% muted and not tempmuted at this point, so lets bail if not existed: raise CommandFail(u'{} is already muted'.format( member.user)) Infraction.mute(self, event, member, reason) existed = u' [was temp-muted]' if existed else '' self.confirm_action( event, maybe_string( reason, u':ok_hand: {u} is now muted (`{o}`)' + existed, u':ok_hand: {u} is now muted' + existed, u=member.user, )) if event.config.notify_action_on and event.config.notify_action_on.mutes: try: event.guild.get_member(user.id).user.open_dm( ).send_message( 'You have been **Temporarily Muted** in the guild **{}** for **{}** for `{}`' .format( event.guild.name, humanize.naturaldelta(duration - datetime.utcnow()), reason or 'no reason specified.')) except: pass else: pass else: raise CommandFail('invalid user')
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 = 0xffd700 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 = 0xffd700 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 role_add(self, event, user, role, reason=None, mode=None): role_obj = None if role.isdigit() and int(role) in event.guild.roles.keys(): role_obj = event.guild.roles[int(role)] else: # First try exact match exact_matches = [ i for i in event.guild.roles.values() if i.name.lower().replace(' ', '') == role.lower() ] if len(exact_matches) == 1: role_obj = exact_matches[0] else: # Otherwise we fuzz it up rated = sorted( [(fuzz.partial_ratio(role, r.name.replace(' ', '')), r) for r in event.guild.roles.values()], key=lambda i: i[0], reverse=True) if rated[0][0] > 40: if len(rated) == 1: role_obj = rated[0][1] elif rated[0][0] - rated[1][0] > 20: role_obj = rated[0][1] if not role_obj: raise CommandFail( 'too many matches for that role, try something more exact or the role ID' ) author_member = event.guild.get_member(event.author) highest_role = sorted( [event.guild.roles.get(r) for r in author_member.roles], key=lambda i: i.position, reverse=True) if not author_member.owner and ( not highest_role or highest_role[0].position < role_obj.position): raise CommandFail( 'you can only {} roles that are ranked lower than your highest role' .format(mode)) member = event.guild.get_member(user) if not member: raise CommandFail('invalid member') self.can_act_on(event, member.id) if mode == 'add' and role_obj.id in member.roles: raise CommandFail(u'{} already has the {} role'.format( member, role_obj.name)) elif mode == 'remove' and role_obj.id not in member.roles: return CommandFail(u'{} doesn\'t have the {} role'.format( member, role_obj.name)) self.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, mode + '_role', actor=event.author, reason=reason or 'no reason') if mode == 'add': member.add_role(role_obj.id) else: member.remove_role(role_obj.id) event.msg.reply(u':ok_hand: {} role {} to {}'.format( 'added' if mode == 'add' else 'removed', role_obj.name, member))
def messageinfo(self, event, mid): try: msg = Message.select(Message).where( (Message.id == mid) ).get() except Message.DoesNotExist: raise CommandFail('the id specified does not exist in our message database.') message_content = msg.content author_id = msg.author.id guild_id = msg.guild_id channel_id = msg.channel_id deleted = msg.deleted num_edits = msg.num_edits if num_edits > 0: num_edits_bool = True else: num_edits_bool = False discrim = str(msg.author.discriminator) # if len(str(cached_name[1])) != 4: # while len(str(temp_str)) < 4: # temp_str = '0' + str(temp_str) cached_name = str(msg.author.username) + '#' + str(discrim) avatar_name = msg.author.avatar content = [] embed = MessageEmbed() member = event.guild.get_member(author_id) if not avatar_name: if member: avatar = default_color(str(member.user.default_avatar)) else: avatar = None elif avatar_name.startswith('a_'): avatar = u'https://cdn.discordapp.com/avatars/{}/{}.gif'.format(author_id, avatar_name) else: avatar = u'https://cdn.discordapp.com/avatars/{}/{}.png'.format(author_id, avatar_name) if member: embed.set_author(name='{} ({})'.format(member.user, member.id), icon_url=avatar) embed.set_thumbnail(url=avatar) else: if avatar: embed.set_author(name='{} ({})'.format(cached_name, author_id), icon_url=avatar) embed.set_thumbnail(url=avatar) else: embed.set_author(name='{} ({})'.format(cached_name, author_id)) # embed.title = "Message Content:" content.append(u'**\u276F Message Information:**') content.append(u'In channel: <#{}>'.format(channel_id)) content.append(u'Edited: **{}**'.format(num_edits_bool)) if deleted: content.append(u'Deleted: **{}**'.format(deleted)) content.append(u'Content: ```{}```'.format(message_content)) if member: content.append(u'\n**\u276F Member Information**') if member.nick: content.append(u'Nickname: {}'.format(member.nick)) content.append('Joined: {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - member.joined_at), member.joined_at.isoformat(), )) if member.roles: roles = [] for r in member.roles: roles.append(member.guild.roles.get(r)) roles = sorted(roles, key=lambda r: r.position, reverse=True) total = len(member.roles) roles = roles[:20] content.append(u'Roles ({}): {}{}'.format( total, ' '.join(r.mention for r in roles), ' (+{})'.format(total-20) if total > 20 else '' )) embed.description = '\n'.join(content) # embed.url = 'https://discordapp.com/channels/{}/{}/{}'.format(guild_id, channel_id, mid) embed.timestamp = datetime.utcnow().isoformat() if not event.author.avatar: auth_avatar = default_color(str(member.user.default_avatar)) elif event.author.avatar.startswith('a_'): auth_avatar = u'https://cdn.discordapp.com/avatars/{}/{}.gif'.format(event.author.id, event.author.avatar) else: auth_avatar = u'https://cdn.discordapp.com/avatars/{}/{}.png'.format(event.author.id, event.author.avatar) embed.set_footer(text='Requested by {}#{} ({})'.format(event.author.username, event.author.discriminator, event.author.id), icon_url=auth_avatar) try: embed.color = get_dominant_colors_user(member.user, avatar) except: embed.color = '00000000' event.msg.reply('', embed=embed)
def unlock_stars(self, event): if event.guild.id in self.locks: del self.locks[event.guild.id] raise CommandSuccess('Starboard has been unlocked') return raise CommandFail('Starboard is not locked')
def can_act_on(self, event, victim_id, throw=True): if event.author.id == victim_id: if not throw: return False raise CommandFail('Cannot execute that action on yourself')
def info(self, event, user=None): if user is None: user = event.author user_id = 0 if isinstance(user, (int, long)): user_id = user user = self.state.users.get(user) if user and not user_id: user = self.state.users.get(user.id) if not user: if user_id: user = self.fetch_user(user_id) User.from_disco_user(user) else: raise CommandFail('unknown user') content = [] content.append(u'**\u276F User Information**') content.append(u'ID: {}'.format(user.id)) content.append(u'Profile: <@{}>'.format(user.id)) if user.presence: emoji, status = get_status_emoji(user.presence) content.append('Status: {} <{}>'.format(status, emoji)) game = user.presence.game if game and game.name: activity = ['Playing', 'Stream'][int(game.type)] if game.type < 2 else None if not game.type: if game.name == 'Spotify': activity = 'Listening to' else: activity = None if activity: content.append(u'{}: {}'.format(activity, u'[{}]({})'.format(game.name, game.url) if game.url else game.name )) created_dt = to_datetime(user.id) content.append('Created: {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - created_dt), created_dt.isoformat() )) for i in self.server_owners: if i == str(user.id): content.append('Server Ownership: {}'.format(self.server_owners[i])) for i in self.server_managers: if i == str(user.id): content.append('Community Manager: {}'.format(self.server_managers[i])) if user.id == self.state.me.id: content.append('Documentation: https://aetherya.stream/') elif rdb.sismember('global_admins', user.id): content.append('Airplane Staff: Global Administrator') elif rdb.sismember('server_managers', user.id): content.append('Server Manager') elif rdb.sismember('server_owner', user.id): content.append('Server Owner') member = event.guild.get_member(user.id) if event.guild else None if member: content.append(u'\n**\u276F Member Information**') if member.nick: content.append(u'Nickname: {}'.format(member.nick)) content.append('Joined: {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - member.joined_at), member.joined_at.isoformat(), )) if member.roles: roles = [] for r in member.roles: roles.append(member.guild.roles.get(r)) roles = sorted(roles, key=lambda r: r.position, reverse=True) total = len(member.roles) roles = roles[:20] content.append(u'Roles ({}): {}{}'.format( total, ' '.join(r.mention for r in roles), ' (+{})'.format(total-20) if total > 20 else '' )) # Execute a bunch of queries async newest_msg = Message.select(Message.timestamp).where( (Message.author_id == user.id) & (Message.guild_id == event.guild.id) ).order_by(Message.timestamp.desc()).limit(1).async() # oldest_msg = Message.select(Message.timestamp).where( # (Message.author_id == user.id) & # (Message.guild_id == event.guild.id) # ).order_by(Message.timestamp.asc()).limit(1).async() infractions = Infraction.select( Infraction.guild_id, fn.COUNT('*') ).where( (Infraction.user_id == user.id) & (Infraction.type_ != 6) & # Unban (~(Infraction.reason ** '[NOTE]%')) ).group_by(Infraction.guild_id).tuples().async() voice = GuildVoiceSession.select( GuildVoiceSession.user_id, fn.COUNT('*'), fn.SUM(GuildVoiceSession.ended_at - GuildVoiceSession.started_at) ).where( (GuildVoiceSession.user_id == user.id) & (~(GuildVoiceSession.ended_at >> None)) ).group_by(GuildVoiceSession.user_id).tuples().async() # Wait for them all to complete (we're still going to be as slow as the # slowest query, so no need to be smart about this.) try: wait_many(newest_msg, infractions, voice, timeout=3) except gevent.Timeout: pass tags = to_tags(guild_id=event.msg.guild.id) if newest_msg.value: content.append(u'\n **\u276F Activity**') statsd.timing('sql.duration.newest_msg', newest_msg.value._query_time, tags=tags) newest_msg = newest_msg.value.get() content.append('Last Message: {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - newest_msg.timestamp), newest_msg.timestamp.isoformat(), )) # if oldest_msg.value: # statsd.timing('sql.duration.oldest_msg', oldest_msg.value._query_time, tags=tags) # oldest_msg = oldest_msg.value.get() # content.append('First Message: {} ago ({})'.format( # humanize.naturaldelta(datetime.utcnow() - oldest_msg.timestamp), # oldest_msg.timestamp.isoformat(), # )) if infractions.value: statsd.timing('sql.duration.infractions', infractions.value._query_time, tags=tags) infractions = list(infractions.value) total = sum(i[1] for i in infractions) content.append(u'\n**\u276F Infractions**') content.append('Total Infractions: {}'.format(total)) content.append('Unique Servers: {}'.format(len(infractions))) if voice.value: statsd.timing('plugin.utilities.info.sql.voice', voice.value._query_time, tags=tags) voice = list(voice.value) content.append(u'\n**\u276F Voice**') content.append(u'Sessions: {}'.format(voice[0][1])) content.append(u'Time: {}'.format(humanize.naturaldelta( voice[0][2] ))) embed = MessageEmbed() avatar = user.avatar if avatar: avatar = u'https://cdn.discordapp.com/avatars/{}/{}.{}'.format( user.id, avatar, u'gif' if avatar.startswith('a_') else u'png' ) else: avatar = u'https://cdn.discordapp.com/embed/avatars/{}.png'.format( int(user.discriminator) % 5 ) embed.set_author(name=u'{}#{}'.format( user.username, user.discriminator, ), icon_url=avatar) embed.set_thumbnail(url=avatar) embed.description = '\n'.join(content) try: embed.color = get_dominant_colors_user(user, avatar) except: pass event.msg.reply('', embed=embed)
def plugin_disable(self, event, plugin): plugin = self.bot.plugins.get(plugin) if not plugin: raise CommandFail('It appears that plugin doesn\'t exist') self.bot.rmv_plugin(plugin.__class__) raise CommandSuccess('Ok, that plugin has been disabled and unloaded')
def reactions_clean(self, event, user, count=10, emoji=None): if isinstance(user, DiscoUser): user = user.id if count > 50: raise CommandFail('cannot clean more than 50 reactions') lock = rdb.lock('clean-reactions-{}'.format(user)) if not lock.acquire(blocking=False): raise CommandFail('already running a clean on user') query = [ (Reaction.user_id == user), (Message.guild_id == event.guild.id), (Message.deleted == 0), ] if emoji: emoji_id = EMOJI_RE.findall(emoji) if emoji_id: query.append((Reaction.emoji_id == emoji_id[0])) else: # TODO: validation? query.append((Reaction.emoji_name == emoji)) try: reactions = list(Reaction.select( Reaction.message_id, Reaction.emoji_id, Reaction.emoji_name, Message.channel_id, ).join( Message, on=(Message.id == Reaction.message_id), ).where( reduce(operator.and_, query) ).order_by(Reaction.message_id.desc()).limit(count).tuples()) if not reactions: raise CommandFail('no reactions to purge') msg = event.msg.reply('Hold on while I clean {} reactions'.format( len(reactions) )) for message_id, emoji_id, emoji_name, channel_id in reactions: if emoji_id: emoji = '{}:{}'.format(emoji_name, emoji_id) else: emoji = emoji_name self.client.api.channels_messages_reactions_delete( channel_id, message_id, emoji, user) msg.edit('Ok, I cleaned {} reactions'.format( len(reactions), )) finally: lock.release()
def info(self, event, user=None): if user is None: user = event.author user_id = 0 if isinstance(user, (int, long)): user_id = user user = self.state.users.get(user) if user and not user_id: user = self.state.users.get(user.id) if not user: if user_id: try: user = self.client.api.users_get(user_id) except APIException: raise CommandFail('unknown user') User.from_disco_user(user) else: raise CommandFail('unknown user') self.client.api.channels_typing(event.channel.id) content = [] content.append(u'**\u276F User Information**') content.append(u'**ID:** {}'.format(user.id)) content.append(u'**Profile:** <@{}>'.format(user.id)) if user.presence: emoji, status = get_status_emoji(user.presence) content.append('**Status:** {} <{}>'.format(status, emoji)) game = user.presence.game if game and game.name: activity = [ 'Playing', 'Stream', 'Listening to', 'Watching', 'Custom Status' ][int(game.type or 0)] if not game.type: activity = None if activity: game_name = game.state if game.type == GameType.CUSTOM_STATUS else game.name content.append(u'**{}:** {}'.format( activity, u'[{}]({})'.format(game_name, game.url) if game.url else game_name)) created_dt = to_datetime(user.id) content.append('**Created:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - created_dt), created_dt.isoformat())) member = event.guild.get_member(user.id) if event.guild else None if member: content.append(u'\n**\u276F Member Information**') if member.nick: content.append(u'**Nickname:** {}'.format(member.nick)) content.append('**Joined:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - member.joined_at), member.joined_at.isoformat(), )) if member.roles: content.append(u'**Roles:** {}'.format(', '.join( (member.guild.roles.get(r).mention for r in sorted( member.roles, key=lambda r: member.guild.roles.get(r).position, reverse=True))))) # "is not None" does not work with Unset types for some rason if bool(member.premium_since): content.append('**Boosting since:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - member.premium_since), member.premium_since.isoformat(), )) # Execute a bunch of queries async newest_msg = Message.select(Message.timestamp).where( (Message.author_id == user.id) & (Message.guild_id == event.guild.id)).limit(1).order_by( Message.timestamp.desc()). async () oldest_msg = Message.select(Message.timestamp).where( (Message.author_id == user.id) & (Message.guild_id == event.guild.id)).limit(1).order_by( Message.timestamp.asc()). async () infractions = Infraction.select( Infraction.guild_id, fn.COUNT('*')).where( (Infraction.user_id == user.id)).group_by( Infraction.guild_id).tuples(). async () voice = GuildVoiceSession.select( GuildVoiceSession.user_id, fn.COUNT('*'), fn.SUM(GuildVoiceSession.ended_at - GuildVoiceSession.started_at)).where( (GuildVoiceSession.user_id == user.id) & (~(GuildVoiceSession.ended_at >> None))).group_by( GuildVoiceSession.user_id).tuples(). async () # Wait for them all to complete (we're still going to be as slow as the # slowest query, so no need to be smart about this.) wait_many(newest_msg, oldest_msg, infractions, voice, timeout=10) tags = to_tags(guild_id=event.msg.guild.id) if newest_msg.value and oldest_msg.value: statsd.timing('sql.duration.newest_msg', newest_msg.value._query_time, tags=tags) statsd.timing('sql.duration.oldest_msg', oldest_msg.value._query_time, tags=tags) newest_msg = newest_msg.value.get() oldest_msg = oldest_msg.value.get() content.append(u'\n **\u276F Activity**') content.append('**Last Message:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - newest_msg.timestamp), newest_msg.timestamp.isoformat(), )) content.append('**First Message:** {} ago ({})'.format( humanize.naturaldelta(datetime.utcnow() - oldest_msg.timestamp), oldest_msg.timestamp.isoformat(), )) if infractions.value: statsd.timing('sql.duration.infractions', infractions.value._query_time, tags=tags) infractions = list(infractions.value) total = sum(i[1] for i in infractions) content.append(u'\n**\u276F Infractions**') content.append('**Total Infractions:** {:,}'.format(total)) content.append('**Unique Servers:** {}'.format(len(infractions))) if voice.value: statsd.timing('plugin.utilities.info.sql.voice', voice.value._query_time, tags=tags) voice = list(voice.value) content.append(u'\n**\u276F Voice**') content.append(u'**Sessions:** {:,}'.format(voice[0][1])) content.append(u'**Time:** {}'.format( humanize.naturaldelta(voice[0][2]))) embed = MessageEmbed() avatar = user.avatar if avatar: avatar = user.avatar_url else: avatar = u'https://cdn.discordapp.com/embed/avatars/{}.png'.format( int(user.discriminator) % 5) embed.set_author(name=u'{}#{}'.format( user.username, user.discriminator, ), icon_url=avatar) embed.set_thumbnail(url=user.avatar_url if user.avatar else avatar) embed.description = '\n'.join(content) embed.color = get_dominant_colors_user( user, user.get_avatar_url('png') if user.avatar else avatar) event.msg.reply('', embed=embed)
def clean(self, event, user=None, size=25, typ=None, mode='all'): """ Removes messages """ if 0 > size >= 10000: raise CommandFail('too many messages must be between 1-10000') if event.channel.id in self.cleans: raise CommandFail('a clean is already running on this channel') query = Message.select(Message.id).where( (Message.deleted >> False) & (Message.channel_id == event.channel.id) & (Message.timestamp > (datetime.utcnow() - timedelta(days=13)))).join(User).order_by( Message.timestamp.desc()).limit(size) if mode == 'bots': query = query.where((User.bot >> True)) elif mode == 'user': query = query.where((User.user_id == user.id)) messages = [i[0] for i in query.tuples()] if len(messages) > 100: msg = event.msg.reply( 'Woah there, that will delete a total of {} messages, please confirm.' .format(len(messages))) msg.chain(False).\ add_reaction(GREEN_TICK_EMOJI).\ add_reaction(RED_TICK_EMOJI) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id=msg.id, conditional=lambda e: (e.emoji.id in (GREEN_TICK_EMOJI_ID, RED_TICK_EMOJI_ID) and e.user_id == event.author.id)).get(timeout=10) except gevent.Timeout: return finally: msg.delete() if mra_event.emoji.id != GREEN_TICK_EMOJI_ID: return event.msg.reply( ':wastebasket: Ok please hold on while I delete those messages...' ).after(5).delete() event.msg.reply('<a:clean:535924986733395969>').after(3).delete() def run_clean(): for chunk in chunks(messages, 100): self.client.api.channels_messages_delete_bulk( event.channel.id, chunk) self.cleans[event.channel.id] = gevent.spawn(run_clean) self.cleans[event.channel.id].join() del self.cleans[event.channel.id]
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)
def jumbo(self, event, emojis): emojis = emojis.split(' ') if len(emojis) == 1: url = ext = '' emoji = emojis[0] if EMOJI_RE.match(emoji): _, eid = EMOJI_RE.findall(emoji)[0] ext = 'gif' if emoji.startswith('<a:') else 'png' url = 'https://cdn.discordapp.com/emojis/{}.{}?v=1'.format( eid, ext) else: ext = 'png' url = self.get_emoji_url(emoji) if not url: raise CommandFail('provided emoji is invalid') r = requests.get(url) try: r.raise_for_status() except requests.HTTPError: raise CommandFail('provided emoji is invalid') return event.msg.reply('', attachments=[('emoji.' + ext, r.content)]) else: urls = [] for emoji in emojis[:5]: if EMOJI_RE.match(emoji): _, eid = EMOJI_RE.findall(emoji)[0] urls.append( 'https://cdn.discordapp.com/emojis/{}.png?v=1'.format( eid)) else: url = self.get_emoji_url(emoji) urls.append(url) if url else None width, height, images = 0, 0, [] for r in Pool(6).imap(requests.get, urls): try: r.raise_for_status() except requests.HTTPError: continue img = Image.open(BytesIO(r.content)) height = img.height if img.height > height else height width += img.width + 10 images.append(img) if not images: raise CommandFail('provided emojis are invalid') image = Image.new('RGBA', (width, height)) width_offset = 0 for img in images: image.paste(img, (width_offset, 0)) width_offset += img.width + 10 combined = BytesIO() image.save(combined, 'png', quality=55) combined.seek(0) return event.msg.reply('', attachments=[('emoji.png', combined)])
def rps(self, event, user=None): p_1 = [] p_1.append(event.author) p_2 = [] if not user: p_2.append(event.guild.get_member(351097525928853506)) # Airplane :D prompt = event.msg.reply('{}, Rock, Paper, Scissors says shoot! (Please react to one of the following).'.format(p_1[0].mention)) prompt.chain(False).\ add_reaction(game_emotes_rps['rock']['default']['emote']).\ add_reaction(game_emotes_rps['paper']['default']['emote']).\ add_reaction(game_emotes_rps['scissors']['default']['emote']) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id = prompt.id, conditional = lambda e: ( e.emoji.id in (game_emotes_rps['rock']['default']['id'], game_emotes_rps['paper']['default']['id'], game_emotes_rps['scissors']['default']['id']) and e.user_id == event.author.id )).get(timeout=15) except gevent.Timeout: prompt.delete() event.msg.reply('{}, you failed to make your choice.'.format(p_1[0].mention)).after(5).delete() return if mra_event.emoji.id == game_emotes_rps['rock']['default']['id']: p_1.append('rock') elif mra_event.emoji.id == game_emotes_rps['paper']['default']['id']: p_1.append('paper') elif mra_event.emoji.id == game_emotes_rps['scissors']['default']['id']: p_1.append('scissors') else: raise CommandFail('invalid emoji selected.') prompt.delete() rand_options = ['rock', 'paper', 'scissors'] p_2.append(choice(rand_options)) outcome = winner_rps(p_1[1], p_2[1]) p_1.append(outcome[0]) p_2.append(outcome[1]) output = '**Results:**\n{0}: <:{2}> `{1}`\n{3}: <:{5}> `{4}`. \n' + outcome[2] event.msg.reply(output.format(p_1[0].mention, p_1[1], game_emotes_rps[p_1[1]][p_1[2]]['emote'], p_2[0].mention, p_2[1], game_emotes_rps[p_2[1]][p_2[2]]['emote'])) else: p_2.append(event.guild.get_member(user)) if p_1[0].id == p_2[0].id: event.msg.reply('You cannot play against yourself.').after(5).delete() return msg = event.msg.reply('{1}, {0} has challenged you to play rock paper scissors. Do you accept?'.format(p_1[0].mention, p_2[0].mention)) msg.chain(False).\ add_reaction(GREEN_TICK_EMOJI).\ add_reaction(RED_TICK_EMOJI) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id=msg.id, conditional=lambda e: ( e.emoji.id in (GREEN_TICK_EMOJI_ID, RED_TICK_EMOJI_ID) and e.user_id == p_2[0].id )).get(timeout=20) except gevent.Timeout: event.msg.reply('{}, your challenge timed out.'.format(p_1[0].mention)).after(5).delete() return finally: msg.delete() if str(mra_event.emoji.id) != str(GREEN_TICK_EMOJI_ID): event.msg.reply('{}, your partner has declined the challenge.'.format(p_1[0].mention)).after(5).delete() return else: try: # Send dm to the first user prompt_p1 = p_1[0].open_dm().send_message('{}, Rock, Paper, Scissors says shoot! (Please react to one of the following).'.format(p_1[0].mention)) except: event.msg.reply('{0}, your DMs are disabled, therefore you are unable to challenge another user. Please open your DMs and try again.'.format(p_1[0].mention)).after(5).delete() return temp = event.msg.reply('{} is selecting their choice, please wait.'.format(unicode(p_1[0].username))) prompt_p1.chain(False).\ add_reaction(game_emotes_rps['rock']['default']['emote']).\ add_reaction(game_emotes_rps['paper']['default']['emote']).\ add_reaction(game_emotes_rps['scissors']['default']['emote']) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id = prompt_p1.id, conditional = lambda e: ( e.emoji.id in (game_emotes_rps['rock']['default']['id'], game_emotes_rps['paper']['default']['id'], game_emotes_rps['scissors']['default']['id']) and e.user_id == p_1[0].id )).get(timeout=15) except gevent.Timeout: prompt_p1.delete() temp.delete() event.msg.reply('Game canceled, {} failed to make their choice.'.format(p_1[0].mention)).after(5).delete() return if mra_event.emoji.id == game_emotes_rps['rock']['default']['id']: p_1.append('rock') elif mra_event.emoji.id == game_emotes_rps['paper']['default']['id']: p_1.append('paper') elif mra_event.emoji.id == game_emotes_rps['scissors']['default']['id']: p_1.append('scissors') temp.delete() prompt_p1.delete() try: # Send dm to second user prompt_p2 = p_2[0].user.open_dm().send_message('{}, Rock, Paper, Scissors says shoot! (Please react to one of the following).'.format(p_2[0].mention)) except: event.msg.reply('{0}, your DMs are disabled, therefore you are unable play other users. Please open your DMs and try again.'.format(p_2[0].mention)).after(5).delete() return temp = event.msg.reply('{} is selecting their choice, please wait.'.format(unicode(p_2[0].user.username))) prompt_p2.chain(False).\ add_reaction(game_emotes_rps['rock']['default']['emote']).\ add_reaction(game_emotes_rps['paper']['default']['emote']).\ add_reaction(game_emotes_rps['scissors']['default']['emote']) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id = prompt_p2.id, conditional = lambda e: ( e.emoji.id in (game_emotes_rps['rock']['default']['id'], game_emotes_rps['paper']['default']['id'], game_emotes_rps['scissors']['default']['id']) and e.user_id == p_2[0].id )).get(timeout=15) except gevent.Timeout: prompt_p2.delete() temp.delete() event.msg.reply('Game canceled, {} failed to make their choice.'.format(p_2[0].mention)).after(5).delete() return if mra_event.emoji.id == game_emotes_rps['rock']['default']['id']: p_2.append('rock') elif mra_event.emoji.id == game_emotes_rps['paper']['default']['id']: p_2.append('paper') elif mra_event.emoji.id == game_emotes_rps['scissors']['default']['id']: p_2.append('scissors') prompt_p2.delete() temp.delete() outcome = winner_rps(p_1[1], p_2[1]) p_1.append(outcome[0]) p_2.append(outcome[1]) output = '**Results:**\n{0}: <:{2}> `{1}`\n{3}: <:{5}> `{4}`. \n' + outcome[2] return event.msg.reply(output.format(p_1[0].mention, p_1[1], game_emotes_rps[p_1[1]][p_1[2]]['emote'], p_2[0].mention, p_2[1], game_emotes_rps[p_2[1]][p_2[2]]['emote']))
def restore(self, event, user): member = event.guild.get_member(user) if member: self.restore_user(event, member) else: raise CommandFail('invalid user')
def lock_stars(self, event): if event.guild.id in self.locks: raise CommandFail('Starboard is already locked') self.locks[event.guild.id] = True raise CommandSuccess('Starboard has been locked')
def clean_cacnel(self, event): if event.channel.id not in self.cleans: raise CommandFail('no clean is running in this channel') self.cleans[event.channel.id].kill() event.msg.reply('Ok, the running clean was cancelled')
def xp_edit(self, event, user, amount=None, action=None): member = event.guild.get_member(user) if not member: raise CommandFail('Invalid member') if not isinstance(amount, int) and action != "reset": raise CommandFail('Invalid amount') # self.can_act_on(event, member.id) if action == 'give': try: user = GuildMemberLevel.select().where( (GuildMemberLevel.user_id == member.id) & (GuildMemberLevel.guild_id == member.guild_id)).get() except GuildMemberLevel.DoesNotExist: user = GuildMemberLevel.create_new(member) user.add_xp(member.guild_id, member.id, amount) raise CommandSuccess('{} is now Level {} ({} XP)'.format( member.user, self.level_from_xp(user.xp + amount), (user.xp + amount))) elif action == 'take': try: user = GuildMemberLevel.select().where( (GuildMemberLevel.user_id == member.id) & (GuildMemberLevel.guild_id == member.guild_id)).get() except GuildMemberLevel.DoesNotExist: user = GuildMemberLevel.create_new(member) event.channel.send_message('You\'re a monster. Negative XP?') user.rmv_xp(member.guild_id, member.id, amount) raise CommandSuccess('{} is now Level {} ({} XP)'.format( member.user, self.level_from_xp(user.xp - amount), (user.xp - amount))) else: try: user = GuildMemberLevel.select().where( (GuildMemberLevel.user_id == member.id) & (GuildMemberLevel.guild_id == member.guild_id)).get() except GuildMemberLevel.DoesNotExist: raise CommandFail('This user cannot be reset.') msg = event.msg.reply('Really reset `{}`?'.format(member)) msg.chain(False).\ add_reaction(GREEN_TICK_EMOJI).\ add_reaction(RED_TICK_EMOJI) try: mra_event = self.wait_for_event( 'MessageReactionAdd', message_id=msg.id, conditional=lambda e: (e.emoji.id in (GREEN_TICK_EMOJI_ID, RED_TICK_EMOJI_ID) and e.user_id == event.author.id)).get(timeout=10) except gevent.Timeout: return finally: msg.delete() if mra_event.emoji.id != GREEN_TICK_EMOJI_ID: return user.reset_member(event.guild.id, member.id) raise CommandSuccess('{} has been reset.'.format(member))