ZUA课表导出

导出郑州航院课程表为ics文件

// ==UserScript==
// @name         ZUA课表导出
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  导出郑州航院课程表为ics文件
// @author       yangwu
// @match        http://202.196.166.135/*
// @match        http://202.196.166.136/*
// @match        http://202.196.166.138/*
// @match        http://202.196.166.139/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    const CRLF = "\r\n"
    function time_Deal(a) {//时间处理
        var class_begin;
        var class_end;
        var week_begin;
        var week_end;
        var week_one;
        var class1;
        var week1;
        week_one = a[1];
        class1 = a.match(/第.*节{/)[0];
        week1 = a.match(/{第.*周/)[0];
        class_begin = class1.substring(1, class1.indexOf(","));
        class_end = class1.substring(class1.indexOf(",") + 1, class1.length - 2);
        week_begin = week1.substring(2, week1.indexOf("-"));
        week_end = week1.substring(week1.indexOf("-") + 1, week1.length - 1);
        a = new Array();
        a.push(week_one);
        a.push(class_begin);
        a.push(class_end);
        a.push(week_begin);
        a.push(week_end);
        return a;
    }//时间处理
    //***************************************
    function weekswitch(i) {
        switch (i) {
            case '日': i = 6;
                break;
            case '一': i = 0;
                break;
            case '二': i = 1;
                break;
            case '三': i = 2;
                break;
            case '四': i = 3;
                break;
            case '五': i = 4;
                break;
            case '六': i = 5;
                break;
        }
        return i;
    }
    function classEndSwitch(i) {
        switch (i) {
            case '1': i = '0845';
                break;
            case '2': i = '0940';
                break;
            case '3': i = '1045';
                break;
            case '4': i = '1140';
                break;
            case '5': i = '1515';
                break;
            case '6': i = '1610';
                break;
            case '7': i = '1715';
                break;
            case '8': i = '1810';
                break;
            case '9': i = '2015';
                break;
            case '10': i = '2110';
                break;
        }
        return i;
    }
    function classBeginSwitch(i) {
        switch (i) {
            case '1': i = '0800';
                break;
            case '2': i = '0855';
                break;
            case '3': i = '1000';
                break;
            case '4': i = '1055';
                break;
            case '5': i = '1430';
                break;
            case '6': i = '1525';
                break;
            case '7': i = '1630';
                break;
            case '8': i = '1725';
                break;
            case '9': i = '1930';
                break;
            case '10': i = '2025';
                break;
        }
        return i;
    }
    function data_get() {
        var iframe = window.top.document.getElementById('iframeautoheight');
        var ifdocument = iframe.contentWindow.document;
        var couse = ifdocument.getElementsByClassName("datelist ");
        var couses = new Array;
        for (var i = 0; i < couse[0].rows.length; i++) {
            couses[i] = new Array;
            for (var j = 0; j < 10; j++) {
                var info = couse[0].rows[i].cells[j].innerHTML;
                couses[i].push(info);
            }
        }
        var data = new Array;
        for (i = 0; i < couses.length; i++) {
            data[i] = new Array;
            data[i].push(couses[i][2]);//课程名称
            data[i].push(couses[i][5]);//教师
            data[i].push(couses[i][8]);//时间
            data[i].push(couses[i][9]);//地点
        }
        for (i = 1; i < data.length; i++) {
            data[i][0] = data[i][0].match(/>.*</)[0].substring(1, data[i][0].match(/>.*</)[0].length - 1);
            data[i][1] = data[i][1].match(/>.*</)[0].substring(1, data[i][1].match(/>.*</)[0].length - 1);
            data[i][2] = data[i][2].match(/>.*</)[0].substring(1, data[i][2].match(/>.*</)[0].length - 1);
        }
        return data
    }
    //数据获取
    //**************************************
    function classDorS(b) {
        if (b.indexOf(";") != -1) {//存在;即为多节课
            b = b.split(";")
        }
        return b;
    }//多节判断
    //*********************************************
    function dataDeal(a) {
        for (var i = 1; i < a.length; i++) {
            a[i][2] = classDorS(a[i][2]);
            a[i][3] = classDorS(a[i][3]);
            if (a[i][2].length < 5) {
                for (var j = 0; j < a[i][2].length; j++) {
                    a[i][2][j] = time_Deal(a[i][2][j]);
                }
            }
            else {
                a[i][2] = time_Deal(a[i][2]);
            }
        }
        return a;

    }
    function firstD(d) {
        var nian = d.split("-");
        var c = new Date();
        c.setFullYear(nian[0], nian[1] - 1, nian[2]);
        return c;
        console.log(c);
    }
    function kaishiriqi(a, b) {
        var c = new Date(firstD(b).getFullYear(),firstD(b).getMonth());
        c.setDate(firstD(b).getDate() + weekswitch(a[0]) + (a[3] - 1) * 7);
        Date.prototype.format = function (fmt) {
            var o = {
                "M+": this.getMonth() + 1,
                "d+": this.getDate(),
                "h+": this.getHours(),
                "m+": this.getMinutes(),
                "s+": this.getSeconds(),
                "q+": Math.floor((this.getMonth() + 3) / 3),
                "S": this.getMilliseconds()
            };

            if (/(y+)/.test(fmt)) {
                fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            }

            for (var k in o) {
                if (new RegExp("(" + k + ")").test(fmt)) {
                    fmt = fmt.replace(
                        RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                }
            }

            return fmt;
        }
        c = c.format("yyyyMMdd");
        return c;
        console.log(c);
    }
    function genFinal(init) {
        var result = "";
        for (var i = 0; i < init.length; ++i) {
            var finalLine = "";
            var line = init[i];
            var len = line.length;
            if (len > 60) {
                var remain_len = len;
                var index = 0;
                while (remain_len > 0) {
                    for (var j = 0; j < index; ++j)
                        result += SPACE;
                    result += line.slice(0, 60);
                    line = line.slice(61);
                    remain_len -= 60;
                    index++;
                }
                line.slice(0, 60);
            }
            else
                finalLine = line;
            result += line + CRLF;
        }
        return result;
    }
    function icsdata(a, c) {
        var b = new Array;
        b.push("BEGIN:VCALENDAR");
        b.push("PRODID:-//TypeScript/Node.js//ZUA Course Exporter v1.0//CN");
        b.push("VERSION:2.0");
        for (var i = 1; i < a.length; i++) {
            if (a[i][2] != "") {
                if (a[i][2].length != 5) {
                    for (var j = 0; j < a[i][2].length; j++) {
                        b.push("BEGIN:VEVENT");
                        b.push("LOCATION:" + a[i][3][j]);
                        b.push("DTSTART;TZID='China Standard Time':" + kaishiriqi(a[i][2][j], c) + 'T' + classBeginSwitch(a[i][2][j][1]) + '00');
                        b.push("DTEND;TZID='China Standard Time':" + kaishiriqi(a[i][2][j], c) + 'T' + classEndSwitch(a[i][2][j][2]) + '00');
                        b.push("SUMMARY;LANGUAGE=zh-cn:" + a[i][0] + "(" + a[i][1] + ")");
                        if(a[i][2][j][4].search("单")!=-1||a[i][2][j][4].search("双")!=-1){
                            b.push("RRULE:FREQ=WEEKLY;COUNT="+((a[i][2][j][4].match(/\d+/i)-a[i][2][j][3])/2+1)+";INTERVAL=2")
                        }else if(a[i][2][j][4].search("单")==-1 && a[i][2][j][4].search("双")==-1){
                            b.push("RRULE:FREQ=WEEKLY;COUNT="+(a[i][2][j][4].match(/\d+/i)-a[i][2][j][3]+1))
                        }
                        b.push("END:VEVENT");
                    }
                }
                else {
                    b.push("BEGIN:VEVENT");
                    b.push("LOCATION:" + a[i][3]);
                    b.push("DTSTART;TZID='China Standard Time':" + kaishiriqi(a[i][2], c) + 'T' + classBeginSwitch(a[i][2][1]) + '00');
                    b.push("DTEND;TZID='China Standard Time':" + kaishiriqi(a[i][2], c) + 'T' + classEndSwitch(a[i][2][2]) + '00');
                    b.push("SUMMARY;LANGUAGE=zh-cn:" + a[i][0] + "(" + a[i][1] + ")");
                    if(a[i][2][4].search("单")!=-1||a[i][2][4].search("双")!=-1){
                        b.push("RRULE:FREQ=WEEKLY;COUNT="+((a[i][2][4].match(/\d+/i)-a[i][2][3])/2+1)+";INTERVAL=2")
                    }else if(a[i][2][4].search("单")==-1 && a[i][2][4].search("双")==-1){
                        b.push("RRULE:FREQ=WEEKLY;COUNT="+(a[i][2][4].match(/\d+/i)-a[i][2][3]+1))
                    }
                    b.push("END:VEVENT");
                }

            }

        }
        b.push("END:VCALENDAR");
        console.log(b);
        return b;
    }
    function danshuang(a){
        for(var i=1;i<a.length;i++){
            if(a[i][2].length!=5){
                for(var j=0;j<a[i][2].length;j++){
                    if(a[i][2][j][4].search("双")!=-1){
                        if(a[i][2][j][3]%2!=0){
                            a[i][2][j][3]=String(Number(a[i][2][j][3])+1);
                        }
                        if(Number(a[i][2][j][4].match(/\d+/i))%2!=0){
                            a[i][2][j][4]=a[i][2][j][4].replace(a[i][2][j][4].match(/\d+/i),Number(a[i][2][j][4].match(/\d+/i))-1);}
                    }
                    if(a[i][2][j][4].search("单")!=-1){
                        if(a[i][2][j][3]%2==0){
                            a[i][2][j][3]=String(Number(a[i][2][j][3])+1);
                        }
                        if(Number(a[i][2][j][4].match(/\d+/i))%2==0){
                            a[i][2][j][4]=a[i][2][j][4].replace(a[i][2][j][4].match(/\d+/i),Number(a[i][2][j][4].match(/\d+/i))-1);}
                    }
                }
            }else if(a[i][2][4].search("双")!=-1){
                if(a[i][2][3]%2!=0){
                    a[i][2][3]=String(Number(a[i][2][3])+1);
                }
                if(Number(a[i][2][4].match(/\d+/i))%2!=0){
                    a[i][2][4]=a[i][2][4].replace(a[i][2][4].match(/\d+/i),Number(a[i][2][4].match(/\d+/i))-1);}
            }else if(a[i][2][4].search("单")!=-1){
                if(a[i][2][3]%2==0){
                    a[i][2][3]=String(Number(a[i][2][3])+1);
                }
                if(Number(a[i][2][4].match(/\d+/i))%2==0){
                    a[i][2][4]=a[i][2][4].replace(a[i][2][4].match(/\d+/i),Number(a[i][2][4].match(/\d+/i))-1);}
        }}
        return a;
    }
    const PAGE = {
        "main": /xs_main.aspx/,
        "course_table": /xsxkqk.aspx/
    };
    const iframe = document.querySelector("#iframeautoheight");
    if (iframe) {
        iframe.addEventListener('load', function () {
            const content = iframe.contentDocument || iframe.contentWindow.document;
            const URL = content.location.href;
            if (PAGE["course_table"].test(URL)) {
                const inject_td = content.querySelector('.search_con');
                const inject_p = content.createElement("p");
                const export_span = content.createElement("span");
                const export_first_day = content.createElement('input');
                const export_btn = content.createElement('button');
                const dwn_anchor = content.createElement("a");
                dwn_anchor.innerHTML = "Download the .ics file";
                dwn_anchor.style.visibility = "hidden";
                inject_p.appendChild(export_span);
                inject_p.appendChild(export_first_day);
                inject_p.appendChild(export_btn);
                inject_p.appendChild(dwn_anchor);
                inject_td.appendChild(content.createElement("br"));
                inject_td.appendChild(inject_p);
                export_span.innerHTML = "   这个学期的第一个星期一是:";
                export_first_day.type = "date";
                export_first_day.value = "2020-02-24";
                export_btn.innerText = "导出课表";
                export_btn.addEventListener('click', (evt) => {
                    evt.preventDefault();
                    var data_1 = data_get();
                    dataDeal(data_1);
                    data_1=danshuang(data_1);
                    console.log(data_1);
                    dwn_anchor.style.visibility = "visible";
                    var result = genFinal(icsdata(data_1, export_first_day.value));
                    var link = window.URL.createObjectURL(new Blob([result], {
                        type: "text/x-vCalendar"
                    }));
                    dwn_anchor.setAttribute("href", link);
                    dwn_anchor.setAttribute("download", "cal.ics");
                })
            }
        })
    }

    // Your code here...
})();