HLJU Class Schedule

Export your classes to a ics file.

当前为 2017-03-07 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        HLJU Class Schedule
// @namespace   https://fuyuhin.me
// @description Export your classes to a ics file.
// @include     http://*.hlju.edu.cn/xsxk/index.xk
// @version     0.2
// @grant       none
// ==/UserScript==
function get_first_week_num(week_sequence){
    return week_sequence.indexOf('1') + 1;
}

function get_last_week_num(week_sequence){
    return week_sequence.lastIndexOf('1') + 1;
}

function date_to_ics_format_string(date) {
    var s = '';
    s = s + date.getFullYear(); 
    var month = date.getMonth() + 1;
    if (month > 9) { 
        s = s + month.toString();
    }
    else{
        s = s + '0' + month.toString();
    }
    var d = date.getDate();
    if (d > 9) {
        s = s + d.toString();
    }
    else{
        s = s + '0' + d.toString();
    }
    s = s + 'T';
    var hour = date.getHours();
    if (hour > 9) {
        s = s + hour.toString();
    }
    else{
        s = s + '0' + hour.toString();
    }
    var minute = date.getMinutes();
    if (minute > 9) {
        s = s + minute.toString();
    }
    else{
        s = s + '0' + minute.toString();
    }
    s = s + '00';
    return s;
}

function get_repead_rule(week_sequence, weekday, until_date)
{
    var week_array = new Array();
    for (var i = 0; i < week_sequence.length; i++) {
        if (week_sequence[i] == '1'){
            week_array.push(i + 1);
        }
    }
    var interval;
    if (week_array[week_array.length - 1] - week_array[0] == week_array.length - 1) {
        interval = '1';
    }
    else{
        interval = '2';
    }
    var byday;
    switch(weekday){
        case '1': byday = 'MO'; break;
        case '2': byday = 'TU'; break;
        case '3': byday = 'WE'; break;
        case '4': byday = 'TH'; break;
        case '5': byday = 'FR'; break;
        case '6': byday = 'SA'; break;
        case '7': byday = 'SU'; break;
    };
    var until = date_to_ics_format_string(until_date);
    return 'RRULE:FREQ=WEEKLY;UNTIL=' + until + 'Z;INTERVAL=' + interval + ';BYDAY=' + byday + ';WKST=SU';
}

function lesson_start_time(begin_session){
    switch (begin_session){
        case '1': return 0800;
        case '2': return 0900;
        case '3': return 1020;
        case '4': return 1120;
        case '5': return 1330;
        case '6': return 1430;
        case '7': return 1540;
        case '8': return 1640;
        case '9': return 1830;
        case '10': return 1925;
        case '11': return 2020;
    }
}

function lesson_end_time(begin_session){
    switch (begin_session){ 
        case '1': return 0850;
        case '2': return 0950;
        case '3': return 1110;
        case '4': return 1210;
        case '5': return 1420;
        case '6': return 1520;
        case '7': return 1630;
        case '8': return 1730;
        case '9': return 1920;
        case '10': return 2015;
        case '11': return 2110;
    }
}

function fuck(week_fuck, weekday_fuck)
{
    var a = 0;
    var b = 0;
    var c = 0;
    var d = 0;
    a = week_fuck - 1;
    b = a * 7;
    c = b + weekday_fuck;
    d = c - 1;
    return d;
}

function get_date(week, weekday, time){
    var first_monday = new Date("2017-02-27");
    var days = 0;
    days = fuck(week, parseInt(weekday));
    first_monday.setDate(first_monday.getDate() + days);
    first_monday.setHours(parseInt(time / 100));
    first_monday.setMinutes(parseInt(time % 100));
    first_monday.setSeconds(0);
    return first_monday;
}

function Event(class_info){
    this.uid = class_info.jxbid;
    this.summary = class_info.kcm;
    this.teacher = class_info.skjs;
    this.print = function () {
        var ics_vevent = '';
        var lessons = class_info.pkxxList;
        for (var i in lessons) {
            var event_begin = 'BEGIN:VEVENT\r\n';
            var event_end = 'END:VEVENT\r\n';
            var dt_start = get_date(get_first_week_num(lessons[i].zcbh), 
                                    parseInt(lessons[i].skxq), 
                                    lesson_start_time(lessons[i].ksjc));
            var dt_end = get_date(get_first_week_num(lessons[i].zcbh), 
                                  parseInt(lessons[i].skxq), 
                                  lesson_end_time(lessons[i].jsjc));
            ics_vevent = ics_vevent + event_begin + 
                    'DTSTART;TZID=Asia/Shanghai:' + date_to_ics_format_string(dt_start) + '\r\n' +
                    'DTEND;TZID=Asia/Shanghai:' + date_to_ics_format_string(dt_end) + '\r\n' +
                    get_repead_rule(lessons[i].zcbh, lessons[i].skxq, 
                        get_date(get_last_week_num(lessons[i].zcbh), 
                            parseInt(lessons[i].skxq), 
                            lesson_end_time(lessons[i].jsjc))) + '\r\n' +
                    'DTSTAMP:20160822T125937Z\r\n' + 
                    'UID:' + this.uid + i.toString() + '\r\n' +
                    'LOCATION:' + lessons[i].jsmc + '\r\n' + 
                    'DESCRIPTION:' + lessons[i].zcmc + '\r\n' + 
                    'SEQUENCE:0\r\n' + 
                    'STATUS:CONFIRMED\r\n' + 
                    'SUMMARY:' + this.summary + ' ' + this.teacher + '\r\n' +
                    'TRANSP:OPAQUE\r\n' + 
                    event_end;
        }
        return ics_vevent;
    }
}

var ics_vevents = '';
for (var key in yxJxbList){
    if (yxJxbList[key].pkxxList[0].jsmc !== '') {
        var event = new Event(yxJxbList[key]);
        ics_vevents = ics_vevents + event.print();
    }
}
var event_begin = 'BEGIN:VCALENDAR\r\nPRODID:Fuyuhin.me\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nMETHOD:PUBLISH\r\nX-WR-CALNAME:HLJU Class Schedule\r\nX-WR-TIMEZONE:Asia/Shanghai\r\nBEGIN:VTIMEZONE\r\nTZID:Asia/Shanghai\r\nX-LIC-LOCATION:Asia/Shanghai\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0800\r\nTZOFFSETTO:+0800\r\nTZNAME:CST\r\nDTSTART:19700101T000000\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\n';
var event_end = 'END:VCALENDAR';
var ics_content = event_begin + ics_vevents + event_end;
// console.log(ics_content);
// alert(ics_content);

function download(fileName, blob){
    var aLink = document.createElement('a');
    var evt = document.createEvent("MouseEvents");
    evt.initEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    aLink.download = fileName;
    aLink.href = URL.createObjectURL(blob);
    aLink.dispatchEvent(evt);
}
 

function stringToBlob(text) {
    var blob = new Blob([text], {"type":'text/plain; charset="UTF-8"'});
    return blob;
}

var blob = stringToBlob(ics_content);
download('Class.ics', blob);