Skip to content
Snippets Groups Projects
Select Git revision
  • 8ed21d95421a93733e6b993dcd2276909eeb0066
  • master default
  • watch-plugin
3 results

vcs_utils.zsh

Blame
  • 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;