UOB_Schedule_Organizer

This userscript provide readable schedule for Univirsity Of Bahrain (UOB) students beside orginal schedule, and view available seats in course schedule page.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        UOB_Schedule_Organizer
// @version     1.1
// @description This userscript provide readable schedule for Univirsity Of Bahrain (UOB) students beside orginal schedule, and view available seats in course schedule page.
// @copyright   2016+, Ali Yusuf
// @icon        http://www.online.uob.edu.bh/favicon.ico
// @namespace   https://greasyfork.org/users/32205
// @include     https://www.online.uob.edu.bh/cgi/regweb/schedule_page_print
// @include     http://www.online.uob.edu.bh/cgi/regweb/schedule_page_print
// @include     https://www.online.uob.edu.bh/cgi/enr/schedule2.class_schedule?*
// @include     http://www.online.uob.edu.bh/cgi/enr/schedule2.class_schedule?*
// @grant       none
// ==/UserScript==

// Load script function needed to make sure that script is loaded before execute the code
function loadScript(url, callback){

    var script = document.createElement("script")
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" ||
                    script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

// Check window path to run the appropriate function
// 1) Schedule Organizer
// 2) Avilable Seat Viewr
if (window.location.pathname == '/cgi/regweb/schedule_page_print')
    loadScript("https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js", function(){
        PrintSchedule ();
    });
else if (window.location.pathname == '/cgi/enr/schedule2.class_schedule')
    loadScript('https://code.jquery.com/jquery-1.12.0.min.js', function(){
        ViewSeats ();
    });
else
    alert("Sorry this page are not supported :)\n-Ali Yusuf");

/***************************************************************************************************************************
//
//
//   1) Schedule Organizer code
//
//
//**************************************************************************************************************************/


/*
- stuctur of subjects[subjectKey[]]:
[
	index 0 ->"subjectName",
	index 1 ->"section",
	index 2 ->"credit",
	index 3 ->"finalExam",
	index 4 ->"timing": [
			index 0 ->{
			"Day":"",
			"from":"",
			"to":"",
			"room":"",
			"site":""
		},
        index 1 ->{..}, ..
    ]
]
*/

function PrintSchedule (){
    var title = '<a href="https://goo.gl/1Xo9c3" target="_blank" >USO</a> - v1.1';
    var days = ['U','M','T','W','H'];
    var hours = [];
    for (i=8;i<20;i+=0.25)
        hours.push(i);
    var subjects = {}; // contain all information of subjects
    var subjectsKey = []; // contain subjects keys
    var parentScheduleTable = document.body.getElementsByTagName('table')[4];
    var scheduleTable = document.body.getElementsByTagName('table')[5];
    var tbody = scheduleTable.getElementsByTagName('tbody')[0];
    var rows = tbody.children;
    var colors = ['aquamarine','bisque','gainsboro','gold','lightblue','greenyellow','khaki','lightgrey','palegoldenrod','pink','plum','sandybrown','tan'];
    
    // Get course information
    
    for (i=0;i<rows.length;i++)
    {
        if (!rows[i].children[0].hasAttribute('colspan'))
        {
            var subject = rows[i].children[0].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
            if (subject != "&nbsp;")
            {
                if (subjectsKey.length>0)
                    subjects[subjectsKey[subjectsKey.length-1]].push(timing);
                
                subject += rows[i].children[1].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                var section = rows[i].children[3].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                var subjectName = rows[i].children[4].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                var credit = rows[i].children[10].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                var finalExam = rows[i].children[11].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                subjects[subject]= [subjectName,section,credit,finalExam];
                subjectsKey.push(subject);
                var timing = [];
            }
            else if (subjectsKey[subjectsKey.length-1] !== '')
            {
                var timingTemp = {};
                timingTemp.day = rows[i].children[5].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                timingTemp.from = rows[i].children[6].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                timingTemp.to = rows[i].children[7].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                timingTemp.room = rows[i].children[8].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                timingTemp.site = rows[i].children[9].innerHTML.replace(/(\s*<\/?font.*?>\s*)/g, "");
                timing.push(timingTemp);
            }
        }
    }
    if (subjectsKey.length>0)
        subjects[subjectsKey[subjectsKey.length-1]].push(timing);
    
    // Build newTable String
    
    var newTable = '<table id="newTable" width="800" border="0" align="center" cellpadding="0" cellspacing="0" bordercolor="#000000">\n  <tbody><tr>\n    <td>\n	<table width="100%" style="border-collapse: collapse;" cellspacing="0" cellpadding="0" bgcolor="#fff">\n		<tbody>\n			<tr height="60" align="center">\n				<td colspan="80" align="center" id="title" >'+title+'<br><br></td>\n			</tr>\n			<tr align="center" style="border-bottom:1pt solid black;">\n				<td><font size="4" face="Times New Roman"><b></b></font></td>\n';
    for (i=0;i<hours.length;i+=4){
        if (hours[i]>7 && hours[i]<12)
            newTable += '				<td style="border:1pt solid;background: whitesmoke;" colspan="4" ><font size="4" face="Times New Roman"><b><nobr>'+hours[i]+' AM</nobr></b></font></td>\n';
        else
        {
            var h = (hours[i] > 12) ? (hours[i]-12):(12);
            newTable += '				<td style="border:1pt solid;background: whitesmoke;" colspan="4" ><font size="4" face="Times New Roman"><b><nobr>'+h+' PM</nobr></b></font></td>\n';
        }
    }
    newTable += '			</tr>\n';
    for (i=0;i<days.length;i++)
    {
        newTable += '			<tr style="border-bottom:1pt solid black;" align="center">\n				<td style="border-bottom: 1pt solid;border-left: 1pt solid;background: whitesmoke;" height="30" ><font style="font-size:40px" face="Times New Roman">'+days[i]+'</font></td>\n';
        for (j=0;j<hours.length;j++)
            if(hours[j]%1===0)
            newTable += '				<td style="border-left:1pt solid;" id="'+days[i]+'-'+hours[j]+'"></td>\n';
            else if(j==hours.length-1)
            newTable += '				<td style="border-right:1pt solid;" id="'+days[i]+'-'+hours[j]+'"></td>\n';
            
            else
                newTable += '				<td id="'+days[i]+'-'+hours[j]+'"></td>\n';
        newTable += '			</tr>\n';
    }
    newTable += '			<tr height="40"></tr>\n		</tbody>\n	</table>\n	</td>\n  </tr>\n</tbody></table>';
    
    // Add newTable to document
    
    var parser = new DOMParser();
    newTable = parser.parseFromString(newTable, "text/html");
    //document.body.insertBefore(newTable.body.childNodes[0],parentScheduleTable.nextSibling);
    
    for (i=0;i<subjectsKey.length;i++)
    {
        for (k=0;k<subjects[subjectsKey[i]][4].length;k++)
            for (d=0;d<days.length;d++)
                if (subjects[subjectsKey[i]][4][k]['day'].search(days[d]) !== -1)
                    {
                        var fTime = subjects[subjectsKey[i]][4][k].from.match(/([\d]*):([\d]*)/);
                        var fHour = parseInt(fTime[1]);
                        var fMin = parseInt(fTime[2]);
                        var tTime = subjects[subjectsKey[i]][4][k].to.match(/([\d]*):([\d]*)/);
                        var tHour = parseInt(tTime[1]);
                        var tMin = parseInt(tTime[2]);

                        newTable.getElementById(days[d]+'-'+(fHour+(fMin/60))).innerHTML += subjectsKey[i]+'<br>'+subjects[subjectsKey[i]][4][k].room+'<br>Sec.'+subjects[subjectsKey[i]][1];
                        
                        var span = (tHour*60+tMin) - (fHour*60+fMin);
                           
                        if (span == 50)
                            span = 60;
                        else if (span == 100)
                            span = 105;
                            
                        var node = newTable.getElementById(days[d]+'-'+(fHour+(fMin/60)));
                        node.setAttribute("colspan", span/15);
                        node.setAttribute("style",'border-right:1pt solid; border-left:1pt solid;border-bottom:1pt solid; background: '+colors[i]+';');
                        
                        if (span == 60)
                            span = 45;
                        else if (span == 75)
                            span = 60;
                        else if (span == 105)
                            span = 90;
                        
                        for (r=0;r<span/15;r++)
                            node.parentNode.removeChild(newTable.getElementById(days[d]+'-'+((fHour+(fMin/60))+((r+1)/4))));
                    }
    }
    document.body.insertBefore(newTable.body.childNodes[0],parentScheduleTable.nextSibling);
    html2canvas(document.getElementById("newTable"), {  
        onrendered: function (canvas) {
            var dataUrl = canvas.toDataURL();
            document.getElementById("title").innerHTML+='<a href="'+dataUrl+'" target="_blank" style="color: inherit; text-decoration: inherit; text-decoration: none;background-color: #EEEEEE;color: #333333;padding: 2px 6px 4px 6px;border-top: 1px solid #CCCCCC;border-right: 1px solid #333333;border-bottom: 1px solid #333333;border-left: 1px solid #CCCCCC;" id="saveTable">Save Table As photo</a><br><br>';
        }
    });
}

/*
    - Tests:
    console.log();
    console.log(subjects);         //Test subjects
    console.log(subjectsKey);      //Test subjectsKey
    console.log(newTable);    //Test newTable
*/

/***************************************************************************************************************************
//
//
//   2) Available Seate Viewer code
//
//
//**************************************************************************************************************************/

function ViewSeats (){
    document.getElementsByTagName('frame')[0].setAttribute("id", "bannerFrame");
    document.getElementsByTagName('frame')[3].setAttribute("id", "mainFrame");
    var bannerFrame = top.frames.banner;
    var mainFrame = top.frames.main;
    var header = bannerFrame.document.querySelector('body > p');
    header.firstElementChild.innerHTML = '<font color="#000000" size="4"> Course Schedule With Available Seats - <a href="https://goo.gl/1Xo9c3" target="_blank">USO</a></font><br>';
    
    // Main frame load listener
    $('#mainFrame').load(function() {
        var inl_s = mainFrame.location.search.search('inl=');
        var crsno_s = mainFrame.location.search.search('crsno=');
        var crd_s = mainFrame.location.search.search('crd=');
        var inl = mainFrame.location.search.substring(inl_s+4,crsno_s-1);
        var crsno = mainFrame.location.search.substring(crsno_s+6,crd_s-1);
        
        // Set Seates to N/A
        var elements = mainFrame.document.querySelectorAll('body > p');
        [].forEach.call(elements, function( el ) {
            var sec = />([0-9]{2})</gm.exec(el.firstElementChild.innerHTML);
            //console.log(sec[1]);
            var seatString = '<br><font color="#000080">Available Seats => </font><font id="secno_'+sec[1]+'" name="courseSeates" color="#FF0000">N/A</font>';
            el.firstElementChild.innerHTML = el.firstElementChild.innerHTML+seatString;
        });
        
        // Get info.
        $.get('https://www.online.uob.edu.bh/cgi/enr/enr_sections?pcrsnbr='+crsno+'&pcrsinlcde='+inl, function( data ) {
            //console.log(data);
            data = data.replace(/(\r\n|\n|\r)/gm,"");
            var sec = [];
            var seat = [];
            var match = [];
            // Sections info.
            var pattern = /color="#FF0000">([0-9]{2})</g;
            while (match = pattern.exec(data)) {
                sec.push(match[1]);
            }
            // Available seats info.
            pattern = /size="2">([0-9]*)</g;
            while (match = pattern.exec(data)) {
                seat.push(match[1]);
            }
            for(i=0;i<seat.length;i++)
            {
                $('#secno_'+sec[i],mainFrame.document).html(seat[i]);
            }
        }); // End get info.
        
    });// End main frame load listener
}