diff --git a/CLAUDE.md b/CLAUDE.md index ac93d49..27e322c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,15 +98,17 @@ pd-cards retrosheet defense 2005 --output "data-input/2005 Live Cardset/" ### Scouting Reports +**CRITICAL**: Scouting reports must ALWAYS be generated for ALL cardsets (no --cardset-id filter). The scouting database is a unified view across all players, and filtering to a single cardset will overwrite the full reports with partial data. + ```bash -# Generate batting scouting reports -pd-cards scouting batters --cardset-id 27 +# Generate all scouting reports (ALWAYS run without cardset filter) +pd-cards scouting all -# Generate pitching scouting reports -pd-cards scouting pitchers --cardset-id 27 +# Upload scouting reports to database server +pd-cards scouting upload -# Generate all scouting reports -pd-cards scouting all --cardset-id 27 +# Full workflow after any card changes: +pd-cards scouting all && pd-cards scouting upload ``` ### S3 Upload diff --git a/pd_cards/commands/scouting.py b/pd_cards/commands/scouting.py index c103bfe..1a7a6f2 100644 --- a/pd_cards/commands/scouting.py +++ b/pd_cards/commands/scouting.py @@ -213,3 +213,104 @@ def all( 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)