def avatar(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') ext = 'gif' if user.avatar.startswith('a_') else 'png' url = user.get_avatar_url() r = requests.get(url) r.raise_for_status() event.msg.reply('', attachments=[('{}.{}'.format(user.id, ext), r.content)])
def infraction_duration(self, event, infraction, duration): try: inf = Infraction.get(id=infraction) except Infraction.DoesNotExist: raise CommandFail('invalid infraction (try `!infractions recent`)') if inf.actor_id != event.author.id and event.user_level < CommandLevels.ADMIN: raise CommandFail('only administrators can modify the duration of infractions created by other moderators') if not inf.active: raise CommandFail('that infraction is not active and cannot be updated') expires_dt = parse_duration(duration, inf.created_at) converted = False if inf.type_ in [Infraction.Types.MUTE.index, Infraction.Types.BAN.index]: inf.type_ = Infraction.Types.TEMPMUTE if inf.type_ == Infraction.Types.MUTE.index else Infraction.Types.TEMPBAN converted = True elif inf.type_ not in [Infraction.Types.TEMPMUTE.index, Infraction.Types.TEMPBAN.index, Infraction.Types.TEMPROLE.index]: raise CommandFail('cannot set the duration for that type of infraction') inf.expires_at = expires_dt inf.save() self.queue_infractions() if converted: raise CommandSuccess('ok, I\'ve made that infraction temporary, it will now expire on {}'.format( inf.expires_at.isoformat() )) else: raise CommandSuccess('ok, I\'ve updated that infractions duration, it will now expire on {}'.format( inf.expires_at.isoformat() ))
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') lock = rdb.lock('clean-{}'.format(event.channel.id)) if not lock.acquire(blocking=False): raise CommandFail('already running a clean on this channel') try: query = Message.select().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)) msgs = list(reversed(query)) event.channel.delete_messages(msgs) event.msg.reply(':wastebasket: Ok, deleted {} messages'.format( len(msgs))).after(5).delete() finally: lock.release()
def tempmute(self, event, user, duration, reason=None): 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)) expire_dt = parse_duration(duration) # Reset the infraction task so we make sure it runs after this new infraction self.inf_task.set_next_schedule(expire_dt) # Create the infraction Infraction.tempmute(self, event, member, reason, expire_dt) if event.config.confirm_actions: event.msg.reply( 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(expire_dt - datetime.utcnow()), )) else: raise CommandFail('invalid user')
def temprole(self, event, user, role, duration, reason=None): member = event.guild.get_member(user) if not member: raise CommandFail('invalid user') self.can_act_on(event, member.id) role_id = role if isinstance(role, (int, long)) else event.config.role_aliases.get(role.lower()) if not role_id or role_id not in event.guild.roles: raise CommandFail('invalid or unknown role') if role_id in member.roles: raise CommandFail(u'{} is already in that role'.format(member.user)) expire_dt = parse_duration(duration) Infraction.temprole(self, event, member, role_id, reason, expire_dt) self.queue_infractions() self.confirm_action(event, maybe_string( reason, u':ok_hand: {u} is now in the {r} role for {t} (`{o}`)', u':ok_hand: {u} is now in the {r} role for {t}', r=event.guild.roles[role_id].name, u=member.user, t=humanize.naturaldelta(expire_dt - datetime.utcnow()), ))
def unmute(self, event, user, reason=None): # TOOD: eventually we should pull the role from the GuildMemberBackup if they arent in server 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 not in member.roles: raise CommandFail(u'{} is not muted'.format(member.user)) Infraction.clear_active( event, member.id, [Infraction.Types.MUTE, Infraction.Types.TEMPMUTE]) self.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'unmuted', actor=unicode(event.author), roles=[event.config.mute_role]) member.remove_role(event.config.mute_role) if event.config.confirm_actions: event.msg.reply(u':ok_hand: {} is now unmuted'.format( member.user)) else: raise CommandFail('invalid user')
def emojistats_custom(self, event, mode, sort): if mode not in ('server', 'global'): raise CommandFail( 'invalid emoji mode, must be `server` or `global`') if sort not in ('least', 'most'): raise CommandFail('invalid emoji sort, must be `least` or `most`') order = 'DESC' if sort == 'most' else 'ASC' if mode == 'server': q = CUSTOM_EMOJI_STATS_SERVER_SQL.format(order, guild=event.guild.id) else: q = CUSTOM_EMOJI_STATS_GLOBAL_SQL.format(order, guild=event.guild.id) q = list(GuildEmoji.raw(q).tuples()) tbl = MessageTable() tbl.set_header('Count', 'Name', 'ID') for emoji_id, name, count in q: tbl.add(count, name, emoji_id) event.msg.reply(tbl.compile())
def unmute(self, event, user, reason=None): # TOOD: eventually we should pull the role from the GuildMemberBackup if they arent in server member = event.guild.get_member(user) if member: if not event.config.temp_mute_role and not event.config.mute_role: raise CommandFail('mute is not setup on this server') roles = {event.config.temp_mute_role, event.config.mute_role } & set(member.roles) if not len(roles): raise CommandFail('{} is not muted'.format(member.user)) Infraction.update(active=False).where( (Infraction.guild_id == event.guild.id) & (Infraction.user_id == member.user.id) & (Infraction.type_ == Infraction.Types.TEMPMUTE) & (Infraction.active == 1)).execute() self.bot.plugins.get('ModLogPlugin').create_debounce( event, member.user.id, 'unmuted', actor=unicode(event.author), roles=roles) for role in roles: member.remove_role(role) if event.config.confirm_actions: event.msg.reply(u':ok_hand: {} is now unmuted'.format( member.user)) else: raise CommandFail('invalid user')
def unmute(self, event, user, reason=None): # TOOD: eventually we should pull the role from the GuildMemberBackup if they arent in server 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 not in member.roles: raise CommandFail(u'{} is not muted'.format(member.user)) Infraction.clear_active(event, member.id, [Infraction.Types.MUTE, Infraction.Types.TEMPMUTE]) self.call( 'ModLogPlugin.create_debounce', event, ['GuildMemberUpdate'], role_id=event.config.mute_role, ) member.remove_role(event.config.mute_role) self.call( 'ModLogPlugin.log_action_ext', Actions.MEMBER_UNMUTED, event.guild.id, member=member, actor=unicode(event.author) if event.author.id != member.id else 'Automatic', ) self.confirm_action(event, u':ok_hand: {} is now unmuted'.format(member.user)) else: raise CommandFail('invalid user')
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() 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 on_play(self, event, url): g = Guild.select(Guild).where((Guild.guild_id == event.guild.id)).get() if g.premium == False: raise CommandFail('This guild does not have premium enabled, please contact an Airplane global administrator.') # item = YoutubeDLInput(url, command='ffmpeg').pipe(BufferedOpusEncoderPlayable) # self.get_player(event.guild.id).queue.append(item) item = YoutubeDLInput(url) song = item.info if song['extractor'] is 'youtube': if song['is_live']: raise CommandFail('Sorry, live streams are not supported.') if song['duration'] > 7200: raise CommandFail('Sorry you are not allowed to play songs over 2 hours.') if song['duration'] > event.config.max_song_length: raise CommandFail('Sorry, you may not go over the server time limit.') item2 = item.pipe(BufferedOpusEncoderPlayable) self.get_player(event.guild.id).queue.append(item2) song = item.info if song['extractor'] is 'youtube': if song['artist']: return event.msg.reply('Now playing **{songname}** by **{author}**. Song length is `{duration}`'.format(songname=song['alt_title'], author=song['artist'], duration=timedelta(seconds=song['duration']))) else: return event.msg.reply('Now playing **{songname}** uploaded by **{author}**. Song length is `{duration}`'.format(songname=song['title'], author=song['uploader'], duration=timedelta(seconds=song['duration']))) else: return CommandSuccess('You\'re playing a song :D')
def archive(self, event, size=50, mode=None, user=None, channel=None): if 0 > size >= 15000: raise CommandFail('too many messages must be between 1-15000') q = Message.select(Message.id).join(User).order_by(Message.id.desc()).limit(size) if mode in ('all', 'channel'): cid = event.channel.id if channel: cid = channel if isinstance(channel, (int, long)) else channel.id channel = event.guild.channels.get(cid) if not channel: raise CommandFail('channel not found') perms = channel.get_permissions(event.author) if not (perms.administrator or perms.read_messages): raise CommandFail('invalid permissions') q = q.where(Message.channel_id == cid) else: user_id = user if isinstance(user, (int, long)) else user.id if event.author.id != user_id: self.can_act_on(event, user_id) q = q.where( (Message.author_id == user_id) & (Message.guild_id == event.guild.id) ) archive = MessageArchive.create_from_message_ids([i.id for i in q]) event.msg.reply('OK, archived {} messages at {}'.format(len(archive.message_ids), archive.url))
def cmd_remind(self, event, duration, content=None): if Reminder.count_for_user(event.author.id) > 15: raise CommandFail('You can only have 15 reminders going at once!') remind_at = parse_duration(duration) if remind_at > (datetime.utcnow() + timedelta(seconds=5 * YEAR_IN_SEC)): raise CommandFail('That\'s too far in the future... I\'ll forget!') if event.msg.message_reference.message_id: referenced_msg: MessageReference = event.channel.get_message( event.msg.message_reference.message_id) content = 'https://discord.com/channels/{}/{}/{}'.format( self.state.channels.get(referenced_msg.channel_id).guild_id, referenced_msg.channel_id, referenced_msg.id) elif not content: raise CommandFail( 'You need to provide content for the reminder, or reply to a message!' ) r = Reminder.create(message_id=event.msg.id, remind_at=remind_at, content=content) self.reminder_task.set_next_schedule(r.remind_at) raise CommandSuccess( 'I\'ll remind you at <t:{0}:f> (<t:{0}:R>)'.format( int(r.remind_at.replace(tzinfo=pytz.UTC).timestamp())))
def mute(self, event, user, reason=None): 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') 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) if event.config.confirm_actions: existed = u' [was temp-muted]' if existed else '' event.msg.reply( maybe_string( reason, u':ok_hand: {u} is now muted (`{o}`)' + existed, u':ok_hand: {u} is now muted' + existed, u=member.user, )) else: raise CommandFail('invalid user')
def manager_info(self, event, user, mode, item): user = self.state.users.get(user) if mode == 'add': special_list = rdb.hget('ServerManagers', '{}'.format(user.id)) temp_list = [] temp_list.append(item) final_list = str(temp_list).strip('[]') new = str('{}, {}'.format(special_list, final_list)) rdb.hset('ServerManagers', '{}'.format(user.id), new) raise CommandSuccess('{} has been added to the list of server managers'.format(user)) if mode == 'remove': special_list = rdb.hget('ServerManagers', '{}'.format(user.id)) if special_list == None: raise CommandFail('User is not a manager on any Airplane protected servers.') temp_list = special_list.split(', ') found = False for x in temp_list: if x == item: found = True temp_list.remove(item) if found == False: raise CommandFail('something went wrong, please try again later') else: new = str(temp_list).strip('[]') rdb.hset('ServerManagers', '{}'.format(user.id), new) raise CommandSuccess('The server has been removed from the list of servers the user manages.')
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 command_markov_many(self, event, entity, count=5): if entity.id not in self.models: raise CommandFail('No model created yet for {}'.format(entity)) for _ in range(int(count)): sentence = self.models[entity.id].make_sentence(max_overlap_total=500) if not sentence: raise CommandFail('Not enough data :(') event.msg.reply('{}: {}'.format(entity, sentence))
def command_markov_one(self, event, entity): if entity.id not in self.models: raise CommandFail('No model created yet for {}'.format(entity)) sentence = self.models[entity.id].make_sentence(max_overlap_ratio=1, max_overlap_total=500) if not sentence: raise CommandFail('Not enough data :(') event.msg.reply('{}: {}'.format(entity, sentence))
def unlock_role(self, event, role_id): if role_id not in event.config.locked_roles: raise CommandFail('role %s is not locked' % role_id) if role_id in self.unlocked_roles and self.unlocked_roles[role_id] > time.time(): raise CommandFail('role %s is already unlocked' % role_id) self.unlocked_roles[role_id] = time.time() + 300 raise CommandSuccess('role is unlocked for 5 minutes')
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 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()), )) 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, )) else: raise CommandFail('invalid user')
def leave_role(self, event, name): role_id = event.config.group_roles.get(name.lower()) if not role_id or role_id not in event.guild.roles: raise CommandFail('invalid or unknown group') member = event.guild.get_member(event.author) if role_id not in member.roles: raise CommandFail('you are not a member of that group') member.remove_role(role_id) raise CommandSuccess(u'you have left the {} group'.format(name))
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)] elif role.lower() in event.config.role_aliases: role_obj = event.guild.roles.get(event.config.role_aliases[role.lower()]) 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 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') victim_level = self.bot.plugins.get('CorePlugin').get_level(event.guild, victim_id) if event.user_level <= victim_level: if not throw: return False raise CommandFail('invalid permissions') return True
def xp_unblock(self, event, user): member = event.guild.get_member(user) if member: self.can_act_on(event, member.id) success = XPBlock.delete().where( (XPBlock.guild_id == event.guild.id) & (XPBlock.user_id == user.id)).execute() if not success: raise CommandFail('{} was not blocked from gaining XP'.format( user, )) else: raise CommandFail('Invalid user') raise CommandSuccess('Unblocked {} from gaining XP.'.format(member))
def kick(self, event, user, reason=None): member = event.guild.get_member(user) if member: self.can_act_on(event, member.id) if event.config.notify_action_on and event.config.notify_action_on.kicks: try: event.guild.get_member(user.id).user.open_dm( ).send_message( 'You have been **Kicked** from the guild **{}** for `{}`' .format(event.guild.name, reason or 'no reason')) except: pass else: pass Infraction.kick(self, event, member, reason) self.confirm_action( event, maybe_string( reason, u':ok_hand: kicked {u} (`{o}`)', u':ok_hand: kicked {u}', u=member.user, )) else: raise CommandFail('invalid user')
def on_tags_raw(self, event, name): tag = self.fetch_tag(name, event.guild.id) if not tag: raise CommandFail('no tag exists by that name') content = tag.content source = self.source_re.search(content) if source: source = source.group(1).lower() url = self.remote_url.format(source) r = requests.get(url) r = self.import_parser.search(r.content) r = r.group(1).decode('utf8').strip('`\n') if r else '' data = {'here': '@here', 'everyone': '@everyone'} r = self.replace_variables(r, data) if r and content == r: return event.msg.reply(( 'This tag was imported from `{source}`: <https://github.com/ThaTiemsz' '/RawgoatTags/blob/master/tags/{source}.md>').format( source=source)) content = self.source_re.sub('', content) Tag.update(content=content).where((Tag.name == tag.name) & ( Tag.guild_id == tag.guild_id)).execute() if len(S(content, False, True)) > 1990: return event.msg.reply( 'This tag is too long. See attached file for the source.', attachments=[('tag_raw_{}.txt'.format(event.msg.id), content)]) event.msg.reply(u'```\n{}\n```'.format(S(content, False, True)))
def ban(self, event, user, reason=None): member = None if isinstance(user, (int, long)): self.can_act_on(event, user) Infraction.ban(self, event, user, reason, guild=event.guild) else: member = event.guild.get_member(user) if member: self.can_act_on(event, member.id) if event.config.notify_action_on and event.config.notify_action_on.bans: try: event.guild.get_member(user.id).user.open_dm( ).send_message( 'You have been **Permanently Banned** from the guild **{}** for `{}`.' .format(event.guild.name, reason or 'no reason specified.')) except: pass else: pass Infraction.ban(self, event, member, reason, guild=event.guild) else: raise CommandFail('invalid user') self.confirm_action( event, maybe_string( reason, u':ok_hand: banned {u} (`{o}`)', u':ok_hand: banned {u}', u=member.user if member else user, ))
def softban(self, event, user, reason=None): """ Ban then unban a user from the server (with an optional reason for the modlog) """ member = event.guild.get_member(user) if member: self.can_act_on(event, member.id) if event.config.notify_action_on and event.config.notify_action_on.bans: try: event.guild.get_member(user.id).user.open_dm( ).send_message( 'You have been **Kicked** from the guild **{}** for `{}`.' .format(event.guild.name, reason or 'no reason specified.')) except: pass else: pass Infraction.softban(self, event, member, reason) self.confirm_action( event, maybe_string( reason, u':ok_hand: soft-banned {u} (`{o}`)', u':ok_hand: soft-banned {u}', u=member.user, )) else: raise CommandFail('invald user')
def search(self, event, query: str): queries = [] if query.isdigit(): queries.append((User.user_id == query)) q = USER_MENTION_RE.findall(query) if len(q) and q[0].isdigit(): queries.append((User.user_id == q[0])) else: queries.append( (User.username**'%{}%'.format(query.replace('%', '')))) if '#' in query: username, discrim = query.rsplit('#', 1) if discrim is not None: queries.append(((User.username == username) & (User.discriminator == discrim))) users = User.select().where(reduce(operator.or_, queries)).limit(10) if len(users) == 0: raise CommandFail('No users found for query `{}`'.format( S(query, escape_codeblocks=True))) if len(users) == 1: if users[0].user_id in self.state.users: return self.info(event, self.state.users.get(users[0].user_id)) raise CommandSuccess( 'Found the following users for your query: ```{}```'.format( '\n'.join([ '{} ({})'.format(str(i), i.user_id) for i in users[:25] ])))