Update calendar generation and data normalization; add read check command

- Add config file support for calendar colors and logos in generate_calendar
- Extend normalization mappings in normalization.toml for fields and teams
- Add 'read check' command to summarize game and field data from input files
- Fix normalization to correctly handle visitor field and value lookups
- Update launch configurations for new data and options
This commit is contained in:
2025-08-26 16:42:19 -05:00
parent c1628f5dfe
commit 2a521e9016
6 changed files with 112 additions and 33 deletions

View File

@@ -1,6 +1,6 @@
import typer
from rich.console import Console
from typing import Annotated, List
from typing import Annotated, List, Optional
from pathlib import Path
from ...utils.sportspress import validate_keys
from ...utils.normalize import normalize_header_key, load_config
@@ -15,13 +15,14 @@ app = typer.Typer()
@app.command(name="calendar")
def generate_calendar_app(
input_file: Annotated[List[Path], typer.Argument(..., help="Path(s) to the CSV file")],
config_file: Annotated[Optional[typer.FileText], typer.Option(..., "--config", "-c", help="Path to a config file")]=None
):
# Read CSV data
data = read_and_normalize_csv_or_xlsx(input_file)
data = personalize_data_for_team(data, "Hounds")
# data = parse_datetime(data)
generate_calendar(data)
generate_calendar(data, config_file)
pass
@app.command(name="calendar-config")

View File

@@ -3,6 +3,7 @@ from calendar import Calendar
from PIL import Image, ImageDraw, ImageFont
from typing import Tuple
from pathlib import Path
import toml
calendar_cell_size = (400, 500)
calendar_cell_width, calendar_cell_height = calendar_cell_size
@@ -72,10 +73,13 @@ def calendar_cell(
return cell_img
def generate_calendar(data):
def generate_calendar(data, config_file=None):
result_calendar = Calendar()
result_calendar.setfirstweekday(6)
baseball_bat = Image.open(f"data/logos/baseball_bat_2.png")
if config_file:
config = toml.load(config_file)
baseball_bat = baseball_bat.resize((90, 90))
for year, month in {(row['datetime'].year, row['datetime'].month) for row in data}:
month_days=list(result_calendar.monthdayscalendar(year, month))
@@ -83,21 +87,15 @@ def generate_calendar(data):
first_thursday=(month, [w[4] for w in month_days if w[4] != 0][0])
colors = {
# 'proviso-west': (139, 69, 19, 256),
'winnemac': (37, 89, 164, 256),
# 'walther': (251, 231, 77, 256),
# 'taft': (64, 119, 0, 256),
'southwest': (230, 136, 60, 256),
# 'maywood': (107, 5, 4, 256),
# 'ozinga': (170, 143, 102, 256),
# 'simeon':(167,192,226),
'Skokie':(72,159,88),
# 'comed':(206,45,137),
'default': (0, 0, 0, 256),
'Loyola': (206,45,137),
'Piotrowski': (251, 231, 77, 256),
'Baseball Alley': (167,192,226),
'default': (128, 128, 128, 256),
}
team_logos={}
if config:
for field, field_options in config['fields'].items():
colors[field] = tuple(field_options.get('bg_color', colors.get('default')))
for team, team_options in config['teams'].items():
team_logos[team] = team_options.get('logo')
for week_num, week in enumerate(month_days):
for day_num, date in enumerate(week):
@@ -111,9 +109,9 @@ def generate_calendar(data):
# Gen square that has one game
if len (filtered_data) == 1:
game = filtered_data[0]
opponent_logo_path = Path(f"data/logos/{game['opponent'].lower()}.png")
if opponent_logo_path.exists():
opponent_logo = Image.open(f"data/logos/{game['opponent'].lower()}.png")
opponent_logo_path = team_logos.get(game['opponent'])
if opponent_logo_path and (opponent_logo_path := Path(opponent_logo_path)) and opponent_logo_path.exists():
opponent_logo = Image.open(opponent_logo_path)
else:
opponent_logo = text_rectangle(text=game['opponent'][0].upper(),width=500, height=500, font_size=400, font="data/fonts/college.ttf")
is_home_game = game['homevisitor'] == "home"
@@ -124,7 +122,7 @@ def generate_calendar(data):
img = calendar_cell(
height=calendar_cell_height,
width=calendar_cell_width,
background_color=colors[game['field']],
background_color=colors.get(game['field'], colors['default']),
left_top_corner = text_rectangle('H' if is_home_game else "A",
"data/fonts/refrigerator-deluxe-bold.otf",
80,
@@ -134,7 +132,7 @@ def generate_calendar(data):
width=calendar_cell_width*.2),
right_top_corner = date_text_image,
center = opponent_logo.resize((int(opponent_logo.width*.5), int(opponent_logo.height*.5))),
bottom_center = text_rectangle(f"{game['time']:%-I:%M}",
bottom_center = text_rectangle(f"{game['time']:%-I:%M}" if game.get('time') else "",
"data/fonts/refrigerator-deluxe-bold.otf",
120,
foreground_color='white',
@@ -145,10 +143,16 @@ def generate_calendar(data):
# img.show()
elif len(filtered_data) == 2:
game1, game2 = filtered_data[:2]
opponent_logo_path = team_logos.get(game1['opponent'])
if opponent_logo_path and (opponent_logo_path := Path(opponent_logo_path)) and opponent_logo_path.exists():
opponent_logo = Image.open(opponent_logo_path)
else:
opponent_logo = text_rectangle(text=game1['opponent'][0].upper(),width=500, height=500, font_size=400, font="data/fonts/college.ttf")
img = calendar_cell(
height=calendar_cell_height,
width=calendar_cell_width,
background_color='red',
background_color=colors.get(game1['field'], colors['default']),
left_top_corner = text_rectangle('DH',
"data/fonts/refrigerator-deluxe-bold.otf",
80,