import argparse import os from rich.console import Console from rich.markdown import Markdown from models import Problem console = Console() def parse_args(): try: parser = argparse.ArgumentParser(description="Luogu CLI 工具") subparsers = parser.add_subparsers(dest="command", required=True) # lgcli parse PID parse_parser = subparsers.add_parser("parse", help="下载指定题目的题面、样例和题解") parse_parser.add_argument("pid", help="题目编号,例如 P1145") # lgcli view PID view_parser = subparsers.add_parser("view", help="查看题目描述") view_parser.add_argument("pid", help="题目编号,例如 P1145") # lgcli solution PID solution_parser = subparsers.add_parser("solution", help="查看题解列表或具体题解内容") solution_parser.add_argument("pid", help="题目编号,例如 P1145") solution_parser.add_argument("--id", help="指定题解文件名(不带.md)", default=None) return parser.parse_args() except argparse.ArgumentError as e: console.print(f"[red]参数解析错误:{e}[/red]") exit(1) except Exception as e: console.print(f"[red]未知错误:{e}[/red]") exit(1) def cmd_view(pid): filename = f"{pid}/{pid}.md" if not os.path.exists(filename): console.print(f"[red]错误:{pid} 尚未解析,请先运行 lgcli parse {pid}[/red]") return try: console.clear() with open(filename, "r", encoding="utf8") as f: content = f.read() console.print(Markdown(content)) except IOError as e: console.print(f"[red]读取文件失败:{e}[/red]") except Exception as e: console.print(f"[red]渲染Markdown失败:{e}[/red]") def cmd_solution(pid): folder = f"{pid}/solutions" if not os.path.exists(folder): console.print(f"[red]错误:{pid} 题解尚未下载,请先运行 lgcli parse {pid}[/red]") return try: files = [f for f in os.listdir(folder) if f.endswith(".md")] if not files: console.print("[yellow]暂无题解。[/yellow]") return if args.id is None: console.clear() console.print("[bold blue]可用题解:[/bold blue]") for i, fname in enumerate(files): console.print(f"{i+1}. {fname[:-3]}") return selected_file = f"{args.id}.md" full_path = os.path.join(folder, selected_file) if not os.path.exists(full_path): console.print(f"[red]错误:题解 {selected_file} 不存在。请检查名称。[/red]") return console.clear() with open(full_path, "r", encoding="utf8") as f: content = f.read() console.print(Markdown(content)) except IOError as e: console.print(f"[red]读取题解文件失败:{e}[/red]") except Exception as e: console.print(f"[red]渲染Markdown失败:{e}[/red]") def cmd_parse(pid): try: p = Problem(pid) p.gen_all() console.print(f"[green]✅ 题目 {pid} 已成功下载到目录 '{pid}'[/green]") except ConnectionError as e: console.print(f"[red]网络连接错误:{e}[/red]") except RuntimeError as e: console.print(f"[red]数据解析错误:{e}[/red]") except Exception as e: console.print(f"[red]未知错误:{e}[/red]") if __name__ == "__main__": try: args = parse_args() if args.command == "parse": cmd_parse(args.pid) elif args.command == "view": cmd_view(args.pid) elif args.command == "solution": cmd_solution(args.pid) except KeyboardInterrupt: console.print("\n[yellow]用户中断操作。[/yellow]") except Exception as e: console.print(f"[red]发生致命错误:{e}[/red]")