From 1aa2ab81fa033d7a8392a25877419b3d4e5df03f Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Fri, 19 Apr 2019 00:31:02 +0000 Subject: [server] add rrule npm module; new eventhelper (untested and WIP) --- server/.eslintignore | 1 + server/lib/eventhelper.js | 98 +++++++++++++++++++++++++++++------------------ server/package-lock.json | 14 +++++++ server/package.json | 1 + 4 files changed, 76 insertions(+), 38 deletions(-) (limited to 'server') diff --git a/server/.eslintignore b/server/.eslintignore index 66af4f4..c74fd45 100644 --- a/server/.eslintignore +++ b/server/.eslintignore @@ -10,6 +10,7 @@ .DS_Store node_modules/ /public/ +/public_documentation/ /tftp/ /ipxe/ipxe/ npm-debug.log* diff --git a/server/lib/eventhelper.js b/server/lib/eventhelper.js index fb359e9..26fe1fc 100644 --- a/server/lib/eventhelper.js +++ b/server/lib/eventhelper.js @@ -1,47 +1,69 @@ -// /* global __appdir */ -// var path = require('path') -// var db = require(path.join(__appdir, 'lib', 'sequelize')) -const later = require('later') - -function isActive (eventData) { - const now = Date.now() / 1000 - if (eventData.repetitive) { - if (now < eventData.startDate || eventData.endDate < now) return false - return later.schedule(getTimeSpans(eventData)).isValid(new Date(now * 1000)) - } else { - return eventData.start < now && now < eventData.end - } +const { RRule } = require('rrule') + +function _fakeUTCToDate (fakeUTC) { + const isoString = fakeUTC.toISOString() + return new Date(isoString.substr(0, isoString.length - 1)) } -function getTimeSpans (eventData) { - const schedule = later.parse.recur() - schedule.after(eventData.startTime).time() - const startTime = eventData.startTime.split(':').map(x => parseInt(x)) - const endTime = eventData.endTime.split(':').map(x => parseInt(x)) - if (startTime[0] > endTime[0] || (startTime[0] === endTime[0] && startTime[1] > endTime[1])) { - _setUpSchedule(eventData, schedule) - schedule.and() +function _pad (x) { + return x < 10 ? '0' + x : x +} + +// #################################################################################### +// #################################################################################### + +class Schedule { + constructor (event) { + const splitStart = event.start.split(' ') + const splitStartTime = splitStart.split(':') + const rule = { + dtstart: new Date(event.start + 'Z'), + until: new Date(event.start + 'Z'), + interval: event.interval, + byhour: splitStartTime[0], + byminute: splitStartTime[1] + } + if (event.intervalType === 'month') rule.freq = RRule.MONTHLY + else if (event.intervalType === 'month') rule.freq = RRule.WEEKLY + else rule.freq = RRule.DAILY + this.rrule = new RRule(rule) + this.endTime = event.end.split(' ')[1] + } + + next () { + const now = formatDate(new Date()) + return _fakeUTCToDate(this.rrule.after(now + 'Z')) + } + + isValid (date) { + date = formatDate(date) + const lastDate = formatDate(this.rrule.before(new Date(date + 'Z'), true)) + let lastDateEnd = lastDate.split(' ')[0] + ' ' + this.endTime + if (lastDateEnd < lastDate) { + let d = new Date(lastDateEnd) + d.setDate(d.getDate() + 1) + lastDateEnd = formatDate(d) + } + return lastDate <= date && date <= lastDateEnd } - schedule.before(eventData.endTime).time() - _setUpSchedule(eventData, schedule) - return schedule } -function getStartTimes (eventData) { - const schedule = later.parse.recur() - schedule.on(eventData.startTime).time() - _setUpSchedule(eventData, schedule) - return schedule +function isActive (event) { + if (event.repetitive) { + const schedule = new Schedule(event) + return schedule.isActive(new Date()) + } else { + const now = formatDate(new Date()) + return event.start <= now && now <= event.end + } } -function _setUpSchedule (eventData, schedule) { - schedule.on(eventData.monthMap.reduce((arr, v, i) => { if (v) arr.push(i + 1); return arr }, [])).month() - schedule.on(eventData.dayMap.reduce((arr, v, i) => { if (v) arr.push(((i + 1) % 7) + 1); return arr }, [])).dayOfWeek() - schedule.every(parseInt(eventData.interval)) - const type = eventData.intervalType - if (type === 'month') schedule.month() - else if (type === 'week') schedule.weekOfYear() - else schedule.dayOfYear() +function formatDate (date) { + if (typeof date === 'string') return date + let result = '' + result += date.getFullYear() + '-' + _pad(date.getMonth() + 1) + '-' + _pad(date.getDate()) + result += ' ' + _pad(date.getHours()) + ':' + _pad(date.getMinutes()) + return result } -module.exports = { isActive, getTimeSpans, getStartTimes } +module.exports = { Schedule, isActive, formatDate } diff --git a/server/package-lock.json b/server/package-lock.json index bd8def2..e49c85a 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -2574,6 +2574,12 @@ "es5-ext": "~0.10.2" } }, + "luxon": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.12.1.tgz", + "integrity": "sha512-Zv/qJb2X1ESTrlniAViWx2aqGwi2cVpeoZFTbPdPiCu4EsadKsmb/QCH8HQjMUpDZKKJIHKHsJxV5Rwpq47HKQ==", + "optional": true + }, "md5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", @@ -3553,6 +3559,14 @@ "glob": "^7.0.5" } }, + "rrule": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.0.tgz", + "integrity": "sha512-TRigkTJtG7Y1yOjNSKvFvVmvj/PzRZLR8lLcPW9GASOlaoqoL1J0kNuUV9I3LuZc7qFT+QB2NbxSLL9d33/ylg==", + "requires": { + "luxon": "^1.3.3" + } + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", diff --git a/server/package.json b/server/package.json index 817149a..d91a6b3 100644 --- a/server/package.json +++ b/server/package.json @@ -23,6 +23,7 @@ "mysql2": "^1.6.5", "node-wol": "^0.1.1", "nodemailer": "^4.7.0", + "rrule": "^2.6.0", "safe-timers": "^1.1.0", "secure-password": "^3.1.0", "sequelize": "^4.43.0", -- cgit v1.2.3-55-g7522