🏠 Home 

SJTU-Course Selection Assistant

添加一个打开选课社区(course.sjtu.plus)的按钮


安装此脚本?
// ==UserScript==
// @name         SJTU-Course Selection Assistant
// @namespace    http://tampermonkey.net/
// @version      0.4.0
// @description  添加一个打开选课社区(course.sjtu.plus)的按钮
// @author       Me
// @match        https://i.sjtu.edu.cn/xsxk/zzxkyzb_cxZzxkYzbIndex.html*
// @connect f002.backblazeb2.com
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @homepageURL https://github.com/dzx-dzx/Course-Selection-Assistant
// @license Apache
// ==/UserScript==
(async function () {
'use strict';
// Your code here...
//From https://stackoverflow.com/questions/21271997/how-to-overwrite-a-function-using-a-userscript
function showHideJxb(obj){
if($(obj).children(".expand_close").attr("class").indexOf("expand1")>0){
$(obj).children(".expand_close").removeClass('expand1').addClass('close1');
$(obj).next(".panel-body").slideDown();
}else{
$(obj).children(".expand_close").removeClass('close1').addClass('expand1');
$(obj).next(".panel-body").slideUp();
}
}
addJS_Node (showHideJxb);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D                                   = document;
var scriptNode                          = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type                         = "text/javascript";
if (text)       scriptNode.textContent  = text;
if (s_URL)      scriptNode.src          = s_URL;
if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
const courseToIdRaw = (await (async () => {
const courseListTimestampResponse = await new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: "https://f002.backblazeb2.com/file/course/course.json",
headers: { "Range": "bytes=0-0" },
onload: function (response) { resolve(response) }
})
})
const latestCourseListTimestamp = parseInt(courseListTimestampResponse.responseHeaders.split('\n').filter((i,/*教务系统似乎私自修改了Array的原型*/s) => s.includes("x-bz-info-src_last_modified_millis"))[0].split(":")[1])
if (GM_getValue('course_list_timestamp') !== latestCourseListTimestamp) {
const courseListResponse = await new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: "https://f002.backblazeb2.com/file/course/course.json",
onload: function (response) { resolve(response) }
})
})
const courseToIdRaw = JSON.parse(courseListResponse.response)
GM_setValue("course_list", courseToIdRaw)
GM_setValue("course_list_timestamp", latestCourseListTimestamp)
return courseToIdRaw
}
else return GM_getValue("course_list")
})())
const courseToIdMap = new Map(Object.entries(courseToIdRaw))
function addButton(tr) {
const classCodeRaw = tr.querySelector("td.jxbmc").textContent
const classCode = classCodeRaw.split("-").at(-2)//什么你说兼容性?能吃吗?
if (!courseToIdMap.has(classCode)) {
console.warn(`课程${classCode}无法找到,请向开发者联系.`); return;
}
const classes = courseToIdMap.get(classCode)
const teachers = Array.from(tr.querySelector("td.jsxmzc").querySelectorAll("a"), a => a.textContent)
const id = teachers.reduce((pre, teacher) => {
if (pre != null) return pre
const res = classes.find((c) => c.teacher === teacher)
if (res) return res.id
else return null
}, null)
if (!id) {
console.warn(`课程${classCode}下教师${teachers}均未找到,请向开发者联系.`); return;
}
const button = document.createElement("button")
button.onclick = function () { window.open(`https://course.sjtu.plus/course/${id}`, "_blank"/*始终新建窗口,改成"course"以覆盖前一窗口*/) }
button.setAttribute("class", "btn btn-primary btn-sm")
button.textContent = "跳转到选课社区"
tr.querySelector("td.jxbmc").append(document.createElement("br"), button)
}
document.querySelectorAll("div.panel-body > table > tbody > tr ").forEach((tr => {
if (tr.querySelector(".kkxymc").textContent !== "") addButton(tr)
}))
const observer = new MutationObserver((mutationList) => {
mutationList.forEach((mutation) => { if (mutation.target.getAttribute("class") === "kkxymc") addButton(mutation.target.parentElement) })
})
observer.observe(document.querySelector("#displayBox"), { "childList": true, "subtree": true })
const saveSelectedCourseButton = document.createElement("button")
saveSelectedCourseButton.onclick = function(){
function getSelectedCourseCode(){
return [...document.querySelectorAll("div.right_div > div > ul td> p.jxb").values()].map(p=>p.getAttribute("title").split("-").at(-2))
}
let selectedCourseCode=getSelectedCourseCode().join(" ")
selectedCourseCode=window.prompt("将保存以下课程代号:", selectedCourseCode)
if(selectedCourseCode) GM_setValue("selected_course_code",selectedCourseCode)
}
saveSelectedCourseButton.setAttribute("class", "btn btn-primary btn-sm")
saveSelectedCourseButton.textContent = "保存已选课到本地"
const loadPreSelectedCourseButton = document.createElement("button")
loadPreSelectedCourseButton.onclick = function(){
let selectedCourseCode=GM_getValue("selected_course_code")
selectedCourseCode=window.prompt("将加载以下课程代号:", selectedCourseCode)
if(selectedCourseCode){
document.querySelector(".form-control.input-sm.filter-input").value=selectedCourseCode
document.querySelector(".input-group-btn").querySelector(".btn.btn-primary.btn-sm").click()
}
}
loadPreSelectedCourseButton.setAttribute("class", "btn btn-primary btn-sm")
loadPreSelectedCourseButton.textContent = "加载之前保存的课程"
document.querySelector("div.col-sm-8.col-md-8.buttons").prepend(saveSelectedCourseButton,loadPreSelectedCourseButton)
})();