adejs/utils/calendar.js

245 lines
6.3 KiB
JavaScript

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 = {
TD: 1,
TP: 2,
CTD: 3,
CM: 4,
Other: 5,
}
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:
case cal.Type.TD:
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("TD") !== -1) {
this.type = cal.Type.TD;
} 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('<html>') === -1) {
this.setFromContent(xhr.responseText);
callback(this);
}
}
};
xhr.send();
if (xhr.responseText.indexOf('<html>') === -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;