-
Notifications
You must be signed in to change notification settings - Fork 52
Feature/gamesreleasedtoday #334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
ed40267
96adc87
1714078
5da84ed
1a84c51
df20fbb
47b0c86
3d83e49
8725759
6b74798
70f63a3
6bc1251
0c27fe5
66f8282
28b61ba
01cc534
7144971
9d4239f
7a0af20
0351e35
896fc8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
from __future__ import annotations | ||
|
||
from collections import defaultdict | ||
from datetime import datetime | ||
from functools import lru_cache | ||
from typing import TYPE_CHECKING, Any, DefaultDict, Dict, List | ||
|
||
import httpx | ||
from loguru import logger | ||
from sqlalchemy.orm import Session | ||
|
||
from app import config | ||
from app.database.models import UserSettings | ||
|
||
if TYPE_CHECKING: | ||
from app.routers.calendar_grid import Day, Week | ||
|
||
|
||
def is_user_signed_up_for_game_releases( | ||
session: Session, | ||
current_user_id: int, | ||
) -> bool: | ||
is_signed_up = bool( | ||
session.query(UserSettings) | ||
.filter(UserSettings.user_id == current_user_id) | ||
.filter(UserSettings.video_game_releases.is_(True)) | ||
.first(), | ||
) | ||
|
||
return is_signed_up | ||
|
||
|
||
def add_game_events_to_weeks( | ||
weeks: List["Week"], | ||
is_active: bool = True, | ||
) -> List["Week"]: | ||
if not is_active: | ||
return weeks | ||
first_week: Week = weeks[0] | ||
last_week: Week = weeks[-1] | ||
first_day: Day = first_week.days[0] | ||
last_day: Day = last_week.days[-1] | ||
first_day_str = datetime.strptime(first_day.set_id(), "%d-%B-%Y") | ||
last_day_str = datetime.strptime(last_day.set_id(), "%d-%B-%Y") | ||
|
||
output = get_games_data_by_dates_from_api( | ||
start_date=first_day_str.strftime("%Y-%m-%d"), | ||
end_date=last_day_str.strftime("%Y-%m-%d"), | ||
) | ||
if not output["success"]: | ||
logger.exception("Unsuccessful RAWG API call") | ||
return weeks | ||
games_by_dates = output["results"] | ||
|
||
unformatted_games_by_dates = get_games_data_separated_by_dates( | ||
games_by_dates, | ||
) | ||
formatted_games = get_formatted_games_in_days(unformatted_games_by_dates) | ||
|
||
return insert_formatted_games_to_weeks(weeks, formatted_games) | ||
|
||
|
||
def insert_formatted_games_to_weeks( | ||
weeks: List["Week"], | ||
formatted_games: DefaultDict[List[str]], | ||
) -> List["Week"]: | ||
for week in weeks: | ||
for day in week.days: | ||
if day.set_id() in formatted_games.keys(): | ||
for game in formatted_games[day.set_id()]: | ||
day.dailyevents.append( | ||
( | ||
f"GR!- {(game)[:10]}", | ||
(game), | ||
), | ||
) | ||
return weeks | ||
|
||
|
||
@lru_cache(maxsize=128) | ||
def get_games_data_by_dates_from_api( | ||
start_date: str, | ||
end_date: str, | ||
) -> Dict[str, Any]: | ||
API = "https://api.rawg.io/api/games" | ||
NO_API_RESPONSE = "The RAWG server did not response" | ||
input_query_string = { | ||
"dates": f"{start_date},{end_date}", | ||
"key": config.RAWG_API_KEY, | ||
} | ||
|
||
output: Dict[str, Any] = {} | ||
try: | ||
response = httpx.get( | ||
API, | ||
params=input_query_string, | ||
) | ||
except httpx.HTTPError: | ||
output["success"] = False | ||
output["error"] = NO_API_RESPONSE | ||
return output | ||
|
||
if response.status_code != httpx.codes.OK: | ||
output["success"] = False | ||
output["error"] = NO_API_RESPONSE | ||
return output | ||
|
||
output["success"] = True | ||
try: | ||
output.update(response.json()) | ||
return output | ||
except KeyError: | ||
output["success"] = False | ||
output["error"] = response.json()["error"]["message"] | ||
return output | ||
|
||
|
||
def get_games_data_separated_by_dates( | ||
api_data: Dict[str, Any], | ||
) -> DefaultDict[List]: | ||
games_data = defaultdict(list) | ||
for result in api_data: | ||
current = { | ||
"name": result["name"], | ||
"platforms": [], | ||
} | ||
if result["platforms"]: | ||
for platform in result["platforms"]: | ||
current["platforms"].append(platform["platform"]["name"]) | ||
ybd_release_date = translate_ymd_date_to_dby(result["released"]) | ||
games_data[ybd_release_date].append(current) | ||
return games_data | ||
|
||
|
||
def get_formatted_games_in_days( | ||
separated_games_dict: DefaultDict[List], | ||
with_platforms: bool = False, | ||
) -> DefaultDict[List[str]]: | ||
formatted_games = defaultdict(list) | ||
|
||
for date, game_data in separated_games_dict.items(): | ||
for game in game_data: | ||
formatted_game_str = format_single_game(game, with_platforms) | ||
formatted_games[date].append(formatted_game_str) | ||
return formatted_games | ||
|
||
|
||
def format_single_game(raw_game: Dict, with_platforms: bool = False) -> str: | ||
formatted_game_str = "" | ||
formatted_game_str += raw_game["name"] | ||
if with_platforms: | ||
formatted_game_str += "-Platforms-<br>" | ||
for platform in raw_game["platforms"]: | ||
formatted_game_str += f"{platform}," | ||
return formatted_game_str | ||
|
||
|
||
def translate_ymd_date_to_dby(ymd_str: str) -> str: | ||
ymd_time = datetime.strptime(ymd_str, "%Y-%m-%d") | ||
return ymd_time.strftime("%d-%B-%Y") | ||
|
||
|
||
def translate_dby_date_to_ymd(dby_str: str) -> str: | ||
dby_time = datetime.strptime(dby_str, "%d-%B-%Y") | ||
return dby_time.strftime("%Y-%m-%d") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import datetime | ||
from typing import Dict, List | ||
|
||
import requests | ||
from fastapi import APIRouter, Depends, Request | ||
from fastapi.responses import RedirectResponse, Response | ||
from sqlalchemy.orm import Session | ||
from starlette.status import HTTP_302_FOUND | ||
|
||
from app.database.models import UserSettings | ||
from app.dependencies import get_db, templates | ||
from app.internal.game_releases_utils import ( | ||
is_user_signed_up_for_game_releases, | ||
) | ||
from app.internal.security.dependencies import current_user | ||
from app.internal.security.schema import CurrentUser | ||
from app.internal.utils import create_model | ||
from app.routers.profile import router as profile_router | ||
|
||
router = APIRouter( | ||
prefix="/game-releases", | ||
tags=["game-releases"], | ||
responses={404: {"description": "Not found"}}, | ||
) | ||
|
||
|
||
@router.post("/get_releases_by_dates") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not a post request. /{date} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need it to be awaited |
||
async def fetch_released_games( | ||
request: Request, | ||
session=Depends(get_db), | ||
) -> Response: | ||
data = await request.form() | ||
|
||
from_date = data["from-date"] | ||
to_date = data["to-date"] | ||
|
||
games = get_games_data(from_date, to_date) | ||
|
||
return templates.TemplateResponse( | ||
"partials/calendar/feature_settings/games_list.html", | ||
{"request": request, "games": games}, | ||
) | ||
|
||
|
||
@router.get("/next-month") | ||
def get_game_releases_month(request: Request) -> List: | ||
today = datetime.datetime.today() | ||
delta = datetime.timedelta(days=30) | ||
today_str = today.strftime("%Y-%m-%d") | ||
in_month_str = (today + delta).strftime("%Y-%m-%d") | ||
|
||
return get_games_data(today_str, in_month_str) | ||
|
||
|
||
def get_games_data(start_date: datetime, end_date: datetime) -> List[Dict]: | ||
API = "https://api.rawg.io/api/games" | ||
|
||
current_day_games = requests.get( | ||
f"{API}?dates={start_date},{end_date}", | ||
) | ||
Comment on lines
+56
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will cause great load on our server, especially with high amount of users. Use JS instead. |
||
current_day_games = current_day_games.json()["results"] | ||
games_data = [] | ||
for result in current_day_games: | ||
current = { | ||
"name": result["name"], | ||
"slug": result["slug"], | ||
"platforms": [], | ||
} | ||
|
||
for platform in result["platforms"]: | ||
current["platforms"].append(platform["platform"]["name"]) | ||
current["release_date"] = result["released"] | ||
games_data.append(current) | ||
|
||
return games_data | ||
|
||
|
||
@router.post("/subscribe") | ||
async def subscribe_game_release_service( | ||
request: Request, | ||
session: Session = Depends(get_db), | ||
user: CurrentUser = Depends(current_user), | ||
) -> Response: | ||
if is_user_signed_up_for_game_releases(session, user.user_id): | ||
return RedirectResponse( | ||
profile_router.url_path_for("profile"), | ||
status_code=HTTP_302_FOUND, | ||
) | ||
games_setting_true_for_model = { | ||
"user_id": user.user_id, | ||
"video_game_releases": True, | ||
} | ||
current_user_settings = session.query(UserSettings).filter( | ||
UserSettings.user_id == user.user_id, | ||
) | ||
if current_user_settings: | ||
# TODO: | ||
# If all users are created with a UserSettings entry - | ||
# unnecessary check | ||
current_user_settings.update(games_setting_true_for_model) | ||
session.commit() | ||
else: | ||
create_model(session, UserSettings, **games_setting_true_for_model) | ||
return RedirectResponse( | ||
profile_router.url_path_for("profile"), | ||
status_code=HTTP_302_FOUND, | ||
) | ||
|
||
|
||
@router.post("/unsubscribe") | ||
async def unsubscribe_game_release_service( | ||
request: Request, | ||
session: Session = Depends(get_db), | ||
user: CurrentUser = Depends(current_user), | ||
) -> RedirectResponse: | ||
current_user_id = user.user_id | ||
Liad-n marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if not is_user_signed_up_for_game_releases(session, current_user_id): | ||
return RedirectResponse( | ||
profile_router.url_path_for("profile"), | ||
status_code=HTTP_302_FOUND, | ||
) | ||
else: | ||
games_setting_false_for_model = { | ||
"user_id": str(current_user_id), | ||
"video_game_releases": False, | ||
} | ||
current_user_settings = session.query(UserSettings).filter( | ||
UserSettings.user_id == current_user_id, | ||
) | ||
if current_user_settings: | ||
# TODO: | ||
# If all users are created with a UserSettings entry - | ||
# unnecessary check | ||
current_user_settings.update(games_setting_false_for_model) | ||
session.commit() | ||
else: | ||
create_model( | ||
session, UserSettings, **games_setting_false_for_model | ||
) | ||
return RedirectResponse( | ||
profile_router.url_path_for("profile"), | ||
status_code=HTTP_302_FOUND, | ||
) |
Uh oh!
There was an error while loading. Please reload this page.