// ==UserScript==
// @name 国开自动刷课
// @namespace ry版
// @version 202305051250
// @description 国家开放大学自动刷课
// @author 流浪的蛊惑
// @match *://lms.ouchn.cn/course/*
// @license GPL-3.0
// @grant none
// @downloadURL none
// ==/UserScript==
function LogHelper() {
const el_text = `
`;
$('.wrapper').append(el_text);
this.WriteHtmlLine = (htmlContent, alignCenter = false, border = { borderTop: false, borderBottom: false }) => {
const el = document.createElement('div');
container = document.querySelector('container-element');
el.classList.add('item');
el.innerHTML = htmlContent;
if (alignCenter) {
el.style.textAlign = "center";
};
if (border.borderTop) {
el.style.borderTop = "1px solid #767676";
}
if (border.borderBottom) {
el.style.borderBottom = "1px solid #767676";
}
console.log(htmlContent);
const body = container.querySelector('.body');
const logEl = container.querySelector('.console');
body.scrollTop = body.scrollHeight;
logEl.appendChild(el);
logEl.scrollTop = logEl.scrollHeight;
}
}
(function () {
const Log = new LogHelper();
const notificationTypesAndText = {
"material": "参考资料",
"web_link": "线上链接",
"online_video": "音视频教材",
"slide": "微课",
"lesson": "录播教材",
"homework": "作业",
"forum": "讨论区",
"chatroom": "iSlide 直播",
"questionnaire": "调查问卷",
"page": "页面",
"course_invite": "課程邀請",
"scorm": "SCORM"
};
async function LearnCourseId(courseId) {
Log.WriteHtmlLine("===== 初始化中 =====", true, { borderBottom: true });
const getCriterion = completion_criterion => completion_criterion == undefined || completion_criterion == "" ? "无" : completion_criterion;
const StartTime = performance.now(); // 代码开始时间
const StartCompletenessData = await new Promise(resolve => $.get(`https://lms.ouchn.cn/api/course/${courseId}/my-completeness`, (data, status, xhr) => status === "success" ? resolve(data) : { study_completeness: undefined }));
const { study_completeness: StrartCompleteness } = StartCompletenessData;
const CoursesModulesData = await new Promise(resolve => $.get(`https://lms.ouchn.cn/api/courses/${courseId}/modules`, (data, status, xhr) => status === "success" ? resolve(data) : { modules: [] }));
const { modules: CoursesModulesModels } = CoursesModulesData;
const CompletedCourseData = StartCompletenessData;
const CompletedCourseModels = CompletedCourseData.completed_result.completed.learning_activity;
for (let CoursesModulesModel of CoursesModulesModels) {
let sleep = parseInt((Math.random() * (15 - 8) + 8) * 1000); // 取8000 - 15000之间的毫秒随机数
await new Promise(resolve => setTimeout(resolve, sleep));
Log.WriteHtmlLine(`课程模块:${CoursesModulesModel.name}(${CoursesModulesModel.id}) 当前进度${StrartCompleteness}% 随机延迟: ${sleep}毫秒`, true, { borderBottom: true });
// 日志输出
const LearnActivitieData = await new Promise(resolve => $.get(`https://lms.ouchn.cn/api/course/${courseId}/all-activities?module_ids=[${CoursesModulesModel.id}]&activity_types=learning_activities,exams,classrooms`, (data, status, xhr) => status === "success" ? resolve(data) : { learning_activities: [] }));
const { learning_activities: LearnActivitieModels } = LearnActivitieData;
try {
for (let LearnActivitieModel of LearnActivitieModels) {
const { completion_criterion, type, title, id, uploads } = LearnActivitieModel;
if (CompletedCourseModels.indexOf(parseInt(id)) !== -1) {
Log.WriteHtmlLine(`课程模块:${CoursesModulesModel.name} 模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)}(${id}) 已完成 跳过`, false, { borderBottom: true });
continue;
} else {
await new Promise(resolve => setTimeout(resolve, sleep));
Log.WriteHtmlLine(`课程模块:${CoursesModulesModel.name} 模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)}(${id}) 任务开始`, false, { borderBottom: true });
}
switch (type) {
case "page":
await new Promise(resolve => $.post(`https://lms.ouchn.cn/api/course/activities-read/${id}`, {}, resolve));
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 完成`);
break;
case "online_video":
for (let VideoUploadModel of uploads) {
await new Promise(resolve => $.post(`https://lms.ouchn.cn/api/course/activities-read/${id}`, {}, resolve)); // 第一次的请求默认为没有参数。
for (let item of VideoUploadModel.videos) {
await new Promise(resolve => setTimeout(resolve, sleep));
await new Promise(resolve => $.ajax({
type: "POST",
url: `https://lms.ouchn.cn/api/course/activities-read/${id}`,
contentType: "application/json",
dataType: "JSON",
data: JSON.stringify({ start: 0, end: item.duration }),
success: resolve,
error: resolve
}));
}
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 完成`);
}
break;
case "material":
for (let uploadModel of uploads) {
await new Promise(resolve => $.ajax({
type: "POST",
url: `https://lms.ouchn.cn/api/course/activities-read/${id}`,
contentType: "application/json",
dataType: "JSON",
data: JSON.stringify({ upload_id: uploadModel.id }),
success: resolve
}));
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 完成`);
}
break;
case "forum":
if (title === "课程答疑讨论区") {
const { topic_category: { id: CategoryId } } = await new Promise(resolve => $.get(`https://lms.ouchn.cn/api/forum/${id}/category?fields=id`, {}, resolve));
await new Promise(resolve => $.ajax({
type: "POST",
url: `https://lms.ouchn.cn/api/topics`,
contentType: "application/json",
dataType: "JSON",
data: JSON.stringify({
title: "好好学习",
content: "
好好学习,天天向上。
",
category_id: CategoryId,
uploads: []
}),
success: resolve,
error: resolve
}));
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 完成`);
} else {
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 不需要发帖 完成`);
}
break;
case "web_link":
Log.WriteHtmlLine(`模块标题:${title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 完成`);
await new Promise(resolve => $.post(`https://lms.ouchn.cn/api/course/activities-read/${id}`, {}, resolve));
break;
default:
Log.WriteHtmlLine(`模块标题:${LearnActivitieModel.title}(${notificationTypesAndText[type]}) 完成标准:${getCriterion(completion_criterion)} 未完成
该任务无法完成。`);
break;
}
}
} catch (error) {
Log.WriteHtmlLine(`代码出现了异常 按F12在控制台查看错误。`, true, { borderBottom: true });
console.error(error);
await new Promise(resolve => setTimeout(resolve, sleep));
}
Log.WriteHtmlLine(`课程模块:${CoursesModulesModel.name}(${CoursesModulesModel.id}) 随机延迟: ${sleep}毫秒`, true, { borderBottom: true });
}
const EndCompletenessData = await new Promise(resolve => $.get(`https://lms.ouchn.cn/api/course/${courseId}/my-completeness`, (data, status, xhr) => status === "success" ? resolve(data) : { study_completeness: undefined }));
const { study_completeness: EndCompleteness } = EndCompletenessData;
const EndTime = performance.now(); // 代码结束时间
Log.WriteHtmlLine(`学习前进度:${StrartCompleteness}% 学习后进度:${EndCompleteness}% 耗时: ${((EndTime - StartTime) / 1000).toFixed(2)}秒`);
}
$('#startTech').on({
click: function () {
const courseId = document.querySelector("#courseId").value;
LearnCourseId(courseId);
this.onclick = null;
this.style.cursor = "no-drop";
this.style.color = "#ccc";
}
})
})();