Exemple #1
0
def profile():
    logger.info("endpoint: profile")

    session_id = get_session_id()
    user_id = int(database.hget(f"web.session:{session_id}", "user_id"))

    if user_id != 0:
        avatar_hash, avatar_url, username, discriminator = (
            stat.decode("utf-8") for stat in database.hmget(
                f"web.user:{user_id}", "avatar_hash", "avatar_url", "username",
                "discriminator"))
        placings = int(database.zscore("users:global", str(user_id)))
        max_streak = int(database.zscore('streak.max:global', str(user_id)))
        missed_birds = [[
            stats[0].decode("utf-8"), int(stats[1])
        ] for stats in database.zrevrangebyscore(f"incorrect.user:{user_id}",
                                                 "+inf", "-inf", 0, 10, True)]
        return {
            "avatar_hash": avatar_hash,
            "avatar_url": avatar_url,
            "username": username,
            "discriminator": discriminator,
            "rank": placings,
            "max_streak": max_streak,
            "missed": missed_birds
        }
    else:
        logger.info("not logged in")
        abort(403, "Sign in to continue")
Exemple #2
0
def get_bird():
    logger.info("endpoint: get bird")
    session_id = get_session_id()
    media_type = flask.request.args.get("media", "images", str)

    filters = Filter.parse(flask.request.args.get("addon", "", str))
    if bool(flask.request.args.get("bw", 0, int)):
        filters.bw = True
    logger.info(f"args: media: {media_type}; filters: {filters};")

    logger.info(
        "bird: " + database.hget(f"web.session:{session_id}", "bird").decode("utf-8")
    )

    tempScore = int(database.hget(f"web.session:{session_id}", "tempScore"))
    if tempScore >= 10:
        logger.info("trial maxed")
        flask.abort(403, "Sign in to continue")

    if media_type not in ("images", "songs"):
        logger.error(f"invalid media type {media_type}")
        flask.abort(406, "Invalid media type")

    answered = int(database.hget(f"web.session:{session_id}", "answered"))
    logger.info(f"answered: {answered}")
    # check to see if previous bird was answered
    if answered:  # if yes, give a new bird
        id_list = songBirds if media_type == "songs" else birdList
        currentBird = random.choice(id_list)
        user_id = int(database.hget(f"web.session:{session_id}", "user_id"))
        if user_id != 0:
            session_increment(user_id, "total", 1)
            increment_bird_frequency(currentBird, user_id)
        prevB = database.hget(f"web.session:{session_id}", "prevB").decode("utf-8")
        while currentBird == prevB and len(id_list) > 1:
            currentBird = random.choice(id_list)
        database.hset(f"web.session:{session_id}", "prevB", str(currentBird))
        database.hset(f"web.session:{session_id}", "bird", str(currentBird))
        database.hset(f"web.session:{session_id}", "media_type", str(media_type))
        logger.info("currentBird: " + str(currentBird))
        database.hset(f"web.session:{session_id}", "answered", "0")
        file_object, ext = asyncio.run(send_bird(currentBird, media_type, filters))
    else:  # if no, give the same bird
        file_object, ext = asyncio.run(
            send_bird(
                database.hget(f"web.session:{session_id}", "bird").decode("utf-8"),
                database.hget(f"web.session:{session_id}", "media_type").decode(
                    "utf-8"
                ),
                filters,
            )
        )

    logger.info(f"file_object: {file_object}")
    logger.info(f"extension: {ext}")
    return flask.send_file(file_object, attachment_filename=f"bird.{ext}")
Exemple #3
0
def hint_bird():
    logger.info("endpoint: hint bird")

    session_id = get_session_id()
    currentBird = database.hget(f"web.session:{session_id}", "bird").decode("utf-8")
    if currentBird != "":  # check if there is bird
        return {"hint": currentBird[0]}

    logger.info("bird is blank")
    flask.abort(406, "Bird is blank")
    return None
