diff --git a/controllers/total/calendar.js b/controllers/total/calendar.js new file mode 100644 index 0000000..8112aea --- /dev/null +++ b/controllers/total/calendar.js @@ -0,0 +1,240 @@ +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() { + console.log(this.type); + 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; diff --git a/controllers/total/templates/total.html b/controllers/total/templates/total.html new file mode 100644 index 0000000..6611685 --- /dev/null +++ b/controllers/total/templates/total.html @@ -0,0 +1,23 @@ +{% extends "pyade/base.html" %} +{% block content %} +
Course name | +Count in hours | +
---|---|
{{ key }} | +{{ value }} | +
Total | +{{ total }} | +