""" Scouting report generation commands. Commands for generating scouting reports and ratings comparisons. """ import asyncio from pathlib import Path from typing import Optional, List import typer from rich.console import Console app = typer.Typer(no_args_is_help=True) console = Console() @app.command() def batters( cardset_ids: Optional[List[int]] = typer.Option(None, "--cardset-id", "-c", help="Cardset ID(s) to include (can specify multiple)"), output_dir: Path = typer.Option(Path("scouting"), "--output", "-o", help="Output directory"), ): """ Generate batting scouting reports. Creates CSV files with batting ratings and comparisons. Example: pd-cards scouting batters --cardset-id 27 --cardset-id 29 """ console.print() console.print("=" * 70) console.print("[bold]BATTING SCOUTING REPORT[/bold]") console.print("=" * 70) if cardset_ids: console.print(f"Cardset IDs: {cardset_ids}") else: console.print("Cardset IDs: All") console.print(f"Output: {output_dir}") console.print() try: import sys sys.path.insert(0, str(Path(__file__).parent.parent.parent)) import scouting_batters as sb import copy async def run_scouting(): # Ensure output directory exists output_dir.mkdir(parents=True, exist_ok=True) console.print("Pulling scouting data...") batting_dfs = await sb.get_scouting_dfs(cardset_ids or []) console.print(f" Received {len(batting_dfs)} rows") console.print("Generating basic scouting report...") await sb.post_calc_basic(copy.deepcopy(batting_dfs)) console.print(f" [green]✓ Saved to {output_dir}/batting-basic.csv[/green]") console.print("Generating ratings guide...") await sb.post_calc_ratings(copy.deepcopy(batting_dfs)) console.print(f" [green]✓ Saved to {output_dir}/batting-ratings.csv[/green]") console.print() console.print("[green]✓ Batting scouting complete[/green]") asyncio.run(run_scouting()) except ImportError as e: console.print(f"[red]Error importing modules: {e}[/red]") raise typer.Exit(1) except Exception as e: console.print(f"[red]Error: {e}[/red]") import traceback traceback.print_exc() raise typer.Exit(1) @app.command() def pitchers( cardset_ids: Optional[List[int]] = typer.Option(None, "--cardset-id", "-c", help="Cardset ID(s) to include (can specify multiple)"), output_dir: Path = typer.Option(Path("scouting"), "--output", "-o", help="Output directory"), ): """ Generate pitching scouting reports. Creates CSV files with pitching ratings and comparisons. Example: pd-cards scouting pitchers --cardset-id 27 --cardset-id 29 """ console.print() console.print("=" * 70) console.print("[bold]PITCHING SCOUTING REPORT[/bold]") console.print("=" * 70) if cardset_ids: console.print(f"Cardset IDs: {cardset_ids}") else: console.print("Cardset IDs: All") console.print(f"Output: {output_dir}") console.print() try: import sys sys.path.insert(0, str(Path(__file__).parent.parent.parent)) import scouting_pitchers as sp import copy async def run_scouting(): # Ensure output directory exists output_dir.mkdir(parents=True, exist_ok=True) console.print("Pulling scouting data...") pitching_dfs = await sp.get_scouting_dfs(cardset_ids or []) console.print(f" Received {len(pitching_dfs)} rows") console.print("Generating basic scouting report...") await sp.post_calc_basic(copy.deepcopy(pitching_dfs)) console.print(f" [green]✓ Saved to {output_dir}/pitching-basic.csv[/green]") console.print("Generating ratings guide...") await sp.post_calc_ratings(copy.deepcopy(pitching_dfs)) console.print(f" [green]✓ Saved to {output_dir}/pitching-ratings.csv[/green]") console.print() console.print("[green]✓ Pitching scouting complete[/green]") asyncio.run(run_scouting()) except ImportError as e: console.print(f"[red]Error importing modules: {e}[/red]") raise typer.Exit(1) except Exception as e: console.print(f"[red]Error: {e}[/red]") import traceback traceback.print_exc() raise typer.Exit(1) @app.command() def all( cardset_ids: Optional[List[int]] = typer.Option(None, "--cardset-id", "-c", help="Cardset ID(s) to include"), output_dir: Path = typer.Option(Path("scouting"), "--output", "-o", help="Output directory"), ): """ Generate all scouting reports (batters and pitchers). Example: pd-cards scouting all --cardset-id 27 """ console.print() console.print("=" * 70) console.print("[bold]FULL SCOUTING REPORT[/bold]") console.print("=" * 70) console.print() # Run batters console.print("[bold]Phase 1: Batters[/bold]") try: import sys sys.path.insert(0, str(Path(__file__).parent.parent.parent)) import scouting_batters as sb import scouting_pitchers as sp import copy async def run_all_scouting(): output_dir.mkdir(parents=True, exist_ok=True) # Batters console.print("Pulling batting data...") batting_dfs = await sb.get_scouting_dfs(cardset_ids or []) console.print(f" Received {len(batting_dfs)} batter rows") await sb.post_calc_basic(copy.deepcopy(batting_dfs)) console.print(f" [green]✓ batting-basic.csv[/green]") await sb.post_calc_ratings(copy.deepcopy(batting_dfs)) console.print(f" [green]✓ batting-ratings.csv[/green]") console.print() console.print("[bold]Phase 2: Pitchers[/bold]") # Pitchers console.print("Pulling pitching data...") pitching_dfs = await sp.get_scouting_dfs(cardset_ids or []) console.print(f" Received {len(pitching_dfs)} pitcher rows") await sp.post_calc_basic(copy.deepcopy(pitching_dfs)) console.print(f" [green]✓ pitching-basic.csv[/green]") await sp.post_calc_ratings(copy.deepcopy(pitching_dfs)) console.print(f" [green]✓ pitching-ratings.csv[/green]") console.print() console.print("=" * 70) console.print("[bold green]✓ ALL SCOUTING REPORTS COMPLETE[/bold green]") console.print("=" * 70) asyncio.run(run_all_scouting()) except ImportError as e: console.print(f"[red]Error importing modules: {e}[/red]") raise typer.Exit(1) except Exception as e: console.print(f"[red]Error: {e}[/red]") import traceback traceback.print_exc() raise typer.Exit(1) @app.command() def upload( input_dir: Path = typer.Option(Path("scouting"), "--input", "-i", help="Input directory with scouting CSVs"), remote_host: str = typer.Option("sba-db", "--host", "-h", help="Remote host to upload to"), remote_dir: str = typer.Option("/home/cal/container-data/pd-database/storage", "--remote-dir", "-r", help="Remote directory path"), dry_run: bool = typer.Option(False, "--dry-run", "-n", help="Show what would be uploaded without uploading"), ): """ Upload scouting reports to remote server via SCP. Uploads the generated CSV files to the Paper Dynasty database server. Example: pd-cards scouting upload pd-cards scouting upload --dry-run pd-cards scouting upload --host sba-db --remote-dir /path/to/storage """ import subprocess console.print() console.print("=" * 70) console.print("[bold]SCOUTING REPORT UPLOAD[/bold]") console.print("=" * 70) console.print() FILES_TO_UPLOAD = [ 'batting-basic.csv', 'batting-ratings.csv', 'pitching-basic.csv', 'pitching-ratings.csv' ] # Verify files exist console.print("[bold]Verifying files...[/bold]") missing_files = [] for filename in FILES_TO_UPLOAD: filepath = input_dir / filename if not filepath.exists(): missing_files.append(str(filepath)) else: console.print(f" [green]✓[/green] {filepath}") if missing_files: console.print() console.print(f"[red]Missing files:[/red]") for f in missing_files: console.print(f" [red]✗[/red] {f}") console.print() console.print("[yellow]Run 'pd-cards scouting all' first to generate reports.[/yellow]") raise typer.Exit(1) console.print() console.print(f"[bold]Upload destination:[/bold] {remote_host}:{remote_dir}") console.print() if dry_run: console.print("[yellow]DRY RUN - No files will be uploaded[/yellow]") console.print() for filename in FILES_TO_UPLOAD: console.print(f" Would upload: {input_dir / filename}") console.print() console.print("=" * 70) console.print("[bold yellow]✓ DRY RUN COMPLETE[/bold yellow]") console.print("=" * 70) return # Upload files via SCP console.print("[bold]Uploading files...[/bold]") try: local_files = [str(input_dir / f) for f in FILES_TO_UPLOAD] scp_command = [ 'scp', *local_files, f"{remote_host}:{remote_dir}/" ] result = subprocess.run( scp_command, check=True, capture_output=True, text=True ) for filename in FILES_TO_UPLOAD: console.print(f" [green]✓[/green] {filename}") console.print() console.print("=" * 70) console.print("[bold green]✓ SCOUTING UPLOAD COMPLETE[/bold green]") console.print("=" * 70) except subprocess.CalledProcessError as e: console.print(f"[red]Upload failed: {e}[/red]") if e.stderr: console.print(f"[red]{e.stderr}[/red]") raise typer.Exit(1) except FileNotFoundError: console.print("[red]Error: 'scp' command not found. Ensure SSH is installed.[/red]") raise typer.Exit(1)