Exemple #4
0
def get_bird():
    logger.info("endpoint: get bird")
    session_id = get_session_id()
    media_type = request.args.get("media", "images", str)
    addon = request.args.get("addon", "", str)
    bw = bool(request.args.get("bw", 0, int))
    logger.info(f"args: media: {media_type}; addon: {addon}; bw: {bw};")

    logger.info(
        "bird: " +
        database.hget(f"web.session:{session_id}", "bird").decode("utf-8"))

    tempScore = int(database.hget(f"web.session:{session_id}", "tempScore"))
    if tempScore >= 10:
        logger.info("trial maxed")
        abort(403, "Sign in to continue")

    if media_type != "images" and media_type != "songs":
        logger.error(f"invalid media type {media_type}")
        abort(406, "Invalid media type")
        return

    answered = int(database.hget(f"web.session:{session_id}", "answered"))
    logger.info(f"answered: {answered}")
    # check to see if previous bird was answered
    if answered:  # if yes, give a new bird
        currentBird = random.choice(birdList)
        prevB = database.hget(f"web.session:{session_id}",
                              "prevB").decode("utf-8")
        while currentBird == prevB and len(birdList) > 1:
            currentBird = random.choice(birdList)
        database.hset(f"web.session:{session_id}", "prevB", str(currentBird))
        database.hset(f"web.session:{session_id}", "bird", str(currentBird))
        database.hset(f"web.session:{session_id}", "media_type",
                      str(media_type))
        logger.info("currentBird: " + str(currentBird))
        database.hset(f"web.session:{session_id}", "answered", "0")
        file_object, ext = asyncio.run(
            send_bird(currentBird, media_type, addon, bw))
    else:  # if no, give the same bird
        file_object, ext = asyncio.run(
            send_bird(
                database.hget(f"web.session:{session_id}",
                              "bird").decode("utf-8"),
                str(database.hget(f"web.session:{session_id}",
                                  "media_type"))[2:-1], addon, bw))

    logger.info(f"file_object: {file_object}")
    logger.info(f"extension: {ext}")
    return flask.send_file(file_object, attachment_filename=f"bird.{ext}")
Exemple #5
0
def skip_bird():
    logger.info("endpoint: skip bird")
    session_id = get_session_id()
    user_id = int(database.hget(f"web.session:{session_id}", "user_id"))

    currentBird = database.hget(f"web.session:{session_id}", "bird").decode("utf-8")
    if currentBird != "":  # check if there is bird
        database.hset(f"web.session:{session_id}", "bird", "")
        database.hset(f"web.session:{session_id}", "answered", "1")
        if user_id != 0:
            streak_increment(user_id, None)  # reset streak
        scibird = asyncio.run(get_sciname(currentBird))
        url = get_wiki_url(currentBird)  # sends wiki page
    else:
        logger.info("bird is blank")
        flask.abort(406, "Bird is blank")
    return {"answer": currentBird, "sciname": scibird, "wiki": url}
Exemple #6
0
def logout():
    logger.info("endpoint: logout")
    redirect_after = request.args.get("redirect", FRONTEND_URL, str)
    if relative_url_regex.fullmatch(redirect_after) is not None:
        redirect_url = redirect_after
    else:
        redirect_url = FRONTEND_URL

    session_id = get_session_id()
    user_id = verify_session(session_id)
    if isinstance(int, user_id):
        logger.info("deleting user data, session data")
        database.delete(f"web.user:{user_id}", f"web.session:{session_id}")
        session.clear()
    else:
        logger.info("deleting session data")
        database.delete(f"web.session:{session_id}")
        session.clear()
    return redirect(redirect_url)
Exemple #7
0
async def get_media(bird, media_type, filters):  # images or songs
    if bird not in birdList + screech_owls:
        raise GenericError("Invalid Bird", code=990)

    # fetch scientific names of birds
    try:
        sciBird = await get_sciname(bird)
    except GenericError:
        sciBird = bird

    session_id = get_session_id()
    database_key = f"web.session:{session_id}"

    media = await get_files(sciBird, media_type, filters)
    logger.info(f"fetched {media_type}: {media}")
    prevJ = int(database.hget(database_key, "prevJ").decode("utf-8"))
    if media:
        j = (prevJ + 1) % len(media)
        logger.info("prevJ: " + str(prevJ))
        logger.info("j: " + str(j))

        for x in range(0, len(media)):  # check file type and size
            y = (x + j) % len(media)
            media_path = media[y]
            extension = media_path.split('.')[-1]
            logger.info("extension: " + str(extension))
            if (media_type == "images" and extension.lower() in valid_types["images"].values()) or \
                    (media_type == "songs" and extension.lower() in valid_types["songs"].values()):
                logger.info("found one!")
                break
            if y == prevJ:
                raise GenericError(f"No Valid {media_type.title()} Found",
                                   code=999)

        database.hset(database_key, "prevJ", str(j))
    else:
        raise GenericError(f"No {media_type.title()} Found", code=100)

    return media_path, extension
