luogu-cli/main.py

114 lines
3.9 KiB
Python
Raw Permalink Normal View History

2025-05-01 14:33:06 +08:00
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]")