示例#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")
示例#2
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
示例#3
0
async def _bw_helper(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            if response.status != 200:
                logger.info("invalid response")
                flask.abort(response.status, "error fetching url")
            if response.content_type not in valid_content_types:
                logger.info("invalid content type")
                flask.abort(415, "invalid content type")
            return (
                _black_and_white(BytesIO(await response.read())),
                response.content_type,
            )
示例#4
0
def login():
    logger.info("endpoint: login")
    redirect_uri = url_for('user.authorize', _external=True, _scheme='https')
    resp = make_response(oauth.discord.authorize_redirect(redirect_uri))
    redirect_after = request.args.get("redirect", FRONTEND_URL, str)
    if relative_url_regex.fullmatch(redirect_after) is not None:
        resp.headers.add(
            'Set-Cookie', 'redirect=' + redirect_after +
            '; Max-Age=180; SameSite=None; HttpOnly; Secure')
    else:
        resp.headers.add(
            'Set-Cookie',
            'redirect=/; Max-Age=180; SameSite=None; HttpOnly; Secure')
    return resp
示例#5
0
def authorize():
    logger.info("endpoint: authorize")
    redirect_uri = url_for('user.authorize', _external=True, _scheme='https')
    oauth.discord.authorize_access_token(redirect_uri=redirect_uri)
    resp = oauth.discord.get('users/@me')
    profile = resp.json()
    # do something with the token and profile
    update_web_user(profile)
    redirect_cookie = str(request.cookies.get("redirect"))
    if relative_url_regex.fullmatch(redirect_cookie) is not None:
        redirection = FRONTEND_URL + redirect_cookie
    else:
        redirection = FRONTEND_URL + "/"
    session.pop("redirect", None)
    return redirect(redirection)
示例#6
0
def convert_bw():
    logger.info("endpoint: convert bw")
    url = flask.request.args.get("url", default=None, type=str)
    logger.info(f"args: url: {url}")

    if not url:
        logger.info("no url")
        flask.abort(415, "url not specified")

    parsed_url = urllib.parse.urlparse(url)
    logger.info(f"parsed url: {parsed_url}")
    if parsed_url.netloc not in valid_endpoints:
        logger.info("invalid url")
        flask.abort(415, "invalid url")

    image, content_type = asyncio.run(_bw_helper(url))
    return flask.send_file(image, mimetype=content_type)
示例#7
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}
示例#8
0
def bird_info():
    logger.info("fetching random bird")
    content = {}
    bird = random.choice(birdList)
    logger.info(f"bird: {bird}")
    content["bird"] = bird
    content["sciName"] = asyncio.run(get_sciname(bird))
    content["imageURL"] = urllib.parse.quote(f"/image/{bird}")
    content["songURL"] = urllib.parse.quote(f"/song/{bird}")
    logger.info(f"{bird} sent!")
    return content
示例#9
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)
示例#10
0
def handle_authlib_error(e):
    logger.info(f"error with oauth login: {e}")
    capture_exception(e)
    return 'An error occurred with the login', 500
示例#11
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,
    }
示例#12
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}")
示例#13
0
def api_index():
    logger.info("index page accessed")
    return "<h1>Hello!</h1><p>This is the index page for the Bird-ID internal API.<p>"
示例#14
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
            }
示例#15
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}")