Exemple #8
0
def check_bird():
    logger.info("endpoint: check bird")
    bird_guess = flask.request.args.get("guess", "", str)

    session_id = get_session_id()
    user_id = int(database.hget(f"web.session:{session_id}", "user_id"))

    currentBird = database.hget(f"web.session:{session_id}", "bird").decode("utf-8")
    if currentBird == "":  # no bird
        logger.info("bird is blank")
        flask.abort(406, "Bird is blank")
    elif bird_guess == "":
        logger.info("empty guess")
        flask.abort(406, "Empty guess")

    # if there is a bird, it checks answer
    logger.info("currentBird: " + str(currentBird.lower().replace("-", " ")))
    logger.info("args: " + str(bird_guess.lower().replace("-", " ")))

    sciBird = asyncio.run(get_sciname(currentBird))
    if spellcheck(bird_guess, currentBird) or spellcheck(bird_guess, sciBird):
        logger.info("correct")

        database.hset(f"web.session:{session_id}", "bird", "")
        database.hset(f"web.session:{session_id}", "answered", "1")

        tempScore = int(database.hget(f"web.session:{session_id}", "tempScore"))
        if user_id != 0:
            bird_setup(user_id, currentBird)
            score_increment(user_id, 1)
            session_increment(user_id, "correct", 1)
            streak_increment(user_id, 1)
        elif tempScore >= 10:
            logger.info("trial maxed")
            flask.abort(403, "Sign in to continue")
        else:
            database.hset(f"web.session:{session_id}", "tempScore", str(tempScore + 1))

        url = get_wiki_url(currentBird)
        return {
            "guess": bird_guess,
            "answer": currentBird,
            "sciname": sciBird,
            "status": "correct",
            "wiki": url,
        }

    logger.info("incorrect")
    database.hset(f"web.session:{session_id}", "bird", "")
    database.hset(f"web.session:{session_id}", "answered", "1")
    database.zincrby("incorrect:global", 1, currentBird)

    if user_id != 0:
        bird_setup(user_id, currentBird)
        incorrect_increment(user_id, currentBird, 1)
        session_increment(user_id, "incorrect", 1)
        streak_increment(user_id, None)  # reset streak

    url = get_wiki_url(currentBird)
    return {
        "guess": bird_guess,
        "answer": currentBird,
        "sciname": sciBird,
        "status": "incorrect",
        "wiki": url,
    }
Exemple #9
0
def check_bird():
    logger.info("endpoint: check bird")
    bird_guess = request.args.get("guess", "", str)

    session_id = get_session_id()
    user_id = int(database.hget(f"web.session:{session_id}", "user_id"))

    currentBird = database.hget(f"web.session:{session_id}",
                                "bird").decode("utf-8")
    if currentBird == "":  # no bird
        logger.info("bird is blank")
        abort(406, "Bird is blank")
    elif bird_guess == "":
        logger.info("empty guess")
        abort(406, "Empty guess")
    else:  # if there is a bird, it checks answer
        logger.info("currentBird: " +
                    str(currentBird.lower().replace("-", " ")))
        logger.info("args: " + str(bird_guess.lower().replace("-", " ")))

        bird_setup(user_id, currentBird)
        sciBird = asyncio.run(get_sciname(currentBird))
        if spellcheck(bird_guess, currentBird) or spellcheck(
                bird_guess, sciBird):
            logger.info("correct")

            database.hset(f"web.session:{session_id}", "bird", "")
            database.hset(f"web.session:{session_id}", "answered", "1")

            tempScore = int(
                database.hget(f"web.session:{session_id}", "tempScore"))
            if user_id != 0:
                database.zincrby("users:global", 1, str(user_id))
                database.zincrby("streak:global", 1, str(user_id))
                # check if streak is greater than max, if so, increases max
                if database.zscore("streak:global",
                                   str(user_id)) > database.zscore(
                                       "streak.max:global", str(user_id)):
                    database.zadd(
                        "streak.max:global", {
                            str(user_id):
                            database.zscore("streak:global", str(user_id))
                        })
            elif tempScore >= 10:
                logger.info("trial maxed")
                abort(403, "Sign in to continue")
            else:
                database.hset(f"web.session:{session_id}", "tempScore",
                              str(tempScore + 1))

            url = get_wiki_url(currentBird)
            return {
                "guess": bird_guess,
                "answer": currentBird,
                "sciname": sciBird,
                "status": "correct",
                "wiki": url
            }

        else:
            logger.info("incorrect")

            database.hset(f"web.session:{session_id}", "bird", "")
            database.hset(f"web.session:{session_id}", "answered", "1")
            database.zincrby("incorrect:global", 1, currentBird)

            if user_id != 0:
                database.zadd("streak:global", {str(user_id): 0})
                database.zincrby(f"incorrect.user:{user_id}", 1, currentBird)

            url = get_wiki_url(currentBird)
            return {
                "guess": bird_guess,
                "answer": currentBird,
                "sciname": sciBird,
                "status": "incorrect",
                "wiki": url
            }