Beispiel #1
0
    async def update_options(self, updated_fields=None):
        logger.info(f"Updating command fields: {updated_fields}")
        await self.role_processor.update_choices(updated_fields)
        await self.group_processor.update_choices(updated_fields)

        if db_utils.is_updated(updated_fields, "group"):
            group_choices = self.group_processor.choices
            group_commands = [self.group_info, self.group_delete, self.role_snapshot_all]
            for command in group_commands:
                command.options[0]["choices"] = group_choices
            self.role_snapshot_role.options[1]["choices"] = group_choices

            if self._sider_group is None:
                self._sider_group = await RoleGroup.get_or_none(name="Sider")

        if db_utils.is_updated(updated_fields, "role"):
            crews = [await Role.get_or_none(name=role) for role in
                     (utils.stream_crew_role, utils.update_crew_role, utils.bot_crew_role)]
            crews = [create_choice(name=role.name, value=role.id) for role in crews if role is not None]
            self.crew_join.options[0]["choices"] = crews
            self.crew_leave.options[0]["choices"] = crews
            self.has_crews = bool(crews)

            if self._sider_group is not None:
                sider_choices = [create_choice(name=role.name, value=role.id)
                                 for role in await Role.filter(group=self._sider_group)][:24]
                sider_choices.insert(0, create_choice(name="Noside", value=-1))
                self.side_join.options[0]["choices"] = sider_choices

        await self.bot.slash.sync_all_commands()
