summaryrefslogtreecommitdiff
path: root/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/index.ts')
-rw-r--r--src/index.ts48
1 files changed, 27 insertions, 21 deletions
diff --git a/src/index.ts b/src/index.ts
index 3d7e588..bb3b6c7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,57 +1,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 {IEvent} from './core/IEvent';
import {ILecture} from './core/ILecture';
-import {IcalSink} from './sinks/IcalSink';
-import {GoogleCalendarSink} from './sinks/GoogleCalendarSink';
+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) => [].concat(...arr1.map((e1) => arr2.map((e2) => [e1, e2])));
+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 sink = config.icsPath == undefined? new GoogleCalendarSink() : new IcalSink(config.icsPath);
-
const baseDate = moment().startOf('week');
- await BPromise.map(xprod(config.courses, range(config.prefetchWeeks)), async ([course, weeksAhead]) => {
- const unfilteredLectures = await SplusApi.getData(course, baseDate.weeks() + weeksAhead);
- const lectures = unfilteredLectures.filter(lecture => anyTrue(config.titleWhitelist, isIncluded(lecture.title)));
+ 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`);
- await BPromise.map(lectures, async (lec: ILecture) => {
- let beginDate = baseDate.clone();
+ 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,
}));
- let endDate = baseDate.clone();
+ const endDate = baseDate.clone();
endDate.add(moment.duration({
days: lec.day + 1,
hours: lec.end,
weeks: weeksAhead,
}));
- const event: IEvent = {
+
+ 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,
- start: beginDate.toDate(),
- end: endDate.toDate(),
};
-
- await sink.createEvent(event);
-
- console.log(lec.title, beginDate.toISOString(), endDate.toISOString());
});
- });
+ }, { concurrency: 1 })); // splus session breaks when sending multiple concurrent calls
- await sink.commit();
+ // ref. https://www.npmjs.com/package/ical-generator
+ const cal = ical({ events: uniqueByKey(events, 'uid') }).toString();
+ fs.writeFileSync(config.icsPath, cal.toString());
}
main(process.argv[2] || './config-example.json').catch(console.log);