예제 #1
0
파일: client.py 프로젝트: Ukabi/UkaBot
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)}')
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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))]
예제 #5
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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)
예제 #6
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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)
예제 #7
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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)
예제 #8
0
파일: cog.py 프로젝트: Ukabi/UkaBot
 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")
예제 #9
0
 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"
         )
예제 #10
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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()
예제 #11
0
    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"
            )
예제 #12
0
 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")
예제 #13
0
    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
예제 #14
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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)
예제 #15
0
    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"
            )
예제 #16
0
파일: cog.py 프로젝트: Ukabi/UkaBot
    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)
예제 #17
0
    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()