""" cli.py — 시스템 전체 CLI 통합 진입점 크롤러, 라인업 관리, 게임 기록 입력 등 모든 기능을 서브 커맨드(subcommand) 형태로 실행할 수 있습니다. """ from __future__ import annotations import argparse import sys from pathlib import Path from playwright.sync_api import sync_playwright from commands.base import add_common_arguments, load_report from commands.record import run as run_record def _parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Baseball Automation CLI") subparsers = parser.add_subparsers(dest="command", required=True) # 1. record 커맨드 (기존 record_game_playwright.py) parser_record = subparsers.add_parser("record", help="크롤링된 리포트를 바탕으로 게임 기록을 자동 입력합니다.") add_common_arguments(parser_record) parser_record.add_argument("--review-only", action="store_true", help="경기기록 대신 합의판정만 일괄 등록") # 2. crawl 커맨드 (네이버 API 크롤링) parser_crawl = subparsers.add_parser("crawl", help="네이버 야구 API에서 데이터를 크롤링하여 JSON 리포트로 저장합니다.") parser_crawl.add_argument("--game-id", required=True, help="크롤링할 네이버 게임 ID (예: 20260501NCLG02026)") parser_crawl.add_argument("--output-dir", default="output", help="리포트를 저장할 디렉토리 (기본값: output)") parser_crawl.add_argument("--start-inning", help="시작 이닝 필터 (예: '2', '3초')") parser_crawl.add_argument("--end-inning", help="종료 이닝 필터 (예: '5', '7말')") parser_crawl.add_argument("--lineup-only", action="store_true", help="라인업 정보만 저장") return parser.parse_args() def interactive_mode() -> int: print("=== Baseball Automation CLI ===") print("1. 네이버 데이터 크롤링 (crawl)") print("2. 관리자 사이트 기록 자동 입력 (record)") print("3. 크롤링 + 기록 입력 한 번에 실행 (crawl & record)") choice = input("\n실행할 작업을 선택하세요 (1/2/3) [3]: ").strip() or "3" if choice not in {"1", "2", "3"}: print("잘못된 선택입니다.") return 1 game_id = input("경기 ID를 입력하세요 (예: 20260501NCLG02026): ").strip() if not game_id: print("경기 ID가 필요합니다.") return 1 game_id = "".join(game_id.split()) base_url = "" user_data_dir = "" if choice in {"2", "3"}: base_url = input("기록 사이트 기본 URL을 입력하세요 (엔터 시 site.txt 자동 참조): ").strip() if not base_url: site_txt = Path("site.txt") if site_txt.exists(): lines = site_txt.read_text(encoding="utf-8").splitlines() if lines and lines[0].startswith("http"): from urllib.parse import urlparse parsed = urlparse(lines[0]) base_url = f"{parsed.scheme}://{parsed.netloc}" print(f"👉 [자동 설정] 기록 사이트 URL: {base_url}") if not base_url: base_url = input("URL을 찾을 수 없습니다. 직접 입력하세요: ").strip() if not base_url: print("URL이 필요합니다.") return 1 user_data_dir = input("크롬 프로필 경로를 입력하세요 (엔터 시 임시 세션): ").strip() manager_game_no = input("관리자 사이트 게임번호를 입력하세요 (예: 11211, 모르면 엔터): ").strip() args = argparse.Namespace( game_id=game_id, base_url=base_url, report_path=None, manager_game_no=manager_game_no or None, user_data_dir=user_data_dir or None, channel="chrome", headless=False, close=False, write_events=True, job_id=None, lineup_only=False, review_only=False, start_inning=None, end_inning=None, output_dir="output", ) if choice in {"1", "3"}: from crawler.report_builder import build_report, filter_report, save_report print(f"\n[{args.game_id}] 데이터 크롤링 시작...") report = build_report(args.game_id) filtered = filter_report(report) out_path = save_report(filtered, Path(args.output_dir)) print(f"✅ 크롤링 및 리포트 저장 완료: {out_path}") if choice in {"2", "3"}: report_path = Path(args.output_dir) / f"{args.game_id}_report.json" report = load_report(report_path) print(f"\n[{args.game_id}] 관리자 사이트 자동 입력 시작...") with sync_playwright() as playwright: run_record(playwright, args, report) return 0 def main() -> int: if len(sys.argv) == 1: return interactive_mode() args = _parse_args() if args.game_id: args.game_id = "".join(args.game_id.split()) if args.command == "record": report_path = Path(args.report_path) if args.report_path else Path("output") / f"{args.game_id}_report.json" report = load_report(report_path) with sync_playwright() as playwright: run_record(playwright, args, report) return 0 if args.command == "crawl": from crawler.report_builder import build_report, filter_report, save_report print(f"[{args.game_id}] 데이터 크롤링 시작...") report = build_report(args.game_id, start_inning=args.start_inning, end_inning=args.end_inning) filtered = filter_report( report, lineup_only=getattr(args, "lineup_only", False), start_inning=args.start_inning, end_inning=args.end_inning ) out_path = save_report(filtered, Path(args.output_dir)) print(f"✅ 크롤링 및 리포트 저장 완료: {out_path}") return 0 return 1 if __name__ == "__main__": sys.exit(main())