-
Notifications
You must be signed in to change notification settings - Fork 0
/
2_extract_subject_timetable.js
133 lines (98 loc) · 3.48 KB
/
2_extract_subject_timetable.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const fs = require('fs');
const env = require('jsdom').env;
const jquery = require('jquery');
const moment = require('moment');
let dataFile = process.argv[2];
let subjectNum = process.argv[3];
// console.log(`Processing subject ${subjectNum} for data file ${dataFile}`);
let html = fs.readFileSync(dataFile);
let log = (txt) => console.log(txt);
env({ html: html, done: function (errors, windowObj) {
if(errors) {
throw new Error(errors);
}
parse(jquery(windowObj));
windowObj.close();
}});
Object.values = Object.values || function(o){return Object.keys(o).map(function(k){return o[k]})};
class SubjectInfo {
constructor(subjectNumber) {
this.subjectNumber = subjectNumber;
this.sessions = {};
}
updateSessionDetails(sessionName, details) {
this.sessions[sessionName] = details
}
toMongoObj() {
return { subjectNumber: this.subjectNumber, sessions: Object.values(this.sessions) };
}
}
class SessionDetails {
constructor(sessionName) {
this.sessionName = sessionName;
this.classes = [];
}
addClass(classs) {
this.classes.push(classs)
}
}
function parse($) {
let subjectInfo = new SubjectInfo(subjectNum)
let currentSession = null;
const DAYS = `Mon Tue Wed Thu Fri Sat Sun`.split(' ');
$('table[cellpaddinng=1] tr').each((i,el)=>{
// New session.
if(el.bgColor == '#cccccc' && el.align == "LEFT") {
let text = $('a',el).first().attr('href');
currentSession = new SessionDetails(text);
}
if(el.bgColor == '#eeeeee') {
let items = $('td', el).get().map((el) => el.textContent);
let items_group = items[0].replace(/^\s+|\s+$/g, '');
let items_activity = items[1].replace(/^\s+|\s+$/g, '');
let items_day = items[2].replace(/^\s+|\s+$/g, '');
let items_startTime = items[3].replace(/^\s+|\s+$/g, '');
let items_duration = items[4].replace(/^\s+|\s+$/g, '');
let items_location = items[5].replace(/^\s+|\s+$/g, '');
let items_weeks = items[7].replace(/^\s+|\s+$/g, '');
let duration_mins = new Number(items_duration.split(' ')[0])
var locationInfo = items_location.trim();
if(locationInfo == '') {
return;
}
var locations = items_location.match(/C[a-zA-Z0-9][^\s]+/g);
if(!locations || !locations[0]) {
return;
// console.log(locationInfo)
// throw new Error("Can't find full location for "+timetableFile);
}
var classLocation = locations[0].split('.');
let classType = ''+items_group[0]+items_group[1]+items_group[2];
// Parse item_weeks
// "5/8-16/9, 7/10-4/11"
// "9/6"
let weeksOn = items_weeks.split(', ').map((period) => period.split('-').map((dateStr) => moment(dateStr, "D/M")))
// .format() is essential to converting it into 24 hour format in our timezone.
// http://stackoverflow.com/questions/24225142/why-does-moment-js-not-parse-24-hour-dates-correctly
let startingTime = moment(items_startTime, "HH:mm Z+1000").format();
let durationInMins = +(items_duration.split(' ')[0]);
let endTime = moment(startingTime).add(durationInMins, 'm').format();
let day = DAYS.indexOf(items_day);
let classInfo = {
startingTime: startingTime,
durationInMins: durationInMins,
endTime: endTime,
day: day,
location: items_location,
building: classLocation[0],
level: classLocation[1],
room: classLocation[2],
classType: classType,
weeksOn: weeksOn
};
currentSession.addClass(classInfo);
subjectInfo.updateSessionDetails(currentSession.sessionName, currentSession)
}
});
console.log(JSON.stringify(subjectInfo.toMongoObj(), null, 2))
}