var crypto = require('crypto'); var fs = require('fs'); var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; var moment = require('moment'); var locale = require('os-locale').sync(); var cal = {}; function fromIcal(string) { return new Date( parseInt(string.substr(0 , 4), 10), parseInt(string.substr(4 , 2), 10), parseInt(string.substr(6 , 2), 10), parseInt(string.substr(9, 2), 10), parseInt(string.substr(11, 2), 10), parseInt(string.substr(13, 2), 10) ); } cal.Type = { TP: 1, CTD: 2, CM: 3, Other: 4, } cal.getTypeName = function(type) { switch (type) { case cal.Type.TP: return "TP"; case cal.Type.CTD: return "CTD"; case cal.Type.CM: return "CM"; default: return "Other"; } } cal.getFactor = function(type) { switch (type) { case cal.Type.TP: return 1; case cal.Type.CTD: return 1.25; case cal.Type.CM: return 1.5; default: return 0; } } cal.Event = class { constructor(content, firstLineIndex = 0) { this.startTime = undefined; this.finishTime = undefined; this.name = undefined; this.location = undefined; this.type = cal.Type.Other; if (content !== undefined) this.setFromContent(content, firstLineIndex); } guessTypeFromName() { if (this.name.indexOf("CTD") !== -1) { this.type = cal.Type.CTD; } else if (this.name.indexOf("TP") !== -1) { this.type = cal.Type.TP; } else if (this.name.indexOf("CM") !== -1) { this.type = cal.Type.CM; } } getDurationInHours() { return (this.finishTime - this.startTime) / (1000 * 60 * 60); } getTdEquivalent() { return this.getDurationInHours() * cal.getFactor(this.type); } setFromContent(content, firstLineIndex = 0) { let index = firstLineIndex; let lines = content.split('\n').map((a) => a.trim()); for (let line of lines.slice(firstLineIndex)) { let split = line.split(':'); switch (split[0]) { case 'END' : if (split[1] === 'VEVENT') return index; case 'DTSTART' : this.startTime = fromIcal(split[1]); break; case 'DTEND' : this.finishTime = fromIcal(split[1]); break; case 'LOCATION': this.location = split[1].replace('\\',''); break; case 'SUMMARY' : this.name = split[1]; this.guessTypeFromName(); break; } index++ } return index; } }; cal.Calendar = class { constructor(content) { this.events = []; if (content !== undefined) this.setFromContent(content); } setFromContent(content) { let index = 0; let lines = content.split('\n').map((a) => a.trim()); while (index < lines.length) { let split = lines[index].split(':'); if (split[0] === 'BEGIN' && split[1] === 'VEVENT') { let event = new cal.Event(); index = event.setFromContent(content, index); this.events.push(event); } else { index++; } } this.events.sort((a,b) => { if (a.startTime < b.startTime) return -1 else if (a.startTime > b.startTime) return 1 else return 0; }); } setFromUrl(url, callback) { let xhr = new XMLHttpRequest(); xhr.open("get", url, true); xhr.onreadystatechange = (e) => { if (xhr.readyState === 4) { if (xhr.responseText.indexOf('') === -1) { this.setFromContent(xhr.responseText); callback(this); } } }; xhr.send(); if (xhr.responseText.indexOf('') === -1) { this.setFromContent(xhr.responseText); } } }; function dateToString(dt) { return dt.getFullYear() + "-" + (dt.getMonth() + 1) + "-" + dt.getDate(); } cal.getUrlFromUser = function(user, firstDate = new Date(), lastDate = new Date(), calType = "ical") { if (firstDate instanceof Date) { firstDate = dateToString(firstDate); } if (lastDate instanceof Date) { lastDate = dateToString(lastDate); } let baseUrl = "https://edt.inp-toulouse.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?"; let resourcesParam = `resources=${user._resources.value}`; let projectIdParam = `projectId=${user._projectId.value}`; let firstDateParam = `firstDate=${firstDate}`; let lastDateParam = `lastDate=${lastDate}`; let calTypeParam = `calType=${calType}`; let parameters = [resourcesParam, projectIdParam, firstDateParam, lastDateParam, calTypeParam].join("&"); return baseUrl + parameters; }; cal.getCalendar = function(user, firstDate = new Date(), lastDate = new Date(), calType, callback) { if (typeof calType === 'function') { callback = calType; calType = "iCal"; } let calendar = new cal.Calendar(); let url = cal.getUrlFromUser(user, firstDate, lastDate, calType); calendar.setFromUrl(url, cal => { callback(cal); }); }; cal.getTotal = function(user, callback) { let firstDate = new Date(2017, 8, 1); let lastDate = new Date(2018, 8, 1); cal.getCalendar(user, firstDate, lastDate, (calendar) => { let res = {}; for (let event of calendar.events) { let hours = event.getDurationInHours(); let td = event.getTdEquivalent(); if (res[event.name] === undefined) { res[event.name] = { time: 0, tdEquivalent: 0, type: cal.getTypeName(event.type) + ' (x' + cal.getFactor(event.type) + ')', }; } res[event.name].time += hours; res[event.name].tdEquivalent += td; } callback(res); }); } module.exports = cal;