summaryrefslogtreecommitdiff
path: root/src/index.ts
blob: eb496cef0f349bc111b40d0078f6057e1e690e5a (plain)
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
import * as moment from 'moment';
import * as BPromise from 'bluebird';
import * as fs from 'fs';
import * as ical from 'ical-generator';

import {createHash} from 'crypto';

import {SplusApi} from './core/SplusApi';
import {ILecture} from './core/ILecture';

const sha256 = (x) => createHash('sha256').update(x, 'utf8').digest('hex');
const flatten = (arr) => [].concat(...arr);
const range = (upper: number): number[] => Array.from(Array(upper), (x, i) => i);
const xprod = (arr1, arr2) => flatten(arr1.map((e1) => arr2.map((e2) => [e1, e2])));
const isIncluded = (s1) => (s2) => s1.includes(s2);
const anyTrue = (arr, cond) => arr.filter(cond).length > 0;
const allFalse = (arr, cond) => !anyTrue(arr, cond);
const uniqueByKey = (arrOfObj, key) => flatten((new Map(arrOfObj.map(obj => [obj[key], obj]))).values());

async function main(configPath) {
    const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
    const baseDate = moment().startOf('week');

    const events = flatten(await BPromise.map(xprod(config.courses, range(config.prefetchWeeks)), async ([course, weeksAhead]) => {
        const week = baseDate.clone().add(weeksAhead, 'weeks').weeks();
        const unfilteredLectures = await SplusApi.getData(course, week);
        const lectures = unfilteredLectures.filter(lecture => allFalse(config.titleBlacklist, isIncluded(lecture.title)));
        console.log(`fetching course ${course} week ${week}, ${lectures.length} lectures found`);

        return lectures.map((lec: ILecture) => {
            const beginDate = baseDate.clone();
            beginDate.add(moment.duration({
                days: lec.day + 1, // for moment: 1 = Monday
                hours: lec.begin,
                weeks: weeksAhead,
            }));

            const endDate = baseDate.clone();
            endDate.add(moment.duration({
                days: lec.day + 1,
                hours: lec.end,
                weeks: weeksAhead,
            }));

            const uid = sha256(JSON.stringify({ lec, beginDate, endDate })).substr(0, 16);
            return {
                uid,
                start: beginDate.toDate(),
                end: endDate.toDate(),
                timestamp: moment().toDate(),
                summary: lec.title,
                description: lec.lecturer + (lec.info !== '' ? ' - ' : '') + lec.info,
                location: lec.room,
            };
        });
    }, { concurrency: 1 })); // splus session breaks when sending multiple concurrent calls

    // ref. https://www.npmjs.com/package/ical-generator
    const cal = ical({ events: uniqueByKey(events, 'uid') }).toString();
    fs.writeFileSync(config.icsPath, cal.toString());
}

main(process.env.SPLUS_CONFIG || process.argv[2] || './config-example.json').catch(console.log);