commit
cfe7fb7439
18 changed files with 7265 additions and 411 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,3 +6,5 @@ vendor/
|
|||
.bundle
|
||||
script/dev.config.py
|
||||
script/__pycache__/*.pyc
|
||||
script/common/__pycache__/*.pyc
|
||||
\.vscode/\.ropeproject/
|
|
@ -1,7 +1,10 @@
|
|||
<script>
|
||||
var cy = cytoscape({
|
||||
|
||||
var data = $.getJSON("{{ site.baseurl }}/public/data/channelslist.json");
|
||||
|
||||
var cy = window.cy = cytoscape({
|
||||
container: document.getElementById('cy'),
|
||||
elements: $.getJSON("{{ site.baseurl }}/public/data/channelslist.json"),
|
||||
elements: data,
|
||||
style: [
|
||||
{
|
||||
selector: 'node',
|
||||
|
@ -29,6 +32,10 @@
|
|||
}
|
||||
});
|
||||
|
||||
cy.on('ready', function (e) {
|
||||
cy.$('#mare').lock();
|
||||
});
|
||||
|
||||
cy.on('tap', 'node', function () {
|
||||
try { // your browser may block popups
|
||||
window.open(this.data('href'));
|
||||
|
@ -36,5 +43,55 @@
|
|||
window.location.href = this.data('href');
|
||||
}
|
||||
});
|
||||
|
||||
cy.automove({
|
||||
nodesMatching: function( node ) {
|
||||
return cy.$('#technologie').allAreNeighbors(node);
|
||||
},
|
||||
reposition: 'drag',
|
||||
dragWith: function( node ) {
|
||||
return node.id() == cy.$('#technologie').id();
|
||||
}
|
||||
});
|
||||
|
||||
cy.automove({
|
||||
nodesMatching: function( node ) {
|
||||
return cy.$('#global').allAreNeighbors(node);
|
||||
},
|
||||
reposition: 'drag',
|
||||
dragWith: function( node ) {
|
||||
return node.id() == cy.$('#global').id();
|
||||
}
|
||||
});
|
||||
|
||||
cy.automove({
|
||||
nodesMatching: function( node ) {
|
||||
return cy.$('#ecologie').allAreNeighbors(node);
|
||||
},
|
||||
reposition: 'drag',
|
||||
dragWith: function( node ) {
|
||||
return node.id() == cy.$('#ecologie').id();
|
||||
}
|
||||
});
|
||||
|
||||
cy.automove({
|
||||
nodesMatching: function( node ) {
|
||||
return cy.$('#project').allAreNeighbors(node);
|
||||
},
|
||||
reposition: 'drag',
|
||||
dragWith: function( node ) {
|
||||
return node.id() == cy.$('#project').id();
|
||||
}
|
||||
});
|
||||
|
||||
cy.automove({
|
||||
nodesMatching: function( node ) {
|
||||
return cy.$('#democratie').allAreNeighbors(node);
|
||||
},
|
||||
reposition: 'drag',
|
||||
dragWith: function( node ) {
|
||||
return node.id() == cy.$('#democratie').id();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -82,6 +82,10 @@
|
|||
{% endif %}
|
||||
{% if page.cytoscape %}
|
||||
<script src="{{ site.baseurl }}/public/js/cytoscape/cytoscape.min.js"></script>
|
||||
<script src="{{ site.baseurl }}/public/js/cytoscape/cytoscape-automove.js"></script>
|
||||
{% endif %}
|
||||
{% if page.chartjs %}
|
||||
<script src="{{ site.baseurl }}/public/js/chartjs/Chart.bundle.min.js"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Icons -->
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 39 KiB |
File diff suppressed because one or more lines are too long
131
pages/channelsstats.md
Normal file
131
pages/channelsstats.md
Normal file
|
@ -0,0 +1,131 @@
|
|||
---
|
||||
layout: page
|
||||
permalink: /channelsstats/
|
||||
title: Statistiques du Chat
|
||||
linktitle: "Statistiques du Chat"
|
||||
linkurl: /channelsstats/
|
||||
description: "Statistiques sur le chat https://coa.crapaud-fou.org"
|
||||
chartjs: true
|
||||
jquery: true
|
||||
---
|
||||
|
||||
Statistiques du <a href="https://coa.crapaud-fou.org">chat</a> (aussi connu sous le nom de mare aux crapauds) :
|
||||
<canvas id="byChannel"></canvas>
|
||||
<canvas id="byTsunamy"></canvas>
|
||||
<canvas id="usersByChannel"></canvas>
|
||||
<script>
|
||||
|
||||
$.getJSON("{{ site.baseurl }}/public/data/channelsstat.json", function (datas){
|
||||
updated = datas['updated']
|
||||
|
||||
labels = datas['labels'];
|
||||
|
||||
var ctx = document.getElementById('byChannel').getContext('2d');
|
||||
var chart = new Chart(ctx, {
|
||||
// The type of chart we want to create
|
||||
type: 'bar',
|
||||
|
||||
// The data for our dataset
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: datas['messagesByChannel'],
|
||||
},
|
||||
|
||||
// Configuration options go here
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: "Nombre de message par canaux (" + updated + ")",
|
||||
position: "top"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
stepSize: 500
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ctx2 = document.getElementById('byTsunamy').getContext('2d');
|
||||
var chart2 = new Chart(ctx2, {
|
||||
// The type of chart we want to create
|
||||
type: 'bar',
|
||||
|
||||
// The data for our dataset
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: datas['messagesByTsunamy'],
|
||||
},
|
||||
|
||||
// Configuration options go here
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: "Nombre de message par Tsunami (" + updated + ")",
|
||||
position: "top"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
stepSize: 500
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ctx3 = document.getElementById('usersByChannel').getContext('2d');
|
||||
var chart3 = new Chart(ctx3, {
|
||||
// The type of chart we want to create
|
||||
type: 'bar',
|
||||
|
||||
// The data for our dataset
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: datas['usersByChannel'],
|
||||
},
|
||||
|
||||
// Configuration options go here
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: "Nombre d'utilisateur actifs par canaux (" + updated + ")",
|
||||
position: "top"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
stacked: true
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
stepSize: 50
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
File diff suppressed because one or more lines are too long
5765
public/data/channelsstat.json
Normal file
5765
public/data/channelsstat.json
Normal file
File diff suppressed because it is too large
Load diff
1
public/data/cohortescolor.json
Normal file
1
public/data/cohortescolor.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"fr": "green", "fr-07": "green", "fr-26": "green", "fr-34": "green", "be": "green", "fr-21": "green", "fr-58": "green", "fr-71": "green", "fr-89": "green", "fr-22": "green", "fr-29": "green", "fr-35": "green", "fr-56": "green", "fr-18": "green", "fr-28": "green", "fr-36": "green", "fr-37": "green", "fr-41": "green", "fr-45": "green", "fr-08": "green", "fr-10": "green", "fr-51": "green", "fr-52": "green", "fr-54": "green", "fr-55": "green", "fr-57": "green", "fr-67": "green", "fr-68": "green", "fr-88": "green", "fr-38": "green", "fr-02": "green", "fr-59": "green", "fr-60": "green", "fr-62": "green", "fr-80": "green", "fr-75": "green", "fr-77": "green", "fr-78": "green", "fr-91": "green", "fr-92": "green", "fr-93": "green", "fr-94": "green", "fr-95": "green", "re": "green", "fr-14": "green", "fr-27": "green", "fr-50": "green", "fr-61": "green", "fr-76": "green", "fr-04": "green", "fr-05": "green", "fr-06": "green", "fr-13": "green", "fr-83": "green", "fr-84": "green", "fr-74": "green", "fr-73": "green", "fr-09": "green", "fr-12": "green", "fr-24": "green", "fr-31": "green", "fr-32": "green", "fr-33": "green", "fr-40": "green", "fr-46": "green", "fr-47": "green", "fr-64": "green", "fr-65": "green", "fr-81": "green", "fr-82": "green", "ch": "green"}
|
1
public/data/cohorteslist.json
Normal file
1
public/data/cohorteslist.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"fr": {"updateMap": "france_fr"}, "fr-07": {"link": "cohorte-2607"}, "fr-26": {"link": "cohorte-2607"}, "fr-34": {"link": "cohorte-34"}, "be": {"link": "cohorte-belgique"}, "fr-21": {"link": "cohorte-bourgogne"}, "fr-58": {"link": "cohorte-bourgogne"}, "fr-71": {"link": "cohorte-bourgogne"}, "fr-89": {"link": "cohorte-bourgogne"}, "fr-22": {"link": "cohorte-bretagne"}, "fr-29": {"link": "cohorte-bretagne"}, "fr-35": {"link": "cohorte-bretagne"}, "fr-56": {"link": "cohorte-bretagne"}, "fr-18": {"link": "cohorte-centre"}, "fr-28": {"link": "cohorte-centre"}, "fr-36": {"link": "cohorte-centre"}, "fr-37": {"link": "cohorte-centre"}, "fr-41": {"link": "cohorte-centre"}, "fr-45": {"link": "cohorte-centre"}, "fr-08": {"link": "cohorte-grand-est"}, "fr-10": {"link": "cohorte-grand-est"}, "fr-51": {"link": "cohorte-grand-est"}, "fr-52": {"link": "cohorte-grand-est"}, "fr-54": {"link": "cohorte-grand-est"}, "fr-55": {"link": "cohorte-grand-est"}, "fr-57": {"link": "cohorte-grand-est"}, "fr-67": {"link": "cohorte-grand-est"}, "fr-68": {"link": "cohorte-grand-est"}, "fr-88": {"link": "cohorte-grand-est"}, "fr-38": {"link": "cohorte-grenoble"}, "fr-02": {"link": "cohorte-hdf"}, "fr-59": {"link": "cohorte-hdf"}, "fr-60": {"link": "cohorte-hdf"}, "fr-62": {"link": "cohorte-hdf"}, "fr-80": {"link": "cohorte-hdf"}, "fr-75": {"link": "cohorte-ile-de-france"}, "fr-77": {"link": "cohorte-ile-de-france"}, "fr-78": {"link": "cohorte-ile-de-france"}, "fr-91": {"link": "cohorte-ile-de-france"}, "fr-92": {"link": "cohorte-ile-de-france"}, "fr-93": {"link": "cohorte-ile-de-france"}, "fr-94": {"link": "cohorte-ile-de-france"}, "fr-95": {"link": "cohorte-ile-de-france"}, "re": {"link": "cohorte-la-reunion"}, "fr-14": {"link": "cohorte-normandie"}, "fr-27": {"link": "cohorte-normandie"}, "fr-50": {"link": "cohorte-normandie"}, "fr-61": {"link": "cohorte-normandie"}, "fr-76": {"link": "cohorte-normandie"}, "fr-04": {"link": "cohorte-paca"}, "fr-05": {"link": "cohorte-paca"}, "fr-06": {"link": "cohorte-paca"}, "fr-13": {"link": "cohorte-paca"}, "fr-83": {"link": "cohorte-paca"}, "fr-84": {"link": "cohorte-paca"}, "fr-74": {"link": "cohorte-paysdesavoie"}, "fr-73": {"link": "cohorte-paysdesavoie"}, "fr-09": {"link": "cohorte-sud-ouest"}, "fr-12": {"link": "cohorte-sud-ouest"}, "fr-24": {"link": "cohorte-sud-ouest"}, "fr-31": {"link": "cohorte-sud-ouest"}, "fr-32": {"link": "cohorte-sud-ouest"}, "fr-33": {"link": "cohorte-sud-ouest"}, "fr-40": {"link": "cohorte-sud-ouest"}, "fr-46": {"link": "cohorte-sud-ouest"}, "fr-47": {"link": "cohorte-sud-ouest"}, "fr-64": {"link": "cohorte-sud-ouest"}, "fr-65": {"link": "cohorte-sud-ouest"}, "fr-81": {"link": "cohorte-sud-ouest"}, "fr-82": {"link": "cohorte-sud-ouest"}, "ch": {"link": "cohorte-suisse"}}
|
7
public/js/chartjs/Chart.bundle.min.js
vendored
Normal file
7
public/js/chartjs/Chart.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
711
public/js/cytoscape/cytoscape-automove.js
Normal file
711
public/js/cytoscape/cytoscape-automove.js
Normal file
|
@ -0,0 +1,711 @@
|
|||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory();
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define([], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["cytoscapeAutomove"] = factory();
|
||||
else
|
||||
root["cytoscapeAutomove"] = factory();
|
||||
})(this, function() {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // identity function for calling harmony imports with the correct context
|
||||
/******/ __webpack_require__.i = function(value) { return value; };
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 3);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
var defaults = __webpack_require__(2);
|
||||
|
||||
var typeofStr = _typeof('');
|
||||
var typeofObj = _typeof({});
|
||||
var typeofFn = _typeof(function () {});
|
||||
|
||||
var isObject = function isObject(x) {
|
||||
return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === typeofObj;
|
||||
};
|
||||
var isString = function isString(x) {
|
||||
return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === typeofStr;
|
||||
};
|
||||
var isFunction = function isFunction(x) {
|
||||
return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === typeofFn;
|
||||
};
|
||||
var isCollection = function isCollection(x) {
|
||||
return isObject(x) && isFunction(x.collection);
|
||||
};
|
||||
|
||||
// Object.assign() polyfill
|
||||
var assign = __webpack_require__(1);
|
||||
|
||||
var eleExists = function eleExists(ele) {
|
||||
return ele != null && !ele.removed();
|
||||
};
|
||||
|
||||
var _elesHasEle = function elesHasEle(eles, ele) {
|
||||
if (eles.has != undefined) {
|
||||
// 3.x
|
||||
_elesHasEle = function elesHasEle(eles, ele) {
|
||||
return eles.has(ele);
|
||||
};
|
||||
} else {
|
||||
// 2.x
|
||||
_elesHasEle = function elesHasEle(eles, ele) {
|
||||
return eles.intersection(ele).length > 0;
|
||||
};
|
||||
}
|
||||
|
||||
return _elesHasEle(eles, ele);
|
||||
};
|
||||
|
||||
var getEleMatchesSpecFn = function getEleMatchesSpecFn(spec) {
|
||||
if (isString(spec)) {
|
||||
return function (ele) {
|
||||
return ele.is(spec);
|
||||
};
|
||||
} else if (isFunction(spec)) {
|
||||
return spec;
|
||||
} else if (isCollection(spec)) {
|
||||
return function (ele) {
|
||||
return _elesHasEle(spec, ele);
|
||||
};
|
||||
} else {
|
||||
throw new Error('Can not create match function for spec', spec);
|
||||
}
|
||||
};
|
||||
|
||||
var bindings = [];
|
||||
|
||||
var bind = function bind(cy, events, selector, fn) {
|
||||
var b = { cy: cy, events: events, selector: selector || 'node', fn: fn };
|
||||
|
||||
bindings.push(b);
|
||||
|
||||
cy.on(b.events, b.selector, b.fn);
|
||||
|
||||
return b;
|
||||
};
|
||||
|
||||
var bindOnRule = function bindOnRule(rule, cy, events, selector, fn) {
|
||||
var b = bind(cy, events, selector, fn);
|
||||
var bindings = rule.bindings = rule.bindings || [];
|
||||
|
||||
bindings.push(b);
|
||||
};
|
||||
|
||||
var unbindAllOnRule = function unbindAllOnRule(rule) {
|
||||
var unbind = function unbind(b) {
|
||||
b.cy.off(b.events, b.selector, b.fn);
|
||||
};
|
||||
|
||||
rule.bindings.forEach(unbind);
|
||||
|
||||
rule.bindings = [];
|
||||
};
|
||||
|
||||
var getRepositioner = function getRepositioner(rule, cy) {
|
||||
var r = rule.reposition;
|
||||
|
||||
if (r === 'mean') {
|
||||
return meanNeighborhoodPosition(getEleMatchesSpecFn(rule.meanIgnores));
|
||||
} else if (r === 'viewport') {
|
||||
return viewportPosition(cy);
|
||||
} else if (r === 'drag') {
|
||||
return dragAlong(rule);
|
||||
} else if (isObject(r)) {
|
||||
if (r.type == undefined || r.type == "inside") {
|
||||
return boxPosition(r);
|
||||
} else if (r.type == "outside") {
|
||||
return outsideBoxPosition(r);
|
||||
}
|
||||
} else {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
var dragAlong = function dragAlong(rule) {
|
||||
return function (node) {
|
||||
var pos = node.position();
|
||||
var delta = rule.delta;
|
||||
|
||||
if (rule.delta != null && !node.same(rule.grabbedNode) && !node.grabbed()) {
|
||||
return {
|
||||
x: pos.x + delta.x,
|
||||
y: pos.y + delta.y
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var meanNeighborhoodPosition = function meanNeighborhoodPosition(ignore) {
|
||||
return function (node) {
|
||||
var nhood = node.neighborhood();
|
||||
var avgPos = { x: 0, y: 0 };
|
||||
var nhoodSize = 0;
|
||||
|
||||
for (var i = 0; i < nhood.length; i++) {
|
||||
var nhoodEle = nhood[i];
|
||||
|
||||
if (nhoodEle.isNode() && !ignore(nhoodEle)) {
|
||||
var pos = nhoodEle.position();
|
||||
|
||||
avgPos.x += pos.x;
|
||||
avgPos.y += pos.y;
|
||||
|
||||
nhoodSize++;
|
||||
}
|
||||
}
|
||||
|
||||
// the position should remain unchanged if we would stack the nodes on top of each other
|
||||
if (nhoodSize < 2) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
avgPos.x /= nhoodSize;
|
||||
avgPos.y /= nhoodSize;
|
||||
|
||||
return avgPos;
|
||||
};
|
||||
};
|
||||
|
||||
var constrain = function constrain(val, min, max) {
|
||||
return val < min ? min : val > max ? max : val;
|
||||
};
|
||||
|
||||
var constrainInBox = function constrainInBox(node, bb) {
|
||||
var pos = node.position();
|
||||
|
||||
return {
|
||||
x: constrain(pos.x, bb.x1, bb.x2),
|
||||
y: constrain(pos.y, bb.y1, bb.y2)
|
||||
};
|
||||
};
|
||||
|
||||
var boxPosition = function boxPosition(bb) {
|
||||
return function (node) {
|
||||
return constrainInBox(node, bb);
|
||||
};
|
||||
};
|
||||
|
||||
var constrainOutsideBox = function constrainOutsideBox(node, bb) {
|
||||
var pos = node.position();
|
||||
var x = pos.x,
|
||||
y = pos.y;
|
||||
var x1 = bb.x1,
|
||||
y1 = bb.y1,
|
||||
x2 = bb.x2,
|
||||
y2 = bb.y2;
|
||||
|
||||
var inX = x1 <= x && x <= x2;
|
||||
var inY = y1 <= y && y <= y2;
|
||||
var abs = Math.abs;
|
||||
|
||||
if (inX && inY) {
|
||||
// inside
|
||||
var dx1 = abs(x1 - x);
|
||||
var dx2 = abs(x2 - x);
|
||||
var dy1 = abs(y1 - y);
|
||||
var dy2 = abs(y2 - y);
|
||||
var min = Math.min(dx1, dx2, dy1, dy2); // which side of box is closest?
|
||||
|
||||
// get position outside, by closest side of box
|
||||
if (min === dx1) {
|
||||
return { x: x1, y: y };
|
||||
} else if (min === dx2) {
|
||||
return { x: x2, y: y };
|
||||
} else if (min === dy1) {
|
||||
return { x: x, y: y1 };
|
||||
} else {
|
||||
// min === dy2
|
||||
return { x: x, y: y2 };
|
||||
}
|
||||
} else {
|
||||
// outside already
|
||||
return { x: x, y: y };
|
||||
}
|
||||
};
|
||||
|
||||
var outsideBoxPosition = function outsideBoxPosition(bb) {
|
||||
return function (node) {
|
||||
return constrainOutsideBox(node, bb);
|
||||
};
|
||||
};
|
||||
|
||||
var viewportPosition = function viewportPosition(cy) {
|
||||
return function (node) {
|
||||
var extent = cy.extent();
|
||||
var w = node.outerWidth();
|
||||
var h = node.outerHeight();
|
||||
var bb = {
|
||||
x1: extent.x1 + w / 2,
|
||||
x2: extent.x2 - w / 2,
|
||||
y1: extent.y1 + h / 2,
|
||||
y2: extent.y2 - h / 2
|
||||
};
|
||||
|
||||
return constrainInBox(node, bb);
|
||||
};
|
||||
};
|
||||
|
||||
var meanListener = function meanListener(rule) {
|
||||
return function (update, cy) {
|
||||
var matches = function matches(ele) {
|
||||
// must meet ele set and be connected to more than (1 edge + 1 node)
|
||||
return rule.matches(ele) && ele.neighborhood().length > 2 && !ele.grabbed();
|
||||
};
|
||||
|
||||
bindOnRule(rule, cy, 'position', 'node', function () {
|
||||
var movedNode = this;
|
||||
|
||||
if (movedNode.neighborhood().some(matches) || rule.meanOnSelfPosition(movedNode) && matches(movedNode)) {
|
||||
update(cy, [rule]);
|
||||
}
|
||||
});
|
||||
|
||||
bindOnRule(rule, cy, 'add remove', 'edge', function () {
|
||||
var edge = this;
|
||||
var src = cy.getElementById(edge.data('source'));
|
||||
var tgt = cy.getElementById(edge.data('target'));
|
||||
|
||||
if ([src, tgt].some(matches)) {
|
||||
update(cy, [rule]);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var dragListener = function dragListener(rule) {
|
||||
return function (update, cy) {
|
||||
bindOnRule(rule, cy, 'grab', 'node', function () {
|
||||
var node = this;
|
||||
|
||||
if (rule.dragWithMatches(node)) {
|
||||
var p = node.position();
|
||||
|
||||
rule.grabbedNode = node;
|
||||
rule.p1 = { x: p.x, y: p.y };
|
||||
rule.delta = { x: 0, y: 0 };
|
||||
}
|
||||
});
|
||||
|
||||
bindOnRule(rule, cy, 'drag', 'node', function () {
|
||||
var node = this;
|
||||
|
||||
if (node.same(rule.grabbedNode)) {
|
||||
var d = rule.delta;
|
||||
var p1 = rule.p1;
|
||||
var p = node.position();
|
||||
var p2 = { x: p.x, y: p.y };
|
||||
|
||||
d.x = p2.x - p1.x;
|
||||
d.y = p2.y - p1.y;
|
||||
|
||||
rule.p1 = p2;
|
||||
|
||||
update(cy, [rule]);
|
||||
}
|
||||
});
|
||||
|
||||
bindOnRule(rule, cy, 'free', 'node', function () {
|
||||
rule.grabbedNode = null;
|
||||
rule.delta = null;
|
||||
rule.p1 = null;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var matchingNodesListener = function matchingNodesListener(rule) {
|
||||
return function (update, cy) {
|
||||
bindOnRule(rule, cy, 'position', 'node', function () {
|
||||
var movedNode = this;
|
||||
|
||||
if (rule.matches(movedNode)) {
|
||||
update(cy, [rule]);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var getListener = function getListener(cy, rule) {
|
||||
if (rule.reposition === 'mean') {
|
||||
return meanListener(rule);
|
||||
} else if (rule.reposition === 'drag') {
|
||||
return dragListener(rule);
|
||||
} else if (isObject(rule.reposition) || rule.when === 'matching' || rule.reposition === 'viewport') {
|
||||
return matchingNodesListener(rule);
|
||||
} else {
|
||||
return rule.when;
|
||||
}
|
||||
};
|
||||
|
||||
var addRule = function addRule(cy, scratch, options) {
|
||||
var rule = assign({}, defaults, options);
|
||||
|
||||
rule.getNewPos = getRepositioner(rule, cy);
|
||||
rule.listener = getListener(cy, rule);
|
||||
|
||||
var nodesAreCollection = isCollection(rule.nodesMatching);
|
||||
|
||||
if (nodesAreCollection) {
|
||||
rule.nodes = rule.nodesMatching.slice();
|
||||
|
||||
rule.matches = function (ele) {
|
||||
return eleExists(ele) && _elesHasEle(rule.nodes, ele);
|
||||
};
|
||||
} else {
|
||||
var matches = getEleMatchesSpecFn(rule.nodesMatching);
|
||||
|
||||
rule.matches = function (ele) {
|
||||
return eleExists(ele) && matches(ele);
|
||||
};
|
||||
}
|
||||
|
||||
if (rule.dragWith != null) {
|
||||
rule.dragWithMatches = getEleMatchesSpecFn(rule.dragWith);
|
||||
}
|
||||
|
||||
rule.listener(function () {
|
||||
update(cy, [rule]);
|
||||
}, cy);
|
||||
|
||||
rule.enabled = true;
|
||||
|
||||
scratch.rules.push(rule);
|
||||
|
||||
return rule;
|
||||
};
|
||||
|
||||
var bindForNodeList = function bindForNodeList(cy, scratch) {
|
||||
scratch.onAddNode = function (evt) {
|
||||
var target = evt.target;
|
||||
|
||||
scratch.nodes.merge(target);
|
||||
};
|
||||
|
||||
scratch.onRmNode = function (evt) {
|
||||
var target = evt.target;
|
||||
|
||||
scratch.nodes.unmerge(target);
|
||||
};
|
||||
|
||||
cy.on('add', 'node', scratch.onAddNode);
|
||||
cy.on('remove', 'node', scratch.onRmNode);
|
||||
};
|
||||
|
||||
var unbindForNodeList = function unbindForNodeList(cy, scratch) {
|
||||
cy.removeListener('add', 'node', scratch.onAddNode);
|
||||
cy.removeListener('remove', 'node', scratch.onRmNode);
|
||||
};
|
||||
|
||||
var update = function update(cy, rules) {
|
||||
var scratch = cy.scratch().automove;
|
||||
|
||||
rules = rules != null ? rules : scratch.rules;
|
||||
|
||||
cy.batch(function () {
|
||||
// batch for performance
|
||||
for (var i = 0; i < rules.length; i++) {
|
||||
var rule = rules[i];
|
||||
|
||||
if (rule.destroyed || !rule.enabled) {
|
||||
break;
|
||||
} // ignore destroyed rules b/c user may use custom when()
|
||||
|
||||
var nodes = rule.nodes || scratch.nodes;
|
||||
|
||||
for (var j = nodes.length - 1; j >= 0; j--) {
|
||||
var node = nodes[j];
|
||||
|
||||
if (node.removed()) {
|
||||
// remove from list for perf
|
||||
nodes.unmerge(node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rule.matches(node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var pos = node.position();
|
||||
var newPos = rule.getNewPos(node);
|
||||
var newPosIsDiff = newPos != null && (pos.x !== newPos.x || pos.y !== newPos.y);
|
||||
|
||||
if (newPosIsDiff) {
|
||||
// only update on diff for perf
|
||||
node.position(newPos);
|
||||
|
||||
node.trigger('automove', [rule]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var automove = function automove(options) {
|
||||
var cy = this;
|
||||
|
||||
var scratch = cy.scratch().automove = cy.scratch().automove || {
|
||||
rules: []
|
||||
};
|
||||
|
||||
if (scratch.rules.length === 0) {
|
||||
scratch.nodes = cy.nodes().slice();
|
||||
|
||||
bindForNodeList(cy, scratch);
|
||||
}
|
||||
|
||||
if (options === 'destroy') {
|
||||
scratch.rules.forEach(function (r) {
|
||||
r.destroy();
|
||||
});
|
||||
scratch.rules.splice(0, scratch.rules.length);
|
||||
|
||||
unbindForNodeList(cy, scratch);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var rule = addRule(cy, scratch, options);
|
||||
|
||||
update(cy, [rule]); // do an initial update to make sure the start state is correct
|
||||
|
||||
return {
|
||||
apply: function apply() {
|
||||
update(cy, [rule]);
|
||||
},
|
||||
|
||||
disable: function disable() {
|
||||
this.toggle(false);
|
||||
},
|
||||
|
||||
enable: function enable() {
|
||||
this.toggle(true);
|
||||
},
|
||||
|
||||
enabled: function enabled() {
|
||||
return rule.enabled;
|
||||
},
|
||||
|
||||
toggle: function toggle(on) {
|
||||
rule.enabled = on !== undefined ? on : !rule.enabled;
|
||||
|
||||
if (rule.enabled) {
|
||||
update(cy, [rule]);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
var rules = scratch.rules;
|
||||
|
||||
unbindAllOnRule(rule);
|
||||
|
||||
rule.destroyed = true;
|
||||
|
||||
rules.splice(rules.indexOf(rule), 1);
|
||||
|
||||
if (rules.length === 0) {
|
||||
unbindForNodeList(cy, scratch);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = automove;
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
// Simple, internal Object.assign() polyfill for options objects etc.
|
||||
|
||||
module.exports = Object.assign != null ? Object.assign.bind(Object) : function (tgt) {
|
||||
for (var _len = arguments.length, srcs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
srcs[_key - 1] = arguments[_key];
|
||||
}
|
||||
|
||||
srcs.forEach(function (src) {
|
||||
Object.keys(src).forEach(function (k) {
|
||||
return tgt[k] = src[k];
|
||||
});
|
||||
});
|
||||
|
||||
return tgt;
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
var defaults = {
|
||||
// specify nodes that should be automoved with one of
|
||||
// - a function that returns true for matching nodes
|
||||
// - a selector that matches the nodes
|
||||
// - a collection of nodes (very good for performance)
|
||||
nodesMatching: function nodesMatching(node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
// specify how a node's position should be updated with one of
|
||||
// - function( node ){ return { x: 1, y: 2 }; } => put the node where the function returns
|
||||
// - { x1, y1, x2, y2 } => constrain the node position within the bounding box (in model co-ordinates)
|
||||
// - { x1, y1, x2, y2, type: 'inside' } => constrain the node position within the bounding box (in model co-ordinates)
|
||||
// - { x1, y1, x2, y2, type: 'outside' } => constrain the node position outside the bounding box (in model co-ordinates)
|
||||
// - 'mean' => put the node in the average position of its neighbourhood
|
||||
// - 'viewport' => keeps the node body within the viewport
|
||||
// - 'drag' => matching nodes are effectively dragged along
|
||||
reposition: 'mean',
|
||||
|
||||
// specify when the repositioning should occur by specifying a function that
|
||||
// calls update() when reposition updates should occur
|
||||
// - function( update ){ /* ... */ update(); } => a manual function for updating
|
||||
// - 'matching' => automatically update on position events for nodesMatching
|
||||
// - set efficiently and automatically for
|
||||
// - reposition: 'mean'
|
||||
// - reposition: { x1, y1, x2, y2 }
|
||||
// - reposition: 'viewport'
|
||||
// - reposition: 'drag'
|
||||
// - default/undefined => on a position event for any node (not as efficient...)
|
||||
when: undefined,
|
||||
|
||||
//
|
||||
// customisation options for non-function `reposition` values
|
||||
//
|
||||
|
||||
// `reposition: 'mean'`
|
||||
|
||||
// specify nodes that should be ignored in the mean calculation
|
||||
// - a function that returns true for nodes to be ignored
|
||||
// - a selector that matches the nodes to be ignored
|
||||
// - a collection of nodes to be ignored (very good for performance)
|
||||
meanIgnores: function meanIgnores(node) {
|
||||
return false;
|
||||
},
|
||||
|
||||
// specify whether moving a particular `nodesMatching` node causes repositioning
|
||||
// - true : the mid node can't be independently moved/dragged
|
||||
// - false : the mid node can be independently moved/dragged (useful if you want the mid node to use `reposition: 'drag' in another rule with its neighbourhood`)
|
||||
meanOnSelfPosition: function meanOnSelfPosition(node) {
|
||||
return true;
|
||||
},
|
||||
|
||||
// `reposition: 'drag'`
|
||||
|
||||
// specify nodes that when dragged cause the matched nodes to move along (i.e. the master nodes)
|
||||
// - a function that returns true for nodes to be listened to for drag events
|
||||
// - a selector that matches the nodes to be listened to for drag events
|
||||
// - a collection of nodes to be listened to for drag events (very good for performance)
|
||||
dragWith: function dragWith(node) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/* eslint-enable */
|
||||
|
||||
module.exports = defaults;
|
||||
|
||||
/***/ }),
|
||||
/* 3 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var automove = __webpack_require__(0);
|
||||
|
||||
// registers the extension on a cytoscape lib ref
|
||||
var register = function register(cytoscape) {
|
||||
if (!cytoscape) {
|
||||
return;
|
||||
} // can't register if cytoscape unspecified
|
||||
|
||||
cytoscape('core', 'automove', automove); // register with cytoscape.js
|
||||
};
|
||||
|
||||
if (typeof cytoscape !== 'undefined') {
|
||||
// expose to global cytoscape (i.e. window.cytoscape)
|
||||
register(cytoscape);
|
||||
}
|
||||
|
||||
module.exports = register;
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
|
@ -1,5 +1,4 @@
|
|||
# getchannels
|
||||
## installation
|
||||
# installation
|
||||
## pre-requis
|
||||
Il faut Python 3 & pip car le code est fait en python.
|
||||
## Installation
|
||||
|
@ -13,8 +12,25 @@ Il faut créer un fichier dev_config.py avec ses infos de connection au Rocket.c
|
|||
'user' : 'username',
|
||||
'password': 'pwd'
|
||||
}
|
||||
# Lancer
|
||||
# Get Channels
|
||||
Permet de générer les infos pour la page
|
||||
https://crapaud-fou.org/channelslist/
|
||||
## Lancer
|
||||
python getchannels.py
|
||||
|
||||
# Commit
|
||||
Un fichier sera créé dans le répertoire [../public/data/result.json](../public/data/result.json)
|
||||
## Commit
|
||||
Des fichiers seront créé
|
||||
* [../public/data/channelslist.json](../public/data/channelslist.json)
|
||||
* [../public/data/cohortescolor.json](../public/data/cohortescolor.json)
|
||||
* [../public/data/cohorteslist.json](../public/data/cohorteslist.json)
|
||||
|
||||
# Get Stats
|
||||
Permet de générer les infos pour la page
|
||||
https://crapaud-fou.org/channelsstats/
|
||||
|
||||
## Lancer
|
||||
python getstats.py
|
||||
|
||||
## Commit
|
||||
Un fichier sera créé
|
||||
* [../public/data/channelsstat.json](../public/data/channelsstat.json)
|
39
script/common/channelhelper.py
Normal file
39
script/common/channelhelper.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
def getNodesOrigin(channel):
|
||||
nodes = []
|
||||
if 'description' not in channel:
|
||||
nodes.append("global")
|
||||
return nodes
|
||||
|
||||
if channel['description'].find("#projet") != -1:
|
||||
nodes.append("project")
|
||||
if channel['description'].find("#democratie") != -1:
|
||||
nodes.append("democratie")
|
||||
if channel['description'].find("#ecologie") != -1:
|
||||
nodes.append("ecologie")
|
||||
if channel['description'].find("#technologie") != -1:
|
||||
nodes.append("technologie")
|
||||
|
||||
if not nodes:
|
||||
nodes.append("global")
|
||||
|
||||
return nodes
|
||||
|
||||
def getTsunamy(channel):
|
||||
value = Tsunami.GLOBAL
|
||||
if 'description' in channel:
|
||||
if channel['description'].find("#projet") != -1:
|
||||
value |= Tsunami.PROJECT
|
||||
if channel['description'].find("#democratie") != -1:
|
||||
value |= Tsunami.DEMOCRACY
|
||||
if channel['description'].find("#ecologie") != -1:
|
||||
value |= Tsunami.ECOLOGY
|
||||
if channel['description'].find("#technologie") != -1:
|
||||
value |= Tsunami.TECHNOLOGY
|
||||
return value
|
||||
|
||||
class Tsunami:
|
||||
GLOBAL = 1 << 0
|
||||
PROJECT = 1 << 1
|
||||
DEMOCRACY = 1 << 2
|
||||
ECOLOGY = 1 << 3
|
||||
TECHNOLOGY = 1 << 4
|
|
@ -8,26 +8,8 @@ from rocketchat_API.rocketchat import RocketChat
|
|||
import json
|
||||
import dev_config as cfg
|
||||
import os
|
||||
|
||||
def getNodesOrigin(channel):
|
||||
nodes = []
|
||||
if 'description' not in channel:
|
||||
nodes.append("global")
|
||||
return nodes
|
||||
|
||||
if channel['description'].find("#projet") != -1:
|
||||
nodes.append("project")
|
||||
if channel['description'].find("#democratie") != -1:
|
||||
nodes.append("democratie")
|
||||
if channel['description'].find("#ecologie") != -1:
|
||||
nodes.append("ecologie")
|
||||
if channel['description'].find("#technologie") != -1:
|
||||
nodes.append("technologie")
|
||||
|
||||
if not nodes:
|
||||
nodes.append("global")
|
||||
|
||||
return nodes
|
||||
import re
|
||||
from common.channelhelper import getNodesOrigin
|
||||
|
||||
colorInfo = {
|
||||
'global': 'orange',
|
||||
|
@ -40,13 +22,14 @@ colorInfo = {
|
|||
rocket = RocketChat(cfg.rocket['user'], cfg.rocket['password'], server_url='https://coa.crapaud-fou.org')
|
||||
|
||||
edge_index = 0
|
||||
sizebase = 100
|
||||
datas = []
|
||||
datas.append( { 'data':{'id':'mare', 'label': 'mare', 'size': '300', 'color': 'black', 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'global', 'label': 'global', 'size': '200', 'color': colorInfo['global'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'ecologie', 'label': 'ecologie', 'size': '200', 'color': colorInfo['ecologie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'democratie', 'label': 'democratie', 'size': '200', 'color': colorInfo['democratie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'technologie', 'label': 'technologie', 'size': '200', 'color': colorInfo['technologie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'project', 'label': 'projet', 'size': '200', 'color': colorInfo['project'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'mare', 'label': 'mare', 'size': sizebase, 'color': 'black', 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'global', 'label': 'global', 'size': sizebase, 'color': colorInfo['global'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'ecologie', 'label': 'ecologie', 'size': sizebase, 'color': colorInfo['ecologie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'democratie', 'label': 'democratie', 'size': sizebase, 'color': colorInfo['democratie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'technologie', 'label': 'technologie', 'size': sizebase, 'color': colorInfo['technologie'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id':'project', 'label': 'projet', 'size': sizebase, 'color': colorInfo['project'], 'href': 'https://coa.crapaud-fou.org/'}})
|
||||
datas.append( { 'data':{'id': 'edge_' + str(edge_index), 'source': 'mare', 'target': 'global', 'color': colorInfo['global']}})
|
||||
edge_index += 1
|
||||
datas.append( { 'data':{'id': 'edge_' + str(edge_index), 'source': 'mare', 'target': 'ecologie', 'color': colorInfo['ecologie']}})
|
||||
|
@ -58,6 +41,8 @@ edge_index += 1
|
|||
datas.append( { 'data':{'id': 'edge_' + str(edge_index), 'source': 'mare', 'target': 'project', 'color': colorInfo['project']}})
|
||||
edge_index += 1
|
||||
|
||||
cohortes = { 'fr': { 'updateMap': 'france_fr'}}
|
||||
cohortescolor = { 'fr': 'green' }
|
||||
index = 0
|
||||
nbChannels = 0
|
||||
nbCohorte = 0
|
||||
|
@ -68,14 +53,24 @@ while True:
|
|||
|
||||
for channel in channels['channels']:
|
||||
if channel['name'].find('cohorte') != -1:
|
||||
if 'description' in channel:
|
||||
m = re.findall(r'#([\w-]+)', channel['description'])
|
||||
for region in m:
|
||||
cohortescolor.update( { region: 'green' } )
|
||||
cohortes.update( { region: { 'link': channel['name']}})
|
||||
nbCohorte += 1
|
||||
continue
|
||||
|
||||
size = channel['usersCount']
|
||||
|
||||
if (channel['_id'] == 'GENERAL') or (channel['_id'] == 'rp5gdRrZubMKic3Nk') :
|
||||
size = sizebase
|
||||
|
||||
node = {
|
||||
'data' : {
|
||||
'id': channel['_id'],
|
||||
'label': channel['fname'] if 'fname' in channel else channel['name'],
|
||||
'size': '100',
|
||||
'size': size,
|
||||
'color': 'grey',
|
||||
'href': 'https://coa.crapaud-fou.org/channel/'+channel['name']
|
||||
}
|
||||
|
@ -107,6 +102,14 @@ channelsFilePath = os.path.abspath(os.path.join(dataFolder,'channelslist.json'))
|
|||
with open(channelsFilePath, "w") as file_write:
|
||||
json.dump(datas, file_write)
|
||||
|
||||
cohortecolorFilePath = os.path.abspath(os.path.join(dataFolder,'cohortescolor.json'))
|
||||
with open(cohortecolorFilePath, "w") as file_write:
|
||||
json.dump(cohortescolor, file_write)
|
||||
|
||||
cohorteFilePath = os.path.abspath(os.path.join(dataFolder,'cohorteslist.json'))
|
||||
with open(cohorteFilePath, "w") as file_write:
|
||||
json.dump(cohortes, file_write)
|
||||
|
||||
pprint("Nb displayed channels : " + str(nbChannels))
|
||||
pprint("Nb cohorte channels : " + str(nbCohorte))
|
||||
pprint("Nb total channels : " + str(totalChannels))
|
||||
|
|
148
script/getstats.py
Normal file
148
script/getstats.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
# coding: utf8
|
||||
|
||||
# toutes les chaines sont en unicode (même les docstrings)
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pprint import pprint
|
||||
from rocketchat_API.rocketchat import RocketChat
|
||||
import json
|
||||
import dev_config as cfg
|
||||
import os
|
||||
import random
|
||||
from datetime import datetime
|
||||
from monthdelta import monthdelta
|
||||
from common.channelhelper import getTsunamy
|
||||
from common.channelhelper import Tsunami
|
||||
|
||||
def getColor():
|
||||
r = random.randrange(255)
|
||||
g = random.randrange(255)
|
||||
b = random.randrange(255)
|
||||
return 'rgb({:0},{:0},{:0})'.format(r,g,b)
|
||||
|
||||
rocket = RocketChat(cfg.rocket['user'], cfg.rocket['password'],
|
||||
server_url='https://coa.crapaud-fou.org')
|
||||
index = 0
|
||||
labels = [None] * 12
|
||||
messagesByChannel = []
|
||||
messagesByTsunamy = []
|
||||
usersByChannel = []
|
||||
messagesDataTsunamy = {
|
||||
"global": [0] * 12,
|
||||
"project": [0] * 12,
|
||||
"democraty": [0] * 12,
|
||||
"ecology": [0] * 12,
|
||||
"technology": [0] * 12,
|
||||
}
|
||||
|
||||
now = datetime.now()
|
||||
date = datetime(now.year, now.month, now.day, 0,0,0)
|
||||
|
||||
info = {
|
||||
"updated": "updated {:02}/{:02}/{:04}".format(now.day, now.month, now.year),
|
||||
"labels": labels,
|
||||
"messagesByChannel": messagesByChannel,
|
||||
"usersByChannel": usersByChannel,
|
||||
"messagesByTsunamy": [{
|
||||
"label": "global",
|
||||
"backgroundColor": getColor(),
|
||||
"data": messagesDataTsunamy['global']
|
||||
},
|
||||
{
|
||||
"label": "projet",
|
||||
"backgroundColor": getColor(),
|
||||
"data": messagesDataTsunamy['project']
|
||||
},
|
||||
{
|
||||
"label": "democratie",
|
||||
"backgroundColor": getColor(),
|
||||
"data": messagesDataTsunamy['democraty']
|
||||
},
|
||||
{
|
||||
"label": "ecologie",
|
||||
"backgroundColor": getColor(),
|
||||
"data": messagesDataTsunamy['ecology']
|
||||
},
|
||||
{
|
||||
"label": "technologie",
|
||||
"backgroundColor": getColor(),
|
||||
"data": messagesDataTsunamy['technology']
|
||||
}]
|
||||
}
|
||||
|
||||
while True:
|
||||
channels = rocket.channels_list(offset=index).json()
|
||||
totalChannels = channels['total']
|
||||
|
||||
for channel in channels['channels']:
|
||||
dataMess = []
|
||||
dataUsers = []
|
||||
pprint( channel['name'] )
|
||||
begin = date - monthdelta(12)
|
||||
end = begin + monthdelta(1)
|
||||
|
||||
tsunamy = getTsunamy(channel)
|
||||
|
||||
for id in range(0, 12):
|
||||
labels[id] = begin.strftime("%b %Y")
|
||||
begindate = begin.isoformat()
|
||||
enddate = end.isoformat()
|
||||
resultMess = rocket.channels_history(channel['_id'], oldest= begindate, latest=enddate, count= 10000).json()
|
||||
lenght = len(resultMess['messages'])
|
||||
dataMess.append(lenght)
|
||||
|
||||
if lenght > 0:
|
||||
if tsunamy & Tsunami.GLOBAL:
|
||||
messagesDataTsunamy['global'][id] += lenght
|
||||
if tsunamy & Tsunami.PROJECT:
|
||||
messagesDataTsunamy['project'][id] += lenght
|
||||
if tsunamy & Tsunami.DEMOCRACY:
|
||||
messagesDataTsunamy['democraty'][id] += lenght
|
||||
if tsunamy & Tsunami.ECOLOGY:
|
||||
messagesDataTsunamy['ecology'][id] += lenght
|
||||
if tsunamy & Tsunami.TECHNOLOGY:
|
||||
messagesDataTsunamy['technology'][id] += lenght
|
||||
|
||||
users = []
|
||||
for mess in resultMess['messages']:
|
||||
users.append(mess['u']['_id'])
|
||||
usersDistinct = set(users)
|
||||
dataUsers.append(len(usersDistinct))
|
||||
else:
|
||||
dataUsers.append(0)
|
||||
|
||||
begin = end
|
||||
end = begin + monthdelta(1)
|
||||
|
||||
color = getColor()
|
||||
messageByChannel = {
|
||||
"label": channel['name'],
|
||||
"backgroundColor": color,
|
||||
"data": dataMess
|
||||
}
|
||||
|
||||
userByChannel = {
|
||||
"label": channel['name'],
|
||||
"backgroundColor": color,
|
||||
"data": dataUsers
|
||||
}
|
||||
|
||||
messagesByChannel.append(messageByChannel)
|
||||
usersByChannel.append(userByChannel)
|
||||
|
||||
if channels['count'] + channels['offset'] >= channels['total']:
|
||||
break
|
||||
index += channels['count']
|
||||
|
||||
# Récupération du répertoire racine du repo
|
||||
rootFolder = os.path.join(os.path.dirname(__file__), '..')
|
||||
# Répertoire pour stocker le fichier de sortie
|
||||
dataFolder = os.path.join(rootFolder, 'public', 'data')
|
||||
|
||||
|
||||
|
||||
statsFilePath = os.path.abspath(
|
||||
os.path.join(dataFolder, 'channelsstat.json'))
|
||||
with open(statsFilePath, "w") as file_write:
|
||||
json.dump(info, file_write)
|
||||
|
|
@ -1 +1,2 @@
|
|||
rocketchat_API==0.6.32
|
||||
MonthDelta==0.9.1
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue