async def showcase(self, ctx): """ [MOD ONLY] Publicly announce the currently selected application in the Spotlight channel, and switch the Spotlight Host role to the application's owner (if valid). """ # Retrieve and showcase the app logger.debug("showcase: {}".format(message_log_str(ctx.message))) self._load_applications() try: current_app = await self._get_current() except IndexError: return # get_current() already handles this try: role = get_named_role(ctx.message.server, self.role_audience_name) except ValueError: logger.exception("Can't retrieve Spotlight Audience role") role = None await self.bot.send_message(self.channel_spotlight, "**WORLD SPOTLIGHT** {2}\n\n" "Our next host is {0}, presenting their project, *{1}*!\n\n" "Welcome, {0}!".format( current_app.user_disp, current_app.project, role.mention if role else "" ) ) await self.send_spotlight_info(self.channel_spotlight, current_app) await self.bot.say("Application showcased: {} ({}) - {}" .format(current_app.user_disp, current_app.user_name_only, current_app.project) ) await self.send_validation_warnings(ctx, current_app) # Deassign the spotlight host role server = ctx.message.server # type: discord.Server host_role = get_named_role(server, self.role_host_name) await remove_role_from_all(self.bot, server, host_role) # Assign the role to the selected app's owner try: user = get_member(ctx, current_app.user_id) except discord.InvalidArgument: logger.warning("Invalid discord ID in application: '{}'".format(current_app.user_id)) await self.bot.say(("Can't set new Spotlight Host role: Application Discord ID " "'{0.user_id}' is invalid or user not on server") .format(current_app)) else: await self.bot.add_roles(user, host_role) await self.bot.say("'{}' role switched to {.mention}." .format(self.role_host_name, user))
async def on_ready(self): await super().on_ready() self.check_in_channel = self.get_channel(self.check_in_channel_id) self.checkin_anytime_roles = tuple( get_named_role(self.server, n) for n in self.cog_config.check_in_window_exempt_roles) milestone_map = {} for pt, ms_map in self.cog_config.milestone_map.items(): milestone_map[model.ProjectType[pt]] = { get_named_role(self.server, r): v for r, v in ms_map.items() } self.c = CheckInController(self.server, self.cog_config, milestone_map) await self.schedule_checkin_announcements()
def _process_checks(data: dict, command: commands.Command, bot: commands.Bot): roles = [] channels = [] new_brief = '' for check in command.checks: # get check data try: check_type = check.kaz_check_id except AttributeError: continue try: check_data = check.kaz_check_data except AttributeError: check_data = [] # process check_type if check_type is CheckId.U_ROLE or check_type is CheckId.U_ROLE_OR_MODS: for role_name in check_data: for server in bot.servers: try: role = get_named_role(server, role_name) roles.append(role.name) break except ValueError: continue else: roles.append(role_name + ' (not found)') if check_type is CheckId.U_ROLE_OR_MODS: roles.append('Moderators') roles.append('Administrators') elif check_type is CheckId.U_MOD: roles = ['Moderators', 'Administrators'] new_brief = '[MOD ONLY] ' + data['brief'] elif check_type is CheckId.U_ADMIN: roles = ['Administrators'] new_brief = '[ADMIN ONLY] ' + data['brief'] elif check_type is CheckId.C_LIST: for ch_id in check_data: ch = bot.get_channel(ch_id) # type: discord.Channel if ch is not None: channels.append('#' + ch.name) break else: channels.append(ch_id + ' (not found)') elif check_type is CheckId.C_MOD: channels = ['Mod channels'] new_brief = '[MOD ONLY] ' + data['brief'] elif check_type is CheckId.C_ADMIN: channels = ['Admin channels'] new_brief = '[ADMIN ONLY] ' + data['brief'] elif check_type is CheckId.C_PM_ONLY: channels = ['PM only'] new_brief = '[PM ONLY]' + data['brief'] if roles: data['users'] = ', '.join(roles) + '. ' + data['users'] if channels: data['channels'] = ', '.join(channels) + '. ' + data['channels'] if new_brief: data['brief'] = new_brief
async def down(self, ctx): """ [MOD ONLY] Uncolours a moderator's username. This command undoes the `.up` command. Arguments: None """ logger.debug("down: {}".format(message_log_str(ctx.message))) for status_role_name, distinguish_role_name in self.distinguish_map.items( ): status_role = discord.utils.get(ctx.message.server.roles, name=status_role_name) if status_role and status_role in ctx.message.author.roles: distinguish_role = get_named_role(ctx.message.server, distinguish_role_name) await self.bot.remove_roles(ctx.message.author, distinguish_role) await self.bot.delete_message(ctx.message) logger.info("down: Took away from {} the {} role".format( ctx.message.author, distinguish_role_name)) break else: err_msg = "down: user's roles not recognised: {}".format( message_log_str(ctx.message)) logger.warning(err_msg) await self.bot.say( "That command is only available to mods and admins.") await self.send_output("[WARNING] " + err_msg)
async def up(self, ctx): """ [MOD ONLY] Colours a moderator's username. This command colours the moderator's username by applying a special role to it. This is used for moderators to be able to signal when they are speaking or intervening officially in their role as moderator. Arguments: None """ logger.debug("up: {}".format(message_log_str(ctx.message))) for status_role_name, distinguish_role_name in self.distinguish_map.items( ): status_role = discord.utils.get(ctx.message.server.roles, name=status_role_name) if status_role and status_role in ctx.message.author.roles: distinguish_role = get_named_role(ctx.message.server, distinguish_role_name) await self.bot.add_roles(ctx.message.author, distinguish_role) await self.bot.delete_message(ctx.message) logger.info("up: Gave {} the {} role".format( ctx.message.author, distinguish_role_name)) break else: err_msg = "up: user's roles not recognised: {}".format( message_log_str(ctx.message)) logger.warning(err_msg) await self.bot.say( "That command is only available to mods and admins.") await self.send_output("[WARNING] " + err_msg)
def __init__(self, bot): super().__init__(bot, 'modnotes', BanToolsConfig) self.cog_config.set_defaults( ban_check_interval=3600, ban_temp_expires='in 7 days', ban_temp_enforce=False, ban_perma_enforce=False ) self.cog_config.set_converters('ban_check_interval', lambda s: timedelta(seconds=s), None) self.cog_config.set_converters('ban_role', lambda r: get_named_role(self.server, r), None) self.cog_config.set_converters('channel_mod', self.get_channel, None) self.cog_modnotes: ModNotes = None self.modnotes_patch_applied = False
async def do_join(self, ctx: commands.Context): logger.debug("join({}): {}".format(self.name, message_log_str(ctx.message)[:256])) role = get_named_role(ctx.message.server, self.name) if role not in ctx.message.author.roles: await self.bot.add_roles(ctx.message.author, role) logger.info("join: Gave role {} to user {}".format( self.name, ctx.message.author)) await self.bot.send_message(self.reply_dest(ctx), self.join_message(ctx)) else: await self.bot.send_message(self.reply_dest(ctx), self.join_error(ctx)) await self.delete_message(ctx)
async def do_leave(self, ctx: commands.Context): logger.debug("leave({}): {}".format(self.name, message_log_str( ctx.message)[:256])) role = get_named_role(ctx.message.server, self.name) if role in ctx.message.author.roles: await self.bot.remove_roles(ctx.message.author, role) logger.info("leave: Removed role {} from user {}".format( self.name, ctx.message.author)) await self.bot.send_message(self.reply_dest(ctx), self.leave_message(ctx)) else: await self.bot.send_message(self.reply_dest(ctx), self.leave_error(ctx)) await self.delete_message(ctx)
async def leave(self, ctx): """ Leave the Spotlight Audience. See `.help spotlight join` for more information. To join the Spotlight Audience, use `.spotlight join`. """ logger.debug("leave: " + message_log_str(ctx.message)[:64]) role = get_named_role(ctx.message.server, self.role_audience_name) if role in ctx.message.author.roles: await self.bot.remove_roles(ctx.message.author, role) logger.info("leave: Removed role {} from user {}" .format(self.role_audience_name, ctx.message.author)) await self.bot.send_message(ctx.message.author, self.msg_leave) else: await self.bot.send_message(ctx.message.author, self.msg_leave_err) await self.bot.delete_message(ctx.message)
async def join(self, ctx): """ Join the Spotlight Audience. This allows you to be pinged by moderators or the Spotlight Host for news about the spotlight (like the start of a new spotlight, or a newly released schedule). To leave the Spotlight Audience, use `.spotlight leave`. """ logger.debug("join: " + message_log_str(ctx.message)[:64]) role = get_named_role(ctx.message.server, self.role_audience_name) if role not in ctx.message.author.roles: await self.bot.add_roles(ctx.message.author, role) logger.info("join: Gave role {} to user {}" .format(self.role_audience_name, ctx.message.author)) await self.bot.send_message(ctx.message.author, self.msg_join) else: await self.bot.send_message(ctx.message.author, self.msg_join_err) await self.bot.delete_message(ctx.message)
def get_role(server: discord.Server, role_arg: str) -> discord.Role: """ Get a role from a passed command parameter (name, mention or ID). :return: """ try: role_id = extract_role_id(role_arg) except discord.InvalidArgument: # no ID, treat as a role name try: role = get_named_role(server, role_arg) # type: discord.Role except discord.InvalidArgument: logger.warning("Cannot find role {!r} as name or ID".format(role_arg)) role = None else: logger.debug("Found role ID in {!r}".format(role_arg)) role = discord.utils.get(server.roles, id=role_id) # type: discord.Role if role is None: raise commands.BadArgument('No such role: {}'.format(role)) return role
async def on_voice_state_update(self, before: discord.Member, after: discord.Member): """ Assigns "in voice" role to members who join voice channels. """ if not self.voice_feature: return # get the role role_voice = get_named_role(before.server, self.role_voice_name) if role_voice is None: err_msg = "Cannot find voice role: {}" .format(self.role_voice_name) logger.warning(err_msg) await self.bot.send_message(self.dest_output, "[WARNING] " + err_msg) return # determine the action to take if after.voice_channel and after.voice_channel.id in self.voice_channel_ids: await self.bot.add_roles(after, role_voice) logger.info("Gave '{}' role to {}".format(self.role_voice_name, after)) else: await self.bot.remove_roles(after, role_voice) logger.info("Took '{}' role from {}".format(self.role_voice_name, after))
async def update_tempbans(self): """ Check and update all current tempbans in modnotes. Unexpired tempbans will be applied and expired tempbans will be removed, when needed. """ logger.info("Checking all tempbans.") try: server = self.bot.get_channel( self.ch_mod.id).server # type: discord.Server except AttributeError: # get_channel failed logger.error("Can't find mod channel") await self.send_output( "**ERROR**: update_tempbans: can't find mod channel") return tempban_role = get_named_role(server, self.role_name) bans_db = self._get_tempbanned_members_db(server) bans_server = self._get_tempbanned_members_server(server) # check if any members who need to be banned for member in bans_db: if member not in bans_server: logger.info( "Applying tempban role '{role}' to {user!s}...".format( role=tempban_role.name, user=member)) await self.bot.add_roles(member, tempban_role) await self.bot.send_message( self.ch_mod, "Tempbanned {.mention}".format(member)) # check if any members who need to be unbanned for member in bans_server: if member not in bans_db: logger.info( "Removing tempban role '{role}' to {user!s}...".format( role=tempban_role.name, user=member)) await self.bot.remove_roles(member, tempban_role) await self.bot.send_message( self.ch_mod, "Unbanned {.mention}".format(member))
def _get_tempbanned_members_server( self, server: discord.Server) -> List[discord.Member]: tempban_role = get_named_role(server, self.role_name) return [m for m in server.members if tempban_role in m.roles]