예제 #1
0
def profile(request: Request):
    logger.info("endpoint: profile")

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

    if user_id == 0:
        logger.info("not logged in")
        raise HTTPException(status_code=403, detail="Sign in to continue")

    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",
        ))
    score = 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,
        "avatar": avatar_url,
        "username": username,
        "discriminator": discriminator,
        "score": score,
        "max_streak": max_streak,
        "missed": missed_birds,
    }
예제 #2
0
async def get_bird(
    request: Request,
    media: str = "images",
    addon: str = "",
    bw: int = 0,
):
    logger.info("endpoint: get bird")
    session_id = get_session_id(request)
    media_type = media

    filters = Filter.parse(addon)
    if bool(bw):
        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")
    #     raise HTTPException(status_code=403, detail="Sign in to continue")

    if media_type not in ("images", "songs"):
        logger.error(f"invalid media type {media_type}")
        raise HTTPException(status_code=422, detail="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:
            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))
        logger.info("currentBird: " + str(currentBird))
        database.hset(f"web.session:{session_id}", "answered", "0")
        file_object, ext, content_type = await send_bird(
            request, currentBird, media_type, filters)
    else:  # if no, give the same bird
        file_object, ext, content_type = await send_bird(
            request,
            database.hget(f"web.session:{session_id}", "bird").decode("utf-8"),
            media_type,
            filters,
        )

    logger.info(f"file_object: {file_object}")
    logger.info(f"extension: {ext}")
    return send_file(file_object, media_type=content_type)
예제 #3
0
async def hint_bird(request: Request):
    logger.info("endpoint: hint bird")

    session_id = get_session_id(request)
    database.zincrby(f"daily.web:{date()}", 1, "hint")

    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")
    raise HTTPException(status_code=404, detail="Bird is blank")
예제 #4
0
async def get_media(
    request: Request, bird: str, media_type: str, filters: Filter
):  # images or songs
    if bird not in birdList + screech_owls:
        raise GenericError("Invalid Bird", code=990)

    if media_type not in ("images", "songs"):
        logger.error(f"invalid media type {media_type}")
        raise HTTPException(status_code=422, detail="Invalid media type")

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

    session_id = get_session_id(request)
    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 extension.lower() in valid_types[media_type].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, content_type_lookup[extension]
예제 #5
0
async def logout(request: Request, redirect: str = "/"):
    logger.info("endpoint: logout")

    if relative_url_regex.fullmatch(redirect) is not None:
        redirect_url = FRONTEND_URL + redirect
    else:
        redirect_url = FRONTEND_URL

    session_id = get_session_id(request)
    user_id = verify_session(session_id)

    if isinstance(user_id, int):
        logger.info("deleting user data, session data")
        database.delete(f"web.user:{user_id}", f"web.session:{session_id}")
    else:
        logger.info("deleting session data")
        database.delete(f"web.session:{session_id}")

    request.session.clear()
    return RedirectResponse(redirect_url)
예제 #6
0
async def skip_bird(request: Request):
    logger.info("endpoint: skip bird")

    session_id = get_session_id(request)
    user_id = int(database.hget(f"web.session:{session_id}", "user_id"))
    database.zincrby(f"daily.web:{date()}", 1, "skip")

    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 = await get_sciname(currentBird)
        url = get_wiki_url(currentBird)  # sends wiki page
    else:
        logger.info("bird is blank")
        raise HTTPException(status_code=404, detail="Bird is blank")
    return {"answer": currentBird, "sciname": scibird, "wiki": url}
예제 #7
0
async def check_bird(request: Request, guess: str):
    logger.info("endpoint: check bird")

    session_id = get_session_id(request)
    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")
        raise HTTPException(status_code=404, detail="Bird is blank")
    if guess == "":
        logger.info("empty guess")
        raise HTTPException(status_code=422, detail="empty guess")

    # if there is a bird, it checks answer
    sciBird = (await get_sciname(currentBird)).lower().replace("-", " ")
    guess = guess.lower().replace("-", " ")
    currentBird = currentBird.lower().replace("-", " ")
    alpha_code = alpha_codes.get(string.capwords(currentBird), "")
    logger.info("currentBird: " + currentBird)
    logger.info("args: " + guess)

    database.zincrby(f"daily.web:{date()}", 1, "check")
    if user_id != 0:
        bird_setup(user_id, currentBird)

    accepted_answers = [currentBird, sciBird]
    if currentBird == "screech owl":
        accepted_answers += screech_owls
        accepted_answers += sci_screech_owls

    if (better_spellcheck(guess, accepted_answers,
                          birdListMaster + sciListMaster)
            or guess.upper() == alpha_code):
        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(f"daily.webscore:{date()}", 1, user_id)
            score_increment(user_id, 1)
            streak_increment(user_id, 1)
        # elif tempScore >= 10:
        #     logger.info("trial maxed")
        #     raise HTTPException(status_code=403, detail="Sign in to continue")
        else:
            database.hset(f"web.session:{session_id}", "tempScore",
                          str(tempScore + 1))

        url = get_wiki_url(currentBird)
        return {
            "guess": 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:
        incorrect_increment(user_id, currentBird, 1)
        streak_increment(user_id, None)  # reset streak

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