// ==UserScript==
// @name 北理工乐学增强
// @namespace YinTianliang_i
// @version 1.0.2
// @description 增强北理工乐学的功能
// @author Yin Tianliang
// @include *//online.bit.edu.cn/*
// @grant none
// require https://code.jquery.com/jquery-3.2.1.min.js
// 页面原先就有jquery, 引入jquery似乎会出问题
// @downloadURL none
// ==/UserScript==
/*jshint esversion: 6 */
let Ajax = {
get: function (url, fn) {
let obj = new XMLHttpRequest(); // XMLHttpRequest对象用于在后台与服务器交换数据
obj.open('GET', url, true);
obj.onreadystatechange = function () {
if (obj.readyState == 4 && obj.status == 200 || obj.status == 304) { // readyState == 4说明请求已完成
fn.call(this, obj.responseText); //从服务器获得数据
}
};
obj.send();
},
post: function (url, data, fn) { // datat应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
let obj = new XMLHttpRequest();
obj.open("POST", url, true);
obj.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 添加http头,发送信息至服务器时内容编码类型
obj.onreadystatechange = function () {
if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) { // 304未修改
fn.call(this, obj.responseText);
}
};
obj.send(data);
}
}
let divTemp = (color, text) => {
return `
${text}
`;
};
function AddClickBack() {
let navigation = document.getElementsByClassName('breadcrumb')[0].children;
let parent_id = navigation[1].firstChild.href.match(/id=(\d+)/)[1];
let label_list = JSON.parse(localStorage["label_" + parent_id]);
if (localStorage["label_" + parent_id]) {
let parent_name = navigation[2].firstChild.textContent;
let parent_url = `${navigation[1].firstChild.href}#${label_list[parent_name]}`;
navigation[2].firstChild.innerHTML =
`${parent_name}`;
}
}
function RefreshLabels(id) {
let label_list = !localStorage["label_" + id] ? {} : JSON.parse(localStorage["label_" + id]);
let weekworks = document.getElementsByClassName('section main clearfix');
for (let week_work of weekworks) {
let label = week_work.getAttribute('aria-label');
label_list[label] = week_work.id;
}
// 当前作业class不同 单独处理
let week_work = document.getElementsByClassName('section main clearfix')[0];
let label = week_work.getAttribute('aria-label');
label_list[label] = week_work.id;
localStorage["label_" + id] = JSON.stringify(label_list);
}
function AddMyACCount(id) {
let table = document.getElementsByClassName('generaltable')[1].children[1];
if (table.rows[0].cells[0].textContent != '0') { // 判断是否已经增加了一行
let row = table.insertRow(0);
row.insertCell(0).textContent = '0';
row.insertCell(1).textContent = 'Your';
row.insertCell(2).textContent = JSON.parse(localStorage["AC_" + id]).length;
} else {
table.rows[0].cells[2].textContent = JSON.parse(localStorage["AC_" + id]).length;
}
}
function RefreshACStatus(id) {
let reg = new RegExp("userloginex|contest_login.php.cid=(\\d+)");
let matches = location.toString().match(reg);
let problem_list = document.getElementsByClassName("activity programming modtype_programming");
for (let problem of problem_list) {
let problem_id = problem.id.split("-")[1];
let dstDiv = problem.firstChild.firstChild.firstChild;
// 有些题目没有没对齐不能忍
if (dstDiv.className == "mod-indent") {
dstDiv.className += " mod-indent-1";
}
// 待优化
id_list = !localStorage["AC_" + id] ? [] : JSON.parse(localStorage["AC_" + id]);
if (id_list.indexOf(problem_id) == -1) {
Ajax.post(`http://online.bit.edu.cn/moodle/mod/programming/result.php?id=${problem_id}`,
null, res => {
matches = res.match(/未能通过的有 *(\d+)* *个/);
if (matches) {
if (matches[1] == "0") {
id_list = id_list.concat(problem_id);
localStorage["AC_" + id] = JSON.stringify(id_list);
// 这个post是异步的, 所以只能每一次post完成都刷新一次AC数
// 确保AC数正确
AddMyACCount(id);
dstDiv.innerHTML = divTemp('green', 'AC');
} else {
dstDiv.innerHTML = divTemp('red', 'WA');
}
} else if (/当前状态:程序编译失败。/.test(res)) {
dstDiv.innerHTML = divTemp('orange', 'CE');
} else if (/当前状态:程序已提交,正等待编译。/.test(res)) {
dstDiv.innerHTML = divTemp('gray', 'PE');
}
});
} else {
dstDiv.innerHTML = divTemp('green', 'AC');
}
}
}
if (/course\/view.php\?id=\d+/.test(location.toString())) {
let id = location.toString().match(/id=(\d+)/)[1]; // 页面id
// 储存锚点 (似乎放在RefreshACStatus后面会bug)
RefreshLabels(id);
// 更新AC状态
RefreshACStatus(id);
// 增加 "自己的AC数"
AddMyACCount(id);
}
// 增加点击日期跳转
if (/mod\/programming\//.test(location.toString())) {
AddClickBack();
}
// 隐藏 上传文件
if (/programming\/submit.php\?id=\d+/.test(location.toString())) {
document.getElementsByClassName('fitem fitem_ffilepicker')[0].style = 'display:none'
}
// TODO:获取提交次数
function get_submit_cnt(id) {
return s.match(/submit="\d+"/).length;
}