Beispiel #2
0
class Help(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    # ---       SLASH COMMANDS       --- #
    @cog_ext.cog_slash(name='help',
                       description='Detailed list of bot commands!',
                       guild_ids=guild_ids,
                       options=[
                           create_option(name='module',
                                         description='Choose category!',
                                         required=True,
                                         option_type=3,
                                         choices=[
                                             create_choice(
                                                 name='Administration',
                                                 value='admin'),
                                             create_choice(name='Info',
                                                           value='info'),
                                             create_choice(name='Market',
                                                           value='market')
                                         ])
                       ])
    async def _help(self, ctx: SlashContext, module: str):
        if module == 'admin':
            embed = discord.Embed(title='Administration',
                                  description=' ',
                                  colour=discord.Colour.blurple())
            embed.set_author(name='Commands List', icon_url=BOT_AVATAR)
            embed.add_field(name=';prune __Amount__',
                            value='Removes the amount of messages specified',
                            inline=False)
            embed.add_field(name=';mute __@user / user ID__',
                            value='Mutes the specified user',
                            inline=False)
            embed.add_field(name=';unmute __@user / user ID__',
                            value='Unmutes the specified user',
                            inline=False)
            embed.set_footer(
                text='User IDs can be found by turning on "Developer Mode"')
        elif module == 'info':
            embed = discord.Embed(title='Info',
                                  description=' ',
                                  colour=discord.Colour.blurple())
            embed.set_author(name='Commands List', icon_url=BOT_AVATAR)
            embed.add_field(name=';ping', value='pong!', inline=False)
        elif module == 'market':
            embed = discord.Embed(title='Market',
                                  description=' ',
                                  colour=discord.Colour.blurple())
            embed.set_author(name='Commands List', icon_url=BOT_AVATAR)
            embed.add_field(name=';coin __1-100__ or ;coin __name__',
                            value='Displays Name / Current Price',
                            inline=False)
            embed.add_field(name=';top __1-100__',
                            value='Displays the top # coins',
                            inline=False)
        await ctx.send(embeds=[embed])
Beispiel #3
0
    def update_options(self):
        choices = [
            create_choice(name=check.capitalize(), value=check)
            for check in self.checks.keys()
        ]
        choices = [create_choice(name="All", value="all")] + choices + \
                  [create_choice(name="None (stats and info only)", value="none")]

        self.check_member.options[1]["choices"] = choices
        self.check_server.options[0]["choices"] = choices
Beispiel #4
0
    async def starboard_autocomplete(self, ctx: AutoCompleteContext):
        if ctx.name != "starboard":
            return

        guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
        starboard_data = guild_data.starboard
        if not starboard_data:
            return
        if starboard_data.blacklist is None:
            return

        if ctx.focused_option == "channel":
            channel_ids = starboard_data.blacklist.get("channels")
            if not channel_ids:
                return
            channels: List[TextChannel] = [
                ctx.guild.get_channel(channel_id) for channel_id in channel_ids
            ]
            choices = [
                create_choice(name=channel.name, value=str(channel.id))
                for channel in channels
                if channel.name.startswith(ctx.user_input)
            ][:25]
        elif ctx.focused_option == "member":
            member_ids = starboard_data.blacklist.get("members")
            if not member_ids:
                return
            members: List[Member] = [
                ctx.guild.get_member(member_id) for member_id in member_ids
            ]
            choices = [
                create_choice(name=member.display_name, value=str(member.id))
                for member in members
                if member.display_name.startswith(ctx.user_input)
            ][:25]
        elif ctx.focused_option == "role":
            role_ids = starboard_data.blacklist.get("roles")
            if not role_ids:
                return
            roles: List[Role] = [
                ctx.guild.get_role(role_id) for role_id in role_ids
            ]
            choices = [
                create_choice(name=role.name, value=str(role.id))
                for role in roles if role.name.startswith(ctx.user_input)
            ][:25]

        await ctx.populate(choices)
Beispiel #5
0
    async def playlist_autocomplete(self, ctx: AutoCompleteContext):
        choices = None
        if ctx.name not in ["music", "global"]:
            return

        guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
        global_data = await self.bot.mongo.get_global_data()

        if ctx.focused_option == "playlist":
            user_guild_data = await guild_data.get_user(ctx.author_id)
            user_global_data = await global_data.get_user(ctx.author_id)
            all_playlists = user_guild_data.music_playlists | user_global_data.music_playlists

            playlists = [
                playlist for playlist in all_playlists
                if playlist.startswith(ctx.user_input)
            ]

            choices = [
                create_choice(name=playlist, value=playlist)
                for playlist in playlists
            ]
        elif ctx.focused_option == "name":
            user_guild_data = await guild_data.get_user(ctx.author_id)
            user_global_data = await global_data.get_user(ctx.author_id)
            if not user_guild_data.music_playlists and not user_global_data.music_playlists:
                return

            input_playlist = ctx.options["playlist"]
            all_playlists = user_guild_data.music_playlists | user_global_data.music_playlists
            tracks_list = all_playlists.get(input_playlist)
            choices = [
                create_choice(name=track, value=track) for track in tracks_list
                if track.startswith(ctx.user_input)
            ]
        elif ctx.focused_option == "member_playlist":
            member_data = await guild_data.get_user(int(ctx.options["member"]))

            playlists = [
                playlist for playlist in member_data.music_playlists
                if playlist.startswith(ctx.user_input)
            ]
            choices = [
                create_choice(name=playlist, value=playlist)
                for playlist in playlists
            ]
        if choices:
            await ctx.populate(choices)
Beispiel #6
0
def get_programme_choices():
    return list(
        create_choice(
            name=f'{programmes[programme_id].uni_name} {programmes[programme_id].display_name}',
            value=programme_id
        ) for programme_id in programmes
    )
Beispiel #7
0
    async def load_emotes(self):
        files = multi_glob(*(abs_join("emotes", f"*{ext}")
                             for ext in image_exts))

        self.emotes = {
            os.path.splitext(os.path.split(filename)[1])[0].replace(
                "_", " ").strip().lower(): filename
            for filename in files
        }

        self.emote_pick.options[0]["choices"] = [
            create_choice(name=key, value=key) for key in self.emotes.keys()
        ][:25]

        if self.emotes:
            self.generate_thumbnail_image()
            self.has_thumbnail = True
        else:
            if os.path.exists(self.emotes_thumbnail):
                os.remove(self.emotes_thumbnail)
            self.has_thumbnail = False

        logger.debug(f"Loaded emotes: {self.emotes}")
        if not self._first_ready:
            await self.bot.slash.sync_all_commands()
Beispiel #8
0
async def loadplugin(ctx, plugin: str):
    '''Allows you to add any number of available plugins to the current instance of bot'''
    potentialplugins = getPluginList()
    loaded = []
    alreadyLoaded = []
    notLoaded = []
    if plugin in potentialplugins:
        if plugin not in loadConfig(['plugins'])[0]:
            await ctx.send('Loading **{}**. Please have patience, this may take a while...'.format(plugin))
            config['plugins'].append(plugin) #probably should make a setter for this
            bot.load_extension('plugins.{}'.format(plugin))
            print('\tLoaded extension: {}'.format(plugin))
            loadedPlugins.append(create_choice(plugin, plugin))
            for i in range(len(unloadedPlugins)):
                if unloadedPlugins[i]['value'] == plugin:
                    unloadedPlugins.pop(i)
                    break
            loaded.append(plugin)
        else:
            alreadyLoaded.append(plugin)
    else:
        notLoaded.append(plugin)
    await savestate(ctx, True)
    returnString = ''
    if len(loaded) > 0:
        returnString += '**Loaded:** ' + ', '.join(loaded) + '\n'
    if len(alreadyLoaded) > 0:
        returnString += '**Not Loaded (already loaded):** ' + ', '.join(alreadyLoaded) + '\n'
    if len(notLoaded) > 0:
        returnString += '**Not Loaded (plugin does not exist):** ' + ', '.join(notLoaded) + '\n'
    await ctx.send(returnString)
    await refreshPlugins()
Beispiel #9
0
async def unloadplugin(ctx, plugin: str):
    '''Allows you to remove any number of available plugins to the current instance of bot'''
    potentialplugins = getPluginList()
    unloaded = []
    alreadyUnloaded = []
    notUnloaded = []
    if plugin in potentialplugins:
        if plugin in loadConfig(['plugins'])[0]:
            config['plugins'].remove(plugin) #this is terrible and naive
            bot.unload_extension('plugins.{}'.format(plugin))
            print('\tUnloaded extension: {}'.format(plugin))
            unloadedPlugins.append(create_choice(plugin, plugin))
            for i in range(len(loadedPlugins)):
                if loadedPlugins[i]['value'] == plugin:
                    loadedPlugins.pop(i)
                    break
            unloaded.append(plugin)
        else:
            alreadyUnloaded.append(plugin)
    else:
        notUnloaded.append(plugin)
    await savestate(ctx, True)
    returnString = ''
    if len(unloaded) > 0:
        returnString += '**Unloaded:** ' + ', '.join(unloaded) + '\n'
    if len(alreadyUnloaded) > 0:
        returnString += '**Not Unloaded (already unloaded):** ' + ', '.join(alreadyUnloaded) + '\n'
    if len(notUnloaded) > 0:
        returnString += '**Not Unloaded (plugin does not exist):** ' + ', '.join(notUnloaded) + '\n'

    await ctx.send(returnString)
    await refreshPlugins()
class DeleteRankCommand(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @slash(
        name='deleterank',
        description=
        'Delete your ranking number and the corresponding offer date (if it exists) from the bot',
        options=[
            create_option(name='programme',
                          description='Study programme',
                          option_type=command_option_type.STRING,
                          required=True,
                          choices=programmes_helper.get_programme_choices() +
                          [create_choice(name='All programmes', value='all')]),
            create_option(name='year',
                          description='Year of application',
                          option_type=command_option_type.INTEGER,
                          required=True,
                          choices=programmes_helper.get_year_choices())
        ])
    async def deleterank(self, ctx: SlashContext, programme: str, year: int):
        user = ctx.author

        if programme == 'all':
            programme = None

        async with (await self.bot.get_db_conn()).acquire() as connection:
            ranks = ranks_service.RanksService(connection)

            await ranks.delete_rank(str(user.id), programme, year)

        await ctx.send(user.mention + ' Rank deleted.')
Beispiel #11
0
    async def add_commands(self, slash: SlashCommand):
        base_command = self.configuration.get("command_prefix",
                                              "") + "randovania-faq"

        for game in enum_lib.iterate_enum(RandovaniaGame):
            faq_entries = list(game.data.faq)
            if not faq_entries:
                continue

            def _shorten(n: str) -> str:
                if len(n) > 100:
                    return n[:97] + "..."
                return n

            slash.add_subcommand(
                functools.partial(self.faq_game_command, game=game),
                base_command,
                name=game.value,
                description=f"Prints the answer to a FAQ for {game.long_name}.",
                options=[
                    manage_commands.create_option(
                        "question",
                        "Which question to answer?",
                        option_type=SlashCommandOptionType.STRING,
                        required=True,
                        choices=[
                            manage_commands.create_choice(
                                f"question_{question_id}", _shorten(question))
                            for question_id, (question,
                                              answer) in enumerate(faq_entries)
                        ])
                ],
            )
Beispiel #12
0
async def register_my_tickets_command(bot, cmd) -> None:
    """Dirty hack to register options on fly for my_tickets command"""
    lotteries = await Lottery.all().order_by("-created_at").limit(10)
    try:
        # force sync_commands to detect new changes and sync slash commands with Discord
        del bot.slash.subcommands["sweepstake"]["tickets"]
    except KeyError:
        pass
    bot.slash.add_subcommand(
        cmd=cmd,
        base="sweepstake",
        name="tickets",
        description="My tickets",
        guild_ids=config.GUILD_IDS,
        options=[
            create_option(
                name="name",
                description="choose sweepstake",
                option_type=3,
                required=True,
                choices=[create_choice(name=_.name, value=_.name) for _ in lotteries],
            )
        ],
    )
    return None
Beispiel #13
0
class SlashCourse(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @cog_ext.cog_slash(
        name="course",
        description="Displays information about a course.",
        options=[
            create_option(
                name="course",
                description="The course code.",
                option_type=3,
                required=True,
            ),
            create_option(
                name="school",
                description="The school the course is at.",
                option_type=3,
                required=False,
                choices=[
                    create_choice(name="Queens University", value="queens"),
                    create_choice(name="University of Waterloo",
                                  value="waterloo"),
                    create_choice(name="University of Toronto", value="uoft"),
                ],
            ),
        ],
    )
    async def _course(self, ctx, course, school=None):
        """/course"""
        if " " in course:
            course = course.split(" ")
            course = f"{course[0].upper()}-{course[1]}"
        else:
            final = ""
            if "-" not in course:
                dash = False
                for i in course:
                    if i.isnumeric() and not dash:
                        final += "-" + i.upper()
                        dash = True
                    else:
                        final += i.upper()

                course = final

        await call_course(ctx, self.bot, course, school)
Beispiel #14
0
    def get_choices(self):
        choices = []

        for i in range(len(self._games)):
            choices.append(
                create_choice(
                    name=self._games[i]["name"],
                    value=self._games[i]["name"],
                ))

        if len(self._games) < 1:
            choices.append(create_choice(
                name="Inválido",
                value="Invalid",
            ))

        return choices
Beispiel #15
0
class ListPermissions(commands.Cog):
    """List Permissions for a specified user/role"""
    def __init__(self, bot):
        self.bot = bot

        self.emoji = bot.emoji_list

        self.paginator = pagination.LinePaginator(prefix="", suffix="")

    @cog_ext.cog_subcommand(
        base="permissions",
        name="get",
        description="Get the permissions of a role or user",
        base_default_permission=True,
        options=[
            manage_commands.create_option(
                name="scope",
                description="Do you want guild perms, or channel overrides",
                required=True,
                option_type=4,
                choices=[
                    manage_commands.create_choice(value=1, name="guild"),
                    manage_commands.create_choice(value=2, name="channel"),
                ],
            ),
            manage_commands.create_option(
                name="target",
                description="The user or role you want to get perms for",
                required=True,
                option_type=9),
        ],
    )
    async def get_permissions(self, ctx: SlashContext, **kwargs):
        mention = int(kwargs.get("target"))

        if user := ctx.guild.get_member(mention):
            if kwargs.get("scope") == 1:
                return await self.perms_guild(ctx, user)
            return await self.perms_channel(ctx, user)

        elif role := ctx.guild.get_role(mention):
            if kwargs.get("scope") == 1:
                return await self.perms_guild(ctx, role)
            return await self.perms_channel(ctx, role)
Beispiel #16
0
    async def add_commands(self, slash: SlashCommand):
        slash.add_slash_command(
            self.database_command,
            name=self.configuration.get("command_prefix", "") +
            "database-inspect",
            description=
            "Consult the Randovania's logic database for one specific room.",
            guild_ids=None,
            options=[
                manage_commands.create_option(
                    "game",
                    "The game's database to check.",
                    option_type=SlashCommandOptionType.STRING,
                    required=True,
                    choices=[
                        manage_commands.create_choice(game.value,
                                                      game.long_name)
                        for game in enum_lib.iterate_enum(RandovaniaGame)
                    ])
            ],
        )

        def add_id(custom_id: str, call, **kwargs):
            self._on_database_component_listener[
                custom_id] = functools.partial(call, **kwargs)

        for game in enum_lib.iterate_enum(RandovaniaGame):
            db = default_database.game_description_for(game)
            world_options = await create_split_worlds(db)
            self._split_worlds[game] = world_options

            add_id(f"{game.value}_world",
                   self.on_database_world_selected,
                   game=game)
            add_id(f"back_to_{game.value}",
                   self.on_database_back_to_game,
                   game=game)

            for i, split_world in enumerate(world_options):
                add_id(f"{game.value}_world_{i}",
                       self.on_database_area_selected,
                       game=game,
                       split_world=split_world,
                       world_id=i)
                for j, area in enumerate(split_world.areas):
                    add_id(f"{game.value}_world_{i}_area_{j}",
                           self.on_area_node_selection,
                           game=game,
                           area=area)

        slash.add_component_callback(
            self.on_database_component,
            components=list(self._on_database_component_listener.keys()),
            use_callback_name=False,
        )
Beispiel #17
0
 async def tag_autocomplete(self, ctx: AutoCompleteContext):
     if ctx.name != "tag" and ctx.focused_option != "tag_name":
         return
     choices = []
     guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
     tags = guild_data.tags
     choices = [
         create_choice(name=tag.name, value=tag.name) for tag in tags
         if tag.name.startswith(ctx.user_input)
     ][:25]
     await ctx.populate(choices)
def deck_slash_options():
    """
    Returns the slash command options for decks.
    :return:
    """
    return [
        create_option(name="code",
                      description=lang.locale('deck_code_desc'),
                      option_type=4,
                      required=True),
        create_option(name="type",
                      description=lang.locale('deck_type_desc'),
                      option_type=3,
                      required=False,
                      choices=[
                          create_choice(name=lang.locale('public_deck'),
                                        value="decklist"),
                          create_choice(name=lang.locale('private_deck'),
                                        value="deck"),
                      ]),
    ]
Beispiel #19
0
 async def level_autocomplete(self, ctx: AutoCompleteContext):
     if self.bot.get_transformed_command_name(ctx) != "levels":
         return
     choices = []
     if ctx.focused_option in ["current_level", "remove"]:
         guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
         roles_by_level = guild_data.roles_by_level
         choices = [
             create_choice(name=level, value=int(level))
             for level in roles_by_level
         ]
     if choices:
         await ctx.populate(choices)
Beispiel #20
0
    async def command_autocomplete(self, ctx: AutoCompleteContext):
        if self.bot.get_transformed_command_name(ctx) != "command":
            return

        guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
        disabled_commands = guild_data.configuration.disabled_commands

        choices = [
            create_choice(name=command_name, value=command_name)
            for command_name in disabled_commands
            if command_name.startswith(ctx.user_input)
        ][:25]

        await ctx.populate(choices)
def timing_slash_options():
    """
    Returns the slash command options for Game's Framework.
    :return:
    """
    return [
        create_option(name="timing",
                      description=lang.locale('timings_type_desc'),
                      option_type=3,
                      required=True,
                      choices=[
                          create_choice(name=lang.locale('mythos_phase'),
                                        value="M"),
                          create_choice(
                              name=lang.locale('investigation_phase'),
                              value="I"),
                          create_choice(name=lang.locale('enemy_phase'),
                                        value="E"),
                          create_choice(name=lang.locale('upkeep_phase'),
                                        value="U"),
                          create_choice(name=lang.locale('skill_test'),
                                        value="S"),
                      ])
    ]
Beispiel #22
0
    async def updateTemplates(self):
        choices = []
        for i in self.manager.get_all_templates():
            choices.append(
                manage_commands.create_choice(i, self.getTemplateName(i)))
        self.slash.commands['version'].options = [
            manage_commands.create_option(
                "version",
                "The game version to set the juggler to.",
                3,
                True,
                choices=choices)
        ]

        await self.slash.sync_all_commands()
Beispiel #23
0
class Games(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.economy = self.bot.get_cog("Economy")
        self.econ_manager = self.economy.manager

    @cog_ext.cog_slash(
        name="slots",
        description="Slot machine minigame",
        guild_ids=[336950154189864961],
        options=[
            create_option(name="amount",
                          description=
                          "How many e฿UX you would like to put into each spin",
                          option_type=SlashCommandOptionType.INTEGER,
                          choices=[
                              create_choice(10, "฿10"),
                              create_choice(50, "฿50"),
                              create_choice(100, "฿100"),
                              create_choice(1000, "฿1,000"),
                              create_choice(10000, "฿10,000"),
                              create_choice(100000, "฿100,000")
                          ],
                          required=False)
        ])
    async def slots(self, ctx: SlashContext, amount: int):
        slots = SlotMachine(ctx, self.bot, amount)
        await slots.play()

    @commands.command(name="connect4", aliases=["c4"])
    async def connect4(self, ctx, target: discord.User, wager: int = 0):
        players = [target, ctx.message.author]
        game = ConnectFour(ctx, self.bot, players, wager)
        await game.play()

    @commands.command("blackjack")
    async def blackjack(self, ctx, minimum: int = 10):
        if minimum >= 10:
            blackjack = BlackJack(ctx, self.bot, minimum)
            await blackjack.play()
        else:
            await ctx.reply("Minimum bet must be at least 10")

    def get_card_string(self, name):
        for card in self.bot.playing_cards:
            if card.name == name:
                return
        return None
def general_card_slash_options():
    """
    Returns the slash command options for general cards.
    :return:
    """
    return [
        create_option(name="name",
                      description=lang.locale('name_description'),
                      option_type=3,
                      required=True),
        create_option(name="type",
                      description=lang.locale('card_type_desc'),
                      option_type=3,
                      required=False,
                      choices=[
                          create_choice(name=lang.locale('scenario'),
                                        value="S"),
                          create_choice(name=lang.locale('act'), value="A"),
                          create_choice(name=lang.locale('agenda'), value="P"),
                          create_choice(name=lang.locale('treachery'),
                                        value="T"),
                          create_choice(name=lang.locale('enemy'), value="E"),
                          create_choice(name=lang.locale('location'),
                                        value="L"),
                          create_choice(name=lang.locale('player_cards'),
                                        value="J"),
                          create_choice(name=lang.locale('mythos'), value="M"),
                      ]),
        create_option(name="sub",
                      description=lang.locale('sub_description'),
                      option_type=3,
                      required=False),
        create_option(name="pack",
                      description=lang.locale('pack_description'),
                      option_type=3,
                      required=False),
    ]
Beispiel #25
0
    async def note_autocomplete(self, ctx: AutoCompleteContext):
        if not self.bot.get_transformed_command_name(ctx).startswith("note"):
            return
        if ctx.focused_option != "name":
            return

        global_data = await self.bot.mongo.get_global_data()
        guild_data = await self.bot.mongo.get_guild_data(ctx.guild_id)
        user_guild_data = await guild_data.get_user(ctx.author_id)
        user_global_data = await global_data.get_user(ctx.author_id)
        if not user_guild_data.notes and not user_global_data.notes:
            return

        choices = [
            create_choice(
                name=f"{count}. | {note['created_at']} | {note['name']}",
                value=note["name"],
            ) for count, note in enumerate(
                user_guild_data.notes + user_global_data.notes, start=1) if
            ctx.user_input in f"{count}. {note['created_at']} | {note['name']}"
        ][:25]

        await ctx.populate(choices)
Beispiel #26
0
class Utilitys(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @cog_ext.cog_slash(
        name='info',
        description='shows info on a user',
        guild_ids=[740531414008856596],
        options=[
            manage_commands.create_option(
                name="user",
                description="the user you want to see the info of",
                option_type=6,
                required=False)
        ])
    async def info(self, ctx, member: discord.Member = None):
        member = member if member != None else ctx.author
        embed = discord.Embed(
            title='User Info',
            description='do `hb: info` to get info about you')
        embed.add_field(name='Name:', value=member.name)
        embed.add_field(name='Discriminator:', value=member.discriminator)
        embed.add_field(name='ID:', value=member.id)
        embed.add_field(name='Bot?', value=member.bot)
        embed.add_field(name='Booster?', value=is_booster(member))
        await ctx.send(embed=embed)

    @cog_ext.cog_slash(
        name='userinfo',
        description='shows info on a user',
        guild_ids=[740531414008856596],
        options=[
            manage_commands.create_option(
                name="user",
                description="the user you want to see the info of",
                option_type=6,
                required=True)
        ])
    async def userinfo(self, ctx, user: discord.User):
        embed = discord.Embed(title='User Info', )
        embed.add_field(name='Name:', value=user.name)
        embed.add_field(name='Discriminator:', value=user.discriminator)
        embed.add_field(name='ID:', value=user.id)
        embed.add_field(name='Bot?', value=user.bot)
        await ctx.send(embed=embed)

    @cog_ext.cog_slash(name='botinfo',
                       description='shows info about this bot',
                       guild_ids=[740531414008856596])
    async def botinfo(self, ctx):
        embed = discord.Embed(
            title='henos bot',
            description='use `hb: help` for a list of the commands')
        embed.add_field(name='Name:', value=self.bot.user.name)
        embed.add_field(name='Discriminator:',
                        value=self.bot.user.discriminator)
        embed.add_field(name='ID:', value=self.bot.user.id)
        embed.add_field(name='Owner:', value='henos')
        embed.add_field(name='Ping:',
                        value=f'{round(self.bot.latency * 1000)} ms')
        embed.add_field(name='Invite:', value='http://tiny.cc/henosbot')
        embed.add_field(name='Servers:', value=len(self.bot.guilds))
        embed.add_field(name='Members:', value=len(self.bot.users))
        embed.add_field(name='Prefixs:', value='hb: , hb:')
        await ctx.send(embed=embed)

    @cog_ext.cog_slash(name='serverinfo',
                       description='shows info on a server',
                       guild_ids=[740531414008856596])
    async def guildinfo(self, ctx):
        embed = discord.Embed(title='Server Info')
        embed.add_field(name='Name:', value=ctx.guild.name)
        embed.add_field(name='ID:', value=ctx.guild.id)
        embed.add_field(name='Channels:', value=len(ctx.guild.channels))
        embed.add_field(name='Members:', value=len(ctx.guild.members))
        embed.add_field(name='Boosts:',
                        value=len(ctx.guild.premium_subscribers))
        embed.add_field(name='Owner:', value=ctx.guild.owner.mention)
        welcome_msgs = await db.ignored(ctx.guild, 'welcome_msgs')
        lvl_msgs = await db.ignored(ctx.guild, 'lvl_msgs')
        embed.add_field(name='Interaction disabled?',
                        value=f'Welcome: {welcome_msgs}, Level: {lvl_msgs}')
        await ctx.send(embed=embed)

    @cog_ext.cog_slash(
        name='disableinteraction',
        description='disables interaction in a server',
        guild_ids=[740531414008856596],
        options=[
            manage_commands.create_option(
                name="type",
                description="the type of thing u want to disable",
                option_type=3,
                required=True)
        ])
    @commands.has_permissions(manage_guild=True)
    async def disableinteraction(self, ctx, type):
        await db.guild_set(ctx.guild, type, False)
        await ctx.send(f'Guild {ctx.guild.name} has disabled {type} messages.')

    @cog_ext.cog_slash(
        name='enableinteraction',
        description='enables interaction in a server',
        guild_ids=[740531414008856596],
        options=[
            manage_commands.create_option(
                name="type",
                description="the type of thing u want to enable",
                option_type=3,
                required=True,
                choices=[
                    manage_commands.create_choice(name='level', value='lvl'),
                    manage_commands.create_choice(name='welcome',
                                                  value='welcome')
                ])
        ])
    @commands.has_permissions(manage_guild=True)
    async def enableinteraction(self, ctx, type):
        await db.guild_set(ctx.guild, type, True)
        await ctx.send(f'Guild {ctx.guild.name} has enabled {type} messages.')

    @commands.command()
    @commands.is_owner()
    async def text(self, ctx, user: discord.User, *, message):
        msg = await user.send('Incoming text message from my owner...')
        await msg.edit(content=f'Message: {message}')
        await ctx.send('Message sent successfully')

    @cog_ext.cog_slash(name='roles',
                       description='shows all the roles in a server',
                       guild_ids=[740531414008856596])
    @commands.guild_only()
    async def roles(self, ctx):
        allroles = ""

        for num, role in enumerate(sorted(ctx.guild.roles, reverse=True),
                                   start=1):
            allroles += f"[{str(num).zfill(2)}] {role.id}\t{role.name}\t[ Users: {len(role.members)} ]\r\n"

        data = BytesIO(allroles.encode('utf-8'))
        await ctx.send(content=f"Roles in **{ctx.guild.name}**",
                       file=discord.File(data,
                                         filename=f"{timetext('Roles')}"))

    @cog_ext.cog_slash(name='joinedat',
                       description='show when a user joined ur server',
                       guild_ids=[740531414008856596],
                       options=[
                           manage_commands.create_option(
                               name='user',
                               description='the user to see the `joinedat` of',
                               option_type=6,
                               required=False)
                       ])
    @commands.guild_only()
    async def joinedat(self, ctx, user: discord.Member = None):
        user = user or ctx.author

        embed = discord.Embed()
        embed.set_thumbnail(url=user.avatar_url)
        embed.description = f'**{user}** joined **{ctx.guild.name}**\n{date(user.joined_at)}'
        await ctx.send(embed=embed)

    @cog_ext.cog_slash(name='mods',
                       description='shows the mods that are currently online',
                       guild_ids=[740531414008856596])
    @commands.guild_only()
    async def mods(self, ctx):
        message = ""
        all_status = {
            "online": {
                "users": [],
                "emoji": "🟢"
            },
            "idle": {
                "users": [],
                "emoji": "🟡"
            },
            "dnd": {
                "users": [],
                "emoji": "🔴"
            },
            "offline": {
                "users": [],
                "emoji": "âš«"
            }
        }

        for user in ctx.guild.members:
            user_perm = ctx.channel.permissions_for(user)
            if user_perm.kick_members or user_perm.ban_members:
                if not user.bot:
                    all_status[str(user.status)]["users"].append(f"**{user}**")

        for g in all_status:
            if all_status[g]["users"]:
                message += f"{all_status[g]['emoji']} {', '.join(all_status[g]['users'])}\n"

        await ctx.send(f"Mods in **{ctx.guild.name}**\n{message}")
Beispiel #27
0
import discord
from discord.ext import commands
import requests
from discord_slash import cog_ext, SlashContext
from main import test_guilds, make_error_embed
from discord_slash.utils.manage_commands import create_option, create_choice

options = [
    create_option(name="species",
                  description="Select a species.",
                  option_type=3,
                  required=True,
                  choices=[
                      create_choice(name="cat", value="cat"),
                      create_choice(name="dog", value="dog"),
                      create_choice(name="panda", value="panda"),
                      create_choice(name="koala", value="koala")
                  ])
]


class AnimalFact(commands.Cog):
    def __init__(self, client):
        self.client = client

    @cog_ext.cog_subcommand(
        base="animal",
        name="fact",
        options=options,
        #guild_ids=test_guilds
    )
Beispiel #28
0
class Greetings(utils.AutoLogCog, utils.StartupCog):
    """Simple greetings and welcome commands"""

    activity_time_format = "%H:%M %d.%m.%Y"

    def __init__(self, bot):
        utils.StartupCog.__init__(self)
        utils.AutoLogCog.__init__(self, logger)
        self.bot = bot
        self.activity_file_path = utils.abs_join("last_activity")
        self._last_greeted_member = None
        self._started_at = None
        self._last_active_at = None

    async def on_startup(self):
        logger.info(f"Logged in as {self.bot.user}")

        guilds_list = [
            f"[{g.name}: {g.member_count} members]" for g in self.bot.guilds
        ]
        logger.info(f"Current servers: {', '.join(guilds_list)}")

        last_activity = self.get_file_activity_time()
        self._started_at = datetime.utcnow()
        self._last_active_at = datetime.utcnow()
        self.update_activity_time_loop.start()

        # Don't send greetings if last activity was less than a 3 hours ago
        if last_activity is None or (self._last_active_at - last_activity >
                                     timedelta(hours=3)):
            await self.send_home_channels_message(
                "Hello hello! I'm back online and ready to work!")

    @tasks.loop(hours=1)
    async def update_activity_time_loop(self):
        self._last_active_at = datetime.utcnow()
        self.update_file_activity_time()

    @commands.Cog.listener()
    async def on_member_join(self, member: discord.Member):
        if member.bot:
            return
        channels = await self.bot.get_cog("Channels").get_welcome_channels(
            member.guild)
        if not channels:
            return

        message = await self.get_welcome_message(member)
        if not message:
            logger.info("Member greeting is disabled")
            return
        for greeting_channel in channels:
            if utils.can_bot_respond(greeting_channel):
                await greeting_channel.send(
                    message, allowed_mentions=discord.AllowedMentions.none())
        logger.info(f"Greeted new guild member {member}")

    def get_file_activity_time(self) -> Optional[datetime]:
        try:
            with open(self.activity_file_path, 'r') as startup_time_file:
                return datetime.strptime(startup_time_file.read(),
                                         self.activity_time_format)
        except (ValueError, OSError):
            return None

    def update_file_activity_time(self):
        """writes to the startup file current _started_at file"""
        last_activity = self._last_active_at.strftime(
            self.activity_time_format)
        with open(self.activity_file_path, 'w') as activity_time_file:
            activity_time_file.write(last_activity)
            logger.info(f"Updated last activity time file: {last_activity}")

    @cog_ext.cog_subcommand(base="home",
                            name="notify",
                            options=[
                                create_option(
                                    name="message",
                                    description="Message to send",
                                    option_type=str,
                                    required=False,
                                ),
                                create_option(
                                    name="attachment_link",
                                    description="Link to attachment to send",
                                    option_type=str,
                                    required=False,
                                )
                            ],
                            guild_ids=guild_ids)
    @has_bot_perms()
    async def home_channel_notify(self,
                                  ctx: SlashContext,
                                  message="",
                                  attachment_link=None):
        """Sends message with the attachment to the home channels of the guilds from the bot"""
        if not message and not attachment_link:
            await ctx.send("Can't send an empty message", hidden=True)
            return

        await ctx.defer()

        file = None
        name = ""
        if attachment_link is not None:
            async with aiohttp.ClientSession() as session:
                async with session.get(attachment_link) as response:
                    if response.ok:
                        file = await response.read()
                        name = Path(urlparse(attachment_link).path).name

        await self.send_home_channels_message(message, file, name)
        await ctx.send("Notification sent")
        logger.important(
            f"{self.format_caller(ctx)} sent global notification {message} with attachment {attachment_link}"
        )

    @cog_ext.cog_subcommand(base="home", name="where", guild_ids=guild_ids)
    async def home_channel_where(self, ctx: SlashContext):
        """Shows where current home of the bot in this server is."""
        current_homes = await self.bot.get_cog("Channels").get_home_channels(
            ctx.guild)
        if current_homes:
            if len(current_homes) == 1:
                await ctx.send(
                    f"My home channel is {current_homes[0].mention}",
                    hidden=True)
            else:
                current_homes = ", ".join(
                    [channel.mention for channel in current_homes])
                await ctx.send(f"My home channels are {current_homes}",
                               hidden=True)
        else:
            await ctx.send("I'm homeless T_T", hidden=True)

    async def send_home_channels_message(self,
                                         message: str,
                                         attachment=None,
                                         attachment_name=""):
        channels = await self.bot.get_cog("Channels").get_home_channels()
        for channel in channels:
            if channel.guild not in self.bot.guilds:
                continue

            file = discord.File(
                io.BytesIO(attachment),
                attachment_name) if attachment is not None else None
            await channel.send(message, file=file)

    def get_start_time(self) -> datetime:
        return self._started_at

    def get_last_activity_time(self) -> datetime:
        return self._last_active_at

    def get_greeting(self, member):
        greetings = \
            ["Hi, {}!",
             "Hello, {}~",
             "Yo, {}!",
             "Sup, {}",
             "{}! Good to see you!",
             "The Skybox waited for you, {}!",
             "Greetings, {} =)",
             "/-//- /--/ {}.",
             "Oh! Hello there, you must be {}.",
             "G'day, {}!",
             "Howdy, {}",
             "Arigato, {}-san",
             "Hoi, {}",
             ]
        message = random.choice(greetings).format(member.display_name)

        if self._last_greeted_member is not None and self._last_greeted_member.id == member.id:
            message = f"{message}\nThis feels oddly familiar..."

        self._last_greeted_member = member
        return message

    @staticmethod
    def get_member_welcome_message(member: discord.Member) -> str:
        """Returns personal part of the welcome message"""
        greetings = \
            ["Welcome, {}!",
             "Glad to see you here, {}!",
             "Welcome here, {}!",
             "{} just joined, welcome!",
             "Welcome, {}. We're not Discord, we demand pizza!",
             "Hello, {}. Have a good time here!",
             ]
        # Discord mobile client have a bug where it shows mention as @invalid-user
        # What exactly triggers that is beyond my understanding right now, so I just put back the display name for now
        return random.choice(greetings).format(member.display_name)

    @staticmethod
    async def get_welcome_message(member: discord.Member) -> Optional[str]:
        """Returns full welcome message for specific server and person"""
        guild_greeting = await GuildGreetings.get_or_none(
            guild_id=member.guild.id)
        if not guild_greeting:
            return None
        member_greeting = Greetings.get_member_welcome_message(member)
        return "\n".join([
            member_greeting, guild_greeting.greeting_text
        ]) if guild_greeting.greeting_text else member_greeting

    @staticmethod
    async def set_guild_greeting_text(guild: discord.Guild,
                                      greeting_text: Optional[str]):
        (greeting, _) = await GuildGreetings.get_or_create(guild_id=guild.id)
        greeting.greeting_text = greeting_text
        await greeting.save()

    @staticmethod
    async def delete_welcome_message(guild: discord.Guild):
        greeting = await GuildGreetings.get_or_none(guild_id=guild.id)
        if greeting:
            await greeting.delete()

    @cog_ext.cog_subcommand(
        base="greeting",
        name="set",
        description=
        "Enables welcome message and sets server specific part of the this message",
        options=[
            create_option(
                name="message",
                description="Server specific part of the welcome message",
                option_type=str,
                required=False,
            ),
            create_option(
                name="template_link",
                description=
                "Link to the message, which text should be used as a welcome message",
                option_type=str,
                required=False,
            ),
        ],
        guild_ids=guild_ids)
    @has_server_perms()
    async def set_greeting(self,
                           ctx: SlashContext,
                           message: str = "",
                           template_link: Optional[str] = None):
        await ctx.defer(hidden=True)
        if not message and template_link:
            message = await utils.get_message_from_link(
                self.bot, template_link)
            message = message.content
        await self.set_guild_greeting_text(ctx.guild, message)
        message = f"'{message}'" if message else message
        logger.db(
            f"{ctx.author} set greeting for guild {ctx.guild} to {message}")
        await ctx.send(
            f"Successfully set message to personal greeting {'and ' + message if message else 'only'}",
            hidden=True)

    @cog_ext.cog_subcommand(
        base="greeting",
        name="delete",
        description="Disables welcome message for new people",
        guild_ids=guild_ids)
    @has_server_perms()
    async def delete_greeting(self, ctx: SlashContext):
        await ctx.defer(hidden=True)
        await self.delete_welcome_message(ctx.guild)
        logger.db(f"{ctx.author} deleted greeting for guild {ctx.guild}'")
        await ctx.send(
            f"Successfully deleted welcome message! Bot won't send welcome message when new people joins",
            hidden=True)

    @cog_ext.cog_subcommand(
        base="greeting",
        name="greet",
        description="Sends greeting for you or specific person",
        options=[
            create_option(
                name="member",
                description="Person to greet",
                option_type=discord.Member,
                required=False,
            ),
            create_option(
                name="hidden",
                description=
                "If enabled, it'll be only you who see the greeting",
                option_type=bool,
                required=False,
            ),
        ],
        guild_ids=guild_ids)
    async def greet(self,
                    ctx: SlashContext,
                    member: discord.Member = None,
                    hidden: bool = False):
        member = member or ctx.author
        message = await self.get_welcome_message(member)
        if not message:
            await ctx.send("Welcome message is disabled for the server",
                           hidden=True)
            return

        await ctx.send(message,
                       hidden=hidden,
                       allowed_mentions=discord.AllowedMentions.none())

    @cog_ext.cog_subcommand(base="greeting",
                            name="list",
                            description="Lists all greetings in database",
                            guild_ids=guild_ids)
    @has_bot_perms()
    async def list_greetings(self, ctx: SlashContext):
        await ctx.defer(hidden=True)
        async for greeting in GuildGreetings.all():
            guild = self.bot.get_guild(greeting.guild_id)
            message = "\n".join([
                f"'{guild.name if guild else 'ID ' + str(greeting.guild_id)}' greeting:",
                greeting.greeting_text
                if greeting.greeting_text else "Personal greeting only",
            ])
            await ctx.send(content=message, hidden=True)

    @cog_ext.cog_slash(options=[
        create_option(
            name="member",
            description="Member who bot should greet",
            option_type=discord.Member,
            required=False,
        )
    ],
                       guild_ids=guild_ids)
    async def hello(self, ctx: SlashContext, member: discord.Member = None):
        """Says hello to you or mentioned member."""
        if member and not isinstance(member, discord.Member):
            raise commands.BadArgument(
                f"Failed to get member '{member}' info!")

        if not utils.can_bot_respond(ctx.channel):
            raise commands.BadArgument(
                f"I can't send messages to this channel"
            )  # This will be shown as hidden response, so we can do that

        member = member or ctx.author
        await ctx.send(self.get_greeting(member))

    async def get_activity_code(self, voice, application_id):
        url = f"https://discord.com/api/v8/channels/{voice.channel.id}/invites"
        api_json = {
            "max_age": 86400,
            "max_uses": 0,
            "target_application_id": f"{application_id}",
            "target_type": 2,
            "temporary": False,
            "validate": None
        }
        headers = {
            "Authorization": f"Bot {self.bot.token}",
            "Content-Type": "application/json"
        }

        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=api_json,
                                    headers=headers) as response:
                data = await response.json()
                code = data["code"]
                return code

    @staticmethod
    async def get_application_icon(application_id):
        async with aiohttp.ClientSession() as session:
            api_url = f"https://discord.com/api/v9/applications/{application_id}/rpc"
            async with session.get(api_url) as response:
                data = await response.json()
                icon_code = data["icon"]

            icon_url = f"https://cdn.discordapp.com/app-icons/{application_id}/{icon_code}.png"
            return icon_url

    @cog_ext.cog_slash(name="activity",
                       options=[
                           create_option(name="type",
                                         description="Type of activity",
                                         option_type=str,
                                         required=True,
                                         choices=[
                                             create_choice(name=name,
                                                           value=name)
                                             for name in activities.keys()
                                         ])
                       ],
                       connector={"type": "activity_type"},
                       guild_ids=guild_ids)
    async def start_activity(self, ctx: SlashContext, activity_type):
        """Creates an activity invite for voice channel you are in"""
        if not ctx.author.voice:
            await ctx.send(
                hidden=True,
                content=
                "You need to be in a voice channel to start an activity!")
            return

        await ctx.defer()
        voice = ctx.author.voice
        application_id = activities[activity_type]
        code = await self.get_activity_code(voice, application_id)
        invite = f"https://discord.gg/{code}"
        icon = await self.get_application_icon(application_id)

        embed = discord.Embed(title="New voice channel activity started!",
                              colour=utils.embed_color)
        embed.set_author(name=activity_type, icon_url=icon, url=invite)
        embed.set_thumbnail(url=icon)
        embed.description = f"**{activity_type}** activity just started in {voice.channel.mention}\n" \
                            f"[Click this link and join!]({invite})\n" \
                            f"This invite will expire after 1 day!"

        await ctx.send(embed=embed)
Beispiel #29
0
class Schedule(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.max_left_arrow = "⏮"
        self.left_arrow = "◀"
        self.max_right_arrow = "⏭"
        self.right_arrow = "▶"

    @staticmethod
    async def _is_played(ctx: Union[commands.Context, SlashContext]) -> None:
        async with aiohttp.ClientSession() as session:
            async with session.get("https://radio17.pl/api/stream/stats/extended") as response:
                json_resp = await response.json()
                embed = discord.Embed(title="Obecnie gramy:")
                is_played = f'{json_resp["current"]["artist"]} - {json_resp["current"]["title"]}'
                embed.add_field(name=is_played, value="https://radio17.pl")
                await ctx.send(embed=embed)

    @staticmethod
    async def _will_play(ctx: Union[commands.Context, SlashContext]) -> None:
        async with aiohttp.ClientSession() as session:
            async with session.get("https://radio17.pl/api/stream/stats/extended") as response:
                embed = discord.Embed(title="Za chwilę będziemy grać:")
                json_resp = await response.json()
                if json_resp["next"] is not None:
                    will_play = f'{json_resp["next"]["artist"]} - {json_resp["next"]["title"]}'
                    embed.add_field(name=will_play, value="https://radio17.pl")
                else:
                    embed.add_field(name="No nie wiem co będzie grane.", value="https://radio17.pl")
                await ctx.send(embed=embed)

    async def _schedule(self, ctx: Union[commands.Context, SlashContext], day: str) -> None:
        async with aiohttp.ClientSession() as session:
            async with session.get("https://radio17.pl/api/schedule") as response:
                json_resp = await response.json()
                # "strony" embeda, kazda z nich odpowiada jednej audycji
                pages = []

                # szczegolny przypadek jesli uzytkownik chce skrocona ramowke
                if day.lower() == "short":
                    short_embed = discord.Embed(title="Dziś jeszcze gramy:")
                    # tylko dla danego dnia tygodnia sprawdza co jest grane, datetime.datetime.today().weekday()
                    # zwraca dzien tygodnia jako numer
                    print(json_resp)
                    for broadcast in json_resp[week_days[datetime.datetime.today().weekday()]]:
                        # broadcast["end_hour"][:2] bierze pierwsze dwie cyfry z godziny podanej w formacie hh:mm:ss
                        if int(broadcast["end_hour"][:2]) > datetime.datetime.today().hour:
                            short_embed.add_field(name=broadcast["title"],
                                                  value=f'{broadcast["start_hour"]} - {broadcast["end_hour"]}',
                                                  inline=False)
                    await ctx.send(embed=short_embed)
                    return
                
                # sprawdza czy dzien tygodnia podany przez uzytkownika jest poprawny
                if day.lower() not in week_days:
                    await ctx.send("Wpisz poprawny dzień tygodnia w języku angielskim!")
                    return

                # dla kazdej audycji tworzy jedna "strone" embeda
                for broadcast in json_resp[day]:
                    embed = discord.Embed(title=broadcast["title"])
                    embed.add_field(name="Nazwa audycji:", value=broadcast["title"], inline=False)
                    embed.add_field(name="Od - do:", value=f'{broadcast["start_hour"]} - {broadcast["end_hour"]}',
                                    inline=False)
                    if broadcast["description"] is not None:
                        embed.add_field(name="Opis:", value=broadcast["description"], inline=False)
                    embed.set_image(url=broadcast["player_image"])
                    pages.append(embed)
                # wysyla pierwsza strone embeda
                message = await ctx.send(embed=pages[0])

                # dodaje kolejno reakcje pod embedem sluzace do przesuwania stron
                await message.add_reaction(self.max_left_arrow)
                await message.add_reaction(self.left_arrow)
                await message.add_reaction(self.right_arrow)
                await message.add_reaction(self.max_right_arrow)

                # funkcja sprawdzajaca czy reakcja dodana pod embedem jest od autora komendy
                def check(reaction, user):
                    return user == ctx.author

                i = 0
                reaction = None
                while True:
                    # reakcja do powrotu do pierwszej strony emebda
                    if str(reaction) == self.max_left_arrow:
                        i = 0
                        await message.edit(embed=pages[i])

                    # reakcja cofa embed o jedna strone
                    elif str(reaction) == self.left_arrow:
                        if i > 0:
                            i -= 1
                            await message.edit(embed=pages[i])

                    # reakcja przenosi na kolejna strone mebeda
                    elif str(reaction) == self.right_arrow:
                        if i < len(pages) - 1:
                            i += 1
                            await message.edit(embed=pages[i])

                    # reakcja przenosi do ostatniej strony embeda
                    elif str(reaction) == self.max_right_arrow:
                        i = len(pages) - 1
                        await message.edit(embed=pages[i])

                    try:
                        # sprawdza czy autor dodal reakcje pod wiadomoscia
                        reaction, user = await self.bot.wait_for("reaction_add", timeout=30.0, check=check)
                        # usuwa dodana reakcje pod wiadomoscia, by mozna bylo dodac kolejna
                        await message.remove_reaction(reaction, user)
                    except:
                        break

                # usuwa reakcje po uplywie 30s
                await message.clear_reactions()

    @commands.command(
        brief="Co jest grane?",
        help="Bot informuje o obecnie granym utworze.",
        name="cjg"
    )
    @commands.cooldown(1, 60, commands.BucketType.user)
    async def is_played(self, ctx: commands.Context) -> None:
        await self._is_played(ctx)
        return

    @cog_ext.cog_slash(
        name="cjg",
        description="Informuje co obecnie jest grane w radiu."
    )
    async def is_played_slash(self, ctx: SlashContext) -> None:
        await self._is_played(ctx)
        return

    @commands.command(
        brief="Co będzie grane?",
        help="Bot informuje jaki utwór będzie grany następnie.",
        name="cbg"
    )
    @commands.cooldown(1, 60, commands.BucketType.user)
    async def will_play(self, ctx: commands.Context) -> None:
        await self._will_play(ctx)
        return

    @cog_ext.cog_slash(
        name="cbg",
        description="Informuje co będzie grane za chwilę w radiu."
    )
    async def will_play_slash(self, ctx: SlashContext) -> None:
        await self._will_play(ctx)
        return

    @commands.command(
        brief="Wysyła ramówkę na dany dzień.",
        help="Przyjmuje dni tygodnia po angielsku i wysyła ramówkę na zadany dzień. Podaje godzinę rozpoczęcia i "
             "zakończenia audycji oraz jej krótki opis. "
    )
    @commands.cooldown(1, 60, commands.BucketType.user)
    async def schedule(self, ctx: commands.Context, day: str) -> None:
        await self._schedule(ctx, day)
        return

    @cog_ext.cog_slash(
        name="schedule",
        description="Wysyła ramówkę na dany dzień.",
        # tworzy opcje do wyboru w wypadku slash command
        options=[
            create_option(
                name="day",
                description="Wybierz dzień tygodnia",
                option_type=3,
                required=True,
                choices=[
                    create_choice(
                        name="Krótsza wersja ramówki",
                        value="short"
                    ),
                    create_choice(
                        name="Poniedziałek",
                        value="monday"
                    ),
                    create_choice(
                        name="Wtorek",
                        value="tuesday"
                    ),
                    create_choice(
                        name="Środa",
                        value="wednesday"
                    ),
                    create_choice(
                        name="Czwartek",
                        value="thursday"
                    ),
                    create_choice(
                        name="Piątek",
                        value="friday",
                    ),
                    create_choice(
                        name="Sobota",
                        value="saturday"
                    ),
                    create_choice(
                        name="Niedziela",
                        value="sunday"
                    )
                ]
            )
        ]
    )
    async def schedule_slash(self, ctx: SlashContext, day: str) -> None:
        if ctx.guild is None:
            await ctx.send("Komenda nie działa w wiadomości prywatnej!")
            return
        await self._schedule(ctx, day)
        return
class Market(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    # ---       SLASH COMMANDS       --- #
    @cog_ext.cog_subcommand(
        base='market',
        name='coin',
        description='Displays cryptocoin info from CoinMarketCap',
        guild_ids=guild_ids,
        options=[
            create_option(
                name='module',
                description=' ',
                required=True,
                option_type=3,
                choices=[
                    create_choice(
                        name='rank',
                        value='rank'
                    ),
                    create_choice(
                        name='name',
                        value='name'
                    )
                ]
            )
        ]
    )
    async def _market_coin(self, ctx: SlashContext, module: str):
        # Variables
        emoji_list = ['◀', '▶']

        # Database
        cur.execute('SELECT * FROM coin_info ORDER BY coin_rank asc')
        rows = cur.fetchall()

        if module == 'rank':
            embed = discord.Embed(
                title='Please enter a rank from 1-100',
                description=' ',
                colour=discord.Colour.blurple()
            )
            await ctx.send(embeds=[embed], delete_after=5.0)

            try:
                msg = await self.bot.wait_for('message', timeout=5.0)
            except asyncio.exceptions.TimeoutError:
                embed = discord.Embed(
                    title=f'{ctx.author} failed to send a message within the allotted time',
                    description=' ',
                    colour=discord.Colour.red()
                )
                await ctx.send(embeds=[embed], delete_after=5.0)

            try:
                coin_number = int(msg.content)
                await msg.delete()  # Deletes message sent by user
                for x in rows:
                    #  ID: x[0] || Name: x[1] || Symbol: x[2] || Price: x[3] || Rank: x[4] || Change: x[5] || Logo: x[6]
                    if x[4] == coin_number:
                        current_page = x[4]
                        embed = discord.Embed(
                            title=f'${str(x[3])}',
                            description=' ',
                            colour=discord.Colour.blurple()
                        )
                        embed.set_author(
                            name=f'{x[4]}. {x[1]} / {x[2]}',
                            icon_url=x[6]
                        )
                        embed.add_field(
                            name='24h %',
                            value=f'{x[5]:.2f}%',
                            inline=False)
                        embed.set_footer(text="")
                message = await ctx.send(embed=embed)

                if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                    await message.add_reaction(emoji_list[1])
                elif current_page >= 100:
                    await message.add_reaction(emoji_list[0])
                else:
                    for emoji in emoji_list:
                        await message.add_reaction(emoji)

                check = reaction_check(message=message, author=ctx.author, emoji=(emoji_list[0], emoji_list[1]))
                while True:  # Continues to run for 10 seconds until user does not click the emojis
                    try:
                        reaction, user = await self.bot.wait_for('reaction_add', timeout=10.0, check=check)
                        if reaction.emoji == emoji_list[0]:  # Left page
                            await message.delete()  # Deletes embed before sending a new one
                            current_page = current_page - 1
                            if current_page <= 0:
                                current_page = 1
                                embed = get_left_coin(1)
                            else:
                                embed = get_left_coin(current_page)

                            message = await ctx.send(embed=embed)
                            if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                                await message.add_reaction(emoji_list[1])
                            elif current_page >= 100:
                                await message.add_reaction(emoji_list[0])
                            else:
                                for emoji in emoji_list:
                                    await message.add_reaction(emoji)
                            check = reaction_check(message=message, author=ctx.author,
                                                   emoji=(emoji_list[0], emoji_list[1]))

                        elif reaction.emoji == emoji_list[1]:  # Right page
                            await message.delete()  # Deletes embed before sending a new one
                            current_page = current_page + 1
                            if current_page >= 100:
                                current_page = 100
                                embed = get_right_coin(100)
                            else:
                                embed = get_right_coin(current_page)

                            message = await ctx.send(embed=embed)
                            if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                                await message.add_reaction(emoji_list[1])
                            elif current_page >= 100:
                                await message.add_reaction(emoji_list[0])
                            else:
                                for emoji in emoji_list:
                                    await message.add_reaction(emoji)

                            check = reaction_check(message=message, author=ctx.author,
                                                   emoji=(emoji_list[0], emoji_list[1]))
                    except TimeoutError:
                        print('Timeout')
            except ValueError:
                await msg.delete()  # Deletes message sent by user
                embed = discord.Embed(
                    title=f'Input is not a rank: {msg.content}',
                    description=' ',
                    colour=discord.Colour.red()
                )
                await ctx.send(embeds=[embed], delete_after=5.0)

        elif module == 'name':
            embed = discord.Embed(
                title='Please enter a name',
                description=' ',
                colour=discord.Colour.blurple()
            )
            await ctx.send(embeds=[embed], delete_after=5.0)

            try:
                msg = await self.bot.wait_for('message', timeout=5.0)
            except asyncio.exceptions.TimeoutError:
                embed = discord.Embed(
                    title=f'{ctx.author} failed to send a message within the allotted time',
                    description=' ',
                    colour=discord.Colour.red()
                )
                await ctx.send(embeds=[embed], delete_after=5.0)

            try:
                coin_name = msg.content.lower()
                await msg.delete()  # Deletes message sent by user
                for x in rows:
                    #  ID: x[0] || Name: x[1] || Symbol: x[2] || Price: x[3] || Rank: x[4] || Change: x[5] || Logo: x[6]
                    if x[1].lower() == coin_name:
                        current_page = x[4]
                        embed = discord.Embed(
                            title=f'${str(x[3])}',
                            description=' ',
                            colour=discord.Colour.blurple()
                        )
                        embed.set_author(
                            name=f'{x[4]}. {x[1]} / {x[2]}',
                            icon_url=x[6]
                        )
                        embed.add_field(
                            name='24h %',
                            value=f'{x[5]:.2f}%',
                            inline=False)
                        embed.set_footer(text="")
                message = await ctx.send(embed=embed)

                if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                    await message.add_reaction(emoji_list[1])
                elif current_page >= 100:
                    await message.add_reaction(emoji_list[0])
                else:
                    for emoji in emoji_list:
                        await message.add_reaction(emoji)

                check = reaction_check(message=message, author=ctx.author, emoji=(emoji_list[0], emoji_list[1]))
                while True:  # Continues to run for 10 seconds until user does not click the emojis
                    try:
                        reaction, user = await self.bot.wait_for('reaction_add', timeout=10.0, check=check)
                        if reaction.emoji == emoji_list[0]:  # Left page
                            await message.delete()  # Deletes embed before sending a new one
                            current_page = current_page - 1
                            if current_page <= 0:
                                current_page = 1
                                embed = get_left_coin(1)
                            else:
                                embed = get_left_coin(current_page)

                            message = await ctx.send(embed=embed)
                            if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                                await message.add_reaction(emoji_list[1])
                            elif current_page >= 100:
                                await message.add_reaction(emoji_list[0])
                            else:
                                for emoji in emoji_list:
                                    await message.add_reaction(emoji)
                            check = reaction_check(message=message, author=ctx.author,
                                                   emoji=(emoji_list[0], emoji_list[1]))

                        elif reaction.emoji == emoji_list[1]:  # Right page
                            await message.delete()  # Deletes embed before sending a new one
                            current_page = current_page + 1
                            if current_page >= 100:
                                current_page = 100
                                embed = get_right_coin(100)
                            else:
                                embed = get_right_coin(current_page)

                            message = await ctx.send(embed=embed)
                            if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                                await message.add_reaction(emoji_list[1])
                            elif current_page >= 100:
                                await message.add_reaction(emoji_list[0])
                            else:
                                for emoji in emoji_list:
                                    await message.add_reaction(emoji)

                            check = reaction_check(message=message, author=ctx.author,
                                                   emoji=(emoji_list[0], emoji_list[1]))
                    except TimeoutError:
                        print('Timeout')
            except ValueError:
                await msg.delete()  # Deletes message sent by user
                embed = discord.Embed(
                    title=f'Input is not a name: {msg.content}',
                    description=' ',
                    colour=discord.Colour.red()
                )
                await ctx.send(embeds=[embed], delete_after= 5.0)

    @cog_ext.cog_subcommand(
        base='market',
        name='top',
        description='Displays the top # coins from 1-100',
        guild_ids=guild_ids
    )
    async def _market_top(self, ctx: SlashContext, *, rank):
        # Variables
        emoji_list = ['◀', '▶']

        # Database
        cur.execute('SELECT * FROM coin_info ORDER BY coin_rank asc')  # 1,2,3...,100
        rows = cur.fetchall()

        try:
            rank = int(rank)

            if rank < 11:
                min = 1
                max = 10
            else:
                min = rank - 10
                max = rank
                if max > 100:
                    max = 100

            embed = discord.Embed(
                title=' ',
                description=' ',
                colour=discord.Colour.blurple()
            )
            #  ID: x[0] || Name: x[1] || Symbol: x[2] || Price: x[3] || Rank: x[4] || Change: x[5] || Logo: x[6]
            for x in rows:
                if min <= x[4] <= max:
                    embed.set_author(name=f'Top {max} Crypto Coins',
                                     icon_url=BOT_AVATAR)
                    embed.add_field(
                        name=f'{x[4]}. {x[1]} / {x[2]}',
                        value=f'${x[3]}',
                        inline=False)
                    embed.set_footer(text="")

            message = await ctx.send(embed=embed)
            if rank <= 10:  # Adds / Removes emoji if it passes threshold
                await message.add_reaction(emoji_list[1])
            elif rank >= 100:
                await message.add_reaction(emoji_list[0])
            else:
                for emoji in emoji_list:
                    await message.add_reaction(emoji)

            check = reaction_check(message=message, author=ctx.author, emoji=(emoji_list[0], emoji_list[1]))
            current_page = max
            while True:
                try:
                    reaction, user = await self.bot.wait_for('reaction_add', timeout=10.0, check=check)
                    if reaction.emoji == emoji_list[0]:  # Left page
                        await message.delete()  # Deletes embed before sending a new one
                        current_page = current_page - 10
                        if current_page <= 0:
                            current_page = 10
                            embed = get_left_10_coins(10)
                        else:
                            embed = get_left_10_coins(current_page)

                        message = await ctx.send(embed=embed)
                        if current_page <= 10:  # Adds / Removes emoji if it passes threshold
                            await message.add_reaction(emoji_list[1])
                        elif current_page >= 100:
                            await message.add_reaction(emoji_list[0])
                        else:
                            for emoji in emoji_list:
                                await message.add_reaction(emoji)

                        check = reaction_check(message=message, author=ctx.author,
                                               emoji=(emoji_list[0], emoji_list[1]))

                    elif reaction.emoji == emoji_list[1]:  # Right page
                        await message.delete()  # Deletes embed before sending a new one
                        current_page = current_page + 10
                        if current_page >= 100:
                            current_page = 100
                            embed = get_right_10_coins(100)
                        else:
                            embed = get_right_10_coins(current_page)
                        message = await ctx.send(embed=embed)

                        if current_page <= 1:  # Adds / Removes emoji if it passes threshold
                            await message.add_reaction(emoji_list[1])
                        elif current_page >= 100:
                            await message.add_reaction(emoji_list[0])
                        else:
                            for emoji in emoji_list:
                                await message.add_reaction(emoji)

                        check = reaction_check(message=message, author=ctx.author,
                                               emoji=(emoji_list[0], emoji_list[1]))
                except TimeoutError:
                    print('Timeout')
        except ValueError:
            embed = discord.Embed(
                title=f'Input is not a rank: {rank}',
                description=' ',
                colour=discord.Colour.red()
            )
            await ctx.send(embeds=[embed], delete_after=5.0)