Select Git revision
index.js 5.14 KiB
var express = require('express');
var axios = require('axios');
var querystring = require('querystring');
var NodeCache = require('node-cache');
var router = express.Router();
var myCache = new NodeCache( { stdTTL: 600, checkperiod: 600, deleteOnExpire: false} );
// When expired, ttl is set to 0 (which means expired in my case)
myCache.on("expired", function (key, value) {
myCache.set(key, value, 0);
})
// Secrets
const [client_id, client_secret, username, password] = require('../secrets.js');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
async function get_token() {
console.log("Fetching OAuth for token...");
let key = "__express__token";
let ttl = myCache.getTtl(key);
if (ttl > 0) {
console.log("Fetched from cache");
return myCache.get(key);
}
const scope = "default linkcs-user:read";
const request = await axios({
method: 'post',
url: 'https://auth.viarezo.fr/oauth/token',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
},
data: querystring.stringify({
'grant_type': 'password',
'client_id': client_id,
'client_secret': client_secret,
'scope': scope,
'username': username,
'password': password,
})
})
const token = request.data.access_token;
console.log(token);
myCache.set(key, token)
return token;
}
async function request_promotion(token, promotion, offset) {
// Checks if cached request
console.log("Fetching LinkCS for promotion = " + promotion + " and offset = " + offset);
let key = '__express__data_' + promotion + '_' + offset;
let ttl = myCache.getTtl(key);
if (ttl > 0) {
console.log("Fetched from cache");
return {users:myCache.get(key), changed: false};
} else {
const url = "https://gateway.linkcs.fr/v1/graphql"
const headers = {Authorization: "Bearer " + token}
const query = '{getPromotion(promotion: ' + promotion + ', limit: 60, offset: ' + offset + ') {login, memberships {association {id, name, type}}}}';
const request = await axios({
url: url + "?query=" + query,
headers: headers
});
const users = request.data.data.getPromotion;
if (ttl === 0) {
old_users = myCache.get(key);
if (old_users === users) {
myCache.ttl(key);
return {users: users, changed: false};
}
}
myCache.set(key, users);
console.log("Fetched from API")
return {users: users, changed: true};
}
}
async function fetch_data(promotion) {
const token = await get_token()
let offset = 0;
let result = await request_promotion(token, promotion, offset);
let total_users = [].concat(result.users);
let changed = result.changed;
while (result.users.length === 60) {
offset += 60;
result = await request_promotion(token, promotion, offset);
changed = changed || result.changed;
total_users = total_users.concat(result.users);
}
return {users: total_users, changed: changed};
}
function create_graph(users) {
let all_nodes = [];
let all_edges = [];
for (let u = 0; u < users.length; u++) {
let user = users[u];
for (let a1 = 0; a1 < user.memberships.length; a1++) {
let asso1 = user.memberships[a1].association;
let id1 = asso1.id;
// Checks if real asso
if(asso1.type === "GROUPE") {
continue;
}
// Increments the value of the node
let node_found = false;
for (let n = 0; n < all_nodes.length; n++) {
if (!node_found && all_nodes[n].id === id1) {
node_found = true;
all_nodes[n].value++;
}
}
if (!node_found) {
all_nodes.push({
id: id1,
value: 1,
label: asso1.name
})
}
for (let a2 = 0; a2 < user.memberships.length; a2++) {
let asso2 = user.memberships[a2].association;
let id2 = asso2.id;
// Checks if edge possible
if (id1 >= id2 || asso2.type === "GROUPE") {
continue;
}
// Finds and increments the node
let edge_found = false
for (let e = 0; e < all_edges.length; e++) {
if (!edge_found && all_edges[e].from === id1 && all_edges[e].to === id2) {
edge_found = true;
all_edges[e].value += 1;
}
}
if (!edge_found) {
all_edges.push({
from: id1,
to: id2,
value: 1
})
}
}
}
}
return [all_nodes, all_edges]
}
/* GET the fetched data. */
router.post('/', function(req, res, next) {
const promotion = req.body.promotion || 2021;
fetch_data(promotion)
.then(result => {
let key = "__express__graph_" + promotion;
let cached_graph = myCache.get(key);
let all_edges;
let all_nodes;
if (result.changed || myCache.get(key) === undefined) {
const graph = create_graph(result.users);
myCache.set(key, graph, 0);
[all_nodes, all_edges] = graph;
} else {
[all_nodes, all_edges] = myCache.get(key);
}
res.send({all_edges: all_edges, all_nodes: all_nodes});
res.end();
})
.catch(e => {
console.log(e);
res.status(500);
res.end();
})
})
module.exports = router;