forked from dhbw-timetable/rapla-parser-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrapla-parser.js
109 lines (96 loc) · 3.46 KB
/
rapla-parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const request = require('request');
const jsdom = require('jsdom');
const Text = require('jsdom/lib/jsdom/living/generated/Text');
const { JSDOM } = jsdom;
function putProperty(tempEvent, values, label, i) {
switch (label.innerHTML) {
case 'Titel:':
tempEvent.title = values[i].innerHTML;
break;
case 'Personen:':
tempEvent.persons = values[i].innerHTML;
break;
case 'Ressourcen:':
tempEvent.ressources = values[i].innerHTML;
break;
}
}
/* Applies hours and minutes (e.g 08:00) from srcMoment to a clone */
function applyMoment(srcMoment, time) {
let mmt = srcMoment.clone();
if (typeof time !== 'undefined'){
let split = time.split(':');
mmt.set('hours', parseInt(split[0]));
mmt.set('minutes', parseInt(split[1]));
}
return mmt;
}
function putDates(tempEvent, tempMoment, anchorElement) {
let time = '99:99-99:99';
const firstElNode = anchorElement.firstChild;
if (typeof firstElNode === typeof Text) {
time = firstElNode.textContent.substring(0,5).concat(firstElNode.textContent.substring(6));
} else {
if (firstElNode.querySelectorAll('span.class=link')) {
putDates(firstElNode);
} else {
time = '08:00-18:00';
}
}
if (!time) {
time = '08:00-18:00';
}
let times = time.split('-');
tempEvent.startDate = applyMoment(tempMoment, times[0]).format('HH:mm DD.MM.YYYY');
tempEvent.endDate = applyMoment(tempMoment, times[1]).format('HH:mm DD.MM.YYYY');
}
function addEvent(events, tempMoment, anchorElement) {
let tempEvent = {};
// Write the time
putDates(tempEvent, tempMoment, anchorElement);
// Write the details
let labels = anchorElement.querySelectorAll('span.tooltip table.infotable tbody tr td.label');
let values = anchorElement.querySelectorAll('span.tooltip table.infotable tbody tr td.value');
labels.forEach((label, i) => putProperty(tempEvent, values, label, i));
let uidstr = (tempEvent.startDate.slice(0, 5) + tempEvent.title).split('')
.map(c => c.charCodeAt(0).toString(16).padStart(2, '0'))
.join('')
.slice(0,35);
tempEvent.UID = uidstr;
events.push(tempEvent);
}
function fetchWeek(url, moment, onDone, onError, sharedObj) {
let events = [], tempMoment = moment.clone();
request(`${url}&day=${moment.date()}&month=${moment.month()+1}&year=${moment.year()}`, (err, res, body) => {
if (err && onError) return onError(err);
const { document } = new JSDOM(body).window;
let weekTableRows = document.querySelectorAll('table.week_table > tbody > tr');
weekTableRows.forEach(tr => {
tr.childNodes.forEach(td => {
if (td.className && td.className.startsWith('week_block')) {
addEvent(events, tempMoment, td.querySelector('a'));
} else if (td.className && td.className.startsWith('week_separatorcell')) {
tempMoment.add(1, 'days');
}
});
// reset date here
tempMoment = moment.clone();
});
sharedObj[moment.format('DD.MM.YYYY')] = events;
onDone();
});
}
function fetchWeeks(url, startMoment, endMoment, onDone, onError) {
let weekPromises = [], sharedObj = {};
// to monday
startMoment.set('day', 1);
endMoment.set('day', 1);
do {
weekPromises.push(new Promise(
(resolve, reject) => fetchWeek(url, startMoment.clone(), resolve, reject, sharedObj)
));
startMoment.add(7, 'days');
} while (!startMoment.isAfter(endMoment));
Promise.all(weekPromises).then(() => { onDone(sharedObj); }).catch(onError);
}
exports.fetchWeeks = fetchWeeks;