async def cog_unload(ctx: Context, *, cog_names: str): loaded_cog_names = {name.lower() for name in bot.cogs.keys()} cog_names = cog_names.lower().split() try: to_unload = set() for cog_name in cog_names: if cog_name in loaded_cog_names: to_unload.add(NAMES_COGS_MAP[cog_name]) elif cog_name not in NAMES_COGS_MAP.keys(): raise KeyError else: raise ValueError except KeyError: error = InvalidArguments(ctx=ctx, message=f"{cog_name} not found") await error.execute() except ValueError: error = InvalidArguments(ctx=ctx, message=f"{cog_name} not loaded") await error.execute() else: unload_cogs(bot, to_unload) loaded_cog_names = {name.lower() for name in bot.cogs.keys()} write(COG_PATH, [ cog_name for cog_name in loaded_cog_names if cog_name not in cog_names ]) await ctx.send(f'Successfully unloaded {", ".join(cog_names)}')
async def remove(self, ctx: Context, *, element: Union[EmojiType, RoleType]): guild = ctx.guild guild_config = self.config.guild(guild) guild_data = guild_config.get() combinations = guild_data.combinations try: if not combinations: raise InvalidArguments( ctx=ctx, title="Data Error", message="No data registered yet" ) try: element = await self.import_emoji(ctx, element) element = element.id if hasattr(element, "id") else element var = "emoji" except InvalidArguments: try: role = await self.import_role(ctx, element) element = role.id var = "role" except InvalidArguments: raise InvalidArguments( ctx=ctx, message="Reference not found" ) if element not in [c[var] for c in combinations]: raise InvalidArguments( ctx=ctx, message="Argument wasn't found in data" ) except InvalidArguments as error: await error.execute() else: for combination in combinations: if combination[var] == element: combinations.remove(combination) break guild_data.combinations = combinations try: await self._edit_rbr_message(ctx, guild_data) except InvalidArguments: pass guild_config.set(guild_data) emoji = await self.import_emoji(ctx, combination.emoji) role = guild.get_role(combination.role) embed = Embed( title="Combination Removed", description=f"{emoji} and {role} successfully unlinked" ) await ctx.send(embed=embed)
async def add(self, ctx: Context, emoji: EmojiType, *, role: RoleType): guild = ctx.guild guild_config = self.config.guild(guild) guild_data = guild_config.get() combinations = guild_data.combinations try: emoji = await self.import_emoji(ctx, emoji) if emoji in [c.emoji for c in combinations]: raise InvalidArguments( ctx=ctx, title="Role Error", message=f"Role {role} already used" ) role = await self.import_role(ctx, role) if role.id in [c.role for c in combinations]: raise InvalidArguments( ctx=ctx, title="Role Error", message=f"Role {role} already used" ) if not can_give_role(role, ctx.me): raise InvalidArguments( ctx=ctx, title="Role Error", message=f"Bot doesn't have enough rights to give role" ) except InvalidArguments as error: await error.execute() else: new = Combination( emoji=emoji.id if hasattr(emoji, "id") else emoji, role=role.id ) combinations.append(new) guild_data.combinations = combinations try: await self._edit_rbr_message(ctx, guild_data) except InvalidArguments: pass guild_config.set(guild_data) embed = Embed( title="Combination Added", description=f"{emoji} successfully linked with {role}" ) await ctx.send(embed=embed)
async def remove(self, ctx: Context, title: str, time: str = None): guild = ctx.guild guild_config = self.config.guild(guild) guild_data = guild_config.get() matches = [ e for e in guild_data.events if e.title.lower() == title.lower() ] try: if not matches: raise InvalidArguments( ctx=ctx, title="Title Error", message="Couldn't find event with provided name") elif len(matches) > 1: if time: matches = [ e for e in matches if e.datetime() == EventData.convert(time) ] if not matches: raise InvalidArguments( ctx=ctx, title="Date Error", message="Couldn't find event with provided date") else: raise InvalidArguments( ctx=ctx, title="Date Error", message= "There are multiple events with same name, please provide a date" ) except InvalidArguments as error: await error.execute() else: match = matches[0] guild_data.events.remove(match) guild_config.set(guild_data) def convert(p: int): ret = guild.get_member(p) if not ret: ret = guild.get_role(p) return ret participants = [c for p in match.participants if (c := convert(p))]
async def remove(self, ctx: Context, emoji: EmojiTypes): try: emoji = await EmojiConverter().convert(ctx, emoji) except BadArgument: error = InvalidArguments( ctx=ctx, title='Emoji Error', message="Provided emoji could not be found" ) await error.execute() else: emoji_parse = str(emoji) if emoji.available else emoji.name answer = await ask_confirmation( ctx=ctx, bot=self.bot, message=( f"Affected emoji: {emoji_parse}\n" "Answer with y/n to confirm removal" ) ) if answer: await emoji.delete() embed = Embed( title="Emoji Removed", description=f"Successfully removed {emoji_parse} from server" ) else: embed = Embed( title="Cancelled" ) await ctx.send(embed= embed)
async def channel(self, ctx: Context, channel: Union[TextChannel, str, int]): try: if not isinstance(channel, TextChannel): channel = await TextChannelConverter().convert( ctx, str(channel)) except BadArgument: error = InvalidArguments( ctx=ctx, title='Channel Error', message='Channel not found or not provided') await error.execute() return else: guild_config = self.config.guild(ctx.guild) guild_data = guild_config.get() guild_data.channel = channel.id guild_config.set(guild_data) embed = Embed( title='Channel Changed', description=f'Successfully updated channel to {channel.mention}' ) await ctx.send(embed=embed)
async def _set_birthday(self, ctx: Context, member: Member, day: int, month: int): try: date = Date.convert_date(day=day, month=month) except ValueError: error = InvalidArguments( ctx=ctx, title="Date Error", message="Couldn't understand provided date") await error.execute() else: member_config = self.config.member(member) member_data = MemberData(birthday=date, name=member.name) member_config.set(member_data) if ctx.author == member: desc = f"Birthday set to {date}" else: desc = f"Birthday of {member} has been set to {date}" embed = Embed(title="Birthday Set", description=desc) await ctx.send(embed=embed)
async def forceset(self, ctx: Context, member_id: int, day: int, month: int): try: member = ctx.guild.get_member(int(member_id)) if member: await self._set_birthday(ctx, member, day, month) else: raise InvalidArguments(ctx=ctx, title="Member Error", message="Couldn't find provided member") except InvalidArguments as error: await error.execute() except TypeError: error = InvalidArguments( ctx=ctx, title="Argument Error", message="Provided member id couldn't be parsed")
async def import_role(ctx: Context, role: RoleType) -> Role: try: return await RoleConverter().convert(ctx, str(role)) except BadArgument: raise InvalidArguments( ctx=ctx, title="Role Error", message=f"Couldn't load {role} role" )
async def create(self, ctx: Context, *, args: str): try: args = [arg.strip() for arg in args.split(sep=SEP)] question = args.pop(0) if len(args) in range(1, 10): guild = ctx.guild # Dict[int, GuildData] guild_data = self.config.guild(guild).get() answers_list = [ f'{FIGURES[n+1]}: {p}' for n, p in enumerate(args) ] answers = "\n\n".join(answers_list) channel = guild.get_channel(guild_data.channel) if channel: embed = Embed(title=question, description=answers) message = await channel.send(embed=embed) for n in range(1, len(answers_list) + 1): await message.add_reaction(FIGURES[n]) embed = Embed( title='Poll sent', description= f'Poll successfully sent to {channel.mention}') await ctx.send(embed=embed) else: raise InvalidArguments( ctx=ctx, title='Channel Error', message='Channel not found or not provided') else: raise InvalidArguments( ctx=ctx, message=("Arguments couldn't be parsed" + "\n" "Check separator or answer count (9 max)")) except InvalidArguments as error: await error.execute()
async def _find_rbr_message(guild: Guild, guild_data: GuildData, ctx: Context=None) -> Message: channel_id = guild_data.channel message_id = guild_data.message channel = guild.get_channel(channel_id) if channel: try: return await channel.fetch_message(message_id) except NotFound: raise InvalidArguments( ctx=ctx, title="Message Not Found", message="Message doesn't exist or not provided" ) else: raise InvalidArguments( ctx=ctx, title="Channel Not Found", message="Channel doesn't exist or not provided" )
async def convert(p: Union[int, str, Member, Role]): try: return await RoleConverter().convert(ctx, str(p)) except BadArgument: try: return await MemberConverter().convert(ctx, str(p)) except BadArgument: raise InvalidArguments( ctx=ctx, title="Participant Error", message="Couldn't find provided participants")
async def import_emoji(ctx: Context, emoji: EmojiType) -> Union[str, Emoji]: emoji = str(emoji) try: emoji = await EmojiConverter().convert(ctx, emoji) except BadArgument: temp = demojize(emoji) if any([emoji == temp, # Not an emoji temp.count(":") != 2, # More or less than an emoji not temp.startswith(":"), # More than an emoji not temp.endswith(":")]): # More than an emoji raise InvalidArguments( ctx=ctx, title="Emoji Error", message=f"Couldn't load {emoji} emoji" ) return emoji
async def role(self, ctx: Context, *, role: Union[int, str, Role]): try: if not isinstance(role, Role): role = await RoleConverter().convert(ctx, str(role)) except BadArgument: error = InvalidArguments(ctx=ctx, title='Role Error', message='Role not found or not provided') await error.execute() else: guild_config = self.config.guild(ctx.guild) guild_data = guild_config.get() guild_data.role = role.id guild_config.set(guild_data) embed = Embed( title='Role Changed', description=f'Successfully updated role to {role.mention}') await ctx.send(embed=embed)
async def _edit_rbr_message(cls, ctx: Context, guild_data: GuildData) -> Message: guild = ctx.guild channel_id = guild_data.channel message_id = guild_data.message combinations = guild_data.combinations message = await cls._find_rbr_message(guild, guild_data, ctx) if message.author.id == ctx.me.id: embed = cls._rbr_message_content(guild, guild_data) await message.edit(embed=embed) await cls._add_reactions( ctx=ctx, message=message, emojis=[c.emoji for c in combinations] ) return message else: raise InvalidArguments( ctx=ctx, title="Message Error", description="Linked message isn't from bot" )
async def add(self, ctx: Context, file_path: str, name: str, *roles: RoleTypes): try: roles = [await RoleConverter().convert(ctx, str(role)) for role in roles] except BadArgument: error = InvalidArguments( ctx=ctx, title='Role Error', message="Provided roles could not be found" ) await error.execute() else: if file_path.startswith("http"): req = rq.get(file_path) if req.ok: byte_data = bytearray(req.content) file = io.BytesIO(bytes(req.content)) else: error = InvalidArguments( ctx=ctx, title='Loading Error', message="Couldn't retrieve picture from privided link" ) await error.execute() else: try: with open(f'{PATH}/{file_path}', 'rb') as image: raw_data = image.read() except FileNotFoundError: error = InvalidArguments( ctx=ctx, title='Loading Error', message="Couldn't retrieve picture from privided path" ) await error.execute() else: byte_data = bytearray((raw_data)) file = io.BytesIO(bytes(byte_data)) answer = await ask_confirmation( ctx=ctx, bot=self.bot, file=File(file, filename="emoji_template.png"), message=( "Waiting for confirmation\n" "Reply with y/n" ) ) if answer: emoji = await ctx.guild.create_custom_emoji( name=name, image=byte_data, roles=roles ) affected_roles = ", ".join([str(role) for role in roles]) if roles else "everyone" embed = Embed( title=f"Successfully created {emoji} emoji", description=f"Affected roles: {affected_roles}" ) else: embed = Embed( title="Cancelled" ) await ctx.send(embed=embed)
async def add(self, ctx: Context, channel: Union[int, str, TextChannel], time: str, title: str, *participants: Union[int, str, Member, Role]): guild = ctx.guild try: # parsing title title = title[:200] # parsing date date = EventData.timestamp(time) # parsing participants (Member(s) or Role(s)) async def convert(p: Union[int, str, Member, Role]): try: return await RoleConverter().convert(ctx, str(p)) except BadArgument: try: return await MemberConverter().convert(ctx, str(p)) except BadArgument: raise InvalidArguments( ctx=ctx, title="Participant Error", message="Couldn't find provided participants") participants = [await convert(p) for p in participants] # parsing channel try: channel = await TextChannelConverter().convert( ctx, str(channel)) channel_id = channel.id except BadArgument: try: # keeping 0 value as a no-announcement-channel criterium channel_id = int(channel) if channel_id: raise ValueError except ValueError: raise InvalidArguments( ctx=ctx, title="Channel Error", message="Couldn't find provided channel") guild_config = self.config.guild(guild) guild_data = guild_config.get() # checking if same event already exists events = ImprovedList(guild_data.events) try: events.index((title.lower(), date), key=lambda e: (e.title.lower(), e.date)) raise InvalidArguments( ctx=ctx, title="Name Error", message="There is another event on same date with same name" ) except ValueError: pass # appending event event = EventData(channel=channel_id, date=date, participants=[p.id for p in participants], title=title) guild_data.events.append(event) guild_config.set(guild_data) # starting event scheduler await self.add_events(guild, event) embed = Embed( title="Event added", description= (f"Title: {title}" + "\n" f"Date: {event.datetime()}" + "\n" f"Participants: {' '.join(map(lambda p: p.mention, participants))}" )) await ctx.send(embed=embed) except InvalidArguments as error: await error.execute()