silvrgit/lib/today/calHandler.js
2016-05-09 11:14:19 +01:00

490 lines
15 KiB
JavaScript

var request = require('request');
var log4js = require('log4js');
var logger = log4js.getLogger();
var STRING = require('string');
var util = require('util');
var Elapsed = require('elapsed');
require('sugar-date');
function processICAL(ical) {
'use strict';
logger.info('+ processICAL');
var workingBlock = [];
var segments = {
meetingStartID: 'DTSTART;TZID=Europe/London:',
meetingStartAlt: 'DTSTART:',
meetingStartAltOther: 'DTSTART;VALUE=DATE:',
meetingEndID: 'DTEND;TZID=Europe/London:',
meetingEndAlt: 'DTEND:',
meetingEndAltOther: 'DTEND;VALUE=DATE:',
meetingDescID: 'DESCRIPTION:',
summaryID: 'SUMMARY:',
begin: 'BEGIN:VEVENT',
end: 'END:VEVENT',
beginAlarm: 'BEGIN:VALARM',
endAlarm: 'END:VALARM',
recur: 'RRULE:'
};
var rules = ['FREQ','WKST','UNTIL','BYMONTH','BYMONTHDAY','INTERVAL','BYDAY'];
function nThDayOfMonth(monthsAhead, wantedDay) {
var now = new Date();
for(var t=0; t < monthsAhead; t++) {
}
}
function processRecurrence(workBlock) {
var _workBlock = workBlock;
// logger.debug('Processing recurrence...');
// logger.debug('Processing recurrence...');
var weekBits = {'SU':0,'MO':1,'TU':2,'WE':3,'TH':4,'FR':5,'SA':6};
var blocks=[];
var now = new Date();
var day = now.getDate();
var dayNum = now.getDay();
var month = now.getMonth();
var year = now.getFullYear();
var recurSettings = {freq:null, wkst:null, until:null, bymonth:null, bymonthday:null, interval:null, byday:null};
var firstSplit = _workBlock.recur.split(';');
for (var t=0; t< firstSplit.length;t++)
{
var ws = firstSplit[t].split('=');
if (rules.indexOf(ws[0]) > -1) {
recurSettings[ws[0].toLowerCase()] = ws[1];
}
}
// if all null discard..
if (recurSettings.freq === null && recurSettings.wkst === null && recurSettings.until === null && recurSettings.byday === null && recurSettings.bymonth === null && recurSettings.bymonthday === null && recurSettings.interval === null) {
return null;
}
if (recurSettings.until !== null) {
// have we expired?
//var _until = Date.create(recurSettings.until).isPast();
return null;
}
if (recurSettings.freq !== null) {
// logger.debug(_workBlock);
var origStart, origEnd, distance, newStart, newEnd;
origStart = Date.create(_workBlock.dtstart);
origEnd = Date.create(_workBlock.dtend);
var _d = origStart.getDate();
var _m = origStart.getMonth();
var _h = origStart.getHours();
var _min = origStart.getMinutes();
var _secs = origStart.getSeconds();
distance = origEnd - origStart;
if (recurSettings.freq === 'YEARLY') {
if (recurSettings.bymonth !== null && recurSettings.bymonthday !== null) {
// ok, a day and month.
newStart = Date.create().set({year:year, month: recurSettings.bymonth - 1 , day: recurSettings.bymonthday, hour:_h, minutes:_min, seconds:_secs});
newEnd = Date.create(newStart).addMilliseconds(distance);
_workBlock.dtstart = newStart;
_workBlock.dtend = newEnd;
} else if (recurSettings.bymonth === null && recurSettings.bymonthday === null) {
// extract month and year from dtstart
newStart = Date.create().set({year:year, month: _m , day: _d, hour:_h, minutes:_min, seconds:_secs});
newEnd = Date.create(newStart).addMilliseconds(distance);
_workBlock.dtstart = newStart;
_workBlock.dtend = newEnd;
}
return _workBlock;
}
if (recurSettings.freq === 'MONTHLY') {
if (recurSettings.bymonthday !== null) {
// ok, a day and month.
newStart = Date.create().set({year:year, month: month , day: recurSettings.bymonthday, hour:_h, minutes:_min, seconds:_secs});
newEnd = Date.create(newStart).addMilliseconds(distance);
_workBlock.dtstart = newStart;
_workBlock.dtend = newEnd;
}
}
if (recurSettings.freq === 'WEEKLY' && recurSettings.interval === null) {
var byDayBit = recurSettings.byday.split(',')[0];
var byDayNumber = weekBits[byDayBit];
if (byDayNumber >= dayNum) {
var daysAdded = byDayNumber - dayNum;
newStart = Date.create().set({year:year, month: month , day: day, hour:_h, minutes:_min, seconds:_secs}).addDays(daysAdded);
newEnd = Date.create(newStart).addMilliseconds(distance);
_workBlock.dtstart = newStart;
_workBlock.dtend = newEnd;
}
}
}
// if we get here we've skipped everything just return the _workblock
return _workBlock;
}
function processBlock(block) {
var _wb;
var workBlock = {
summary: '',
dtstart: null,
dtend: null,
description: '',
timeStart: null,
timeEnd: null,
duration: 0,
combined: '',
recur: null
};
var alarmFlag = false, ws, blockStep;
for (var step = 0; step < block.length; step++) {
blockStep = block[step];
if (blockStep.indexOf(segments.recur) >= 0) {
workBlock.recur = STRING(block[step].split(segments.recur)[1]).collapseWhitespace().s;
//logger.debug(workBlock.recur);
}
if (blockStep.indexOf(segments.summaryID) >= 0) {
workBlock.summary = STRING(block[step].split(segments.summaryID)[1]).collapseWhitespace().s;
}
if (blockStep.indexOf(segments.meetingStartID) >= 0) {
ws = STRING(block[step].split(segments.meetingStartID)[1]).collapseWhitespace().s;
workBlock.dtstart = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingEndID) >= 0) {
ws = STRING(block[step].split(segments.meetingEndID)[1]).collapseWhitespace().s;
workBlock.dtend = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingStartAlt) >= 0) {
ws = STRING(block[step].split(segments.meetingStartAlt)[1]).collapseWhitespace().s;
workBlock.dtstart = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingEndAlt) >= 0) {
ws = STRING(block[step].split(segments.meetingEndAlt)[1]).collapseWhitespace().s;
workBlock.dtend = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingStartAltOther) >= 0) {
ws = STRING(block[step].split(segments.meetingStartAltOther)[1]).collapseWhitespace().s;
workBlock.dtstart = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingEndAltOther) >= 0) {
ws = STRING(block[step].split(segments.meetingEndAltOther)[1]).collapseWhitespace().s;
workBlock.dtend = Date.create(ws);
}
if (blockStep.indexOf(segments.meetingDescID) >= 0) {
if (!alarmFlag) {
workBlock.description = STRING(block[step].split(segments.meetingDescID)[1]).collapseWhitespace().s;
}
}
if (blockStep.indexOf(segments.beginAlarm) >= 0) {
alarmFlag = true;
}
}
// We have to check recuring stuff before the cron stuff is processed.
if (workBlock.recur !== null) {
_wb = processRecurrence(workBlock);
// logger.warn('returning:', _wb);
if (_wb !== null) {
if (!Array.isArray(_wb)) {
workBlock = _wb;
} else {
logger.error('We made an array');
}
}
}
//logger.debug(workBlock);
if (workBlock.dtstart !== null) {
workBlock.timeStart = workBlock.dtstart.format('{24hr}:{mm}:{ss}');
workBlock.combined = '<em>' + workBlock.timeStart + '</em> - ';
workBlock.long = '<em>' + workBlock.dtstart.format('{Weekday}') +', ' + workBlock.timeStart + '</em> - ';
}
workBlock.combined = workBlock.combined + workBlock.summary;
workBlock.longcombined = workBlock.long + workBlock.summary;
if (workBlock.dtend !== null) {
workBlock.timeEnd = workBlock.dtend.format('{24hr}:{mm}:{ss}');
}
if (workBlock.dtstart !== null && workBlock.dtend !== null) {
var elapsedTime = new Elapsed(workBlock.dtstart, workBlock.dtend);
workBlock.duration = elapsedTime.optimal;
workBlock.combined = workBlock.combined + ', ' + elapsedTime.optimal;
workBlock.longcombined = workBlock.longcombined + ', ' + elapsedTime.optimal;
}
return workBlock;
}
var lines = ical.split('\r\n'), l = lines.length, counter = 0;
var alarmed = false;
while (counter < l) {
if (lines[counter].indexOf(segments.begin) < 0) {
counter++;
} else {
var subcounter = 0, subBlock = [];
alarmed = false;
while (subcounter < 75) {
if (lines[counter + subcounter].indexOf(segments.end) < 0) {
if (lines[counter + subcounter].indexOf(segments.beginAlarm) > -1) {
alarmed = true;
}
if (!alarmed) {
subBlock.push(lines[counter + subcounter]);
}
if (lines[counter + subcounter].indexOf(segments.endAlarm) > -1) {
alarmed = false;
}
subcounter++;
} else {
break;
}
}
counter = counter + subcounter;
var b = processBlock(subBlock);
if (Array.isArray(b)) {
logger.error('!returned an array...');
} else {
if (b.dtstart !== null) {
workingBlock.push(b);
}
}
}
}
logger.info('- processICAL');
// If (workingBlock.dtstart == null) return {};
return workingBlock;
}
module.exports = {
calendars: ['https://calendar.google.com/calendar/ical/martind2000%40gmail.com/private-40cfebc9f7dcfa7fde6b9bf2f0092c93/basic.ics',
'https://calendar.google.com/calendar/ical/mt5pgdhknvgoc8usfnrso9vkv0%40group.calendar.google.com/private-58876002af9f302a593acfa6fa792dcf/basic.ics',
'https://www.tripit.com/feed/ical/private/DB96E4BB-94A9BD8F9CC1CF51C6CC0D920840F4F5/tripit.ics',
'https://calendar.google.com/calendar/ical/en.uk%23holiday%40group.v.calendar.google.com/public/basic.ics',
'https://calendar.google.com/calendar/ical/i8dglj12p5nuv20sbjmun5s588%40group.calendar.google.com/private-c8adccb41e56d6a2f285078aaed313f5/basic.ics'],
jsonBlock: [],
getTodaysSimple: function() {
'use strict';
logger.info('+ getTodaysSimple');
var today = {
entries: []
};
for (var t = 0; t < this.jsonBlock.length; t++) {
if (this.jsonBlock[t].dtstart.isToday()) {
today.entries.push(this.jsonBlock[t]);
}
}
logger.info('- getTodaysSimple');
return today;
},
getTomorrow: function() {
'use strict';
logger.info('+ getTomorrow');
var today = {
entries: []
};
for (var t = 0; t < this.jsonBlock.length; t++) {
if (this.jsonBlock[t].dtstart.isTomorrow()) {
today.entries.push(this.jsonBlock[t]);
}
}
logger.info('- getTomorrow');
return today;
},
getWeek: function() {
'use strict';
logger.info('+ getWeek');
var today = {
entries: []
};
var now, twoDays, sevenDays;
now = Date.create('today');
// logger.debug(now);
twoDays = Date.create(now).addDays(2).beginningOfDay();
// logger.debug(twoDays);
sevenDays = Date.create(twoDays).addDays(5).beginningOfDay();
// logger.debug(now, twoDays, sevenDays);
for (var t = 0; t < this.jsonBlock.length; t++) {
if (this.jsonBlock[t].dtstart.isBetween(twoDays, sevenDays)) {
today.entries.push(this.jsonBlock[t]);
}
}
logger.info('- getWeek');
return today;
},
getTodaysMeetings: function() {
'use strict';
logger.info('+ getTodaysMeetings');
var today = {
previous: [], upcoming: [], current: {}
};
var now = new Date();
for (var t = 0; t < this.jsonBlock.length; t++) {
if (this.jsonBlock[t].dtstart.isToday()) {
if (this.jsonBlock[t].dtstart.isAfter(now)) {
today.upcoming.push(this.jsonBlock[t]);
} else {
today.previous.push(this.jsonBlock[t]);
}
if (now.isBetween(this.jsonBlock[t].dtstart, this.jsonBlock[t].dtend)) {
today.current = this.jsonBlock[t];
}
}
}
// logger.debug(today);
logger.info('- getTodaysMeetings');
return today;
}, getSimpleCalV2: function(url, cb) {
'use strict';
var self = this;
// Var calJson = [];
try {
request(url, function(err, res, body) {
if (err) {
logger.error('Get remote Calendar Request failed');
// Callback.call(null, new Error('Request failed'));
return;
}
self.jsonBlock = processICAL(body);
// logger.debug(self.jsonBlock);
var st = self.getTodaysSimple();
if (typeof cb === 'function') {
cb(st);
}
}, function(error, response, body) {
if (response.statusCode !== 200) {
logger.error(response.statusCode);
logger.error(body);
}
});
} catch (e) {
console.log(e);
}
}, getSimpleCalV3: function(url) {
'use strict';
var self = this;
return new Promise(function(resolve, reject) {
try {
request(url, function(err, res, body) {
if (err) {
// logger.error(err);
return reject(err);
// Throw err;
}
self.jsonBlock = processICAL(body);
// logger.debug(self.jsonBlock);
var st = self.getTodaysSimple();
return resolve(st);
}, function(error, response, body) {
if (response.statusCode !== 200) {
logger.error(response.statusCode);
logger.error(body);
return reject(error);
}
});
} catch (e) {
console.log(e);
return reject(e);
}
});
// Var calJson = [];
}, getAdvancedCalV3: function(url) {
'use strict';
var self = this;
return new Promise(function(resolve, reject) {
try {
request(url, function(err, res, body) {
if (err) {
// logger.error(err);
return reject(err);
// Throw err;
}
self.jsonBlock = processICAL(body);
// logger.debug(self.jsonBlock);
var st = self.getTodaysSimple().entries;
var tom = self.getTomorrow().entries;
var week = self.getWeek().entries;
var obj = {today:st, tomorrow:tom, week:week};
logger.debug(obj);
return resolve(obj);
}, function(error, response, body) {
if (response.statusCode !== 200) {
logger.error(response.statusCode);
logger.error(body);
return reject(error);
}
});
} catch (e) {
console.log(e);
return reject(e);
}
});
// Var calJson = [];
}
/**
* Created by Martin on 16/02/2016.
*/
};