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, }
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)
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")
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]
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)
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}
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, }