コード例 #1
0
ファイル: compo_test.py プロジェクト: cbx33/wVote
    def test_will_load_if_week_is_none(self, mocker):
        self.mock_pickle(mocker)

        compo.current_week = None
        compo.next_week = None

        compo.get_week(False)

        compo.pickle.load.assert_called()
        assert compo.pickle.load.call_count == 2
コード例 #2
0
ファイル: http_server.py プロジェクト: Metallion/wVote
async def admin_control_handler(request: web_request.Request) -> CoroutineType:
    auth_key = request.match_info["authKey"]

    if key_valid(auth_key, admin_keys):
        this_week = compo.get_week(False)
        next_week = compo.get_week(True)

        data = await request.post()

        def data_param(week, param, field):
            nonlocal data

            if field in data:
                week[param] = data[field]

        data_param(this_week, "theme", "currentWeekTheme")
        data_param(this_week, "date", "currentWeekDate")
        data_param(next_week, "theme", "nextWeekTheme")
        data_param(next_week, "date", "nextWeekDate")

        if "submissionsOpen" in data:
            if data["submissionsOpen"] == "Yes":
                compo.get_week(True)["submissionsOpen"] = True
            if data["submissionsOpen"] == "No":
                compo.get_week(True)["submissionsOpen"] = False

        if "rolloutWeek" in data:
            if data["rolloutWeek"] == "on":
                compo.move_to_next_week()

        if "newEntryEntrant" in data:
            new_entry_week = True
            if "newEntryWeek" in data:
                new_entry_week = False

            new_entry_discord_id = None
            if "newEntryDiscordID" in data:
                if data["newEntryDiscordID"] != "":
                    try:
                        new_entry_discord_id = int(data["newEntryDiscordID"])
                    except ValueError:
                        new_entry_discord_id = None

            compo.create_blank_entry(data["newEntryEntrant"],
                                     new_entry_discord_id, new_entry_week)
        compo.save_weeks()
        return web.Response(status=204, text="Nice")
    else:
        return web.Response(status=404, text="File not found")
コード例 #3
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
async def submit(context: commands.Context) -> None:
    """Provides a link to submit your entry."""
    global config

    week = compo.get_week(True)

    if not week["submissionsOpen"]:
        closed_info = "Sorry! Submissions are currently closed."
        await context.send(closed_info)
        return

    for entry in week["entries"]:
        if entry["discordID"] == context.author.id:
            key = keys.create_edit_key(entry["uuid"])
            url = "%s/edit/%s" % (config["url_prefix"], key)
            edit_info = ("Link to edit your existing "
                         "submission: " + url + expiry_message())
            await context.send(edit_info)
            return

    new_entry = compo.create_blank_entry(context.author.name,
                                         context.author.id)
    week["entries"].append(new_entry)
    key = keys.create_edit_key(new_entry["uuid"])
    url = "%s/edit/%s" % (config["url_prefix"], key)

    await context.send("Submission form: " + url + expiry_message())
コード例 #4
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
async def submit(context: commands.Context) -> None:
    """
    Creates a submission entry for the user.
    Replies with a link to the management panel with options to create or edit.
    """
    week = compo.get_week(True)

    if not week["submissionsOpen"]:
        closed_info = "Sorry! Submissions are currently closed."
        await context.send(closed_info)
        return

    for entry in week["entries"]:
        if entry["discordID"] == context.author.id:
            key = http_server.create_edit_key(entry["uuid"])
            url = "%s/edit/%s" % (url_prefix(), key)
            edit_info = ("Link to edit your existing "
                         "submission: " + url + expiry_message())
            await context.send(edit_info)
            return

    new_entry = compo.create_blank_entry(context.author.name,
                                         context.author.id)
    key = http_server.create_edit_key(new_entry)
    url = "%s/edit/%s" % (url_prefix(), key)

    await context.send("Submission form: " + url + expiry_message())
コード例 #5
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
def help_message() -> str:
    """
    Creates and returns a help message for guiding users in the right direction.
    Additionally lets users know whether the submissions for this week are
    currently open.

    Returns
    -------
    str
        The generated help message.
    """
    msg = ("Hey there! I'm 8Bot-- My job is to help you participate in "
           "the 8Bit Music Theory Discord Weekly Composition Competition.\n")

    if compo.get_week(True)["submissionsOpen"]:
        msg += "Submissions for this week's prompt are currently open.\n"
        msg += "If you'd like to submit an entry, DM me the command `" + \
            client.command_prefix[0] + "submit`, and I'll give you "
        msg += "a secret link to a personal submission form."
    else:
        msg += "Submissions for this week's prompt are now closed.\n"
        msg += ("To see the already submitted entries for this week, "
                "head on over to " + url_prefix())

    return msg
