feat: 增加章节学习次数功能#616
Conversation
fix: 优化章节学习次数访问表现 feat: 添加章节学习次数配置说明及失败处理逻辑 fix: 恢复意外的修改
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds an optional post-study phase that, when enabled, iterates courses after normal task completion, fetches chapter data, runs ChangesChapter Learning Count Increase
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
main.py (1)
552-559: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHoist
target_countassignment out of the loop.
common_config["target_count"] = target_countis invariant across iterations and only needs to be set once before the loop. Minor cleanup.♻️ Proposed tidy-up
if add_learning_count: logger.info("刷课完成,开始增加章节学习次数...") + common_config["target_count"] = target_count for course in course_task: - common_config["target_count"] = target_count increase_learning_count_for_course(chaoxing, course, common_config)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@main.py` around lines 552 - 559, Hoist the invariant target_count assignment out of the course loop in the post-processing block in main.py. Move common_config["target_count"] = target_count to just before the for course in course_task loop, and keep increase_learning_count_for_course and the completion logging unchanged so each iteration reuses the same config value without redundant reassignment.api/base.py (1)
1214-1215: 🚀 Performance & Scalability | 🔵 TrivialHeads-up: runtime scales linearly with
target_countat ~30s each.Each chapter visit blocks for a hard-coded
time.sleep(30), so with the defaulttarget_count=100a single course takes ~50 minutes (plus per-request overhead), repeated for every course. Consider making the interval configurable or documenting the expected duration so users aren't surprised.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/base.py` around lines 1214 - 1215, The chapter-visit loop in the relevant course-processing flow uses a hard-coded 30-second sleep, which makes runtime scale linearly with target_count and can surprise users. Update the logic around the time.sleep(30) step to use a configurable interval or expose it as a parameter in the surrounding function, and make sure the default behavior is clearly documented in the method handling chapter traversal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/base.py`:
- Around line 1122-1134: The GET request in the student study Ajax call is
missing a timeout, so it can hang indefinitely if the connection stalls. Update
the _session.get call inside the relevant request path to pass a timeout value
consistent with _send_monitor_heartbeat and _extract_and_send_setlog (use the
same 5-second timeout) so the request fails fast like the other network calls.
- Around line 1190-1193: The loop in the reusable point-replication logic can
spin forever when points is empty, because the outer while in the method that
processes points never makes progress. Update the method containing the
while/for iteration to fail safe on an empty points input before entering the
loop, so total cannot stay stuck at 0; keep the fix localized to that helper
rather than relying on increase_learning_count_for_course to guard it.
---
Nitpick comments:
In `@api/base.py`:
- Around line 1214-1215: The chapter-visit loop in the relevant
course-processing flow uses a hard-coded 30-second sleep, which makes runtime
scale linearly with target_count and can surprise users. Update the logic around
the time.sleep(30) step to use a configurable interval or expose it as a
parameter in the surrounding function, and make sure the default behavior is
clearly documented in the method handling chapter traversal.
In `@main.py`:
- Around line 552-559: Hoist the invariant target_count assignment out of the
course loop in the post-processing block in main.py. Move
common_config["target_count"] = target_count to just before the for course in
course_task loop, and keep increase_learning_count_for_course and the completion
logging unchanged so each iteration reuses the same config value without
redundant reassignment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b4c6f582-40e7-4d91-9850-d4bda6ed49e0
📒 Files selected for processing (5)
README.mdapi/base.pyapi/process.pyconfig_template.inimain.py
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
api/base.py (2)
1125-1138: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winKeep transient request errors inside the failure counter.
A timeout/connection error from this GET bypasses
consecutive_failuresand aborts the whole count phase. CatchRequestExceptionhere and returnNone, matching the non-200 path.🛡️ Proposed fix
- _resp = _session.get( - url="https://mooc1.chaoxing.com/mooc-ans/mycourse/studentstudyAjax", - params={ - "courseId": _course["courseId"], - "clazzid": _course["clazzId"], - "chapterId": point["id"], - "cpi": _course["cpi"], - "verificationcode": "", - "mooc2": 1, - "microTopicId": 0, - "editorPreview": 0, - }, - timeout=8, - ) + try: + _resp = _session.get( + url="https://mooc1.chaoxing.com/mooc-ans/mycourse/studentstudyAjax", + params={ + "courseId": _course["courseId"], + "clazzid": _course["clazzId"], + "chapterId": point["id"], + "cpi": _course["cpi"], + "verificationcode": "", + "mooc2": 1, + "microTopicId": 0, + "editorPreview": 0, + }, + timeout=8, + ) + except RequestException as exc: + logger.error(f"章节访问失败 -> [{point['title']}]: {exc}") + return None🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/base.py` around lines 1125 - 1138, The GET in the course study flow bypasses the failure counter when it raises a transient request error instead of returning a non-200 response. Update the request handling around _session.get in the student study fetch path to catch RequestException, treat it like the existing non-200 branch, and return None so the caller’s consecutive_failures logic continues to count the failure. Preserve the current behavior for successful responses and keep the change localized to the method that performs the study-page fetch.
1146-1168: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winOnly increment
totalaftersetlogsucceeds.
_extract_and_send_setlog()currently has no success signal, so missingsetlog, HTTP failures, and exceptions still lead tototal += 1. Since this is the count-recording API, treat failure as a failed visit.🛡️ Proposed fix
- def _extract_and_send_setlog(self, html_text): + def _extract_and_send_setlog(self, html_text) -> bool: @@ if not match: logger.trace("未在响应中找到 setlog URL") - return + return False setlog_url = match.group(1) try: session = SessionManager.get_session() resp = session.get(setlog_url, timeout=5) logger.trace(f"Setlog sent -> {resp.status_code}") - except Exception as e: + return resp.ok + except RequestException as e: logger.trace(f"Setlog failed (non-critical): {e}") + return False @@ # 第 1 步:从 HTML 中提取 setlog URL 并执行(真正的计次 API) - self._extract_and_send_setlog(html_text) + if not self._extract_and_send_setlog(html_text): + logger.error(f"章节 setlog 发送失败, 当前章节: {point['title']}") + consecutive_failures += 1 + if consecutive_failures >= max_consecutive_failures: + logger.error( + f"章节学习次数增加连续失败 {consecutive_failures} 次, 终止任务" + ) + return StudyResult.ERROR + continue + + consecutive_failures = 0 # 第 2 步:立即发送 monitor 心跳包(模拟 fn()) self._send_monitor_heartbeat(course, point)Also applies to: 1215-1228
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/base.py` around lines 1146 - 1168, The _extract_and_send_setlog helper currently logs failures but does not tell callers whether the setlog call actually succeeded, so total can be incremented even when the visit record was not sent. Change _extract_and_send_setlog to return a success/failure signal based on finding the setlog URL, the session.get call, and the HTTP response, and then update the callers around total += 1 to only increment when _extract_and_send_setlog reports success. Keep the logic aligned with the existing SessionManager.get_session and logger.trace flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@api/base.py`:
- Around line 1125-1138: The GET in the course study flow bypasses the failure
counter when it raises a transient request error instead of returning a non-200
response. Update the request handling around _session.get in the student study
fetch path to catch RequestException, treat it like the existing non-200 branch,
and return None so the caller’s consecutive_failures logic continues to count
the failure. Preserve the current behavior for successful responses and keep the
change localized to the method that performs the study-page fetch.
- Around line 1146-1168: The _extract_and_send_setlog helper currently logs
failures but does not tell callers whether the setlog call actually succeeded,
so total can be incremented even when the visit record was not sent. Change
_extract_and_send_setlog to return a success/failure signal based on finding the
setlog URL, the session.get call, and the HTTP response, and then update the
callers around total += 1 to only increment when _extract_and_send_setlog
reports success. Keep the logic aligned with the existing
SessionManager.get_session and logger.trace flow.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 26917f4c-7839-4388-9c48-340fd4480c1d
📒 Files selected for processing (3)
api/base.pyapi/process.pymain.py
🚧 Files skipped from review as they are similar to previous changes (2)
- api/process.py
- main.py
问题
在学习时发现部分课程有章节学习次数的考核目标,比较变态
解决
通过分析章节页面的网络行为,并结合其他同学对该考核目标的反馈,成功推测并模拟了前端的关键请求行为,从而实现了该自动化功能
Summary by CodeRabbit
add_learning_countandtarget_countsettings (with matching CLI options) to control whether the extra step runs and the total target count.