Batting card generation active

Fully functional through to png files
This commit is contained in:
Cal Corum 2023-10-14 23:42:53 -05:00
parent 5974ec665e
commit cfdf0e985d
4 changed files with 206 additions and 22 deletions

123
check_cards.py Normal file
View File

@ -0,0 +1,123 @@
import asyncio
import datetime
import logging
import sys
import requests
from creation_helpers import get_args
from db_calls import db_get, url_get
date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}'
log_level = logging.INFO
logging.basicConfig(
filename=f'logs/{date}.log',
format='%(asctime)s - check-cards - %(levelname)s - %(message)s',
level=log_level
)
async def main(args):
arg_data = get_args(args)
cardset_name = arg_data['cardset_name']
print(f'Searching for cardset: {cardset_name}')
c_query = await db_get('cardsets', params=[('name', cardset_name)])
if c_query['count'] == 0:
print(f'I do not see a cardset named {cardset_name}')
return
cardset = c_query['cardsets'][0]
del c_query
p_query = await db_get(
'players',
params=[('inc_dex', False), ('cardset_id', cardset['id']), ('short_output', True)]
)
if p_query['count'] == 0:
raise ValueError(f'No players returned from Paper Dynasty API')
all_players = p_query['players']
del p_query
errors = []
successes = []
cxn_error = False
count = -1
for x in all_players:
if 'pitching' in x['image'] and 'skip_arms' in arg_data and arg_data['skip_arms'].lower() == 'true':
pass
elif 'batting' in x['image'] and 'skip_bats' in arg_data and arg_data['skip_bats'].lower() == 'true':
pass
elif 'sombaseball' in x['image']:
errors.append((x, f'Bad card url: {x["image"]}'))
elif 'start_id' in arg_data and int(arg_data['start_id']) > x['player_id']:
pass
else:
count += 1
if count % 20 == 0:
print(f'Card #{count + 1} being pulled is {x["p_name"]}...')
elif 'test_count' in arg_data and int(arg_data['test_count']) < count:
print(f'Done test run')
break
if 'html_cards' in arg_data and arg_data['html_cards'].lower() == 'true':
card_url = f'{x["image"]}&html=true'
timeout = 2
else:
card_url = x['image']
timeout = 6
try:
resp = await url_get(card_url, timeout=timeout)
except ConnectionError as e:
if cxn_error:
raise e
cxn_error = True
errors.append((x, e))
except ValueError as e:
errors.append((x, e))
else:
successes.append(x)
if x['image2'] is not None:
if 'html_cards' in arg_data and arg_data['html_cards'].lower() == 'true':
card_url = f'{x["image2"]}&html=true'
else:
card_url = x['image2']
try:
resp = await url_get(card_url, timeout=6)
except ConnectionError as e:
if cxn_error:
raise e
cxn_error = True
errors.append((x, e))
except ValueError as e:
errors.append((x, e))
else:
successes.pop(x)
if len(errors) > 0:
logging.error(f'All Errors:')
for x in errors:
logging.error(f'ID {x[0]["player_id"]} {x[0]["p_name"]} - Error: {x[1]}')
if len(successes) > 0:
logging.info(f'All Successes:')
for x in successes:
logging.info(f'ID {x["player_id"]} {x["p_name"]}')
print(f'\nAll done!\nErrors: {len(errors)}\nSuccesses: {len(successes)}')
if __name__ == '__main__':
asyncio.run(main(sys.argv[1:]))

View File

@ -417,6 +417,23 @@ TESTING = False
YES = ['y', 'yes', 'yeet', 'please', 'yeah'] YES = ['y', 'yes', 'yeet', 'please', 'yeah']
def get_args(args):
logging.info(f'Process arguments: {args}')
final_args = {}
for x in args:
if "=" not in x:
raise TypeError(f'Invalid <key>=<value> argument: {x}')
key, value = x.split("=")
logging.info(f'key: {key} / value: {value}')
if key in final_args:
raise ValueError(f'Duplicate argument: {key}')
final_args[key] = value
return final_args
async def pd_players_df(cardset_id: int): async def pd_players_df(cardset_id: int):
p_query = await db_get( p_query = await db_get(
'players', 'players',
@ -895,5 +912,23 @@ def sanitize_chance_output(total_chances, min_chances=1.0, rounding=0.05):
# r_val = mround(total_chances) if total_chances >= min_chances else 0 # r_val = mround(total_chances) if total_chances >= min_chances else 0
r_val = Decimal(total_chances) if total_chances >= min_chances else Decimal(0) r_val = Decimal(total_chances) if total_chances >= min_chances else Decimal(0)
logging.debug(f'r_val: {r_val}') logging.debug(f'r_val: {r_val}')
return Decimal(float(math.floor(r_val / Decimal(rounding)) * Decimal(rounding))).quantize(Decimal("0.05")) rounded_val = Decimal(float(math.floor(r_val / Decimal(rounding)) * Decimal(rounding))).quantize(Decimal("0.05"))
# return r_val.quantize(Decimal(rounding)) if math.floor(rounded_val) == rounded_val:
return rounded_val
exact_chances = [
Decimal('1.05'), Decimal('1.1'), Decimal('1.2'), Decimal('1.25'), Decimal('1.3'), Decimal('1.35'),
Decimal('1.4'), Decimal('1.5'), Decimal('1.6'), Decimal('1.65'), Decimal('1.7'), Decimal('1.75'),
Decimal('1.8'), Decimal('1.9'), Decimal('1.95'), Decimal('2.1'), Decimal('2.2'), Decimal('2.25'),
Decimal('2.4'), Decimal('2.5'), Decimal('2.55'), Decimal('2.6'), Decimal('2.7'), Decimal('2.75'),
Decimal('2.8'), Decimal('2.85'), Decimal('3.2'), Decimal('3.25'), Decimal('3.3'), Decimal('3.4'),
Decimal('3.5'), Decimal('3.6'), Decimal('3.75'), Decimal('3.8'), Decimal('3.9'), Decimal('4.2'),
Decimal('4.25'), Decimal('4.5'), Decimal('4.75'), Decimal('4.8'), Decimal('5.1'), Decimal('5.4'),
Decimal('5.7')
]
if rounded_val > exact_chances[-1]:
return rounded_val
for x in exact_chances:
if rounded_val <= x:
return x

View File

@ -74,6 +74,35 @@ async def db_get(
raise ValueError(f'DB: {resp.text}') raise ValueError(f'DB: {resp.text}')
async def url_get(url: str, timeout: int = 3):
log_string = f'get:\n{url}'
logging.info(log_string) if master_debug else logging.debug(log_string)
retries = 0
while True:
try:
resp = requests.get(url, timeout=timeout)
break
except requests.ReadTimeout as e:
logging.error(f'Get Timeout: {url} / retries: {retries} / timeout: {timeout}')
if retries > 1:
raise ConnectionError(f'DB: The internet was a bit too slow for me to grab the data I needed. Please '
f'hang on a few extra seconds and try again.')
timeout += [2, 5][retries]
retries += 1
if resp.status_code == 200:
logging.debug(f'return: {resp.text}')
if master_debug:
logging.info(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}')
else:
logging.debug(f'return: {log_string[:1200]}{" [ S N I P P E D ]" if len(log_string) > 1200 else ""}')
return resp
else:
logging.warning(resp.text)
raise ValueError(f'DB: {resp.text}')
async def db_patch(endpoint: str, object_id: int, params: list, api_ver: int = 2, timeout: int = 3): async def db_patch(endpoint: str, object_id: int, params: list, api_ver: int = 2, timeout: int = 3):
req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params) req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id, params=params)
log_string = f'patch:\n{endpoint} {params}' log_string = f'patch:\n{endpoint} {params}'

View File

@ -17,7 +17,8 @@ import pydantic
import sys import sys
from creation_helpers import pd_players_df, get_batting_stats, pd_battingcards_df, pd_battingcardratings_df, \ from creation_helpers import pd_players_df, get_batting_stats, pd_battingcards_df, pd_battingcardratings_df, \
get_pitching_stats, get_pitching_peripherals, pd_pitchingcards_df, pd_pitchingcardratings_df, pd_positions_df get_pitching_stats, get_pitching_peripherals, pd_pitchingcards_df, pd_pitchingcardratings_df, pd_positions_df, \
get_args
from db_calls import db_get, db_put, db_post, db_patch from db_calls import db_get, db_put, db_post, db_patch
from typing import Literal from typing import Literal
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
@ -44,23 +45,6 @@ def sanitize_name(start_name: str) -> str:
.replace("ú", "u")) .replace("ú", "u"))
def get_args(args):
logging.info(f'Process arguments: {args}')
final_args = {}
for x in args:
if "=" not in x:
raise TypeError(f'Invalid <key>=<value> argument: {x}')
key, value = x.split("=")
logging.info(f'key: {key} / value: {value}')
if key in final_args:
raise ValueError(f'Duplicate argument: {key}')
final_args[key] = value
return final_args
# class BattingStat(pydantic.BaseModel): # class BattingStat(pydantic.BaseModel):
# fg_id: int # fg_id: int
# vs_hand: Literal['L', 'R'] # vs_hand: Literal['L', 'R']
@ -270,13 +254,20 @@ async def main(args):
if df_data['key_bbref'] in pos_data[0].index: if df_data['key_bbref'] in pos_data[0].index:
logging.debug(f'Running {pos_data[1]} stats for {player_data.at[df_data["key_bbref"], "p_name"]}') logging.debug(f'Running {pos_data[1]} stats for {player_data.at[df_data["key_bbref"], "p_name"]}')
no_data = False no_data = False
average_range = (int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']) +
int(pos_data[0].at[df_data["key_bbref"], 'bis_runs_total']) +
min(
int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']),
int(pos_data[0].at[df_data["key_bbref"], 'bis_runs_total'])
)) / 3
position_payload.append({ position_payload.append({
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']), "player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": pos_data[1].upper(), "position": pos_data[1].upper(),
"innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']), "innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']),
"range": cde.get_if_range( "range": cde.get_if_range(
pos_code=pos_data[1], pos_code=pos_data[1],
tz_runs=int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']), tz_runs=round(average_range),
r_dp=0, r_dp=0,
season_pct=season_pct season_pct=season_pct
), ),
@ -293,13 +284,19 @@ async def main(args):
for pos_data in [(df_lf, 'lf'), (df_cf, 'cf'), (df_rf, 'rf')]: for pos_data in [(df_lf, 'lf'), (df_cf, 'cf'), (df_rf, 'rf')]:
if df_data["key_bbref"] in pos_data[0].index: if df_data["key_bbref"] in pos_data[0].index:
no_data = False no_data = False
average_range = (int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']) +
int(pos_data[0].at[df_data["key_bbref"], 'bis_runs_total']) +
min(
int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']),
int(pos_data[0].at[df_data["key_bbref"], 'bis_runs_total'])
)) / 3
of_payloads.append({ of_payloads.append({
"player_id": int(player_data.at[df_data["key_bbref"], 'player_id']), "player_id": int(player_data.at[df_data["key_bbref"], 'player_id']),
"position": pos_data[1].upper(), "position": pos_data[1].upper(),
"innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']), "innings": float(pos_data[0].at[df_data["key_bbref"], 'Inn_def']),
"range": cde.get_of_range( "range": cde.get_of_range(
pos_code=pos_data[1], pos_code=pos_data[1],
tz_runs=int(pos_data[0].at[df_data["key_bbref"], 'tz_runs_total']), tz_runs=round(average_range),
season_pct=season_pct season_pct=season_pct
) )
}) })