Greasy Fork

来自缓存

Greasy Fork is available in English.

好大学在线 助手 新版(修改版)

修复了“好大学在线 助手 新版”的一个BUG,添加下载视频和下载课件

// ==UserScript==
// @name         好大学在线 助手 新版(修改版)
// @namespace    https://github.com/1357310795/cnmooc-assistant
// @homepage     https://github.com/1357310795/cnmooc-assistant
// @author       沈鸿飞 Laurence-042 Teruteru
// @description  修复了“好大学在线 助手 新版”的一个BUG,添加下载视频和下载课件
// @version      1.1.1
// @match        https://*.cnmooc.org/study/initplay/*.mooc
// @match        https://*.cnmooc.org/study/unit/*.mooc
// @match        https://*.cnmooc.org/examTest/stuExamList/*.mooc
// @match        https://cnmooc.org/study/initplay/*.mooc
// @match        https://cnmooc.org/study/unit/*.mooc
// @match        https://cnmooc.org/examTest/stuExamList/*.mooc
// @run-at       document-idle
// @license      MIT License
// ==/UserScript==

// 满分批阅当前 mark()
// 使用方法:在console中调用assistant.mark()
var add_button, answers, assistant_api, assistant_div, auto_fill, complete_item, fold_unit_nav, fun, get_quiz_answers, mark, name, options, pause_quiz_timer, print_answers, questions, test_answer, unblock_video_progress,
    indexOf = [].indexOf;

mark = async function () {
    var sleep;
    sleep = function (ms) {
        return new Promise(function (resolve) {
            return setTimeout(resolve, ms);
        });
    };
    $('input[id^=quiz_]').each(function (i, e) {
        var max_point;
        max_point = e.className.match(/max\[(\d+)\]/)[1];
        return e.setAttribute('value', max_point);
    });
    if ($('#reviewSubmitDiv').css('display') !== 'none') {
        $('#submitReviewBtn').click();
    } else {
        $('#gotoReviewSubmitBtn').click();
    }
    await sleep(1000);
    $("input[value='提交互评']").click();
    await sleep(2000);
    console.log('完成一次批阅');
    return $("input[value='确定']").click();
};

// 修改doSubExam逻辑可以在跳转是插入自己逻辑

// 完成该项
complete_item = function () {
    var itemId = $('#itemId').val();
    var res = $.ajax({
	    type : "POST",
	    url : CONTEXTPATH+"/study/updateDurationVideo.mooc",
	    dataType:"json",
	    data : {
	        itemId : itemId,
	        isOver : 1,
	        duration : 99999999999,
	        currentPosition : 99999999999
	    },
	    success : function(response) {
	    },
	    error : function() {

	    }
	});
    return res;
};

// 解锁视频进度
unblock_video_progress = function () {
    $('#isOver').val(2);
    return eval($(".video-show script").html());
};

// 暂停计时
pause_quiz_timer = function () {
    var useTimeFlag;
    if (typeof unsafeWindow !== "undefined" && unsafeWindow !== null) {
        return unsafeWindow.useTimeFlag = false;
    } else {
        return useTimeFlag = false;
    }
};

// answers={question.quizId:[options(string)]}
answers = null;

questions = null;

options = null;

// async 修改自 doSubmitExam_ajax
test_answer = async function (questions) {
    var allRightFlag, gradeId, i, question, reSubmit, ret_data, score, totalScore, userQuiz2, user_Quiz, user_quizs;
    //处理每道题计时
    _quizUseTimeRecord[_quizIdRecord] = _quizUseTimeRecord[_quizIdRecord] || 0;
    _quizUseTimeRecord[_quizIdRecord] = parseInt(_quizUseTimeRecord[_quizIdRecord]) + _quizUseTime;
    user_quizs = (function () {
        var j, len, results;
        results = [];
        for (j = 0, len = questions.length; j < len; j++) {
            question = questions[j];
            results.push(JSON.stringify(question));
        }
        return results;
    })();
    reSubmit = $('#reSubmit').val();
    gradeId = $('#gradeId').val();
    userQuiz2 = [];
    totalScore = 0;
    allRightFlag = true;
    i = 0;
    while (i < user_quizs.length) {
        user_Quiz = JSON.parse(user_quizs[i]);
        user_Quiz['useTime'] = _quizUseTimeRecord[user_Quiz['quizId']];
        _quizUseTimeRecord[user_Quiz['quizId']] = 0;
        userQuiz2.push(JSON.stringify(user_Quiz));
        score = parseInt(user_Quiz['markQuizScore']);
        totalScore += score;
        if (score === 0) {
            allRightFlag = false;
        }
        i++;
    }
    if (allRightFlag) {
        totalScore = 10000;
    }
    user_quizs = userQuiz2;
    console.log(user_quizs);
    ret_data = (await $.when($.ajax({
        url: CONTEXTPATH + '/examSubmit/7681/saveExam/1/' + examPaperId + '/' + examSubmitId + '.mooc?testPaperId=' + examTestPaperId,
        type: 'post',
        data: {
            gradeId: gradeId,
            reSubmit: reSubmit,
            submitquizs: user_quizs,
            submitFlag: 0,
            useTime: 1,
            totalScore: totalScore,
            testPaperId: examTestPaperId
        },
        dataType: 'json',
        success: function (data) {
            if (!data.successFlag) {
                throw Error(data.successFlag = false);
            }
        },
        error: function () {
            return console.log('test_answer error');
        }
    })));
    return JSON.parse(ret_data.examSubmit.submitContent);
};

get_quiz_answers = async function() {
    var current_round_option_ids, i, j, l, len, len1, len2, m, n, o, oi, option_id_flags, perfect_answer, qi, question, ref, result, test_result;

    // 初始化页面问题
    console.log("try to get questions");
    questions = (function() {
        var j, len, ref, results;
        ref = $('#exam_paper').quiz().getPractice();
        results = [];
        for (j = 0, len = ref.length; j < len; j++) {
            question = ref[j];
            results.push(JSON.parse(question));
        }
        return results;
    })();
    console.log(questions);

    // 枚举、测试、更新答案
    console.log("try to get options");
    options = $('[option_id]').map(function(i, e) {
        return e.getAttribute('option_id');
    });
    console.log(options);

    // 获取问题分段
    var option_section = [];
    var base = 0;
    var all_test_options = $('.test-options');
    for (i=0;i<all_test_options.length;i++) {
        var count = all_test_options[i].childElementCount;
        option_section.push({count:count,base:base});
        base = base + count;
    }
    console.log(option_section)


    answers = {};
    ref = [1, 2, 4, 8, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15];
    for (j = 0, len = ref.length; j < len; j++) {
        oi = ref[j];
        console.log("oi:"+oi);
        option_id_flags = [];
        for (i = l = 0; l <= 3; i = ++l) {
            option_id_flags.push((oi << i & 0b1000) === 0b1000);
        }
        console.log("option_id_flags:");
        console.log(option_id_flags);
        // 检测已有正确答案,对每一题生成答案,设置userAnswer
        for (qi = m = 0, len1 = questions.length; m < len1; qi = ++m) {
            question = questions[qi];
            perfect_answer = answers[question.quizId];
            if (perfect_answer) {
                question.userAnswer = perfect_answer.join(',');
            } else {
                current_round_option_ids = [];
                // option_id 并非连续
                var section = option_section[qi];
                for (i = n = 0; n <= 3 && n<=section.count; i = ++n) {
                    if (option_id_flags[i]) {
                        current_round_option_ids.push(options[section.base + i]);
                    }
                }
                question.userAnswer = current_round_option_ids.join(',');
            }
        }
        console.log(questions);
        // 枚举的答案准备完成,开始测试
        test_result = (await test_answer(questions));
        for (o = 0, len2 = test_result.length; o < len2; o++) {
            result = test_result[o];
            result = JSON.parse(result);
            console.log(result);
            if (result.markResult) {

                // perfect_options=(parseInt option for option in result.userAnswer.split(','))
                answers[result.quizId] = result.userAnswer.split(',');
            }
        }
    }
    console.log(answers);
    return answers;
};
// async 查看习题答案
print_answers = async function () {
    var j, len, option, option_id_from, pretty_options, qi, question, x;
    if (!answers) {
        await get_quiz_answers();
    }
    pretty_options = '';
    for (qi = j = 0, len = questions.length; j < len; qi = ++j) {
        question = questions[qi];
        option_id_from = options[qi * 4];
        x = (function () {
            var l, len1, ref, results;
            ref = answers[question.quizId];
            results = [];
            for (l = 0, len1 = ref.length; l < len1; l++) {
                option = ref[l];
                results.push(String.fromCharCode('A'.charCodeAt(0) + parseInt(option) - option_id_from));
            }
            return results;
        })();
        pretty_options += `第${qi + 1}题:${x.join(',')}\n`;
    }
    console.log(pretty_options);
    alert(pretty_options);
};

// 自动完成习题
auto_fill = async function () {
    var answer_ids, k, v;
    if (!answers) {
        await get_quiz_answers();
    }
    answer_ids = [];
    for (k in answers) {
        v = answers[k];
        answer_ids = answer_ids.concat(v);
    }
    // todo:多选题再次点击会取消选择
    $("[option_id]").filter(function (i, e) {
        var ref;
        return ref = e.getAttribute('option_id'), indexOf.call(answer_ids, ref) >= 0;
    }).find('[class|="input"]').click();
};

assistant_api = {
    '解锁视频进度': unblock_video_progress,
    '完成该项': complete_item,
    '暂停答题计时': pause_quiz_timer,
    '自动完成习题': auto_fill,
    '查看习题答案': print_answers,
    '下载课件': downloadcourseware,
    '下载视频': downloadvideo
};

fold_unit_nav = function () {
    return $('.tr-chapter').click();
};


// userscript 环境
if (typeof unsafeWindow !== "undefined" && unsafeWindow !== null) {
    // 暴露assistant接口
    unsafeWindow.assistant = {};
    for (name in assistant_api) {
        fun = assistant_api[name];
        unsafeWindow.assistant[fun.name] = fun;
    }
    unsafeWindow.assistant.mark = mark;

    // 返回课程主页改为返回导航
    $('#backCourse').contents().last().replaceWith('返回导航');
    $('#backCourse').off('click');
    $("#backCourse").on('click', function () {
        return location.href = CONTEXTPATH + "/portal/session/unitNavigation/" + $("#courseOpenId").val() + ".mooc";
    });
    //干掉错误显示的
    $('.header-nav nav-center ').hide();


    // 助手界面显示
    assistant_div = document.createElement('div');
    assistant_div.id = 'assistant';
    $('.main-scroll').prepend(assistant_div);

    // 助手界面添加按钮
    add_button = function (text, fun) {
        var btn;
        btn = document.createElement('button');
        btn.textContent = text;
        btn.onclick = fun;
        // todo:优雅的样式设置
        btn.style = 'margin:5px;padding:5px';
        return assistant_div.appendChild(btn);
    };
    for (name in assistant_api) {
        fun = assistant_api[name];
        add_button(name, fun);
    }

    // tab切换
    $('.tab-inner').on('click', function () {
        // todo:智能判断可用功能
        return console.log(this);
    });
    fold_unit_nav();
    unsafeWindow.doSubExam = doSubExam;
}
get_quiz_answers = async function () {
    var current_round_option_ids, i, j, l, len, len1, len2, m, n, o, oi, option_id_flags, perfect_answer, qi, question, ref, result, test_result;

    // 初始化页面问题
    console.log("try to get questions");
    questions = (function () {
        var j, len, ref, results;
        ref = $('#exam_paper').quiz().getPractice();
        results = [];
        for (j = 0, len = ref.length; j < len; j++) {
            question = ref[j];
            results.push(JSON.parse(question));
        }
        return results;
    })();
    console.log(questions);

    // 枚举、测试、更新答案
    console.log("try to get options");
    options = $('[option_id]').map(function (i, e) {
        return e.getAttribute('option_id');
    });
    console.log(options);

    // 获取问题分段
    var option_section = [];
    var base = 0;
    var all_test_options = $('.test-options');
    for (i = 0; i < all_test_options.length; i++) {
        var count = all_test_options[i].childElementCount;
        option_section.push({ count: count, base: base });
        base = base + count;
    }
    console.log(option_section)


    answers = {};
    ref = [1, 2, 4, 8, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15];
    for (j = 0, len = ref.length; j < len; j++) {
        oi = ref[j];
        console.log("oi:" + oi);
        option_id_flags = [];
        for (i = l = 0; l <= 3; i = ++l) {
            option_id_flags.push((oi << i & 0b1000) === 0b1000);
        }
        console.log("option_id_flags:");
        console.log(option_id_flags);
        // 检测已有正确答案,对每一题生成答案,设置userAnswer
        for (qi = m = 0, len1 = questions.length; m < len1; qi = ++m) {
            question = questions[qi];
            perfect_answer = answers[question.quizId];
            if (perfect_answer) {
                question.userAnswer = perfect_answer.join(',');
            } else {
                current_round_option_ids = [];
                // option_id 并非连续
                var section = option_section[qi];
                for (i = n = 0; n <= 3 && n <= section.count; i = ++n) {
                    if (option_id_flags[i]) {
                        current_round_option_ids.push(options[section.base + i]);
                    }
                }
                question.userAnswer = current_round_option_ids.join(',');
            }
        }
        console.log(questions);
        // 枚举的答案准备完成,开始测试
        test_result = (await test_answer(questions));
        for (o = 0, len2 = test_result.length; o < len2; o++) {
            result = test_result[o];
            result = JSON.parse(result);
            console.log(result);
            if (result.markResult) {

                // perfect_options=(parseInt option for option in result.userAnswer.split(','))
                answers[result.quizId] = result.userAnswer.split(',');
            }
        }
    }
    console.log(answers);
    return answers;
};

function downloadcourseware()
{
    openNewWindow("/download/nodes/" + $("#courseOpenId").val() + "/"+ $("#nodeId").val() +".mooc");
}
function downloadvideo()
{
    openNewWindow($(".jwvideo")[0].children[0].src);
}

function openNewWindow(url) {
	let a = document.createElement("a");
	document.body.appendChild(a);
	a.style = "display: none";
	a.target = "_blank";
	a.href = url;
	a.click();
	document.body.removeChild(a);
}

//router=
//    10:video_helper_init
//#    20:pdf_helper # pdf页面
//#    50:quiz_helper # 选择题

//router[$('#itemType').val()]()