// ==UserScript==
// @name 电子科技大学研究生课表考表导出
// @namespace http://tampermonkey.net/
// @version 0.1.3
// @description 以ICS格式导出电子科技大学研究生课表考表
// @author KiWeng
// @match https://yjsjy.uestc.edu.cn/pyxx/pygl/xkjg/*
// @match https://yjsjy.uestc.edu.cn/pyxx/pygl/kskcxx/index*
// @require https://cdn.jsdelivr.net/npm/[email protected]/ics.deps.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/pikaday.min.js
// @grant none
// @license MIT
// ==/UserScript==
(function () {
"use strict";
let addStyle = (stylePath) => {
var container = document.getElementsByTagName("head")[0];
var addStyle = document.createElement("link");
addStyle.rel = "stylesheet";
addStyle.type = "text/css";
addStyle.media = "screen";
addStyle.href = stylePath;
container.appendChild(addStyle);
};
addStyle("https://cdn.jsdelivr.net/npm/[email protected]/css/pikaday.css");
let start_monday_date = new Date("2022-02-21");
let week_date_table = []; // 本学期所有日期,默认到20周结束
const timeTable = [
// 硬编码时间表
["08:30", "09:15"], // startTime, endTime
["09:20", "10:05"],
["10:20", "11:05"],
["11:10", "11:55"],
["14:30", "15:15"],
["15:20", "16:05"],
["16:20", "17:05"],
["17:10", "17:55"],
["19:30", "20:15"],
["20:20", "21:05"],
["21:10", "21:55"],
["22:00", "22:45"],
];
const xkjg = window.location.href.indexOf("xkjg") > -1 ? true : false;
const kskcxx = window.location.href.indexOf("kskcxx") > -1 ? true : false;
const cal = ics();
let generate_button = () => {
// 按钮生成
let download_ics = document.createElement("button");
download_ics.type = "button";
download_ics.style = "margin-left:15px;height:30px;vertical-align:top";
download_ics.className = "btn btn-xs btn-return ";
download_ics.innerHTML =
'<i class="icon-hdd align-top bigger-150"></i>导出ics文件';
if (xkjg) {
let inserted_node = document.createElement("input");
inserted_node.type = "text";
inserted_node.id = "datepicker";
inserted_node.placeholder = "请选择本学期第一周后再下载!";
inserted_node.style = "width:200px;height:30px;margin-left:15px";
document
.getElementById("xq")
.insertAdjacentElement("afterend", inserted_node);
download_ics.disabled = "disabled";
let date_chose = false;
var picker = new Pikaday({
field: document.getElementById("datepicker"),
pickWholeWeek: true,
firstDay: 1,
onSelect: function (date) {
start_monday_date = new Date(date);
start_monday_date.setDate(
start_monday_date.getDate() -
((start_monday_date.getDay() - 1 + 7) % 7)
);
week_date_table = [];
for (let i = 0; i < 20; i++) {
let week_arr = [];
for (let j = 0; j < 7; j++) {
let tmp_date = new Date(start_monday_date);
tmp_date.setDate(tmp_date.getDate() + 7 * i + j);
week_arr.push(tmp_date);
}
week_date_table.push(week_arr);
}
download_ics.disabled = "";
date_chose = true;
},
});
picker;
}
if (xkjg) {
document
.getElementById("datepicker")
.insertAdjacentElement("afterend", download_ics);
download_ics.addEventListener("click", parse_xkjg);
} else if (kskcxx) {
document
.getElementById("xqbh")
.insertAdjacentElement("afterend", download_ics);
download_ics.addEventListener("click", parse_kskcxx);
}
};
let insert_weekly_events = (
name,
description,
location,
start_time,
end_time,
duration
) => {
const rrule = new Object();
rrule.freq = "WEEKLY";
rrule.count = duration;
cal.addEvent(name, description, location, start_time, end_time, rrule);
};
let parse_kskcxx = () => {
const exams = document
.getElementById("sample-table-1")
.getElementsByTagName("tbody")[0].rows;
for (let exam of exams) {
if (exam.cells[11].innerText === "") continue;
const exam_info = {
name: exam.cells[5].innerText,
roomNo: exam.cells[8].innerText,
room: exam.cells[9].innerText,
seatNo: exam.cells[10].innerText,
time: exam.cells[11].innerText,
};
const description = `考场号:${exam_info["roomNo"]} 座位号:${exam_info["seatNo"]}`;
const regex = /(\d+)-(\d+)-(\d+)日 (\d+):(\d+)~(\d+):(\d+)/gu;
const time_info = regex.exec(exam_info["time"]);
// 起止时间
const event_start_time = new Date(
parseInt(time_info[1]),
parseInt(time_info[2]) - 1,
parseInt(time_info[3]),
parseInt(time_info[4]),
parseInt(time_info[5])
);
const event_end_time = new Date(
parseInt(time_info[1]),
parseInt(time_info[2]) - 1,
parseInt(time_info[3]),
parseInt(time_info[6]),
parseInt(time_info[7])
);
cal.addEvent(
exam_info["name"],
description,
exam_info["room"],
event_start_time.toUTCString(),
event_end_time.toUTCString()
);
}
cal.download();
};
let parse_xkjg = () => {
const courses = document
.getElementById("sample-table-1")
.getElementsByTagName("tbody")[0].rows;
for (let course of courses) {
const course_info = {
name: course.cells[3].innerText,
teacher: course.cells[7].innerText,
campus: course.cells[8].innerText,
time_location: course.cells[9].innerText,
description: course.cells[10].innerText,
};
const description = `任课教师:${course_info["teacher"]}
班级说明:${course_info["description"]}`;
if (course_info["time_location"] === "") continue; // ignore courses with empty location
for (let line of course_info["time_location"].split("\n")) {
// Every line is like '1-10周,星期二第3-4节 星期四第3-4节 (二教307)'
const re_loc = /\(([^)]+)\)/;
const loc = re_loc.exec(line)[1];
const re_duration = /(\d+)-(\d+)周/gu;
const week_duration = re_duration.exec(line);
const [start_week, end_week] = [
week_duration[1],
week_duration[2],
];
const han2nubmer_week = {
一: 0,
二: 1,
三: 2,
四: 3,
五: 4,
六: 5,
日: 6,
};
const re_week = /星期([一二三四五六日])第(\d+)-(\d+)节/gu;
const array = [...line.matchAll(re_week)];
for (const element of array) {
const weekday_han = element[1];
const weekday = han2nubmer_week[weekday_han];
const [start_time, end_time] = [
timeTable[element[2] - 1][0],
timeTable[element[3] - 1][1],
];
// 起止时间
const event_start_time = new Date(start_monday_date);
event_start_time.setDate(
event_start_time.getDate() +
(start_week - 1) * 7 +
weekday
);
event_start_time.setHours(start_time.split(":")[0]);
event_start_time.setMinutes(start_time.split(":")[1]);
const event_end_time = new Date(start_monday_date);
event_end_time.setDate(
event_end_time.getDate() +
(start_week - 1) * 7 +
weekday
);
event_end_time.setHours(end_time.split(":")[0]);
event_end_time.setMinutes(end_time.split(":")[1]);
const duration = end_week - start_week + 1;
insert_weekly_events(
course_info["name"],
description,
`${course_info["campus"]} ${loc}`,
event_start_time.toUTCString(),
event_end_time.toUTCString(),
duration
);
}
}
}
cal.download();
};
generate_button();
})();