2015-06-13 19:14:45 +02:00
|
|
|
//schedule.js
|
2015-08-16 13:42:14 +02:00
|
|
|
/**
|
|
|
|
* Module for parsing downloaded schedule pages into useable/readable JSON objects.
|
|
|
|
* Usually used after a lookup with the supplied information from it.
|
|
|
|
* @module schedule
|
2015-08-16 13:48:08 +02:00
|
|
|
* @author Bram van der Veen <96aa48@gmail.com>
|
2015-08-16 13:42:14 +02:00
|
|
|
*/
|
2015-08-16 01:37:27 +02:00
|
|
|
|
|
|
|
//Import first-party modules.
|
2016-06-18 15:06:51 +02:00
|
|
|
const url = require('url');
|
2015-08-16 01:37:27 +02:00
|
|
|
|
|
|
|
//Import third-party modules.
|
2016-06-18 15:06:51 +02:00
|
|
|
const http = require('socks5-http-client');
|
|
|
|
const cheerio = require('cheerio');
|
2015-08-16 01:37:27 +02:00
|
|
|
|
|
|
|
//Import self-written modules.
|
2016-06-18 15:06:51 +02:00
|
|
|
const config = require('./configuration');
|
2015-06-13 19:14:45 +02:00
|
|
|
|
2015-08-16 01:37:27 +02:00
|
|
|
/**
|
|
|
|
* Function being called by Express when the user requests a schedule.
|
|
|
|
* @param {Object} req - Request object supplied by Express.
|
|
|
|
* @param {Object} res - Response object supplied by Express.
|
|
|
|
* @param {Function} next - Next function supplied by Express.
|
|
|
|
*/
|
2015-06-27 15:03:50 +02:00
|
|
|
function get(req, res, next) {
|
2016-06-18 15:26:06 +02:00
|
|
|
getSchedule(req.match.url, (json) => {
|
2015-06-13 22:36:18 +02:00
|
|
|
req.match.json = json;
|
|
|
|
next();
|
2015-06-13 19:14:45 +02:00
|
|
|
});
|
|
|
|
}
|
2015-08-16 13:18:01 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Function for getting the information off of the schedule servers.
|
2015-08-16 18:47:05 +02:00
|
|
|
* @param {String} getUrl - The url of the page that needs to be downloaded.
|
2015-08-16 13:18:01 +02:00
|
|
|
* @param {Function} callback - Callback function to return the downloaded information.
|
|
|
|
*/
|
2015-08-16 18:47:05 +02:00
|
|
|
function getSchedule(getUrl, callback) {
|
2016-06-18 15:06:51 +02:00
|
|
|
let options = url.parse(getUrl);
|
2015-08-15 21:07:22 +02:00
|
|
|
options.socksPort = config().torPort;
|
|
|
|
options.socksHost = config().torHost;
|
2015-06-24 17:07:52 +02:00
|
|
|
|
2016-06-18 15:26:06 +02:00
|
|
|
http.get(options, (res) => {
|
2016-06-18 15:06:51 +02:00
|
|
|
let _download = '';
|
2015-06-13 19:14:45 +02:00
|
|
|
|
2016-06-18 15:26:06 +02:00
|
|
|
res.on('data', (data) => _download += data);
|
|
|
|
res.on('end', () => callback(toJSON(_download)));
|
2015-06-13 19:14:45 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-08-16 13:18:01 +02:00
|
|
|
/**
|
|
|
|
* Function for getting the names of the schedules with Regular Expressions
|
|
|
|
* @param {String} page - The downloaded page with schedule information.
|
|
|
|
* @return {Array} names - An array populated with the schedule names (basic, week)
|
|
|
|
*/
|
|
|
|
function scheduleNames(page) {
|
2016-06-18 15:06:51 +02:00
|
|
|
let extract = cheerio('table tr td[valign="bottom"] table tr td b, table tr td[valign="bottom"] table tr td a', page).text().split(/\s\s/);
|
|
|
|
let tab = 0;
|
|
|
|
let names = [];
|
2015-06-21 00:21:25 +02:00
|
|
|
|
|
|
|
for (element of extract) {
|
2015-08-16 13:18:01 +02:00
|
|
|
element != '' ? names.push({
|
2015-08-15 17:00:27 +02:00
|
|
|
'letter': element.substr(0, 1),
|
|
|
|
'value' : element.match(/.*rooster|t\/m|\d\d\s\w{3}/gi).join(' ').slice(1).toLowerCase(),
|
|
|
|
'tab': tab++
|
|
|
|
}) : null;
|
2015-06-21 00:21:25 +02:00
|
|
|
}
|
2015-06-21 17:06:45 +02:00
|
|
|
|
2015-08-16 13:18:01 +02:00
|
|
|
return names;
|
2015-06-21 00:21:25 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 13:18:01 +02:00
|
|
|
/**
|
|
|
|
* Function for converting the page (string) into a JSON datastructure.
|
|
|
|
* @param {String} page - The downloaded page with schedule information.
|
|
|
|
* @return {Object} scheduleData - The converted JSON datastructure.
|
|
|
|
*/
|
2015-08-15 21:07:22 +02:00
|
|
|
function toJSON(page) {
|
2016-06-18 15:06:51 +02:00
|
|
|
let result = cheerio('td:nth-child(3) table', page);
|
|
|
|
let names = scheduleNames(page);
|
|
|
|
let isTeacher = cheerio(cheerio(page).find('tr.CoreDark').find('td')[3]).find('a').html() == null;
|
|
|
|
let amountOfDays = cheerio(result).find('tr.AccentDark').find('td').length - 1;
|
|
|
|
let amountOfHours = config().amountOfHours;
|
2015-06-13 22:07:06 +02:00
|
|
|
|
2016-06-18 15:06:51 +02:00
|
|
|
let scheduleData = [];
|
2015-06-13 19:14:45 +02:00
|
|
|
|
2016-06-18 15:06:51 +02:00
|
|
|
let offset = isTeacher ? 5 : 6;
|
2015-06-16 15:22:34 +02:00
|
|
|
|
2015-06-13 19:14:45 +02:00
|
|
|
//Looping for amount of days
|
2015-08-15 21:07:22 +02:00
|
|
|
for (day = 0; day < amountOfDays; day++) {
|
|
|
|
scheduleData[day] = [];
|
2015-06-13 19:14:45 +02:00
|
|
|
|
|
|
|
//Looping for amount of hours
|
2015-08-15 21:07:22 +02:00
|
|
|
for (hour = 0; hour < amountOfHours; hour++) {
|
2016-06-18 15:06:51 +02:00
|
|
|
let schedule = cheerio('tr:nth-child('+ (offset + hour) +')', result);
|
2015-06-13 19:14:45 +02:00
|
|
|
|
|
|
|
//Looping for (optional) specialhours
|
2016-06-18 15:06:51 +02:00
|
|
|
let specialHours = schedule.find('table').eq(day).children().length;
|
2015-08-15 21:07:22 +02:00
|
|
|
scheduleData[day][hour] = {teacher: [], chamber: [], course: [], changed: []};
|
|
|
|
for (subhour = 0; subhour < specialHours; subhour++) {
|
2016-06-18 15:06:51 +02:00
|
|
|
let selectedHour = schedule.find('table').eq(day).find('tr').eq(subhour).find('td');
|
2015-06-16 15:04:07 +02:00
|
|
|
//Give the value of the schedule hour to the fitting array.
|
2015-08-15 21:07:22 +02:00
|
|
|
scheduleData[day][hour].teacher[subhour] = selectedHour.eq(0).text().replace(/\r|\n/g, '');
|
|
|
|
scheduleData[day][hour].chamber[subhour] = selectedHour.eq(2).text();
|
|
|
|
scheduleData[day][hour].course[subhour] = selectedHour.eq(4).text();
|
2015-06-16 15:04:07 +02:00
|
|
|
//Check if the hour is 'changed' by the schedule authors, if so set to true.
|
2015-08-15 21:07:22 +02:00
|
|
|
scheduleData[day][hour].changed[subhour] = selectedHour.eq(0).attr().class == 'tableCellNew' ? true : false;
|
2015-06-13 19:14:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-16 13:18:01 +02:00
|
|
|
scheduleData.names = names;
|
2015-06-21 17:06:45 +02:00
|
|
|
|
2015-08-15 21:07:22 +02:00
|
|
|
return scheduleData;
|
2015-06-13 19:14:45 +02:00
|
|
|
}
|
|
|
|
|
2015-08-16 01:37:27 +02:00
|
|
|
/**
|
|
|
|
* Function for doing a lookup in the database containing all records
|
|
|
|
* of students, teachers and classrooms.
|
|
|
|
* @param {Object} lookup - Object with all of the information from the request.
|
|
|
|
* @param {Function} callback - Callback function for the API module.
|
|
|
|
*/
|
|
|
|
function api(lookup, callback) {
|
|
|
|
getSchedule(lookup.data[0].url, callback);
|
|
|
|
}
|
|
|
|
|
2015-06-13 22:07:06 +02:00
|
|
|
//Exporting the schedule function.
|
2015-08-16 13:18:01 +02:00
|
|
|
module.exports = {
|
|
|
|
'get': get,
|
|
|
|
'api': api
|
|
|
|
};
|