コード例 #6
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
async def postentries(context: commands.Context) -> None:
    """
    Post the entries of the week to the current channel.
    Works in the postentries channel or in DMs.
    """
    week = compo.get_week(False)
    await publish_entries(context, week)
コード例 #7
0
async def submit_vote_handler(request: web_request.Request) -> web.Response:
    """Record user votes"""
    vote_input = await request.json()

    auth_key = vote_input["voteKey"]

    if not keys.key_valid(auth_key, keys.vote_keys):
        return web.Response(status=401, text="Invalid or expired vote token")

    user_id = keys.vote_keys[auth_key]["userID"]
    user_name = keys.vote_keys[auth_key]["userName"]
    user_votes = vote_input["votes"]

    week = compo.get_week(False)

    # If user has submitted a vote already, then remove it, so we can
    # replace it with the new one
    for v in week["votes"]:
        if int(v["userID"]) == int(user_id):
            week["votes"].remove(v)

    # Find the user's entry
    user_entry = None

    for entry in week["entries"]:
        if entry["discordID"] == user_id:
            user_entry = entry
            break

    # Remove the user's vote on their own entry (Search by UUID to prevent name spoofing).
    if user_entry is not None:
        user_votes = [
            vote for vote in user_votes
            if vote["entryUUID"] != user_entry["uuid"]
        ]

        # Find the user's highest rating
        max_vote = max(vote["rating"] for vote in user_votes)

        # Grant the user rating equal to their highest vote on each category
        for param in week["voteParams"]:
            user_votes.append({
                "entryUUID": user_entry["uuid"],
                "voteForName": user_name,
                "voteParam": param,
                "rating": max_vote
            })

    vote_data = {
        "ratings": user_votes,
        "userID": user_id,
        "userName": user_name
    }

    week["votes"].append(vote_data)

    compo.save_weeks()

    return web.Response(status=200, text="FRICK yeah")
コード例 #8
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
async def howmany(context: commands.Context) -> None:
    """
    Prints how many entries are currently submitted for the upcoming week.
    """

    response = "%d, so far." % compo.count_valid_entries(compo.get_week(True))

    await context.send(response)
