Skip to content

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

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions app/internal/game_releases_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from __future__ import annotations

from collections import defaultdict
from datetime import datetime
from typing import TYPE_CHECKING, List

import requests
from sqlalchemy.orm import Session

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 = (
session.query(UserSettings)
.filter(UserSettings.user_id == current_user_id)
.filter(UserSettings.video_game_releases.is_(True))
.first()
)

if is_signed_up:
return True
return False


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")
games_by_dates = get_games_data_separated_by_days(
start_date=first_day_str.strftime("%Y-%m-%d"),
end_date=last_day_str.strftime("%Y-%m-%d"),
)
formatted_games = get_formatted_games_in_days(games_by_dates)
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


def get_games_data_separated_by_days(
start_date: datetime,
end_date: datetime,
) -> defaultdict[List]:
API = "https://api.rawg.io/api/games"

current_day_games = requests.get(
f"{API}?dates={start_date},{end_date}",
)
current_day_games = current_day_games.json()["results"]
games_data = defaultdict(list)
for result in current_day_games:
current = {}
current["name"] = result["name"]
if result["platforms"]:
current["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]:
formatted_games = defaultdict(list)

for date, game_data in separated_games_dict.items():
for game in game_data:
formatted_game_str = ""
formatted_game_str += game["name"]
if with_platforms:
formatted_game_str += "-Platforms-<br>"
for platform in game["platforms"]:
formatted_game_str += f"{platform},"
formatted_games[date].append(formatted_game_str)
return formatted_games


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")
2 changes: 2 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def create_tables(engine, psql_environment):
export,
four_o_four,
friendview,
game_release_dates_service,
google_connect,
joke,
login,
Expand Down Expand Up @@ -133,6 +134,7 @@ async def swagger_ui_redirect():
weekview.router,
weight.router,
whatsapp.router,
game_release_dates_service.router,
]

for router in routers_to_include:
Expand Down
16 changes: 9 additions & 7 deletions app/routers/calendar.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from http import HTTPStatus

from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from starlette.responses import Response
from fastapi.responses import HTMLResponse, Response

from app.dependencies import templates
from app.routers import calendar_grid as cg
Expand All @@ -11,7 +10,7 @@
prefix="/calendar/month",
tags=["calendar"],
responses={404: {"description": "Not found"}},
include_in_schema=False
include_in_schema=False,
)


Expand All @@ -25,18 +24,21 @@ async def calendar(request: Request) -> Response:
"request": request,
"day": day,
"week_days": cg.Week.DAYS_OF_THE_WEEK,
"weeks_block": cg.get_month_block(day)
}
"weeks_block": cg.get_month_block(day),
},
)


@router.get("/add/{date}")
async def update_calendar(
request: Request, date: str, days: int
request: Request,
date: str,
days: int,
) -> HTMLResponse:
last_day = cg.Day.convert_str_to_date(date)
next_weeks = cg.create_weeks(cg.get_n_days(last_day, days))
template = templates.get_template(
'partials/calendar/monthly_view/add_week.html')
"partials/calendar/monthly_view/add_week.html",
)
content = template.render(weeks_block=next_weeks)
return HTMLResponse(content=content, status_code=HTTPStatus.OK)
6 changes: 5 additions & 1 deletion app/routers/calendar_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import pytz

from app.internal.game_releases_utils import add_game_events_to_weeks

MONTH_BLOCK: int = 6

locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
Expand Down Expand Up @@ -177,7 +179,9 @@ def create_weeks(
"""Return lists of Weeks objects."""
ndays: List[Day] = list(days)
num_days: int = len(ndays)
return [Week(ndays[i : i + length]) for i in range(0, num_days, length)]
_weeks = [Week(ndays[i : i + length]) for i in range(0, num_days, length)]

return add_game_events_to_weeks(_weeks, is_active=False)


def get_month_block(day: Day, n: int = MONTH_BLOCK) -> List[Week]:
Expand Down
131 changes: 131 additions & 0 deletions app/routers/game_release_dates_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
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

router = APIRouter(
prefix="/game-releases",
tags=["game-releases"],
responses={404: {"description": "Not found"}},
)


@router.post("/get_releases_by_dates")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a post request. /{date}

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
Copy link
Member

Choose a reason for hiding this comment

The 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", 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", 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

if not is_user_signed_up_for_game_releases(session, current_user_id):
return RedirectResponse("/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", status_code=HTTP_302_FOUND)
7 changes: 7 additions & 0 deletions app/static/game_releases.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.game-title {
font-size: 1.1em;
font-weight: bolder;
}
.secondary-title {
font-weight: bold;
}
17 changes: 17 additions & 0 deletions app/static/js/game_releases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
get_games_btn = document.getElementById("get-games");
get_games_btn.addEventListener("click", function (e) {
let formData = new FormData();
formData.append("from-date", document.getElementById("from-date").value);
formData.append("to-date", document.getElementById("to-date").value);
let clickedElem = e.target.id;
fetch("/game-releases/get_releases_by_dates", {
method: "post",
body: formData,
})
.then(function (response) {
return response.text();
})
.then(function (body) {
document.querySelector("#content-div").innerHTML = body;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

innerText maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
I'm not sure it would work here, wouldn't I be lacking formatting?

});
});
1 change: 1 addition & 0 deletions app/templates/partials/calendar/calendar_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
{% endblock content %}
</div>
</div>
{% include 'partials/calendar/feature_settings/game_release_modal.html' %}
<!-- Scripts -->
<script src="{{ url_for('static', path='/js/grid_scripts.js') }}"></script>
<script src="{{ url_for('static', path='/js/grid_navigation.js') }}"></script>
Expand Down
Loading