#!/usr/bin/env python3 """ EF Course Autopilot — 交互式循环运行脚本 从 token.txt 文件读取 JWT token(默认读取运行目录下的 token.txt)。 token 需从浏览器开发者工具中获取,详见 README.md。 用法示例: python3 ef_course_loop.py # 默认读取 ./token.txt python3 ef_course_loop.py --token-file /path/to/token.txt """ import argparse import sys import time from ef_course_autopilot import EFCourseAutopilot def read_token(token_file: str) -> str: """从指定文件读取 token(仅支持单行内容)""" try: with open(token_file, "r") as f: token = f.read().strip() if not token: print(f"❌ token 文件为空: {token_file}") sys.exit(1) print(f" 📄 从文件读取 token ({token_file})") return token except FileNotFoundError: print(f"❌ token 文件不存在: {token_file}") print(f" 请创建 {token_file} 并将 ef_access_token 粘贴到第一行") sys.exit(1) except IOError as e: print(f"❌ 读取文件失败: {e}") sys.exit(1) def main(): parser = argparse.ArgumentParser( description="EF Course Autopilot — 交互式循环运行", formatter_class=argparse.RawDescriptionHelpFormatter, epilog="""\ 使用示例: python3 ef_course_loop.py # 默认读取 ./token.txt python3 ef_course_loop.py --token-file /path/to/token.txt token.txt 说明: - 仅能包含一行,即 ef_access_token 的值 - 从浏览器开发者工具中取请求携带的 ef_access_token 内容,手动粘贴 """, ) parser.add_argument( "--token-file", default="token.txt", help="从文件读取 JWT token(默认: ./token.txt)", ) parser.add_argument( "--verify-ssl", action="store_true", help="启用SSL证书验证(默认禁用)", ) args = parser.parse_args() print("=" * 60) print(" EF Course Autopilot — 交互式循环运行") print("=" * 60) while True: # 1. 从文件获取 token token = read_token(args.token_file) # 2. 输入课程数量 while True: try: count_str = input("请输入要完成的课程数量: ").strip() count = int(count_str) if count <= 0: print("❌ 数量必须大于 0") continue break except ValueError: print("❌ 请输入有效数字") # 3. 循环完成课程 total_success = 0 total_fail = 0 start_time = time.time() for i in range(count): print(f"\n{'=' * 60}") print(f" 第 {i + 1}/{count} 门课程") print(f"{'=' * 60}") autopilot = EFCourseAutopilot( token=token, skip_on_fail=True, verify_ssl=args.verify_ssl, ) try: success = autopilot.run() if success: total_success += 1 else: total_fail += 1 except Exception as e: print(f"\n❌ 课程执行异常: {e}") total_fail += 1 elapsed = time.time() - start_time print(f"\n{'#' * 60}") print(f" 本轮完成!") print(f" 计划: {count} 门") print(f" ✅ 成功: {total_success}") print(f" ❌ 失败: {total_fail}") print(f" ⏱️ 耗时: {elapsed:.1f}秒") print(f"{'#' * 60}") # 4. 询问是否继续 again = input("\n是否继续?(y/n): ").strip().lower() if again != "y": print("\n程序结束。") break if __name__ == "__main__": main()