Skip to content

Commit

Permalink
feat: add right facing mode
Browse files Browse the repository at this point in the history
  • Loading branch information
2jun0 committed Apr 30, 2024
1 parent dbaf00f commit 79e5739
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 16 deletions.
17 changes: 17 additions & 0 deletions src/renders/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def __init__(self) -> None:
async def get_pokemon_left_sprites(self) -> dict[PokemonType, tuple[str, str]]:
return {pokemon: await self._create_left_sprite_urls(pokemon.national_no) for pokemon in PokemonType}

@file_cache("pokemon_right_sprites")
async def get_pokemon_right_sprites(self) -> dict[PokemonType, tuple[str, str]]:
return {pokemon: await self._create_right_sprite_urls(pokemon.national_no) for pokemon in PokemonType}

@file_cache("pokeball")
async def get_pokeball(self) -> str:
return await self._get_as_base64(POKEBALL_URL)
Expand All @@ -41,3 +45,16 @@ async def _create_left_sprite_urls(self, national_no: int) -> tuple[str, str]:
frame_2 = poke_url + "_2.png"

return (await self._get_as_base64(frame_1), await self._get_as_base64(frame_2))

async def _create_right_sprite_urls(self, national_no: int) -> tuple[str, str]:
start_url = f"{SPRITE_BASE_URL}/o-r_hgss"
poke_url = start_url + "/o-r_hs_" + str(national_no).zfill(3)

if national_no in [3, 25]:
frame_1 = poke_url + "_m-1.png"
frame_2 = poke_url + "_m-2.png"
else:
frame_1 = poke_url + "_1.png"
frame_2 = poke_url + "_2.png"

return (await self._get_as_base64(frame_1), await self._get_as_base64(frame_2))
20 changes: 15 additions & 5 deletions src/renders/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
import random
from typing import Generator

from src.exceptions.base import InternalError
from src.models.pokemon_type import PokemonType
from src.renders.images import ImageLoader
from src.schemas.pokemons import PokemonFace
from src.template import svgs as svgs_templates

pokemon_templates = {PokemonFace.LEFT: svgs_templates.pokemon_left, PokemonFace.RIGHT: svgs_templates.pokemon_right}


class SVGRenderer:
pokeball: str
Expand All @@ -16,26 +20,32 @@ async def prepare(cls, *, image_loader: ImageLoader):
logging.info("Load images start")
cls.pokeball = await image_loader.get_pokeball()
cls.pokemon_left_sprites = await image_loader.get_pokemon_left_sprites()
cls.pokemon_right_sprites = await image_loader.get_pokemon_right_sprites()
logging.info("Load images end")

def render_svg(self, *, pokemons: list[PokemonType], commit_point: int, username: str) -> str:
def render_svg(self, *, pokemons: list[PokemonType], commit_point: int, username: str, face: PokemonFace) -> str:
return svgs_templates.base.format(
username=username,
commit_point=commit_point,
n_pokemons=len(pokemons),
pokemons="\n".join(self._render_pokemons(pokemons)),
pokemons="\n".join(self._render_pokemons(pokemons, face)),
poke_ball_url=self.pokeball,
)

def _render_pokemons(self, pokemons: list[PokemonType]) -> Generator[str, None, None]:
def _render_pokemons(self, pokemons: list[PokemonType], face: PokemonFace) -> Generator[str, None, None]:
for idx, pokemon in enumerate(pokemons):
num = idx + 1
duration = random.uniform(10, 15)
offset = random.randint(-75, 80)
delay = random.uniform(0, 10)

frame_1, frame_2 = self.pokemon_left_sprites[pokemon]
if face is PokemonFace.LEFT:
frame_1, frame_2 = self.pokemon_left_sprites[pokemon]
elif face is PokemonFace.RIGHT:
frame_1, frame_2 = self.pokemon_right_sprites[pokemon]
else:
raise InternalError

yield svgs_templates.pokemon.format(
yield pokemon_templates[face].format(
num=num, duration=duration, offset=offset, delay=delay, frame_1=frame_1, frame_2=frame_2
)
9 changes: 4 additions & 5 deletions src/routes/pokemons.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
from fastapi import Response
from fastapi import Query, Response
from fastapi.routing import APIRouter

from src.dependencies.db import SessionDep
from src.dependencies.facades import PokemonsFacadeDep
from src.schemas.pokemons import PokemonFace

router = APIRouter()


@router.get("/pokemons/{username}")
async def get_pokemons_svg(
username: str,
session: SessionDep,
pokemons_facade: PokemonsFacadeDep,
username: str, session: SessionDep, pokemons_facade: PokemonsFacadeDep, face: PokemonFace = Query(PokemonFace.LEFT)
):
return Response(
content=await pokemons_facade.render_pokemons(session=session, username=username),
content=await pokemons_facade.render_pokemons(session=session, username=username, face=face),
headers={"content-type": "image/svg+xml", "Cache-Control": "max-age=3600"},
)
6 changes: 6 additions & 0 deletions src/schemas/pokemons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from enum import Enum


class PokemonFace(str, Enum):
LEFT = "left"
RIGHT = "right"
5 changes: 3 additions & 2 deletions src/services/pokemons_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from src.exceptions.external import GithubAPIRequestFailedError, GithubAPIUnavailableError
from src.external.github_api import GithubAPI
from src.renders.svg import SVGRenderer
from src.schemas.pokemons import PokemonFace
from src.services.user import UserService
from src.setting import settings

Expand All @@ -24,7 +25,7 @@ def __init__(
self._renderer = renderer
self._background_tasks = background_tasks

async def render_pokemons(self, *, session: AsyncSession, username: str) -> str:
async def render_pokemons(self, *, session: AsyncSession, username: str, face: PokemonFace) -> str:
user = await self._user_service.get_user(session=session, username=username)

if user is not None:
Expand All @@ -43,7 +44,7 @@ async def render_pokemons(self, *, session: AsyncSession, username: str) -> str:
raise GithubAPIUnavailableError from e

return self._renderer.render_svg(
pokemons=user.pokemon_types, commit_point=user.total_commit_point, username=username
pokemons=user.pokemon_types, commit_point=user.total_commit_point, username=username, face=face
)

async def _get_commit_points(self, username: str) -> dict[int, int]:
Expand Down
3 changes: 2 additions & 1 deletion src/template/svgs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ def load_svg_template(path: str) -> str:


base = load_svg_template("templates/svgs/base.svg")
pokemon = load_svg_template("templates/svgs/pokemon.svg")
pokemon_left = load_svg_template("templates/svgs/pokemon-left.svg")
pokemon_right = load_svg_template("templates/svgs/pokemon-right.svg")
16 changes: 14 additions & 2 deletions templates/svgs/base.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions templates/svgs/pokemon-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 79e5739

Please sign in to comment.