Пример #1
0
    async def remove_scheduled_events(self, ctx, tag=None):
        """
        Removes a scheduled event.

        For create channel events the tag is create + the channel's name.
        For delete channel events the tag is delete + the channel's id.
        For purge messages from channel the tag is purge + the channel's id.
        For send message in channel the tag is send + the channel's id.

        If no tag is provided then all scheduled events will be canceled.

        Usage: ?remove_scheduled_events createsome_channel_name
        Usage: ?remove_scheduled_events delete182736519823
        Usage: ?remove_scheduled_events purge182736519823
        Usage: ?remove_scheduled_events send182736519823
        """

        schedule.clear(tag)
        if tag is None:
            execute_statement(create_delete_query("configure__schedule"))
            await ctx.send(f"Removed all scheduled events")
        else:
            execute_statement(
                create_delete_query("configure__schedule", "tag", f"'{tag}'"))
            await ctx.send(f"Removed all scheduled events with tag [{tag}]")
Пример #2
0
    async def purge(self,
                    ctx,
                    channel_id,
                    weekday,
                    at_time,
                    number_of_messages=0):
        """
        Purges the [number_of_messages] latest messages from the specified channel.
        If no [number_of_messages] is provided the given channel will be emptied.

        Usage: ?configure schedule purge some_channel_id monday 13:00 2
        """
        channel_to_purge = self.bot.get_channel(int(channel_id))
        number = None if number_of_messages == 0 else int(number_of_messages)

        await scheduler.schedule_new_task(self.bot,
                                          ctx,
                                          _schedule_purge,
                                          "configure/schedule/purge",
                                          weekday,
                                          at_time,
                                          "purge" + channel_id,
                                          channel=channel_to_purge,
                                          number=number)

        if at_time != "0":
            execute_statement(
                create_insert_scheduled_event_query(task="purge",
                                                    weekday=weekday,
                                                    at_time=at_time,
                                                    tag="purge" + channel_id,
                                                    channel_id=int(channel_id),
                                                    number=number_of_messages))
Пример #3
0
    async def send_message(self, ctx, channel_id, weekday, at_time, *args):
        """
        Sends [message] in the specified channel every [weekday] at [at_time].

        Usage: ?configure schedule send_message 8126387123 monday 13:00 some message here
        """
        await scheduler.schedule_new_task(self.bot,
                                          ctx,
                                          _message_channel,
                                          "configure/schedule/send_message",
                                          weekday,
                                          at_time,
                                          "send" + channel_id,
                                          channel=self.bot.get_channel(
                                              int(channel_id)),
                                          message=" ".join(args[:]))

        if at_time != "0":
            execute_statement(
                create_insert_scheduled_event_query(task="send_message",
                                                    weekday=weekday,
                                                    at_time=at_time,
                                                    tag="send" + channel_id,
                                                    channel_id=int(channel_id),
                                                    message=" ".join(args[:])))
Пример #4
0
    async def create_channel(self, ctx, channel_name, category_id, weekday,
                             at_time):
        """
        Creates a channel at a specified time every week.

        Usage: ?configure schedule create_channel some_channel_name 12756371253 monday 13:00
        """
        await scheduler.schedule_new_task(self.bot,
                                          ctx,
                                          _create_channel,
                                          "configure/schedule/create_channel",
                                          weekday,
                                          at_time,
                                          "create" + channel_name,
                                          guild=ctx.message.guild,
                                          channel_name=channel_name,
                                          category=discord.utils.get(
                                              ctx.guild.categories,
                                              id=int(category_id)))

        if at_time != "0":
            execute_statement(
                create_insert_scheduled_event_query(
                    task="create_channel",
                    weekday=weekday,
                    at_time=at_time,
                    tag="create" + channel_name,
                    channel_name=channel_name,
                    category_id=int(category_id),
                    guild_id=ctx.message.guild.id))
Пример #5
0
    async def claim(self, ctx):
        """
        Use this command to gain access to the leaderboards.

        Usage: ?claim
        """
        await message_wrapper.delete_message(bot=self.bot,
                                             message=ctx.message,
                                             source="Claim")

        if await _validate_eligibility(ctx):
            execute_statement(
                f"INSERT INTO idclaims (name, user_id) VALUES ('{ctx.author.display_name}', {ctx.author.id})"
            )

            role = discord.utils.get(ctx.message.guild.roles, name="claimed")
            await ctx.message.author.add_roles(role)

            command_channel = discord.utils.get(ctx.message.guild.channels,
                                                name="leaderboards")
            await message_wrapper.message_user(self.bot,
                                               ctx.message.author,
                                               _create_introductory_message(),
                                               source="Claim")
            await message_wrapper.message_channel(
                bot=self.bot,
                channel=ctx.message.channel,
                message=
                f""":white_check_mark: {ctx.message.author.mention} you have claimed the nickname """
                f"""{ctx.message.author.display_name}. Type ?help in {command_channel.mention} """
                f"""for help on how to get started.""")
