First integration for stat page
This commit is contained in:
parent
025c3599ff
commit
11ca40c677
6 changed files with 375 additions and 1 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
# site/data/*.json
|
# site/data/*.json
|
||||||
!site/data/*.sample.json
|
!site/data/*.sample.json
|
||||||
config
|
config
|
||||||
.vscode
|
.vscode
|
||||||
|
*.pyc
|
54
scripts/common/channelhelper.py
Normal file
54
scripts/common/channelhelper.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
def getAllChannels(rocket):
|
||||||
|
index = 0
|
||||||
|
allChannels = []
|
||||||
|
while True:
|
||||||
|
channels = rocket.channels_list(offset= index).json()
|
||||||
|
|
||||||
|
allChannels.extend([ channel for channel in channels['channels'] if 'archived' not in channel])
|
||||||
|
if channels['count'] + channels['offset'] >= channels['total']:
|
||||||
|
break
|
||||||
|
index += channels['count']
|
||||||
|
return allChannels
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("Ce fichier est juste une librarie")
|
141
scripts/getstats.py
Normal file
141
scripts/getstats.py
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
# 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 os
|
||||||
|
import random
|
||||||
|
from datetime import datetime
|
||||||
|
from monthdelta import monthdelta
|
||||||
|
from common.channelhelper import getTsunamy, Tsunami, getAllChannels
|
||||||
|
|
||||||
|
def getColor():
|
||||||
|
r = random.randrange(255)
|
||||||
|
g = random.randrange(255)
|
||||||
|
b = random.randrange(255)
|
||||||
|
return 'rgb({:0},{:0},{:0})'.format(r,g,b)
|
||||||
|
|
||||||
|
def save(info):
|
||||||
|
# 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, 'site', 'data')
|
||||||
|
|
||||||
|
statsFilePath = os.path.abspath(
|
||||||
|
os.path.join(dataFolder, 'channelsstat.json'))
|
||||||
|
with open(statsFilePath, "w") as file_write:
|
||||||
|
json.dump(info, file_write)
|
||||||
|
|
||||||
|
def createElement(label, color, data) :
|
||||||
|
return {
|
||||||
|
"label": label,
|
||||||
|
"backgroundColor": color,
|
||||||
|
"data": data
|
||||||
|
}
|
||||||
|
|
||||||
|
def setTsunamyInfo(tsunamy, messagesDataTsunamy, id, length):
|
||||||
|
if tsunamy & Tsunami.GLOBAL:
|
||||||
|
messagesDataTsunamy[Tsunami.GLOBAL][id] += length
|
||||||
|
if tsunamy & Tsunami.PROJECT:
|
||||||
|
messagesDataTsunamy[Tsunami.PROJECT][id] += length
|
||||||
|
if tsunamy & Tsunami.DEMOCRACY:
|
||||||
|
messagesDataTsunamy[Tsunami.DEMOCRACY][id] += length
|
||||||
|
if tsunamy & Tsunami.ECOLOGY:
|
||||||
|
messagesDataTsunamy[Tsunami.ECOLOGY][id] += length
|
||||||
|
if tsunamy & Tsunami.TECHNOLOGY:
|
||||||
|
messagesDataTsunamy[Tsunami.TECHNOLOGY][id] += length
|
||||||
|
|
||||||
|
def main():
|
||||||
|
rocket = RocketChat(None, None, auth_token= os.environ['ROCKETCHAT_AUTH'], user_id= os.environ['ROCKETCHAT_USERID'], server_url=os.environ['ROCKETCHAT_SERVER'])
|
||||||
|
|
||||||
|
labels = [None] * 12
|
||||||
|
messagesByChannel = []
|
||||||
|
usersByChannel = []
|
||||||
|
messagesDataTsunamy = {
|
||||||
|
Tsunami.GLOBAL: [0] * 12,
|
||||||
|
Tsunami.PROJECT: [0] * 12,
|
||||||
|
Tsunami.DEMOCRACY: [0] * 12,
|
||||||
|
Tsunami.ECOLOGY: [0] * 12,
|
||||||
|
Tsunami.TECHNOLOGY: [0] * 12,
|
||||||
|
}
|
||||||
|
usersGlobal = []
|
||||||
|
|
||||||
|
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": [
|
||||||
|
createElement("global", getColor(), messagesDataTsunamy[Tsunami.GLOBAL]),
|
||||||
|
createElement("project", getColor(), messagesDataTsunamy[Tsunami.PROJECT]),
|
||||||
|
createElement("democratie", getColor(), messagesDataTsunamy[Tsunami.DEMOCRACY]),
|
||||||
|
createElement("ecologie", getColor(), messagesDataTsunamy[Tsunami.ECOLOGY]),
|
||||||
|
createElement("technologie", getColor(), messagesDataTsunamy[Tsunami.TECHNOLOGY])
|
||||||
|
],
|
||||||
|
"usersGlobal": usersGlobal
|
||||||
|
}
|
||||||
|
|
||||||
|
uniqueUserGlobal = [None] * 12
|
||||||
|
|
||||||
|
for channel in getAllChannels(rocket):
|
||||||
|
dataMess = []
|
||||||
|
dataUsers = []
|
||||||
|
print( channel['name'] )
|
||||||
|
begin = date - monthdelta(12)
|
||||||
|
end = begin + monthdelta(1)
|
||||||
|
|
||||||
|
tsunamy = getTsunamy(channel)
|
||||||
|
|
||||||
|
for id in range(0, 12):
|
||||||
|
if uniqueUserGlobal[id] == None:
|
||||||
|
uniqueUserGlobal[id] = []
|
||||||
|
labels[id] = begin.strftime("%b %Y")
|
||||||
|
print(f"\t{labels[id]}")
|
||||||
|
begindate = begin.isoformat()
|
||||||
|
enddate = end.isoformat()
|
||||||
|
|
||||||
|
resultMess = rocket.channels_history(channel['_id'], oldest= begindate, latest=enddate, count= 10000).json()
|
||||||
|
resultMess = list(filter(lambda mess: 't' not in mess, resultMess['messages']))
|
||||||
|
length = len(resultMess)
|
||||||
|
dataMess.append(length)
|
||||||
|
|
||||||
|
if length > 0:
|
||||||
|
setTsunamyInfo(tsunamy, messagesDataTsunamy, id, length)
|
||||||
|
|
||||||
|
users = []
|
||||||
|
for mess in resultMess:
|
||||||
|
users.append(mess['u']['_id'])
|
||||||
|
uniqueUserGlobal[id].append(mess['u']['_id'])
|
||||||
|
usersDistinct = set(users)
|
||||||
|
dataUsers.append(len(usersDistinct))
|
||||||
|
else:
|
||||||
|
dataUsers.append(0)
|
||||||
|
|
||||||
|
begin = end
|
||||||
|
end = begin + monthdelta(1)
|
||||||
|
|
||||||
|
color = getColor()
|
||||||
|
messageByChannel = createElement(channel['name'], color,dataMess)
|
||||||
|
userByChannel = createElement( channel['name'], color,dataUsers)
|
||||||
|
|
||||||
|
messagesByChannel.append(messageByChannel)
|
||||||
|
usersByChannel.append(userByChannel)
|
||||||
|
|
||||||
|
for id in range(0, 12):
|
||||||
|
uniqueUserGlobal[id] = len(set(uniqueUserGlobal[id]))
|
||||||
|
|
||||||
|
userGlobal = createElement( 'global', 'red', uniqueUserGlobal)
|
||||||
|
usersGlobal.append(userGlobal)
|
||||||
|
|
||||||
|
save(info)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
12
site/coa/index.html
Normal file
12
site/coa/index.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script type"javascript">
|
||||||
|
window.location.replace("/");
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Cette page n'existe pas
|
||||||
|
</body>
|
||||||
|
</html>
|
165
site/coa/stats/index.html
Normal file
165
site/coa/stats/index.html
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
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>
|
||||||
|
<canvas id="usersGlobal"></canvas>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$.getJSON("../../data/channelsstat.json", function (datas){
|
||||||
|
updated = datas['updated']
|
||||||
|
|
||||||
|
labels = datas['labels'];
|
||||||
|
|
||||||
|
var ctx = $('#byChannel');
|
||||||
|
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 = $("#byTsunamy");
|
||||||
|
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 = $("#usersByChannel");
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var ctx4 = $("#usersGlobal");
|
||||||
|
var chart4 = new Chart(ctx4, {
|
||||||
|
// The type of chart we want to create
|
||||||
|
type: 'bar',
|
||||||
|
|
||||||
|
// The data for our dataset
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: datas['usersGlobal'],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Configuration options go here
|
||||||
|
options: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: "Nombre d'utilisateur actifs (" + updated + ")",
|
||||||
|
position: "top"
|
||||||
|
},
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
stacked: true
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
stacked: true,
|
||||||
|
ticks: {
|
||||||
|
stepSize: 50
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
site/data/channelsstat.json
Normal file
1
site/data/channelsstat.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue