diff --git a/app/card_creation.py b/app/card_creation.py
new file mode 100644
index 0000000..7f0f8fe
--- /dev/null
+++ b/app/card_creation.py
@@ -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'
{player.p_name}
'
+
+
+def get_batter_card_data(player, batting_card, ratings_vl, ratings_vr) -> dict:
+
+ return {}
diff --git a/app/main.py b/app/main.py
index f187f3b..423c32a 100644
--- a/app/main.py
+++ b/app/main.py
@@ -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)
diff --git a/app/routers_v2/battingcardratings.py b/app/routers_v2/battingcardratings.py
index 987825f..d7f25ff 100644
--- a/app/routers_v2/battingcardratings.py
+++ b/app/routers_v2/battingcardratings.py
@@ -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}')
diff --git a/app/routers_v2/players.py b/app/routers_v2/players.py
index d2f00ff..3f39c43 100644
--- a/app/routers_v2/players.py
+++ b/app/routers_v2/players.py
@@ -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,
diff --git a/requirements.txt b/requirements.txt
index e6c901c..9d19235 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,5 @@ pygsheets
pybaseball
python-multipart
requests
+html2image
+jinja2