Пример #6
0
    async def leaderboard(self, ctx, score):
        """
        Submit your score to a given leaderboard.

        Usage: ?jogger 507
        """
        await _validate_user(self.bot, ctx, score)

        # extract data
        try:
            score = float(score.replace(",", "."))
            invoked_leaderboard = ctx.invoked_with
            if invoked_leaderboard == "leaderboard":
                await ctx.send(
                    "Please submit to a specific leaderboard, such as jogger, type ?help for example usage."
                )
                return

            if invoked_leaderboard != "jogger":
                score = int(score)
        except:
            return

        # get previous top 3
        previous_top_3 = execute_statement(
            create_select_top_x_scores_query(table_name=invoked_leaderboard,
                                             limit=3)).all(as_dict=True)

        # insert entry into leaderboard
        execute_statement(
            f"INSERT INTO leaderboard__{invoked_leaderboard} (name, score, submit_date) VALUES ('{ctx.author.display_name}', {score}, DATE '{datetime.now().date()}')"
        )

        # select 10 highest ranks
        descending_score_dict = execute_statement(
            create_select_top_x_scores_query(table_name=invoked_leaderboard,
                                             limit=10)).all(as_dict=True)

        leaderboard_channel = discord.utils.get(ctx.guild.channels,
                                                name=invoked_leaderboard)
        embed = _create_leaderboard_embed(leaderboard=invoked_leaderboard,
                                          score_dict=descending_score_dict,
                                          command_channel=discord.utils.get(
                                              ctx.guild.channels,
                                              name="leaderboards"))
        if ctx.channel.name != "momos_test_dungeon":
            await _update_leaderboard_embed(embed, leaderboard_channel)
        await _congratulate_submitter(ctx, leaderboard_channel, previous_top_3,
                                      descending_score_dict[:3])
Пример #7
0
async def _validate_claimed_user(bot, ctx):
    """Validates that current nickname matches claimed_id"""
    author_id = ctx.author.id
    author_name = ctx.author.display_name
    statement = create_select_query(table_name="leaderboard__idclaims",
                                    where_key="user_id",
                                    where_value=author_id)
    try:
        rows = execute_statement(statement)
        user_id = rows.first(as_dict=True).get("user_id")
        user_name = rows.first(as_dict=True).get("name")

        if len(rows.all()
               ) > 1 or user_id != author_id or user_name != author_name:
            raise AssertionError("Username doesn't match claimed username")
    except Exception as e:
        await ctx.send(
            "Something wrong with your claimed name, did you change your nickname? Contact an admin."
        )
        await pm_dev_error(
            bot=bot,
            error_message=
            f"\nAuthor ID: {author_id}, Author Name: {author_name}\nSQL QUERY: {statement}",
            source="_validate_claimed_user")
        raise AssertionError("Username doesn't match claimed username")
Пример #8
0
async def _validate_eligibility(ctx):
    """
    Checks that the user has not already claimed access to the leaderboards and has a valid nickname.
    """
    error_in_nickname = _check_invalid_nickname(
        ctx.message.author.display_name)
    rows = execute_statement(
        create_select_query(table_name="leaderboard__idclaims",
                            where_key="user_id",
                            where_value=str(
                                ctx.message.author.id))).all(as_dict=True)

    if len(rows) > 0:
        await message_wrapper.message_channel(
            bot=ctx.bot,
            channel=ctx.message.channel,
            message=
            f""":no_entry: You have already claimed access to the leaderboards, """
            f"""{ctx.message.author.mention}, if you have recently changed your nickname, """
            f"""please contact an admin.""",
            source="claim")
        return False
    elif error_in_nickname:
        await message_wrapper.message_channel(bot=ctx.bot,
                                              channel=ctx.channel,
                                              message=error_in_nickname)
        return False
    return True
async def add_to_leaderboards_test(bot, ctx):
    # check that user is not in test leaderboard before
    assert (len(
        execute_statement(
            create_select_query(
                table_name="leaderboard__test",
                where_key="name",
                where_value=f"'{ctx.author.display_name}'")).all(
                    as_dict=True)) == 0)
    try:
        await catch_with_channel_message(
            invoke_wrapper.invoke_event_now, common.TEST_RESULTS_CHANNEL,
            f":no_entry: Error during leaderboard #test invocation", True,
            f"integration/leaderboard", bot, ctx, f"leaderboard",
            f"leaderboard", *["500000000"])
        await common.TEST_RESULTS_CHANNEL.send(
            f":white_check_mark:  Leaderboard[Add to leaderboard]: Successfully added "
            f"a user to the test leaderboard!")

        # check that user is in test leaderboard after
        assert (len(
            execute_statement(
                create_select_query(
                    table_name="leaderboard__test",
                    where_key="name",
                    where_value=f"'{ctx.author.display_name}'")).all(
                        as_dict=True)) == 1)
        # remove user from leaderboard table again
        execute_statement(
            create_delete_query(table_name="leaderboard__test",
                                where_key="name",
                                where_value=f"'{ctx.author.display_name}'"))
        # check that user is no longer in leaderboard
        assert (len(
            execute_statement(
                create_select_query(
                    table_name="leaderboard__test",
                    where_key="name",
                    where_value=f"'{ctx.author.display_name}'")).all(
                        as_dict=True)) == 0)
    except Exception as e:
        traceback.print_exc()
        await common.TEST_RESULTS_CHANNEL.send(
            f":no_entry: Leaderboard: Error during add_to_leaderboard integration-tests: {e}"
        )
        raise ValueError("Error in Leaderboards integration-test")
Пример #10
0
    async def delete_channel(self, ctx, channel_id, weekday, at_time):
        """
        Deletes a channel at a specified time every week.

        Usage: ?configure schedule delete_channel some_channel_id monday 13:00
        """
        await scheduler.schedule_new_task(self.bot,
                                          ctx,
                                          _remove_channel,
                                          "configure/schedule/delete_channel",
                                          weekday,
                                          at_time,
                                          "delete" + channel_id,
                                          channel=self.bot.get_channel(
                                              int(channel_id)))

        if at_time != "0":
            execute_statement(
                create_insert_scheduled_event_query(
                    task="remove_channel",
                    weekday=weekday,
                    at_time=at_time,
                    tag="delete" + channel_id,
                    channel_id=int(channel_id)))
Пример #11
0
def _rename_user_in_idclaims(new_name, user_id) -> bool:
    """
    :param new_name: The new name to replace the previous name with
    :param user_to_replace: The string to find in the entry
    :return: Returns bool if the user was found and the name that was replaced
    """
    previous_entry = execute_statement(
        create_select_query("leaderboard__idclaims", "user_id",
                            f"'{user_id}'")).all(as_dict=True)
    execute_statement(
        create_update_query("leaderboard__idclaims", "name", f"'{new_name}'",
                            "user_id", f"'{user_id}'"))
    updated_entry = execute_statement(
        create_select_query("leaderboard__idclaims", "user_id",
                            f"'{user_id}'")).all(as_dict=True)

    try:
        if previous_entry[0].get("name") != new_name and updated_entry[0].get(
                "name") == new_name:
            return True
        else:
            return False
    except:
        return False
Пример #12
0
    async def from_leaderboard(self, ctx, leaderboard, user_name):
        """
        [Admin only]: Delete a user from a given leaderboard.

        Usage: ?delete from_leaderboard jogger McMomo
        """
        if leaderboard in common.LEADERBOARD_LIST:
            in_leaderboard_before = execute_statement(
                create_select_query(f"leaderboard__{leaderboard}", "name",
                                    f"'{user_name}'")).all(True)
            execute_statement(
                create_delete_query(f"leaderboard__{leaderboard}", "name",
                                    f"'{user_name}'"))
            in_leaderboard_after = execute_statement(
                create_select_query(f"leaderboard__{leaderboard}", "name",
                                    f"'{user_name}'")).all(True)

            if len(in_leaderboard_before) == 1 and len(
                    in_leaderboard_after) == 0:
                await ctx.send(f"Removed {user_name} from {leaderboard}")
            else:
                await ctx.send(f"Could not find {user_name} in {leaderboard}")
        else:
            await ctx.send(f"Can't find the {leaderboard} leaderboard")
Пример #13
0
def _schedule_event(bot: discord.ext.commands.Bot):
    task_info_list = execute_statement(
        create_select_query("configure__schedule")).all(as_dict=True)
    for task_info in task_info_list:
        local_guild: discord.Guild = bot.get_guild(task_info.get("guild_id"))
        re_schedule_task(
            bot,
            _get_task(task_info.get("task")),
            task_info.get("weekday"),
            task_info.get("at_time"),
            task_info.get("tag"),
            message=task_info.get("message"),
            channel=bot.get_channel(int(task_info.get("channel_id"))),
            number=task_info.get("number"),
            guild=local_guild,
            category=None if local_guild is None else discord.utils.get(
                local_guild.categories, id=int(task_info.get("category_id"))))
Пример #14
0
    async def list(self, ctx, leaderboard):
        """
        List your position in a given leaderboard.

        This command will list the top 5 of the leaderboard as well as your position and your closest competitors.

        Usage: ?list jogger
        """
        if leaderboard not in common.LEADERBOARD_LIST:
            await ctx.send(f"The **{leaderboard}** leaderboard does not exist."
                           )
            return

        rows = execute_statement(
            create_select_top_x_scores_query(leaderboard)).all(as_dict=True)

        found = False
        list_message = f"**---{leaderboard.capitalize()} list:---**\n"

        for index, entry in enumerate(rows):
            # if user is top 5
            if index < 5:
                if entry.get("name") == ctx.author.display_name:
                    found = True
                list_message += f"{index + 1}. {entry.get('name')} {entry.get('score')}\n"
            elif index == 5:
                if found:
                    await ctx.send(list_message)
                    return
                else:
                    list_message += "-----------------\n"
            elif index > 5 and entry.get("name") == ctx.author.display_name:
                list_message += f"{index - 1}. {rows[index - 2].get('name')} {entry.get('score')}\n"
                list_message += f"{index}. {rows[index - 1].get('name')} {entry.get('score')}\n"
                list_message += f"{index + 1}. {entry.get('name')} {entry.get('score')}\n"
                await ctx.send(list_message)
                return

        if not found:
            await ctx.send(
                f"Could not find {ctx.author.display_name} in {discord.utils.get(ctx.guild.channels, name=leaderboard).mention}"
            )
        # Leaderboard had fewer than 5 entries
        else:
            await ctx.send(list_message)
Пример #15
0
    async def refresh(self, ctx, leaderboard):
        """
        [Admin only] Refreshes a given leaderboard. Useful after manual intervention.
        """
        if leaderboard not in common.LEADERBOARD_LIST and leaderboard != "test":
            await ctx.send(f"Could not find the {leaderboard} leaderboard.")
            return

        descending_score_dict = execute_statement(
            create_select_top_x_scores_query(table_name=leaderboard,
                                             limit=10)).all(as_dict=True)

        leaderboard_channel = discord.utils.get(ctx.guild.channels,
                                                name=leaderboard)
        embed = _create_leaderboard_embed(leaderboard=leaderboard,
                                          score_dict=descending_score_dict,
                                          command_channel=discord.utils.get(
                                              ctx.guild.channels,
                                              name="leaderboards"))

        await _update_leaderboard_embed(embed, leaderboard_channel)
        await ctx.send(f"Refreshed the {leaderboard} leaderboard.")
Пример #16
0
async def _congratulate_submitter(ctx, leaderboard_channel,
                                  previous_top_3: dict, current_top_3: dict):
    """Sends a congratulations message custom to which ranking the user got"""
    name = ctx.author.display_name

    # if submission made top 3
    if any(name == entry.get("name") for entry in current_top_3):
        for index, user in enumerate(current_top_3):
            # new rank 1
            if index == 0 and name == user.get(
                    "name") and not name == previous_top_3[0].get("name"):
                await ctx.send(
                    f":crown: :first_place: CONGRATULATIONS {ctx.author.mention} on your new #{index + 1} placement in the {leaderboard_channel.mention} leaderboard!"
                    f"\nPlease send an in-game screenshot to any admin for verification."
                )
            # new top 3
            elif name == user.get("name") and not any(
                    name == user_entry.get("name")
                    for user_entry in previous_top_3):
                await ctx.send(
                    f":crown: Congratulations {ctx.author.mention} on your #{index + 1} placement in the {leaderboard_channel.mention} leaderboard!"
                    f"\nPlease send an in-game screenshot to any admin for verification."
                )
            elif name == user.get("name"):
                await ctx.send(
                    f":crown: Congratulations {ctx.author.mention} on your #{index + 1} position in the {leaderboard_channel.mention} leaderboard!"
                )
    # submission not top 3
    else:
        record_collection = execute_statement(
            create_select_top_x_scores_query(leaderboard_channel.name))
        ranking = get_ranking_of_user(name=name,
                                      record_collection=record_collection)
        await ctx.send(
            f"Nice work {ctx.author.mention} on your #{ranking} position in the {leaderboard_channel.mention} leaderboard, keep it up!"
        )