def infractions_archive(self, event): user = User.alias() actor = User.alias() q = Infraction.select(Infraction, user, actor).join( user, on=((Infraction.user_id == user.user_id).alias('user')) ).switch(Infraction).join( actor, on=((Infraction.actor_id == actor.user_id).alias('actor')) ).where(Infraction.guild_id == event.guild.id) buff = StringIO() w = csv.writer(buff) for inf in q: w.writerow([ inf.id, inf.user_id, unicode(inf.user).encode('utf-8'), inf.actor_id, unicode(inf.actor).encode('utf-8'), unicode({i.index: i for i in Infraction.Types.attrs}[inf.type_]).encode('utf-8'), unicode(inf.reason).encode('utf-8'), ]) event.msg.reply('Ok, here is an archive of all infractions', attachments=[ ('infractions.csv', buff.getvalue()) ])
def infraction_search(self, event, query=None): q = (Infraction.guild_id == event.guild.id) if query and isinstance(query, list) and isinstance( query[0], DiscoUser): query = query[0].id elif query: query = ' '.join(query) if query and (isinstance(query, int) or query.isdigit()): q &= ((Infraction.id == int(query)) | (Infraction.user_id == int(query)) | (Infraction.actor_id == int(query))) elif query: q &= (Infraction.reason**query) user = User.alias() actor = User.alias() infractions = Infraction.select(Infraction, user, actor).join( user, on=((Infraction.user_id == user.user_id).alias('user') )).switch(Infraction).join( actor, on=((Infraction.actor_id == actor.user_id ).alias('actor'))).where(q).order_by( Infraction.created_at.desc()).limit(6) tbl = MessageTable() tbl.set_header('ID', 'Created', 'Type', 'User', 'Moderator', 'Active', 'Reason') last_tbl_str = None for inf in infractions: type_ = {i.index: i for i in Infraction.Types.attrs}[inf.type_] reason = inf.reason or '' if len(reason) > 256: reason = reason[:256] + '...' if inf.active: active = 'yes' if inf.expires_at: active += ' (expires in {})'.format( humanize.naturaldelta(inf.expires_at - datetime.utcnow())) else: active = 'no' tbl.add(inf.id, inf.created_at.isoformat(), str(type_), unicode(inf.user), unicode(inf.actor), active, clamp(reason, 128)) tbl_str = tbl.compile() if len(tbl_str) >= 2000: break last_tbl_str = tbl_str event.msg.reply(last_tbl_str or "No infractions found.")
def infraction_info(self, event, infraction): try: user = User.alias() actor = User.alias() infraction = Infraction.select(Infraction, user, actor).join( user, on=((Infraction.user_id == user.user_id).alias('user')) ).switch(Infraction).join( actor, on=((Infraction.actor_id == actor.user_id).alias('actor') )).where((Infraction.id == infraction) & (Infraction.guild_id == event.guild.id)).get() except Infraction.DoesNotExist: raise CommandFail( 'cannot find an infraction with ID `{}`'.format(infraction)) type_ = {i.index: i for i in Infraction.Types.attrs}[infraction.type_] embed = MessageEmbed() if type_ in (Infraction.Types.MUTE, Infraction.Types.TEMPMUTE, Infraction.Types.TEMPROLE): embed.color = 0xfdfd96 elif type_ in (Infraction.Types.KICK, Infraction.Types.SOFTBAN): embed.color = 0xffb347 else: embed.color = 0xff6961 embed.title = str(type_).title() embed.set_thumbnail(url=infraction.user.get_avatar_url()) embed.add_field(name='User', value=unicode(infraction.user), inline=True) embed.add_field(name='Moderator', value=unicode(infraction.actor), inline=True) embed.add_field(name='Active', value='yes' if infraction.active else 'no', inline=True) if infraction.active and infraction.expires_at: embed.add_field(name='Expires', value=humanize.naturaldelta(infraction.expires_at - datetime.utcnow())) embed.add_field(name='Reason', value=infraction.reason or '_No Reason Given', inline=False) embed.timestamp = infraction.created_at.isoformat() event.msg.reply('', embed=embed)
def xp_leaderboard(self, event, places=None, offset=None): places = places if places else 10 offset = offset if offset else 0 user = User.alias() leaderboard = GuildMemberLevel.select(GuildMemberLevel, user).join( user, on=((GuildMemberLevel.user_id == user.user_id).alias('user')) ).where(GuildMemberLevel.guild_id == event.guild.id, GuildMemberLevel.xp > 0).order_by( GuildMemberLevel.xp.desc()).offset(offset).limit(places) tbl = MessageTable() tbl.set_header('Place', 'User', 'Level (XP)') for place, entry in enumerate(leaderboard, start=(offset if offset else 1)): tbl.add(place, str(entry.user), '{} ({})'.format(self.level_from_xp(entry.xp), entry.xp)) event.msg.reply(tbl.compile())
def guild_infractions_list(guild): user = User.alias() actor = User.alias() columns = [ Infraction.id, Infraction.type_, user.user_id, user.username, actor.user_id, actor.username, Infraction.reason, Infraction.created_at, Infraction.expires_at, ] def serialize(inf): type_ = {i.index: i for i in Infraction.Types.attrs}[inf.type_] return { 'id': inf.id, 'user': serialize_user(inf.user), 'actor': serialize_user(inf.actor), 'type': str(type_), 'reason': inf.reason, 'metadata': inf.metadata, 'expires_at': (inf.expires_at.isoformat() if inf.expires_at else None) if inf.active else 'Expired', 'created_at': inf.created_at.isoformat() if inf.created_at else None } sort_order = [] for idx in xrange(32): ch = 'order[{}][column]'.format(idx) if ch not in request.values: break cd = 'order[{}][dir]'.format(idx) column = columns[int(request.values.get(ch))] order = request.values.get(cd) if order == 'asc': column = column.asc() else: column = column.desc() sort_order.append(column) base_q = Infraction.select(Infraction, user, actor).join( user, on=(Infraction.user_id == user.user_id).alias('user'), ).switch(Infraction).join( actor, on=(Infraction.actor_id == actor.user_id).alias('actor'), ).where(Infraction.guild_id == guild.guild_id).order_by(*sort_order) search = request.values.get('search[value]') opts = [] if search: opts.append(user.username**u'%{}%'.format(search)) opts.append(actor.username**u'%{}%'.format(search)) opts.append(Infraction.reason**u'%{}%'.format(search)) if search.isdigit(): opts.append(user.user_id == int(search)) opts.append(actor.user_id == int(search)) opts.append(Infraction.id == int(search)) if opts: filter_q = base_q.where(reduce(operator.or_, opts)) else: filter_q = base_q final_q = filter_q.offset(int(request.values.get('start'))).limit( int(request.values.get('length'))) return jsonify({ 'draw': int(request.values.get('draw')), 'recordsTotal': base_q.count(), 'recordsFiltered': filter_q.count(), 'data': map(serialize, final_q), })
def guild_infractions(guild): user = User.alias() actor = User.alias() page = int(request.values.get('page', 1)) if page < 1: page = 1 limit = int(request.values.get('limit', 1000)) if limit < 1 or limit > 1000: limit = 1000 q = Infraction.select(Infraction, user, actor).join( user, on=((Infraction.user_id == user.user_id).alias('user') )).switch(Infraction).join( actor, on=((Infraction.actor_id == actor.user_id).alias('actor'))) queries = [] if 'filtered' in request.values: filters = json.loads(request.values['filtered']) for f in filters: if f['id'] not in CAN_FILTER: continue if f['id'] == 'type': queries.append( Infraction.type_ == Infraction.Types.get(f['value'])) elif f['id'] == 'reason': queries.append( Infraction.reason**('%' + f['value'].lower().replace('%', '') + '%')) else: queries.append(getattr(Infraction, f['id']) == f['value']) if queries: q = q.where((Infraction.guild_id == guild.guild_id) & reduce(operator.and_, queries)) else: q = q.where((Infraction.guild_id == guild.guild_id)) sorted_fields = [] if 'sorted' in request.values: sort = json.loads(request.values['sorted']) for s in sort: if s['id'] not in CAN_SORT: continue if s['desc']: sorted_fields.append(getattr(Infraction, s['id']).desc()) else: sorted_fields.append(getattr(Infraction, s['id'])) if sorted_fields: q = q.order_by(*sorted_fields) else: q = q.order_by(Infraction.id.desc()) q = q.paginate( page, limit, ) return jsonify( [i.serialize(guild=guild, user=i.user, actor=i.actor) for i in q])