Factor out rendering of game participants
This commit is contained in:
parent
61078f0201
commit
01e4c5e36b
1
NOTES.md
1
NOTES.md
@ -20,6 +20,7 @@
|
|||||||
- [ ] "Display components" like "a tables of games" that can be inserted into multiple pages
|
- [ ] "Display components" like "a tables of games" that can be inserted into multiple pages
|
||||||
* Oh no, did I just re-invent React? :P
|
* Oh no, did I just re-invent React? :P
|
||||||
- [ ] Data presentation methods like "translating a list of Deck IDs into Deck Names"
|
- [ ] Data presentation methods like "translating a list of Deck IDs into Deck Names"
|
||||||
|
- [X] Externalize datastorage (currently)
|
||||||
...
|
...
|
||||||
- [ ] Authentication (will need to link `user` table to `player`)
|
- [ ] Authentication (will need to link `user` table to `player`)
|
||||||
...
|
...
|
||||||
|
@ -10,6 +10,7 @@ from ..sql import crud, schemas
|
|||||||
from ..sql.database import get_db
|
from ..sql.database import get_db
|
||||||
|
|
||||||
from .players import list_players
|
from .players import list_players
|
||||||
|
from .games import _render_game_participants
|
||||||
|
|
||||||
api_router = APIRouter(prefix="/deck", tags=["deck"])
|
api_router = APIRouter(prefix="/deck", tags=["deck"])
|
||||||
html_router = APIRouter(
|
html_router = APIRouter(
|
||||||
@ -115,6 +116,7 @@ def _build_deck_score_history(deck_id: str, db: Session):
|
|||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
.score,
|
.score,
|
||||||
|
"game_participants": _render_game_participants(game, db),
|
||||||
}
|
}
|
||||||
for game in games_involving_this_deck
|
for game in games_involving_this_deck
|
||||||
]
|
]
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from functional import seq
|
from functional import seq
|
||||||
from typing import List, Mapping
|
from typing import List, Mapping, Union
|
||||||
|
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.routers.decks import list_decks
|
|
||||||
from app.sql import models
|
from app.sql import models
|
||||||
from .players import list_players
|
from .players import list_players
|
||||||
from ..elo import rerank
|
from ..elo import rerank
|
||||||
@ -117,7 +116,7 @@ def games_html(request: Request, db=Depends(get_db)):
|
|||||||
games = list_games(db=db)
|
games = list_games(db=db)
|
||||||
# TODO - a more "data-intensive application" implementation would fetch only the decks involved in the games for
|
# TODO - a more "data-intensive application" implementation would fetch only the decks involved in the games for
|
||||||
# this page
|
# this page
|
||||||
decks = list_decks(db=db, limit=-1)
|
decks = crud.get_decks(db=db, limit=-1)
|
||||||
decks_by_id = {deck.id: deck for deck in decks}
|
decks_by_id = {deck.id: deck for deck in decks}
|
||||||
game_names = {game.id: _build_game_deck_names(game, decks_by_id) for game in games}
|
game_names = {game.id: _build_game_deck_names(game, decks_by_id) for game in games}
|
||||||
return jinja_templates.TemplateResponse(
|
return jinja_templates.TemplateResponse(
|
||||||
@ -127,6 +126,25 @@ def games_html(request: Request, db=Depends(get_db)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Although this is underscore-prefixed, it _is_ intentionally called from `decks.py`, since that logic
|
||||||
|
# is used there, too.
|
||||||
|
# Maybe this should be extracted to a file that's appropriate for "logic that's to do with games, but which is not a
|
||||||
|
# router"?
|
||||||
|
# Still learning my way around FastAPI project structure!
|
||||||
|
def _render_game_participants(
|
||||||
|
game: models.Game, db: Session
|
||||||
|
) -> List[Mapping[str, Union[str, int]]]:
|
||||||
|
return (
|
||||||
|
seq(range(6))
|
||||||
|
.map(lambda i: i + 1)
|
||||||
|
.map(lambda i: f"deck_id_{i}")
|
||||||
|
.map(lambda key: getattr(game, key))
|
||||||
|
.filter(lambda x: x) # Not every game has 6 participants!
|
||||||
|
.map(lambda deck_id: crud.get_deck_by_id(db, deck_id))
|
||||||
|
.map(lambda deck: {"owner": deck.owner.name, "name": deck.name, "id": deck.id})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _build_game_deck_names(
|
def _build_game_deck_names(
|
||||||
game: models.Game, decks_by_id: Mapping[int, models.Deck]
|
game: models.Game, decks_by_id: Mapping[int, models.Deck]
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
@ -146,7 +164,7 @@ def _build_game_deck_names(
|
|||||||
def game_html(request: Request, game_id: str, db=Depends(get_db)):
|
def game_html(request: Request, game_id: str, db=Depends(get_db)):
|
||||||
game = read_game(game_id, db)
|
game = read_game(game_id, db)
|
||||||
|
|
||||||
decks = list_decks(db=db, limit=-1)
|
decks = crud.get_decks(db=db, limit=-1)
|
||||||
decks_by_id = {deck.id: deck for deck in decks}
|
decks_by_id = {deck.id: deck for deck in decks}
|
||||||
game_deck_names = _build_game_deck_names(game, decks_by_id)
|
game_deck_names = _build_game_deck_names(game, decks_by_id)
|
||||||
|
|
||||||
|
@ -7,9 +7,12 @@ SQLALCHEMY_DATABASE_URL = os.environ.get(
|
|||||||
"DATABASE_URL", "sqlite:///database/sql_app.db"
|
"DATABASE_URL", "sqlite:///database/sql_app.db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if SQLALCHEMY_DATABASE_URL.startswith("sqlite"):
|
||||||
engine = create_engine(
|
engine = create_engine(
|
||||||
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
engine = create_engine(SQLALCHEMY_DATABASE_URL)
|
||||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
<h2>Game history</h2>
|
<h2>Game history</h2>
|
||||||
{% if game_history %}
|
{% if game_history %}
|
||||||
(TODO - extract a translation-from-deckid-to-names method)
|
|
||||||
(Or...just link them as a relationship/ForeignKey)
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
@ -28,12 +26,12 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href="/game/{{ entry.game.id }}">{{ entry.game.date.strftime('%Y-%m-%d') }}</a></td>
|
<td><a href="/game/{{ entry.game.id }}">{{ entry.game.date.strftime('%Y-%m-%d') }}</a></td>
|
||||||
<td>
|
<td>
|
||||||
{% for participant_id in range(6) %}
|
<ul>
|
||||||
{% set deck_id = entry.game['deck_id_' ~ (participant_id+1)] %}
|
{% for participant in entry.game_participants %}
|
||||||
{% if deck_id is not none %}
|
<li><a href="/deck/{{ participant.id }}">{{ participant.owner }} ({{ participant.name }})</a></li>
|
||||||
<a href="/deck/{{ deck_id }}">{{ deck_id }}</a>
|
{% endfor %}
|
||||||
{% endif %}
|
</ul>
|
||||||
{% endfor %}</td>
|
</td>
|
||||||
<td>{{ "Win" if entry.game.winning_deck_id == deck.id else "Loss" }}</td>
|
<td>{{ "Win" if entry.game.winning_deck_id == deck.id else "Loss" }}</td>
|
||||||
<td>{{ entry.score|int }}</td>
|
<td>{{ entry.score|int }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user