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) - 1, 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 = { CM: 1, CTD: 2, TD: 3, TP: 4, Other: { BE: 5, Examen: 6, Projet: 7, APP: 8, }, Unknown: 9, } cal.getTypeName = function(type) { switch (type) { case cal.Type.TD: return "TD"; case cal.Type.TP: return "TP"; case cal.Type.CTD: return "CTD"; case cal.Type.CM: return "CM"; case cal.Type.Other.BE: case cal.Type.Other.Projet: case cal.Type.Other.Examen: case cal.Type.Other.APP: return "Other"; default: return "Unknown"; } } cal.getFactor = function(type) { switch (type) { case cal.Type.TD: case cal.Type.TP: case cal.Type.Other.BE: return 1; case cal.Type.Other.Projet: return 1; case cal.Type.Other.Examen: return 0; case cal.Type.Other.APP: return 1.5; case cal.Type.CTD: return 1.25; case cal.Type.CM: return 1.5; default: return 0; } } cal.getTypeFromName = function(name) { if (name.indexOf("CTD") !== -1) { return cal.Type.CTD; } else if (name.indexOf("TP") !== -1) { return cal.Type.TP; } else if (name.indexOf("TD") !== -1) { return cal.Type.TD; } else if (name.indexOf("CM") !== -1) { return cal.Type.CM; } else if (name.indexOf("BE") !== -1) { return cal.Type.Other.BE; } else if (name.toLowerCase().indexOf("exam") !== -1) { return cal.Type.Other.Examen; } else if (name.toLowerCase().indexOf("projet") !== -1) { return cal.Type.Other.Projet; } else if (name.indexOf("APP ") !== -1) { return cal.Type.Other.APP; } else { return cal.Type.Unkown; } } cal.Event = class { constructor(content, firstLineIndex = 0) { this.startTime = undefined; this.finishTime = undefined; this.name = undefined; this.location = undefined; this.type = cal.Type.Unkown; if (content !== undefined) this.setFromContent(content, firstLineIndex); } guessTypeFromName() { this.type = cal.getTypeFromName(this.name); } 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(2000, 8, 1); let lastDate = new Date(3000, 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); }); } cal.getTotalByCourse = function(user, callback) { let firstDate = new Date(2000, 8, 1); let lastDate = new Date(3000, 8, 1); cal.getCalendar(user, firstDate, lastDate, (calendar) => { let res = {}; for (let event of calendar.events) { // Guess name of event, last element of split('-'); let split = event.name.split(' -').map(x => x.trim()); let name = split[split.length - 1]; if (res[name] === undefined) { res[name] = {} for (let type in cal.Type) { res[name][type] = 0; } res[name].totalTdEquivalent = 0; } let type = event.type; let typeName; if (type in cal.Type.Other) { typeName = "Other"; } else { typeName = cal.getTypeName(type); } res[name][typeName]++; res[name].totalTdEquivalent += event.getTdEquivalent(); } callback(res); }); } module.exports = cal;