Beispiel #1
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")
Beispiel #2
0
    def test_current_week_none(self, mocker):
        self.mock_pickle(mocker)

        compo.current_week = None
        compo.next_week = "Raiden"

        compo.save_weeks()

        compo.pickle.dump.assert_not_called()
Beispiel #3
0
    def test_valid_write(self, mocker):
        self.mock_pickle(mocker)

        compo.current_week = "Solid"
        compo.next_week = "Snake"

        compo.save_weeks()

        compo.pickle.dump.assert_called()
        assert compo.pickle.dump.call_count == 2
Beispiel #4
0
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")
Beispiel #5
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)
Beispiel #6
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")
Beispiel #7
0
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")
Beispiel #8
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)
Beispiel #9
0
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()