Phase 1 card images

This commit is contained in:
Cal Corum 2023-09-24 18:59:32 -05:00
parent 8a0d094227
commit 89aebd441d
5 changed files with 144 additions and 14 deletions

41
app/card_creation.py Normal file
View File

@ -0,0 +1,41 @@
import pandas as pd
chance_df = pd.DataFrame(
{
'd20-1': [0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.25, 0.2, 0.15, 0.1, 0.05],
'd20-2': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1],
'd20-3': [0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 0.75, 0.6, 0.45, 0.3, 0.15],
'd20-4': [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1, 0.8, 0.6, 0.4, 0.2],
'd20-5': [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.25, 1, 0.75, 0.5, 0.25],
'd20-6': [0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 1.5, 1.2, 0.9, 0.6, 0.3],
'd20-7': [0.35, 0.7, 1.05, 1.4, 1.75, 2.1, 1.75, 1.4, 1.05, 0.7, 0.35],
'd20-8': [0.4, 0.8, 1.2, 1.6, 2, 2.4, 2, 1.6, 1.2, 0.8, 0.4],
'd20-9': [0.45, 0.9, 1.35, 1.8, 2.25, 2.7, 2.25, 1.8, 1.35, 0.9, 0.45],
'd20-10': [0.5, 1, 1.5, 2, 2.5, 3, 2.5, 2, 1.5, 1, 0.5],
'd20-11': [0.55, 1.1, 1.65, 2.2, 2.75, 3.3, 2.75, 2.2, 1.65, 1.1, 0.55],
'd20-12': [0.6, 1.2, 1.8, 2.4, 3, 3.6, 3, 2.4, 1.8, 1.2, 0.6],
'd20-13': [0.65, 1.3, 1.95, 2.6, 3.25, 3.9, 3.25, 2.6, 1.95, 1.3, 0.65],
'd20-14': [0.7, 1.4, 2.1, 2.8, 3.5, 4.2, 3.5, 2.8, 2.1, 1.4, 0.7],
'd20-15': [0.75, 1.5, 2.25, 3, 3.75, 4.5, 3.75, 3, 2.25, 1.5, 0.75],
'd20-16': [0.8, 1.6, 2.4, 3.2, 4, 4.8, 4, 3.2, 2.4, 1.6, 0.8],
'd20-17': [0.85, 1.7, 2.55, 3.4, 4.25, 5.1, 4.25, 3.4, 2.55, 1.7, 0.85],
'd20-18': [0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 4.5, 3.6, 2.7, 1.8, 0.9],
'd20-19': [0.95, 1.9, 2.85, 3.8, 4.75, 5.7, 4.75, 3.8, 2.85, 1.9, 0.95],
'd20-20': [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
},
index=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
)
def get_batter_card_html(request, player, batting_card, ratings_vl, ratings_vr):
"""
create header_data
create column data
return data to be templated
"""
return f'<html lang="en"><body><h1>{player.p_name}</h1></body></html>'
def get_batter_card_data(player, batting_card, ratings_vl, ratings_vr) -> dict:
return {}

View File

