Initial commit

This commit is contained in:
Thomas Forgione 2017-09-23 09:02:29 +00:00
commit d048eccbea
No known key found for this signature in database
GPG Key ID: 95D964F74A96119E
26 changed files with 14072 additions and 0 deletions

36
.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
# package-lock : this file should be committed, but I don't really like it
# so unless someone disagrees and explains why, I'll leave this here
package-lock.json
# Don't version private files
config/private.js

View File

@ -0,0 +1,5 @@
const url = require('create-url').url;
module.exports = [
url('/', 'index', 'index'),
]

View File

@ -0,0 +1,3 @@
module.exports.index = function(req, res, render) {
res.send('Hello');
}

73
index.js Normal file
View File

@ -0,0 +1,73 @@
const config = require('./settings/config.js');
require('app-module-path').addPath(config.BASE_DIR);
require('app-module-path').addPath(config.UTILS_DIR);
const express = require('express');
const pug = require('pug');
const http = require('http');
const path = require('path');
const log = require('log');
function main() {
let app = express();
let http = require('http').Server(app);
let bodyParser = require('body-parser');
let session = require('cookie-session');
let cookieParser = require('cookie-parser');
app.set('view engine', 'pug');
app.set('trust proxy', 1);
app.use(cookieParser(config.SECRET_KEY));
app.use(session({keys:[config.SECRET_KEY]}));
// Log request and time to answer
app.use(function(req, res, next) {
let start = Date.now();
res.on('finish', function() {
log.request(req, res, Date.now() - start);
});
res.locals.session = req.session;
next();
});
// Give app access to all urls
app.use(require('create-url'));
// Load controllers
require('controllers')(app);
// Static files
app.use('/static', express.static(config.STATIC_DIR));
// When route not found, raise not found
app.use(function(req, res) {
res.setHeader('Content-Type', 'text/html');
res.render('404.pug', res.locals, function(err, result) {
if (err)
console.log(err);
res.send(result);
});
});
http.listen(config.PORT, config.LISTEN_ADDRESS, function() {
log.ready(
'Now listening ' + config.LISTEN_ADDRESS +
':' + config.PORT
);
});
// On sigint, stop the server
process.on('SIGINT', function() {
process.stdout.write('\r');
log.debug('Stopping server...');
process.exit(0);
});
}
if (require.main === module) {
main();
}

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "adejs",
"version": "0.0.1",
"description": "Simple access to N7's ADE",
"main": "src/index.js",
"repository": {
"type": "git",
"url": "https://gitea.tforgione.fr/tforgione/adejs"
},
"keywords": [
"ADE",
"calendar"
],
"author": "Thomas Forgione",
"license": "MIT",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"cookie-session": "^1.3.1",
"express": "^4.15.4",
"pg": "^7.3.0",
"pug": "^2.0.0-rc.4",
"xmlhttprequest": "^1.8.0"
}
}

19
settings/config.js Normal file
View File

@ -0,0 +1,19 @@
const join = require('path').join;
module.exports.BASE_DIR = join(__dirname, '..');
module.exports.UTILS_DIR = join(module.exports.BASE_DIR, 'utils');
module.exports.STATIC_DIR = join(module.exports.BASE_DIR, 'static');
module.exports.DEBUG = true;
module.exports.LISTEN_ADDRESS = '0.0.0.0';
module.exports.PORT = 4000;
module.exports.ADE_BASE_URL =
"https://edt.inp-toulouse.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?"
const privateConf = require('./private.js');
for (let key in privateConf) {
module.exports[key] = privateConf[key];
}

3
settings/private.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
'SECRET_KEY': 'gi+u6x&1%*wa8e$)ngeg4v3_h044owr%i8-pao+z(_4-_if%7b'
};

1353
static/bootstrap/css/bootstrap-grid.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,330 @@
html {
box-sizing: border-box;
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
@-ms-viewport {
width: device-width;
}
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
color: #212529;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: none !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: .5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: bold;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
a,
area,
button,
[role="button"],
input,
label,
select,
summary,
textarea {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #868e96;
text-align: left;
caption-side: bottom;
}
th {
text-align: left;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
html{box-sizing:border-box;font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}*,::after,::before{box-sizing:inherit}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

8185
static/bootstrap/css/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3831
static/bootstrap/js/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

6
static/bootstrap/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4
static/bootstrap/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

5
static/bootstrap/js/popper.min.js vendored Normal file

File diff suppressed because one or more lines are too long

51
utils/controllers.js Normal file
View File

@ -0,0 +1,51 @@
var express = require('express');
var fs = require('fs');
var log = require('log');
module.exports = function(app) {
log.debug("Loading controllers :");
fs.readdirSync(__dirname + '/../controllers').forEach(function(name) {
// views.js in controller, with function as pages (views.py for django)
var obj = require('./../controllers/' + name + '/views');
// urls.js, just like django urls.py
var urls = require('./../controllers/' + name + '/urls');
name = obj.name || name;
// allow specifying the view engine
if (obj.engine) app.set('view engine', obj.engine);
log.debug(' ' + name + ':');
for (let url of urls) {
app.get(url.url, ((url) => function(req, res, next) {
var path = obj[url.view](req, res, function(view) {
let viewPath = __dirname + '/../controllers/' + name + '/views/' + view;
res.render(viewPath, res.locals, function(err, out) {
if (err !== null) {
log.pugerror(err);
}
res.send(out);
});
}, next);
})(url));
log.debug(' ' + url.url + ' -> ' + name + '.' + url.view);
}
log.debug();
// mount the app
// parent.use(app);
});
}

18
utils/create-url.js Normal file
View File

@ -0,0 +1,18 @@
let urls = {};
module.exports = function(req, res, next) {
res.locals.urls = urls;
return next();
}
module.exports.url = function(url, viewName, urlName) {
let ret = {
url: url,
view: viewName,
name: urlName,
};
urls[urlName] = ret;
return ret;
}

107
utils/log.js Normal file
View File

@ -0,0 +1,107 @@
var express = require('express');
var http = require('http');
var log = {};
log.Color = {
DEFAULT: 0,
BLACK : 1,
RED : 2,
GREEN : 3,
YELLOW : 4,
BLUE : 5,
MAGENTA: 6,
CYAN : 7,
ORANGE : 8,
};
log.getColorCode = function(c) {
switch (c) {
case log.Color.DEFAULT: return '\u001b[0m';
case log.Color.BLACK: return '\u001b[30m';
case log.Color.RED: return '\u001b[31m';
case log.Color.GREEN: return '\u001b[32m';
case log.Color.YELLOW: return '\u001b[33m';
case log.Color.BLUE: return '\u001b[34m';
case log.Color.MAGENTA: return '\u001b[35m';
case log.Color.CYAN: return '\u001b[36m';
case log.Color.ORANGE: return '\u001b[38;5;202m';
}
}
log.write = function(elt, color) {
console.log(log.getColorCode(color) + elt + log.getColorCode(log.Color.DEFAULT));
}
log.ready = function(msg) {
log.write('[RDY] ' + new Date() + ' ' + msg, log.Color.GREEN);
}
log.request = function(req, res, time) {
var isStatic = req.url.substr(0, 7) === '/static' || req.url === '/favicon.ico';
let mess = '[REQ] ' + new Date() + ' ';
mess += (req.headers['x-forwarded-for'] || req.connection.remoteAddress);
if (time !== undefined) {
mess += ' in ' + (" " + time).slice(-6) + ' ms';
}
mess += ': ';
if (isStatic && req.url === '/favicon.ico') {
mess += '/static';
}
mess += req.url;
log.write(mess, isStatic ? log.Color.YELLOW : log.Color.CYAN);
}
log.socket = {};
log.socket.connect = function(socket) {
let mess = '[SOK] ' + new Date() + ' ';
mess += (req.headers['x-forwarded-for'] || req.connection.remoteAddress);
mess += ' disconnect';
log.write(mess, log.Color.MAGENTA);
}
log.socket.disconnect = function(socket) {
let mess = '[SOK] ' + new Date() + ' ';
mess += (req.headers['x-forwarded-for'] || req.connection.remoteAddress);
mess += ' connect';
log.write(mess, log.Color.MAGENTA);
}
log.dberror = function(error) {
log.write('[DBE] ' + new Date() + ' ' + error, log.Color.RED);
}
log.prefetcherror = function(error) {
log.write('[PFE] ' + new Date() + ' ' + error, log.Color.RED);
}
log.mailerror = function(error) {
log.write('[MLE] ' + new Date() + ' ' + error, log.Color.RED);
}
log.debug = function(info) {
log.write('[DBG] ' + (info !== undefined ? info : ''), log.Color.YELLOW);
}
log.pugerror = function(error) {
log.write('[PER] ' + new Date() + ' ' + error, log.Color.RED);
}
log.warning = function(message) {
log.write('[WRN] ' + new Date() + ' ' + message, log.Color.ORANGE);
}
module.exports = log;