コード例 #9
0
async def admin_preview_handler(request: web_request.Request) -> web.Response:
    """Display next weeks votable entries"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    return web.json_response(format_week(compo.get_week(True), False))
コード例 #10
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
def help_message(full: bool = False, is_admin: bool = False) -> str:
    """
    Creates and returns a help message for guiding users in the right direction.
    Additionally lets users know whether the submissions for this week are
    currently open.

    Returns
    -------
    str
        The generated help message.
    """
    global config

    commands = ["howmany", "submit", "vote", "status", "myresults"]
    admin_commands = [
        "getentryplacements", "postentries", "postentriespreview", "manage"
    ]

    msg = ("Hey there! I'm 8Bot-- My job is to help you participate in "
           "the 8Bit Music Theory Discord Weekly Composition Competition.\n")

    if compo.get_week(True)["submissionsOpen"]:
        msg += "Submissions for this week's prompt are currently open.\n"
        msg += "If you'd like to submit an entry, DM me the command `" + \
            client.command_prefix[0] + "submit`, and I'll give you "
        msg += "a secret link to a personal submission form. \n"
    else:
        msg += "Submissions for this week's prompt are now closed.\n"
        msg += ("To see the already submitted entries for this week, "
                "head on over to " + config["url_prefix"]) + "\n"

    if not full:
        msg += "Send `" + client.command_prefix[
            0] + "help` to see all available "
        msg += "commands."
    else:
        msg += "\nI understand the following commands: \n"

        for command in commands:
            msg += "`" + client.command_prefix[0] + command + "`: "
            msg += client.get_command(command).short_doc + "\n"

        if is_admin:
            msg += "\nAlso since you're an admin, here are some secret commands: \n"

            for command in admin_commands:
                msg += "`" + client.command_prefix[0] + command + "`: "
                msg += client.get_command(command).short_doc + "\n"

        if len(client.command_prefix) > 1:
            msg += "\n"
            msg += "Besides `" + client.command_prefix[
                0] + "` I understand the "
            msg += "following prefixes: " + ", ".join(
                "`" + prefix + "`" for prefix in client.command_prefix[1:])

    return msg
コード例 #11
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
async def crudbroke(context: commands.Context) -> None:
    week = compo.get_week(True)

    if not "crudbroke" in week:
        week["crudbroke"] = 0

    week["crudbroke"] += 1

    message = "Dang, that's happened %d times this week." % week["crudbroke"]

    await context.send(message)
コード例 #12
0
async def admin_get_data_handler(request: web_request.Request) -> web.Response:
    """Display admin data:

       - Week information
       - Submissions
       - Votes
    """
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    this_week = compo.get_week(False)
    next_week = compo.get_week(True)

    weeks = [format_week(this_week, True), format_week(next_week, True)]
    votes = get_week_votes(this_week)

    data = {"weeks": weeks, "votes": votes}

    return web.json_response(data)
コード例 #13
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
async def myresults(context: commands.Context) -> None:
    """Shows you your results on the latest vote."""
    week = compo.get_week(False)

    if week["votingOpen"]:
        await context.send(
            "You can't really get results while they're still coming "
            "in, despite what election coverage would lead you to believe; sorry."
        )
        return

    user_entry = None

    for entry in week["entries"]:
        if entry["discordID"] == context.author.id:
            user_entry = entry
            break

    if not user_entry:
        await context.send("You didn't submit anything for this week!")
        return

    compo.verify_votes(week)
    scores = compo.fetch_votes_for_entry(week["votes"], entry["uuid"])

    if len(scores) == 0:
        await context.send(
            "Well this is awkward, no one voted on your entry...")
        return

    message = []
    message.append(
        "Please keep in mind that music is subjective, and that "
        "these scores shouldn't be taken to represent the quality of"
        " your entry-- your artistic work is valuable, regardless of"
        " what results it was awarded, so don't worry too much about it")
    message.append("And with that out of the way...")
    message.append("*drumroll please*")
    for category in week["voteParams"]:
        category_scores = [
            s['rating'] for s in scores if s['voteParam'] == category
        ]
        if len(category_scores) == 0:
            # The user received votes, but not in this category
            category_scores = [0]
        text = "%s: You got an average score of %1.2f" \
            % (category, statistics.mean(category_scores))
        message.append(text)

    message.append("Your total average was: %1.2f!" %
                   statistics.mean(s['rating'] for s in scores))

    await context.send("\n".join(message))
コード例 #14
0
ファイル: compo_test.py プロジェクト: cbx33/wVote
    def test_will_load_only_one_week_is_none(self, mocker):
        self.mock_pickle(mocker)

        compo.current_week = "CURRENT WEEK"
        compo.next_week = None

        result = compo.get_week(False)

        compo.open.assert_called_with("weeks/next-week.pickle", "rb")
        compo.pickle.load.assert_called()
        assert compo.pickle.load.call_count == 1
        assert result == "CURRENT WEEK"
コード例 #15
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
async def status(context: commands.Context) -> None:

    week = compo.get_week(True)

    for entry in week["entries"]:
        if entry["discordID"] == context.author.id:
            await context.send(entry_info_message(entry))
            return

    await context.send(
        "You haven't submitted anything yet! But if you want to you can with %ssubmit !"
        % client.command_prefix[0])
コード例 #16
0
async def admin_control_handler(request: web_request.Request) -> web.Response:
    """Update week information"""
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    this_week = compo.get_week(False)
    next_week = compo.get_week(True)

    data = await request.json()

    next_week["theme"] = data["weeks"][1]["theme"]
    next_week["date"] = data["weeks"][1]["date"]
    next_week["submissionsOpen"] = data["weeks"][1]["submissionsOpen"]

    this_week["theme"] = data["weeks"][0]["theme"]
    this_week["date"] = data["weeks"][0]["date"]
    this_week["votingOpen"] = data["weeks"][0]["votingOpen"]

    compo.save_weeks()
    return web.Response(status=204, text="Nice")
コード例 #17
0
ファイル: bot.py プロジェクト: cbx33/wVote
async def getentryplacements(context: commands.Context) -> None:
    """Prints the entries ranked according to the STAR algoritm."""
    ranked = compo.get_ranked_entrant_list(compo.get_week(False))

    message = "```\n"

    for e in ranked:
        message += "%d - %s - %s (%f)\n" \
            % (e["votePlacement"], e["entrantName"],
               e["entryName"], e["voteScore"])

    message += "\n```"

    await context.send(message)
コード例 #18
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
async def googleformslist(context: commands.Context) -> None:
    """
    Generates the list of Google forms for the entries.
    """
    entries = compo.get_week(False)["entries"]

    response = "```\n"

    for e in entries:
        if not compo.entry_valid(e):
            continue
        response += "%s - %s\n" % (e["entrantName"], e["entryName"])

    response += "\n```"

    await context.channel.send(response)
コード例 #19
0
async def get_entry_handler(request: web_request.Request) -> web.Response:
    """Return an entry for editing"""
    auth_key = request.match_info["authKey"]

    if not compo.get_week(True)["submissionsOpen"]:
        return web.Response(status=400,
                            text="Submissions are currently closed!")

    if not keys.key_valid(auth_key, keys.edit_keys):
        return web.Response(status=401, text="Invalid or expired link")

    key = keys.edit_keys[auth_key]

    entry = compo.find_entry_by_uuid(key["entryUUID"])

    return web.json_response(get_editable_entry(entry))
コード例 #20
0
async def admin_viewvote_handler(request: web_request.Request) -> web.Response:
    """?"""
    auth_key = request.match_info["authKey"]
    user_id = request.match_info["userID"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    week = compo.get_week(False)

    for v in week["votes"]:
        if int(v["userID"]) == int(user_id):
            return web.Response(status=200,
                                body=json.dumps(v),
                                content_type="application/json")

    return web.Response(status=404, text="File not found")
コード例 #21
0
async def admin_deletevote_handler(
        request: web_request.Request) -> web.Response:
    """Delete every vote from an user"""
    auth_key = request.match_info["authKey"]
    user_id = request.match_info["userID"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    week = compo.get_week(False)
    week["votes"] = [
        vote for vote in week["votes"] if vote["userID"] != user_id
    ]

    compo.save_weeks()

    return web.Response(status=204)
コード例 #22
0
ファイル: http_server.py プロジェクト: Metallion/wVote
async def edit_handler(request: web_request.Request) -> CoroutineType:
    auth_key = request.match_info["authKey"]

    if not compo.get_week(True)["submissionsOpen"]:
        return web.Response(status=404,
                            text="Submissions are currently closed!")

    if key_valid(auth_key, edit_keys):
        key = edit_keys[auth_key]

        form = compo.get_edit_form_for_entry(key["entryUUID"], auth_key)
        html = submit_template.replace("[ENTRY-FORM]", form)
        html = html.replace("[ENTRANT-NAME]",
                            compo.get_entrant_name(key["entryUUID"]))

        return web.Response(status=200, body=html, content_type="text/html")
    else:
        return web.Response(status=404, text="File not found")
コード例 #23
0
async def admin_spoof_handler(request: web_request.Request) -> web.Response:
    """Create a fake new entry

       TODO: Take in more data?
    """
    auth_key = request.match_info["authKey"]

    if not keys.key_valid(auth_key, keys.admin_keys):
        return web.Response(status=401, text="Invalid or expired admin link")

    entry_data = await request.json()

    new_entry = compo.create_blank_entry(entry_data["entrantName"],
                                         int(entry_data["discordId"]))
    week = compo.get_week(entry_data["nextWeek"])
    week["entries"].append(new_entry)

    return web.Response(status=204, text="Nice")
コード例 #24
0
ファイル: bot.py プロジェクト: TrueAerosoul/wVote
async def openvoting(context: commands.Context) -> None:
    week = compo.get_week(False)
    week["votingOpen"] = True

    await context.send("Voting for the current week is now open.")
    compo.save_weeks()
コード例 #25
0
ファイル: bot.py プロジェクト: Metallion/wVote
async def on_message(message: discord.message.Message) -> CoroutineType:
    """
    Processes a message that is seen by the bot.

    Parameters
    ----------
    message : discord.message.Message
        The message seen by the bot
    """
    if message.author.id != client.user.id:
        if message.content.startswith(client.command_prefix):
            command = message.content[len(client.command_prefix):].lower()

            if command in ["postentries", "postentriespreview"] \
                    and str(message.author.id) in client.admins:
                week = compo.get_week(False)

                if command == "postentriespreview":
                    if not message.channel.type == discord.ChannelType.private:
                        await message.channel.send(dm_reminder)
                        return
                    week = compo.get_week(True)

                if command == "postentries" \
                        and postentries_channel != 0 \
                        and message.channel.id != postentries_channel \
                        and message.channel.type != discord.ChannelType.private:
                    await message.channel.send("This isn't the right channel"
                                               " for this!")
                    return

                async with message.channel.typing():
                    for entry in week["entries"]:
                        if not compo.entry_valid(entry):
                            continue

                        discord_user = client.get_user(entry["discordID"])

                        if discord_user is None:
                            entrant_ping = "@" + entry["entrantName"]
                        else:
                            entrant_ping = discord_user.mention

                        upload_files = []
                        upload_message = "%s - %s" % (entrant_ping,
                                                      entry["entryName"])

                        if "entryNotes" in entry:
                            upload_message += "\n" + entry["entryNotes"]

                        if entry["mp3Format"] == "mp3":
                            upload_files.append(
                                discord.File(io.BytesIO(bytes(entry["mp3"])),
                                             filename=entry["mp3Filename"]))
                        elif entry["mp3Format"] == "external":
                            upload_message += "\n" + entry["mp3"]

                        upload_files.append(
                            discord.File(io.BytesIO(bytes(entry["pdf"])),
                                         filename=entry["pdfFilename"]))

                        await message.channel.send(upload_message,
                                                   files=upload_files)

            if command == "manage" and str(message.author.id) in client.admins:
                if message.channel.type == discord.ChannelType.private:
                    key = http_server.create_admin_key()

                    url = "%s/admin/%s" % (url_prefix(), key)
                    await message.channel.send("Admin interface: " + url
                                               + expiry_message())
                    return

                else:

                    await message.channel.send(dm_reminder)
                    return

            if command == "submit":
                if message.channel.type == discord.ChannelType.private:
                    if not compo.get_week(True)["submissionsOpen"]:
                        closed_info = "Sorry! Submissions are currently closed."
                        await message.channel.send(closed_info)
                        return

                    week = compo.get_week(True)

                    for entry in week["entries"]:
                        if entry["discordID"] == message.author.id:
                            key = http_server.create_edit_key(entry["uuid"])
                            url = "%s/edit/%s" % (url_prefix(), key)
                            edit_info = ("Link to edit your existing "
                                         "submission: " + url
                                         + expiry_message())
                            await message.channel.send(edit_info)
                            return

                    new_entry = compo.create_blank_entry(
                        message.author.name, message.author.id)
                    key = http_server.create_edit_key(new_entry)
                    url = "%s/edit/%s" % (url_prefix(), key)

                    await message.channel.send("Submission form: " + url
                                               + expiry_message())
                    return

                else:
                    await message.channel.send(dm_reminder)
                    return

            if command == "help":
                await message.channel.send(help_message())
                return
        else:
            if message.channel.type == discord.ChannelType.private:
                await message.channel.send(help_message())
                return

            if str(client.user.id) in message.content:
                await message.channel.send(help_message())
                return
コード例 #26
0
async def get_entries_handler(request: web_request.Request) -> web.Response:
    """Display this weeks votable entries"""
    return web.json_response(format_week(compo.get_week(False), False))
コード例 #27
0
ファイル: bot.py プロジェクト: MrMyastan/wVote
async def postentriespreview(context: commands.Context) -> None:
    """
    Post the entries of the next week. Only works in DMs.
    """
    week = compo.get_week(True)
    await publish_entries(context, week)
コード例 #28
0
async def file_post_handler(request: web_request.Request) -> web.Response:
    """Handle user submission.
       If user was an admin, mark entry as meddled with.

       This takes multipart/form-encoding because of large files
    """
    auth_key = request.match_info["authKey"]
    uuid = request.match_info["uuid"]

    is_authorized_user = (keys.key_valid(auth_key, keys.edit_keys)
                          and keys.edit_keys[auth_key]["entryUUID"] == uuid
                          and compo.get_week(True)["submissionsOpen"])

    is_admin = keys.key_valid(auth_key, keys.admin_keys)
    is_authorized = is_authorized_user or is_admin
    if not is_authorized:
        return web.Response(status=401, text="Invalid or expired link")

    # Find the entry
    choice = None
    for which_week in [True, False]:
        week = compo.get_week(which_week)

        for entryIndex, entry in enumerate(week["entries"]):
            if entry["uuid"] == uuid:
                choice = (week, entryIndex, entry)
                break

    if choice is None:
        return web.Response(status=404,
                            text="That entry doesn't seem to exist")

    week, entryIndex, entry = choice

    # Process it
    reader = await request.multipart()
    if reader is None:
        return web.Response(status=400, text="Error uploading data idk")

    async for field in reader:
        if is_admin:
            if field.name == "entrantName":
                entry["entrantName"] = \
                    (await field.read(decode=True)).decode("utf-8")
            elif field.name == "entryNotes":
                entry["entryNotes"] = \
                    (await field.read(decode=True)).decode("utf-8")
                if entry["entryNotes"] == "undefined":
                    entry["entryNotes"] = ""
            elif field.name == "deleteEntry":
                week["entries"].remove(entry)
                compo.save_weeks()
                return web.Response(status=200,
                                    text="Entry successfully deleted.")

        if field.name == "entryName":
            entry["entryName"] = \
                (await field.read(decode=True)).decode("utf-8")
        elif field.name == "mp3Link":
            url = (await field.read(decode=True)).decode("utf-8")
            if len(url) > 1:
                if not any(
                        url.startswith(host)
                        for host in config["allowed_hosts"]):
                    return web.Response(
                        status=400,
                        text="You entered a link to a website we don't allow.")

                entry["mp3"] = url
                entry["mp3Format"] = "external"
                entry["mp3Filename"] = ""
        elif field.name == "mp3" or field.name == "pdf":
            if field.filename == "":
                continue
            if not field.filename.endswith(field.name):
                errMsg = "Wrong file format! Expected %s" % field.name
                return web.Response(status=400, text=errMsg)

            size = 0
            entry[field.name] = None

            entry[field.name + "Filename"] = field.filename

            if field.name == "mp3":
                entry["mp3Format"] = "mp3"

            while True:
                chunk = await field.read_chunk()
                if not chunk:
                    break
                size += len(chunk)
                if size > 1000 * 1000 * 8:  # 8MB limit
                    entry[field.name] = None
                    entry[field.name + "Filename"] = None
                    return web.Response(status=413, text=too_big_text)
                if entry[field.name] is None:
                    entry[field.name] = chunk
                else:
                    entry[field.name] += chunk

    if not is_admin:
        # Move the entry to the end of the list
        week["entries"].append(week["entries"].pop(entryIndex))

    compo.save_weeks()

    await bot.submission_message(entry, is_admin)

    return web.Response(status=204)
コード例 #29
0
ファイル: http_server.py プロジェクト: Metallion/wVote
async def file_post_handler(request: web_request.Request) -> CoroutineType:
    auth_key = request.match_info["authKey"]
    uuid = request.match_info["uuid"]

    if (key_valid(auth_key, edit_keys)
        and edit_keys[auth_key]["entryUUID"] == uuid
        and compo.get_week(True)["submissionsOpen"]) \
            or key_valid(auth_key, admin_keys):
        for which_week in [True, False]:
            week = compo.get_week(which_week)

            for entry in week["entries"]:
                if entry["uuid"] != uuid:
                    continue

                reader = await request.multipart()

                if reader is None:
                    return web.Response(status=400, text="Not happening babe")

                while True:
                    field = await reader.next()

                    if field is None:
                        break

                    if field.name == "entryName":
                        entry["entryName"] = \
                            (await field.read(decode=True)).decode("utf-8")
                    elif (field.name == "entrantName"
                          and key_valid(auth_key, admin_keys)):
                        entry["entrantName"] = \
                            (await field.read(decode=True)).decode("utf-8")
                    elif (field.name == "entryNotes"
                          and key_valid(auth_key, admin_keys)):
                        entry["entryNotes"] = \
                            (await field.read(decode=True)).decode("utf-8")

                    elif (field.name == "deleteEntry"
                          and key_valid(auth_key, admin_keys)):
                        week["entries"].remove(entry)
                        compo.save_weeks()
                        return web.Response(status=200,
                                            text="Entry successfully deleted.")

                    elif field.name == "mp3Link":
                        url = (await field.read(decode=True)).decode("utf-8")
                        if len(url) > 1:
                            entry["mp3"] = url
                            entry["mp3Format"] = "external"
                            entry["mp3Filename"] = ""

                    elif field.name == "mp3" or field.name == "pdf":
                        if field.filename == "":
                            continue

                        size = 0
                        entry[field.name] = None

                        entry[field.name + "Filename"] = field.filename

                        if field.name == "mp3":
                            entry["mp3Format"] = "mp3"

                        while True:
                            chunk = await field.read_chunk()

                            if not chunk:
                                break

                            size += len(chunk)

                            if size > 1024 * 1024 * 8:  # 8MB limit
                                entry[field.name] = None
                                entry[field.name + "Filename"] = None
                                return web.Response(status=413,
                                                    text=too_big_text)

                            if entry[field.name] is None:
                                entry[field.name] = chunk
                            else:
                                entry[field.name] += chunk

                compo.save_weeks()

                await bot.submission_message(entry)

                return web.Response(status=200,
                                    body=submit_success,
                                    content_type="text/html")

        return web.Response(status=400,
                            text="That entry doesn't seem to exist")

    else:
        return web.Response(status=403, text="Not happening babe")
コード例 #30
0
ファイル: http_server.py プロジェクト: Metallion/wVote
def get_admin_controls(auth_key: str) -> str:
    this_week = compo.get_week(False)
    next_week = compo.get_week(True)

    html = ""

    def text_field(field: str, label: str, value: str) -> None:
        nonlocal html
        html += "<form action='/admin/edit/%s' " % auth_key
        html += ("onsubmit='setTimeout(function()"
                 "{window.location.reload();},100);' ")
        html += ("method='post' accept-charset='utf-8' "
                 "enctype='application/x-www-form-urlencoded'>")

        html += "<label for='%s'>%s</label>" % (field, label)
        html += "<input name='%s' type='text' value='%s' />" % (
            field, html_lib.escape(value))
        html += "<input type='submit' value='Submit'/>"
        html += "</form><br>"

    text_field("currentWeekTheme", "Theme/title of current week",
               this_week["theme"])
    text_field("currentWeekDate", "Date of current week", this_week["date"])
    text_field("nextWeekTheme", "Theme/title of next week", next_week["theme"])
    text_field("nextWeekDate", "Date of next week", next_week["date"])

    if compo.get_week(True)["submissionsOpen"]:
        html += "<p>Submissions are currently OPEN</p>"
    else:
        html += "<p>Submissions are currently CLOSED</p>"

    # TODO: This is all html code, so it should probably go in a .html ;P

    html += "<form action='/admin/edit/%s' " % auth_key
    html += "onsubmit='setTimeout(function(){window.location.reload();},100);' "
    html += ("method='post' accept-charset='utf-8' "
             "enctype='application/x-www-form-urlencoded'>")
    html += "<label for='submissionsOpen'>Submissions Open</label>"
    html += "<input type='radio' name='submissionsOpen' value='Yes'>"
    html += "<label for='Yes'>Yes</label>"
    html += "<input type='radio' name='submissionsOpen' value='No'>"
    html += "<label for='No'>No</label>"
    html += "<input type='submit' value='Submit'/>"
    html += "</form><br>"

    html += ("<form style='border: 1px solid black;' "
             "action='/admin/edit/%s' " % auth_key)
    html += "onsubmit='setTimeout(function(){window.location.reload();},100);' "
    html += ("method='post' accept-charset='utf-8' "
             "enctype='application/x-www-form-urlencoded'>")
    html += "<label>Force create an entry</label><br>"
    html += "<label for='newEntryEntrant'>Spoofed entrant name</label>"
    html += "<input type='text' name='newEntryEntrant' value='Wiglaf'><br>"
    html += ("<label for='newEntryDiscordID'>(Optional) "
             "Spoofed entrant discord ID</label>")
    html += "<input type='text' name='newEntryDiscordID' value=''><br>"
    html += ("<label for='newEntryWeek'>Place entry in current week "
             "instead of next week?</label>")
    html += "<input type='checkbox' name='newEntryWeek' value='on'><br>"
    html += "<input type='submit' value='Submit'/>"
    html += "</form><br>"

    html += "<form action='/admin/edit/%s' " % auth_key
    html += "onsubmit='setTimeout(function(){window.location.reload();},100);' "
    html += ("method='post' accept-charset='utf-8' "
             "enctype='application/x-www-form-urlencoded'>")
    html += ("<label for='rolloutWeek'>Archive current week, "
             "and make next week current</label>")
    html += "<input type='checkbox' name='rolloutWeek' value='on'>"
    html += "<input type='submit' value='Submit'/>"
    html += "</form>"

    return html