@ -1,4 +1,7 @@
import os
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from .routers_v2 import (
current, teams, rarity, cardsets, players, packtypes, packs, cards, events, results, rewards,
@ -9,6 +12,8 @@ app = FastAPI(
responses={404: {'description': 'Not found'}}
)
# templates = Jinja2Templates(directory=os.path.dirname(os.path.abspath(__file__)))
app.include_router(current.router)
app.include_router(teams.router)
app.include_router(rarity.router)

View File

@ -1,10 +1,10 @@
from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from typing import Literal, Optional, List
import logging
import pydantic
from pydantic import validator, root_validator
from ..db_engine import db, BattingCardRatings, model_to_dict, chunked, BattingCard
from ..db_engine import db, BattingCardRatings, model_to_dict, chunked, BattingCard, Player, query_to_csv
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
logging.basicConfig(
@ -74,7 +74,7 @@ class BattingCardRatingsModel(pydantic.BaseModel):
values['flyout_bq'] + values['flyout_lf_b'] + values['flyout_rf_b'] + values['groundout_a'] +
values['groundout_b'] + values['groundout_c'])
if total_chances != 108:
if round(total_chances) != 108:
raise ValueError("Must have exactly 108 chances on the card")
return values
@ -86,7 +86,8 @@ class RatingsList(pydantic.BaseModel):
@router.get('')
async def get_card_ratings(
battingcard_id: list = Query(default=None), vs_hand: Literal['R', 'L', 'vR', 'vL'] = None,
short_output: bool = False, token: str = Depends(oauth2_scheme)):
short_output: bool = False, csv: bool = False, cardset_id: list = Query(default=None),
token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
@ -100,13 +101,23 @@ async def get_card_ratings(
if battingcard_id is not None:
all_ratings = all_ratings.where(BattingCardRatings.battingcard_id << battingcard_id)
if vs_hand is not None:
all_ratings = all_ratings.where(BattingCardRatings.vs_hand << vs_hand[-1])
all_ratings = all_ratings.where(BattingCardRatings.vs_hand == vs_hand[-1])
if cardset_id is not None:
set_players = Player.select(Player.player_id).where(Player.cardset_id << cardset_id)
set_cards = BattingCard.select(BattingCard.id).where(BattingCard.player << set_players)
all_ratings = all_ratings.where(BattingCardRatings.battingcard << set_cards)
return_val = {'count': all_ratings.count(), 'ratings': [
model_to_dict(x, recurse=not short_output) for x in all_ratings
]}
db.close()
return return_val
if csv:
return_val = query_to_csv(all_ratings)
db.close()
return Response(content=return_val, media_type='text/csv')
else:
return_val = {'count': all_ratings.count(), 'ratings': [
model_to_dict(x, recurse=not short_output) for x in all_ratings
]}
db.close()
return return_val
@router.get('/{ratings_id}')

View File

@ -1,10 +1,17 @@
from fastapi import APIRouter, Depends, HTTPException, Response, Query
import os.path
from fastapi import APIRouter, Depends, HTTPException, Request, Response, Query
from fastapi.responses import FileResponse
from fastapi.templating import Jinja2Templates
from html2image import Html2Image
from typing import Optional, List
import logging
import pydantic
from pandas import DataFrame
from ..db_engine import db, Player, model_to_dict, fn, chunked, Paperdex, Cardset, Rarity
from ..card_creation import get_batter_card_html, get_batter_card_data
from ..db_engine import db, Player, model_to_dict, fn, chunked, Paperdex, Cardset, Rarity, BattingCard, \
BattingCardRatings
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA
logging.basicConfig(
@ -19,6 +26,9 @@ router = APIRouter(
)
templates = Jinja2Templates(directory="storage/templates")
class PlayerPydantic(pydantic.BaseModel):
player_id: int = None
p_name: str
@ -60,7 +70,7 @@ async def get_players(
has_vanity_card: Optional[bool] = None, strat_code: Optional[str] = None, bbref_id: Optional[str] = None,
fangr_id: Optional[str] = None, inc_dex: Optional[bool] = True, in_desc: Optional[str] = None,
flat: Optional[bool] = False, sort_by: Optional[str] = False, cardset_id_exclude: list = Query(default=None),
limit: Optional[int] = None, csv: Optional[bool] = None):
limit: Optional[int] = None, csv: Optional[bool] = None, short_output: Optional[bool] = False):
all_players = Player.select()
if all_players.count() == 0:
db.close()
@ -158,7 +168,7 @@ async def get_players(
return_val = {'count': len(final_players), 'players': []}
for x in final_players:
this_record = model_to_dict(x, recurse=not flat)
this_record = model_to_dict(x, recurse=not (flat or short_output))
if inc_dex:
this_dex = Paperdex.select().where(Paperdex.player == x)
@ -319,6 +329,67 @@ async def get_one_player(player_id, csv: Optional[bool] = False):
return return_val
@router.get('/{player_id}/batting-card')
async def get_player_card(
request: Request, player_id: int, variant: int = 0, d: str = None, html: Optional[bool] = False):
if os.path.isfile(f'storage/cards/{player_id}-{d}-v{variant}.png') and html is False:
db.close()
return FileResponse(
path=f'storage/cards/{player_id}-{d}-v{variant}.png',
media_type='image/png'
)
try:
this_player = Player.get_by_id(player_id)
except Exception:
db.close()
raise HTTPException(status_code=404, detail=f'No player found with id {player_id}')
this_bc = BattingCard.get_or_none(BattingCard.player == this_player, BattingCard.variant == variant)
if this_bc is None:
raise HTTPException(status_code=404, detail=f'Batting card not found for id {player_id}, variant {variant}')
rating_vl = BattingCardRatings.get_or_none(
BattingCardRatings.battingcard == this_bc, BattingCardRatings.vs_hand == 'L')
rating_vr = BattingCardRatings.get_or_none(
BattingCardRatings.battingcard == this_bc, BattingCardRatings.vs_hand == 'R')
if None in [rating_vr, rating_vl]:
raise HTTPException(status_code=404, detail=f'Ratings not found for batting card {this_bc.id}')
hti = Html2Image(
browser='chromium',
size=(1200, 600),
output_path=f'storage/cards',
custom_flags=['--no-sandbox', '--disable-remote-debugging', '--headless', '--disable-gpu',
'--disable-software-rasterizer', '--disable-dev-shm-usage']
)
card_data = {
'player': this_player,
'card_type': 'batter',
'results_vl_one': 'Big Dongs',
'results_vl_two': 'Lesser Dongs',
'results_vl_three': 'Sad Dongs',
'results_vr_one': 'Light Dongs',
'results_vr_two': 'Hefty Dongs',
'results_vr_three': 'Obese Dongs',
'request': request
}
html_response = templates.TemplateResponse("player_card.html", card_data)
if html:
db.close()
return html_response
logging.debug(f'body:\n{html_response.body.decode("UTF-8")}')
x = hti.screenshot(
html_str=str(html_response.body.decode("UTF-8")),
save_as=f'{player_id}-{d}-v{variant}.png'
)
db.close()
return FileResponse(path=x[0], media_type='image/png')
@router.patch('/{player_id}')
async def v1_players_patch(
player_id, name: Optional[str] = None, image: Optional[str] = None, image2: Optional[str] = None,

View File

@ -7,3 +7,5 @@ pygsheets
pybaseball
python-multipart
requests
html2image
jinja2