Nice formatting
This commit is contained in:
parent
dae9643cd0
commit
042ac0f9d3
|
@ -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('<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;
|
|
@ -0,0 +1,23 @@
|
|||
{% extends "pyade/base.html" %}
|
||||
{% block content %}
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Course name</th>
|
||||
<th>Count in hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in total_by_course.items %}
|
||||
<tr>
|
||||
<td>{{ key }}</td>
|
||||
<td>{{ value }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="table-active">
|
||||
<td><strong>Total</strong></td>
|
||||
<td><strong>{{ total }}</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -0,0 +1,26 @@
|
|||
extends ../../../templates/base.pug
|
||||
|
||||
block content
|
||||
table.table.table-bordered.table-striped.table-hover
|
||||
thead
|
||||
tr
|
||||
th Course name
|
||||
th Detected type
|
||||
th Count in hours
|
||||
th Count in TD equivalent
|
||||
tbody
|
||||
each course in courses
|
||||
tr
|
||||
td #{course.name}
|
||||
td #{course.type}
|
||||
td #{course.time}
|
||||
td #{course.tdEquivalent}
|
||||
tr
|
||||
td
|
||||
strong #{total.name}
|
||||
td
|
||||
strong #{total.type}
|
||||
td
|
||||
strong #{total.time}
|
||||
td
|
||||
strong #{total.tdEquivalent}
|
|
@ -0,0 +1,5 @@
|
|||
const url = require('create-url').url;
|
||||
|
||||
module.exports = [
|
||||
url('/total', 'total', 'total'),
|
||||
]
|
|
@ -0,0 +1,31 @@
|
|||
const cal = require('./calendar');
|
||||
|
||||
module.exports.total = function(req, res, render) {
|
||||
cal.getTotal(req.session.user, (table) => {
|
||||
let courses = [];
|
||||
let total = {
|
||||
name: "Total",
|
||||
type: "Total",
|
||||
time: 0,
|
||||
tdEquivalent: 0,
|
||||
}
|
||||
|
||||
for (let key in table) {
|
||||
courses.push({
|
||||
name: key,
|
||||
type: table[key].type,
|
||||
time: table[key].time,
|
||||
tdEquivalent: table[key].tdEquivalent,
|
||||
});
|
||||
|
||||
total.time += table[key].time;
|
||||
total.tdEquivalent += table[key].tdEquivalent;
|
||||
}
|
||||
|
||||
res.locals.courses = courses;
|
||||
res.locals.total = total;
|
||||
|
||||
|
||||
render('total.pug');
|
||||
});
|
||||
}
|
2
index.js
2
index.js
|
@ -9,6 +9,7 @@ const http = require('http');
|
|||
const path = require('path');
|
||||
const log = require('log');
|
||||
const model = require('model');
|
||||
const repl = require('repl');
|
||||
|
||||
// Load models
|
||||
model.load(config.CONTROLLERS_DIR);
|
||||
|
@ -79,6 +80,7 @@ function startServer() {
|
|||
const commands = {
|
||||
runserver: startServer,
|
||||
reinitdb: model.reinitialize,
|
||||
shell: repl.start,
|
||||
}
|
||||
|
||||
function showHelp() {
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
"cookie-session": "^1.3.1",
|
||||
"emailjs": "^1.0.12",
|
||||
"express": "^4.15.4",
|
||||
"moment": "^2.18.1",
|
||||
"os-locale": "^2.1.0",
|
||||
"pg": "^7.3.0",
|
||||
"pug": "^2.0.0-rc.4",
|
||||
"xmlhttprequest": "^1.8.0"
|
||||
|
|
|
@ -23,7 +23,7 @@ html
|
|||
ul.navbar-nav
|
||||
if session.user !== undefined
|
||||
li.nav-item
|
||||
a.nav-link(href='#') Total
|
||||
a.nav-link(href=getUrl("total")) Total
|
||||
ul.navbar-nav.ml-auto
|
||||
if session.user === undefined
|
||||
li.nav-item
|
||||
|
|
Loading…
Reference in New Issue