From 03e2366c38e57cc3bf0336668f7a27bb0b23791a Mon Sep 17 00:00:00 2001 From: cat_shark <1716967236@qq.com> Date: Thu, 21 May 2026 15:41:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=87=8D=E5=A4=8D=E7=AD=94?= =?UTF-8?q?=E9=A2=98=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ef_course_autopilot.py | 68 ++++++++++++++++++++++++++++++++++++++++++ ef_course_loop.py | 6 ++++ 2 files changed, 74 insertions(+) diff --git a/ef_course_autopilot.py b/ef_course_autopilot.py index b0903d4..a579b8a 100755 --- a/ef_course_autopilot.py +++ b/ef_course_autopilot.py @@ -360,6 +360,9 @@ class EFCourseAutopilot: - 步骤②-④ (api.ef.studio域): 需要 Authorization: Bearer JWT token """ + # 类级别:本次运行中已处理过的课程 (course_id:node_id) + _processed_lessons: set = set() + def __init__( self, token: str = "", @@ -399,6 +402,7 @@ class EFCourseAutopilot: self.lesson = LessonSession() self.activities: list[ActivityInfo] = [] self.results: list[SubmitResult] = [] + self.repeat_detected = False def _setup_session(self): """配置HTTP会话的通用headers和SSL设置""" @@ -871,6 +875,57 @@ class EFCourseAutopilot: return False + def _save_diagnostic_report(self): + """当检测到重复课程时,保存诊断报告供开发者分析""" + import datetime + + report = { + "timestamp": datetime.datetime.now().isoformat(), + "course_id": self.ctx.course_id, + "node_id": self.ctx.node_id, + "unit_id": self.ctx.unit_id, + "level_id": self.ctx.level_id, + "lesson_id": self.lesson.lesson_id, + "session_id": self.lesson.session_id, + "activities": [], + "results": [], + } + + for act in self.activities: + act_info = { + "activity_id": act.activity_id, + "tasks": [ + { + "task_id": t.task_id, + "task_type": t.task_type, + "task_detail": t.task_detail, + "expected_response": t.expected_response, + } + for t in act.tasks + ], + } + report["activities"].append(act_info) + + for r in self.results: + report["results"].append({ + "task_id": r.task_id, + "task_type": r.task_type, + "success": r.success, + "skipped": r.skipped, + "error": r.error, + "new_version": r.new_version, + }) + + safe_cid = self.ctx.course_id[:8] if self.ctx.course_id else "unknown" + safe_nid = self.ctx.node_id[:8] if self.ctx.node_id else "unknown" + filename = f"diagnostic_{safe_cid}_{safe_nid}_{int(time.time())}.json" + + with open(filename, "w") as f: + json.dump(report, f, ensure_ascii=False, indent=2) + + self._log(f"\n 诊断报告已保存至: {filename}") + self._log(f" 请将此文件提供给开发者以优化对新课程的支持") + # -------------------------------------------------------- # 主流程 # -------------------------------------------------------- @@ -910,6 +965,16 @@ class EFCourseAutopilot: else: self.step_get_focus() + # 检测是否重复处理同一课程 + lesson_key = f"{self.ctx.course_id}:{self.ctx.node_id}" + if lesson_key in self._processed_lessons: + self.repeat_detected = True + self._log("\n⚠️ 检测到重复课程!该课程已处理过但未能晋级。") + self._log(" 请手动登录平台检查课程状态,或联系开发者分析。") + self._save_diagnostic_report() + self._log(f" 诊断文件已保存,请提供给开发者") + return False + # 步骤②: 注册课程会话 self.step_open_lesson_enrollment() @@ -976,6 +1041,9 @@ class EFCourseAutopilot: # 步骤⑤: 检查并激活下一单元 self.step_activate_next_unit() + # 标记该课程已处理(避免下次循环重复提交) + self._processed_lessons.add(f"{self.ctx.course_id}:{self.ctx.node_id}") + return all(r.success for r in self.results) except requests.exceptions.HTTPError as e: diff --git a/ef_course_loop.py b/ef_course_loop.py index a1bed47..41ae2f4 100755 --- a/ef_course_loop.py +++ b/ef_course_loop.py @@ -101,6 +101,12 @@ token.txt 说明: try: success = autopilot.run() + if autopilot.repeat_detected: + print("\n⚠️ 检测到重复课程,自动循环终止。") + print(" 请手动登录平台检查课程状态,或联系开发者优化。") + print(f" 诊断文件已保存至当前目录。") + total_fail += 1 + break if success: total_success += 1 else: