claude-configs/skills/major-domo/cli_schedule.py
Cal Corum 43d32e9b9d Update major-domo skill CLI refactor and plugin/config updates
- Refactor major-domo skill: api_client.py, cli.py, and CLI modules (admin, common, injuries, results, schedule, transactions) with significant simplification (-275 lines net)
- Update CLI_REFERENCE.md and SKILL.md docs for major-domo
- Update create-scheduled-task SKILL.md
- Update plugins blocklist.json and known_marketplaces.json
- Add patterns/ directory to repo
- Update CLAUDE.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 02:00:41 -05:00

219 lines
6.0 KiB
Python

#!/usr/bin/env python3
"""
Major Domo CLI - Schedule Operations
Commands for listing and filtering game schedules.
"""
from typing import Annotated, Optional
import typer
from cli_common import (
state,
console,
output_json,
output_table,
handle_error,
get_season,
safe_nested,
)
schedule_app = typer.Typer(
help="Schedule operations",
invoke_without_command=True,
no_args_is_help=False,
)
@schedule_app.callback()
def schedule_callback(
ctx: typer.Context,
team: Annotated[
Optional[str], typer.Option("--team", "-t", help="Filter by team abbreviation")
] = None,
week: Annotated[
Optional[int], typer.Option("--week", "-w", help="Filter by specific week")
] = None,
week_start: Annotated[
Optional[int], typer.Option("--week-start", help="Start week for range")
] = None,
week_end: Annotated[
Optional[int], typer.Option("--week-end", help="End week for range")
] = None,
season: Annotated[
Optional[int], typer.Option("--season", "-s", help="Season number")
] = None,
limit: Annotated[
int, typer.Option("--limit", "-n", help="Max results to display")
] = 50,
):
"""
List game schedules with optional filters.
By default, shows recent schedules for the current season.
Use filters to narrow down results.
Examples:
majordomo schedule --team CAR
majordomo schedule --week 5
majordomo schedule --week-start 1 --week-end 4
"""
# Only invoke if no subcommand was called
if ctx.invoked_subcommand is not None:
return
try:
season = get_season(season)
# Handle week vs week_start/week_end
if week is not None:
week_start = week
week_end = week
# Get schedules from API using low-level get method
result = state.api.get(
"schedules",
season=season,
team_abbrev=team,
week_start=week_start,
week_end=week_end,
short_output=False,
)
schedules = result.get("schedules", [])
# Limit results
schedules = schedules[:limit]
if state.json_output:
output_json(schedules)
return
if not schedules:
console.print(
f"[yellow]No schedules found for the given filters (Season {season})[/yellow]"
)
return
# Build table rows
rows = []
for s in schedules:
away_abbrev = safe_nested(s, "away_team", "abbrev")
home_abbrev = safe_nested(s, "home_team", "abbrev")
rows.append(
[
s.get("week", ""),
s.get("game_num", ""),
away_abbrev,
"@",
home_abbrev,
]
)
# Build title with filters
title_parts = [f"Schedule (Season {season})"]
if team:
title_parts.append(f"Team: {team}")
if week:
title_parts.append(f"Week {week}")
elif week_start and week_end:
title_parts.append(f"Weeks {week_start}-{week_end}")
title = " | ".join(title_parts)
output_table(title, ["Week", "Gm", "Away", "@", "Home"], rows)
except Exception as e:
handle_error(e)
@schedule_app.command("list")
def schedule_list(
team: Annotated[
Optional[str], typer.Option("--team", "-t", help="Filter by team abbreviation")
] = None,
week: Annotated[
Optional[int], typer.Option("--week", "-w", help="Filter by specific week")
] = None,
week_start: Annotated[
Optional[int], typer.Option("--week-start", help="Start week for range")
] = None,
week_end: Annotated[
Optional[int], typer.Option("--week-end", help="End week for range")
] = None,
season: Annotated[
Optional[int], typer.Option("--season", "-s", help="Season number")
] = None,
limit: Annotated[
int, typer.Option("--limit", "-n", help="Max results to display")
] = 50,
):
"""
List game schedules with optional filters (explicit command).
This is the same as calling 'majordomo schedule' without a subcommand.
"""
try:
season = get_season(season)
# Handle week vs week_start/week_end
if week is not None:
week_start = week
week_end = week
# Get schedules from API using low-level get method
result = state.api.get(
"schedules",
season=season,
team_abbrev=team,
week_start=week_start,
week_end=week_end,
short_output=False,
)
schedules = result.get("schedules", [])
# Limit results
schedules = schedules[:limit]
if state.json_output:
output_json(schedules)
return
if not schedules:
console.print(
f"[yellow]No schedules found for the given filters (Season {season})[/yellow]"
)
return
# Build table rows
rows = []
for s in schedules:
away_abbrev = safe_nested(s, "away_team", "abbrev")
home_abbrev = safe_nested(s, "home_team", "abbrev")
rows.append(
[
s.get("week", ""),
s.get("game_num", ""),
away_abbrev,
"@",
home_abbrev,
]
)
# Build title with filters
title_parts = [f"Schedule (Season {season})"]
if team:
title_parts.append(f"Team: {team}")
if week:
title_parts.append(f"Week {week}")
elif week_start and week_end:
title_parts.append(f"Weeks {week_start}-{week_end}")
title = " | ".join(title_parts)
output_table(title, ["Week", "Gm", "Away", "@", "Home"], rows)
except Exception as e:
handle_error(e)