-
Notifications
You must be signed in to change notification settings - Fork 1
/
birthdays.js
76 lines (69 loc) · 3.07 KB
/
birthdays.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
const path = require('path')
const crypto = require('crypto')
require('dotenv').config({ path: path.join(__dirname, '.env') })
const ics = require('node-ical')
const moment = require('moment')
const R = require('ramda')
module.exports = (_now) => {
// global constants
const url = process.env.BIRTHDAY_CALENDAR
const now = (!(_now instanceof moment)) ? moment() : _now
// function definitions
const getEvents = (item) => item.type === 'VEVENT'
const extractStuff = (item) => {
const d = moment(item.start)
return {
...R.pick(['start', 'summary'], item),
uid: crypto.createHash('md5').update(item.uid).digest('hex'),
date: d.format('MM-DD'),
day: d.date(),
month: d.month() // zero-based!
}}
const byDate = (a, b) => moment(a.start).isSameOrBefore(moment(b.start)) ? -1 : 1
const next = (item, days) => {
const max = now.clone().add(days, 'days')
const bday = moment(item.start)
switch(days) {
case 0: // today
return item.month === now.month() && item.day === now.date()
case 1: // tomorrow
return item.month === now.month() && item.day - now.date() === 1
default: // periods of several days
return bday.isBefore(max) && bday.isSameOrAfter(now)
}
}
// const year = (item) => next(item, 365)
const month = (item) => next(item, 30)
const fortnight = (item) => next(item, 14)
const week = (item) => next(item, 7)
const tomorrow = (item) => next(item, 1)
const today = (item) => next(item, 0)
const contains = (a, b) => a.uid === b.uid
return new Promise((resolve, reject) => {
ics.fromURL(url, {}, (err, data) => {
if (err) return reject(err)
const events = R.pipe(
R.values,
R.filter(getEvents),
R.map(extractStuff),
R.sort(byDate),
)(data)
// R.differenceWith: make sure we're not repeating birthdays in several time buckets
// R.reduce(R.concat, [], ...): need to get an array of all previous birthdays so as not to repeat them
const zero = R.filter(today, events)
const one = R.differenceWith(contains, R.filter(tomorrow, events), zero)
const seven = R.differenceWith(contains, R.filter(week, events), R.reduce(R.concat, [], [one, zero]))
const fourteen = R.differenceWith(contains, R.filter(fortnight, events), R.reduce(R.concat, [], [seven, one, zero]))
const thirty = R.differenceWith(contains, R.filter(month, events), R.reduce(R.concat, [], [fourteen, seven, one, zero]))
resolve({
currentDatetime: moment().format("DD.MM.YYYY HH:mm"),
argumentDatetime: ((_now instanceof moment) ? _now.format("DD.MM.YYYY HH:mm") : undefined),
today: zero,
tomorrow: one,
week: seven,
fortnight: fourteen,
month: thirty
})
})
})
}