aboutsummaryrefslogtreecommitdiff
path: root/src/server/lib/schools/hetmml
diff options
context:
space:
mode:
authorNoah Loomans <noahloomans@gmail.com>2018-02-17 18:11:46 +0100
committerNoah Loomans <noahloomans@gmail.com>2018-02-17 18:11:46 +0100
commit2e4b9dc1cc48e5d35243bcef32b8acd29171bf23 (patch)
tree619cb2bfd1f41430d7b834a54738a8ca512fa36a /src/server/lib/schools/hetmml
parent4da5def0e14dbbbbdd7396921799b4753f073c26 (diff)
Move school spesific files to school spesifc folders
Diffstat (limited to 'src/server/lib/schools/hetmml')
-rw-r--r--src/server/lib/schools/hetmml/getScheduleData.js127
-rw-r--r--src/server/lib/schools/hetmml/getURLOfUser.js8
2 files changed, 135 insertions, 0 deletions
diff --git a/src/server/lib/schools/hetmml/getScheduleData.js b/src/server/lib/schools/hetmml/getScheduleData.js
new file mode 100644
index 0000000..303af6d
--- /dev/null
+++ b/src/server/lib/schools/hetmml/getScheduleData.js
@@ -0,0 +1,127 @@
+const Promise = require('bluebird');
+const cheerio = require('cheerio');
+const iconv = require('iconv-lite');
+const debounce = require('promise-debounce');
+const _ = require('lodash');
+const request = Promise.promisify(require('request'));
+
+const getUrlOfUser = require('./getURLOfUser');
+
+let meetingpointData;
+let lastUpdate;
+
+function scrapeUsers(html) {
+ const page = cheerio.load(html);
+ const script = page('script').eq(1).text();
+
+ const regexs = [/var classes = \[(.+)\];/, /var teachers = \[(.+)\];/, /var rooms = \[(.+)\];/, /var students = \[(.+)\];/];
+ const items = regexs.map(regex => script.match(regex)[1].split(',').map(item => item.replace(/"/g, '')));
+
+ const classes = items[0].map((item, index) => ({
+ type: 'c',
+ value: item,
+ index,
+ }));
+
+ const teachers = items[1].map((item, index) => ({
+ type: 't',
+ value: item,
+ index,
+ }));
+
+ const rooms = items[2].map((item, index) => ({
+ type: 'r',
+ value: item,
+ index,
+ }));
+
+ const students = items[3].map((item, index) => ({
+ type: 's',
+ value: item,
+ index,
+ }));
+
+ return _.flatten([classes, teachers, rooms, students]);
+}
+
+function scrapeWeeks(html) {
+ const page = cheerio.load(html);
+ const weekSelector = page('select[name="week"]');
+ const weeks = _.map(weekSelector.children(), option => ({
+ id: cheerio(option).attr('value'),
+ text: cheerio(option).text(),
+ }));
+
+ return weeks;
+}
+
+function scrapeAltText(html) {
+ const page = cheerio.load(html);
+ return page('center > font').eq(2).text().trim();
+}
+
+function combineUsers(usersArrays) {
+ return _.uniqBy(_.flatten(usersArrays), user => `${user.type}/${user.value}`);
+}
+
+function getAlts(users) {
+ const requests = users.map(user =>
+ request(getUrlOfUser('dag', user.type, user.index, 7), { timeout: 8000, encoding: null }));
+
+ return Promise.all(requests).then(teacherResponses =>
+ teacherResponses.map((teacherResponse, index) => {
+ const teacherResponseBody = iconv.decode(teacherResponse.body, 'iso-8859-1');
+
+ const teacherName = scrapeAltText(teacherResponseBody);
+
+ return {
+ ...users[index],
+ alt: teacherName,
+ };
+ }));
+}
+
+function getScheduleData() {
+ const navbarRequests = [
+ request('http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/frames/navbar.htm', { timeout: 5000 }),
+ request('http://www.meetingpointmco.nl/Roosters-AL/doc/basisroosters/frames/navbar.htm', { timeout: 5000 }),
+ ];
+
+ return Promise.all(navbarRequests)
+ .then(([dailyScheduleResponse, basisScheduleResponse]) => {
+ const users = scrapeUsers(dailyScheduleResponse.body);
+ const dailyScheduleWeeks = scrapeWeeks(dailyScheduleResponse.body);
+ const basisScheduleWeeks = scrapeWeeks(basisScheduleResponse.body);
+
+ const teachers = users.filter(user => user.type === 't');
+
+ return getAlts(teachers)
+ .then(teachersWithAlts => ({
+ users: combineUsers([teachersWithAlts, users]),
+ dailyScheduleWeeks,
+ basisScheduleWeeks,
+ }))
+ .catch(() => ({
+ // Just return the user data without the alts if getAlts fails, since
+ // the alts are non-essential.
+ users,
+ dailyScheduleWeeks,
+ basisScheduleWeeks,
+ }));
+ });
+}
+
+function getScheduleDataCacheWrapper() {
+ if (meetingpointData == null || new Date() - lastUpdate > 30 * 60 * 1000) { // 30 minutes
+ return getScheduleData().then((meetingpointData_) => {
+ lastUpdate = new Date();
+ meetingpointData = meetingpointData_;
+
+ return meetingpointData;
+ });
+ }
+
+ return Promise.resolve(meetingpointData);
+}
+
+module.exports = debounce(getScheduleDataCacheWrapper);
diff --git a/src/server/lib/schools/hetmml/getURLOfUser.js b/src/server/lib/schools/hetmml/getURLOfUser.js
new file mode 100644
index 0000000..f44d1a3
--- /dev/null
+++ b/src/server/lib/schools/hetmml/getURLOfUser.js
@@ -0,0 +1,8 @@
+const leftPad = require('left-pad'); // I imported this just to piss you off ;)
+
+function getURLOfUser(scheduleType, type, index, week) {
+ return `http://www.meetingpointmco.nl/Roosters-AL/doc/${scheduleType}roosters/` +
+ `${leftPad(week, 2, '0')}/${type}/${type}${leftPad(index + 1, 5, '0')}.htm`;
+}
+
+module.exports = getURLOfUser;