gaussianWotQuality2.ts 8 KB
Newer Older
1
import {DataFinder} from "../lib/DataFinder";
2
import {MonitConstants} from "../lib/constants2";
3

Éloïs's avatar
Éloïs committed
4
const membersQuality = require(__dirname + '/tools/membersQuality')
5
const getLang = require(__dirname + '/../lib/getLang')
Éloïs's avatar
Éloïs committed
6
7

// gaussianWotQuality cache
8
var previousNextYn = "no";
Éloïs's avatar
Éloïs committed
9

10
module.exports = async (req:any, res:any, next:any) => {
11
12
  
  var { duniterServer  } = req.app.locals
13
14

  const dataFinder = new DataFinder(duniterServer)
15
16
  
  try {
Éloïs's avatar
Éloïs committed
17
      // get GET parameters
18
19
20
      const format = req.query.format || 'HTML';
      const sentries = req.query.sentries || 'yes';
      const unit = req.query.unit || 'quality';
21
      const nextYn = (req.query.nextYn=="yes") ? "yes":"no";
22
23

      // get lg file
24
      const LANG = getLang(`${__dirname}/../lg/gaussianWotQuality_${req.query.lg||MonitConstants.DEFAULT_LANGUAGE}.txt`);
Éloïs's avatar
Éloïs committed
25
26
27
28
29
30

      // Définition des contantes
      const conf = duniterServer.conf;
      const qualityMax = (1/conf.xpercent);

      // Définition des variables
31
      let lastUpgradeTimeDatas = membersQuality(MonitConstants.QUALITY_CACHE_ACTION.INIT);
Éloïs's avatar
Éloïs committed
32
33
34
35
36
37
38
39
      let tabUidIndex = [];
      let tabMembersQuality= [];
      let tabMembersQualitySorted = [];
      let tabLabels = [];
      let tabColors = [];
      let tabLimit1 = [];

      // Récupérer la liste des identités ayant actuellement le statut de membre
40
      let membersList = await dataFinder.getMembers();
Éloïs's avatar
Éloïs committed
41
42

      // Si les données de qualité n'ont jamais été calculés, le faire
43
      if (lastUpgradeTimeDatas == 0 || (lastUpgradeTimeDatas+MonitConstants.MIN_WOT_QUALITY_CACHE_UPDATE_FREQ) < (Math.floor(Date.now() / 1000)) || (previousNextYn != nextYn))
Éloïs's avatar
Éloïs committed
44
45
      {
        // Calculer dSen
46
47
        var dSen = Math.ceil(Math.pow(membersList.length, 1 / conf.stepMax));
        if (nextYn == "yes") { dSen++; }
Éloïs's avatar
Éloïs committed
48
49

        // récupérer la wot
Éloïs's avatar
Éloïs committed
50
        const wot = duniterServer.dal.wotb;
Éloïs's avatar
Éloïs committed
51
52

        // Initialiser le cache des données de qualité
53
        membersQuality(MonitConstants.QUALITY_CACHE_ACTION.INIT, 0, dSen, conf.stepMax, conf.xpercent, wot.memCopy());
Éloïs's avatar
Éloïs committed
54
55
      }

56
57
58
      // Mettre a jour previousNextYn
      previousNextYn = (nextYn=="yes") ? "yes":"no";

59
      // Calculer nbSentries, limit1 and label
60
      const nbSentries = (sentries=="no") ? membersList.length:membersQuality(MonitConstants.QUALITY_CACHE_ACTION.GET_SENTRIES_COUNT);
61
62
63
64
65
      let limit1 = 1;
      let label = LANG['QUALITY'];
      switch (unit)
      {
          case 'percentReached': limit1 = conf.xpercent*100; label = LANG['PERCENT_REACHED']; break;
66
          case 'nbReached': limit1 = parseInt(String(conf.xpercent*nbSentries)); label = LANG['NB_REACHED']; break;
67
68
69
70
71
72
73
74
75
76
77
          default: break;
      }

      // Remplir les tableaux tabUidIndex et tabLimit1
      for(const member of membersList)
      {
        tabUidIndex[member.wotb_id] = member.uid;
        tabLimit1.push(limit1);
      }

      // Récupérer le tableau de qualité des membres
Éloïs's avatar
Éloïs committed
78
      tabMembersQuality= [];
79
      for (let i=0;membersQuality(MonitConstants.QUALITY_CACHE_ACTION.GET_QUALITY, i) >= 0;i++)
Éloïs's avatar
Éloïs committed
80
      {
81
82
        if (sentries == "no")
        {
83
          tabMembersQuality[i] = membersQuality(MonitConstants.QUALITY_CACHE_ACTION.GET_QUALITY, i, -1);
84
85
86
        }
        else
        {
87
          tabMembersQuality[i] = membersQuality(MonitConstants.QUALITY_CACHE_ACTION.GET_QUALITY, i);
88
        }
Éloïs's avatar
Éloïs committed
89
90
      }

91
      // Initialisation du tableau tabMembersQualitySorted
Éloïs's avatar
Éloïs committed
92
93
94
95
96
      for (let i=0;i<tabMembersQuality.length;i++)
      {
        tabMembersQualitySorted.push(0);
      }

97
      // Trier le tableau de façon gaussienne
Éloïs's avatar
Éloïs committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
      let debut = true;
      let membersQualityAlreadyCounted = [];
      for (let i=0;i<tabMembersQuality.length;i++)
      {
        let min = qualityMax;
        let idMin = 0;

        for (let j=0;j<tabMembersQuality.length;j++)
        {
          if (tabMembersQuality[j] < min && typeof(membersQualityAlreadyCounted[j])=='undefined')
          {
            min = tabMembersQuality[j];
            idMin = j;
          }
        }

        // Remplir les tableaux triée de façon gaussienne
115
        let idGaussian = i/2;
Éloïs's avatar
Éloïs committed
116
117
        if(!debut)
        {
118
          idGaussian = tabMembersQuality.length-(i/2);
Éloïs's avatar
Éloïs committed
119
120
121
122
123
124
125
126
        }
        debut = !debut;
        tabMembersQualitySorted[idGaussian] = tabMembersQuality[idMin];

        // Exclure les membres déjà traités
        membersQualityAlreadyCounted[idMin] = true;

        // Définir le label pour cet abscisse
127
        tabLabels[idGaussian] = tabUidIndex[idMin];
Éloïs's avatar
Éloïs committed
128
129

        // Définir la couleur
130
131
132
133
134
        if (tabMembersQuality[idMin] >= 1.10)
        {
          tabColors[idGaussian] = 'rgba(128, 0, 128, 0.5)';
        }
        else if (tabMembersQuality[idMin] >= 1.05)
Éloïs's avatar
Éloïs committed
135
136
137
        {
          tabColors[idGaussian] = 'rgba(0, 0, 255, 0.5)';
        }
138
        else if (tabMembersQuality[idMin] >= 1.00)
Éloïs's avatar
Éloïs committed
139
140
141
        {
          tabColors[idGaussian] = 'rgba(0, 255, 0, 0.5)';
        }
142
        else if (tabMembersQuality[idMin] >= 0.95)
Éloïs's avatar
Éloïs committed
143
144
145
        {
          tabColors[idGaussian] = 'rgba(255, 128, 0, 0.5)';
        }
146
        else if (tabMembersQuality[idMin] >= 0.90)
Éloïs's avatar
Éloïs committed
147
148
149
150
151
152
153
154
        {
          tabColors[idGaussian] = 'rgba(255, 0, 0, 0.5)';
        }
        else
        {
          tabColors[idGaussian] = 'rgba(0, 0, 0, 0.5)';
        }
      }
155
156
157
158
159
160
161
162
163
164

      // Si le client demande les données dans une autre unité, faire la transformation
      let unitCoeff = 1.0;
      if (unit=='percentReached' || unit=='nbReached')
      {
        unitCoeff = parseFloat(conf.xpercent);
        if (unit=='nbReached') { unitCoeff *= parseFloat(nbSentries); }
        else { unitCoeff *= 100.0; }
        for (let i=0;i<tabMembersQualitySorted.length;i++)
        {
165
          tabMembersQualitySorted[i] = tabMembersQualitySorted[i]*unitCoeff;
166
167
        }
      }
168
      
Éloïs's avatar
Éloïs committed
169
170
171
172
173
174
175
176
      // Si le client demande la réponse au format JSON, le faire
      if (format == 'JSON')
      {
        let tabJson = [];
        for (let i=0;i<tabMembersQualitySorted.length;i++)
        {
          tabJson.push({
            label: tabLabels[i],
177
            quality: tabMembersQualitySorted[i]
Éloïs's avatar
Éloïs committed
178
179
180
181
182
183
184
185
          });
        }
        res.status(200).jsonp( tabJson )
      }
      else
      {
        res.locals = {
        host: req.headers.host.toString(),
186
187
188
189
190
191
          form: `
            <select name="unit">
              <option name="unit" value ="quality">${LANG['QUALITY']}
              <option name="unit" value ="percentReached" ${unit == 'percentReached' ? 'selected' : ''}>${LANG['PERCENT_REACHED']}
              <option name="unit" value ="nbReached" ${unit == 'nbReached' ? 'selected' : ''}>${LANG['NB_REACHED']}
            </select>`,
192
193
          form2: `<input type="checkbox" name="sentries" value="no" ${sentries == 'no' ? 'checked' : ''}> ${LANG["IF_NO_SENTRIES"]}<br>
            <input type="checkbox" name="nextYn" value="yes" ${nextYn == 'yes' ? 'checked' : ''}> ${LANG["NEXT_YN"]}`,
Éloïs's avatar
Éloïs committed
194
195
196
197
198
          chart: {
            type: 'bar',
            data: {
              labels: tabLabels,
              datasets: [{
199
                label: label,
Éloïs's avatar
Éloïs committed
200
201
202
203
204
205
206
                data: tabMembersQualitySorted,
                backgroundColor: tabColors,
                borderWidth: 0
              },
              {
                label: 'limit',
                data: tabLimit1,
207
208
209
210
211
212
213
                backgroundColor: 'rgba(0, 255, 0, 0.5)',
                borderColor: 'rgba(0, 255, 0, 1)',
                borderWidth: 2,
                type: 'line',
                fill: false,
                pointStyle: 'dash'
              }]
214
            },
Éloïs's avatar
Éloïs committed
215
216
217
            options: {
              title: {
                display: true,
218
                text: LANG['DISTRIBUTION_QUALITY']
Éloïs's avatar
Éloïs committed
219
220
221
222
223
224
              },
              legend: {
                display: false
              },
              scales: {
                yAxes: [{
225
226
227
228
229
                  position: 'left',
                  ticks: {
                    min: 0,
                    max: parseFloat(((1/conf.xpercent)*unitCoeff).toFixed(2))
                  }
Éloïs's avatar
Éloïs committed
230
231
                }]
              }
232
233
234
            }
          }
        }
Éloïs's avatar
Éloïs committed
235
        next()
236
237
238
239
240
      }
  } catch (e) {
    // En cas d'exception, afficher le message
    res.status(500).send(`<pre>${e.stack || e.message}</pre>`);
  }
241
}