Compare commits

...

3 Commits

Author SHA1 Message Date
Benjamin Dauvergne fabd6894e1 wip 2022-04-08 12:57:03 +02:00
Benjamin Dauvergne 6c4ed8b0da wip 2022-03-29 11:22:51 +02:00
Benjamin Dauvergne a4ef5ac5a3 wip 2022-03-29 09:35:58 +02:00
6 changed files with 162 additions and 1 deletions

19
cd06-audit/Makefile Normal file
View File

@ -0,0 +1,19 @@
PREFIX := ~/envs/publik-env-py3/bin/
WCS_MANAGE := $(PREFIX)wcs-manage
CHRONO_MANAGE := $(PREFIX)chrono-manage
prod:
make WCS_MANAGE='sudo -u wcs /usr/bin/wcs-manage' all
all: wcs
wcs:
@$(WCS_MANAGE) runscript --all-tenants wcs-crawl.py
chrono:
@$(CHRONO_MANAGE) tenant_command runscript --all-tenants chrono-crawl.py
install:
sudo apt install python3-pandas python3-ipdb

View File

@ -0,0 +1,15 @@
import collections
import pprint
import pandas as pd
from chrono.agendas.models import Agenda, Event
from django.db import connection
print(connection.tenant.domain_url)
agendas = collections.OrderedDict()
for agenda in Agenda.objects.filter(kind='event').order_by('label').prefetch_related('events'):
agendas[agenda.label] = pd.DataFrame(agenda.events.values_list('start_datetime', flat=True))
pprint.pprint(agendas)

View File

@ -0,0 +1,12 @@
;Catégorie;Formulaire;Workflow;Nombre de statuts;Nombre de champs;Nombre de champs de traitement;Nombre de champs avec conditions;Nombre de pages;Nombre de sauts sur expiration;Nombre de sauts sur trigger;Nombre de sauts sur condition;Nombre de demandes;Usage du disque (en Mo);Âge (min);Âge (25%);Âge (50%);Âge (75%);Âge (max);Heure de réception (min);Heure de réception (25%);Heure de réception (50%);Heure de réception (75%);Heure de réception (max)
0;Cat1;Test agenda lock;RdV;5;5;1;0;2;0;0;0;4;0.0;293.07144195567133;293.0722926497772;293.07388987159146;294.48206406160307;298.70264566030096;9.383333333333333;9.433333333333334;9.458333333333332;11.679166666666667;18.316666666666666
1;Cat1;Test liste autocomplétion;Par défaut;5;3;0;0;0;0;0;0;0;0.0;;;;;;;;;;
2;Cat1;Formulaire cible;Workflow cible;5;3;2;0;0;0;0;0;2;0.0;717.8747407953472;717.8755365127922;717.8763322302373;717.8771279476823;717.8779236651274;14.116666666666667;14.133333333333333;14.15;14.166666666666668;14.183333333333334
3;Cat1;Formulaire initial;Workflow avec re-soumission;6;8;1;0;1;0;0;0;5;0.0813455581665039;506.90012288534723;594.7640927918171;594.7742085317476;714.125690012338;717.879196955625;8.166666666666666;13.583333333333334;14.083333333333334;16.6;16.85
4;;Coin;Par défaut;5;0;0;0;0;0;0;0;0;0.0;;;;;;;;;;
5;Cat1;Test FranceConnect;FranceConnect;5;1;0;0;0;0;0;0;3;0.0;315.8225188749421;315.8264019765278;315.83028507811343;315.83872836475115;315.84717165138886;14.85;15.05;15.25;15.35;15.45
6;Cat1;Test users datas;Par défaut;5;1;0;0;0;0;0;0;0;0.0;;;;;;;;;;
7;Cat1;Test listes à choix mulitple;Par défaut;5;3;0;0;0;0;0;0;0;0.0;;;;;;;;;;
8;Cat1;Tirage au sort (exemple);Formulaire pour tirage au sort;1;4;0;1;2;0;0;0;1;0.0;175.9640237115162;175.9640237115162;175.9640237115162;175.9640237115162;175.9640237115162;12.05;12.05;12.05;12.05;12.05
9;Cat1;Multipage;Par défaut;5;6;0;0;2;0;0;0;0;0.0;;;;;;;;;;
10;Cat1;Test enchaînement listes;Par défaut;5;2;0;1;0;0;0;0;0;0.0;;;;;;;;;;
1 Catégorie Formulaire Workflow Nombre de statuts Nombre de champs Nombre de champs de traitement Nombre de champs avec conditions Nombre de pages Nombre de sauts sur expiration Nombre de sauts sur trigger Nombre de sauts sur condition Nombre de demandes Usage du disque (en Mo) Âge (min) Âge (25%) Âge (50%) Âge (75%) Âge (max) Heure de réception (min) Heure de réception (25%) Heure de réception (50%) Heure de réception (75%) Heure de réception (max)
2 0 Cat1 Test agenda lock RdV 5 5 1 0 2 0 0 0 4 0.0 293.07144195567133 293.0722926497772 293.07388987159146 294.48206406160307 298.70264566030096 9.383333333333333 9.433333333333334 9.458333333333332 11.679166666666667 18.316666666666666
3 1 Cat1 Test liste autocomplétion Par défaut 5 3 0 0 0 0 0 0 0 0.0
4 2 Cat1 Formulaire cible Workflow cible 5 3 2 0 0 0 0 0 2 0.0 717.8747407953472 717.8755365127922 717.8763322302373 717.8771279476823 717.8779236651274 14.116666666666667 14.133333333333333 14.15 14.166666666666668 14.183333333333334
5 3 Cat1 Formulaire initial Workflow avec re-soumission 6 8 1 0 1 0 0 0 5 0.0813455581665039 506.90012288534723 594.7640927918171 594.7742085317476 714.125690012338 717.879196955625 8.166666666666666 13.583333333333334 14.083333333333334 16.6 16.85
6 4 Coin Par défaut 5 0 0 0 0 0 0 0 0 0.0
7 5 Cat1 Test FranceConnect FranceConnect 5 1 0 0 0 0 0 0 3 0.0 315.8225188749421 315.8264019765278 315.83028507811343 315.83872836475115 315.84717165138886 14.85 15.05 15.25 15.35 15.45
8 6 Cat1 Test users datas Par défaut 5 1 0 0 0 0 0 0 0 0.0
9 7 Cat1 Test listes à choix mulitple Par défaut 5 3 0 0 0 0 0 0 0 0.0
10 8 Cat1 Tirage au sort (exemple) Formulaire pour tirage au sort 1 4 0 1 2 0 0 0 1 0.0 175.9640237115162 175.9640237115162 175.9640237115162 175.9640237115162 175.9640237115162 12.05 12.05 12.05 12.05 12.05
11 9 Cat1 Multipage Par défaut 5 6 0 0 2 0 0 0 0 0.0
12 10 Cat1 Test enchaînement listes Par défaut 5 2 0 1 0 0 0 0 0 0.0

23
cd06-audit/utils.py Normal file
View File

@ -0,0 +1,23 @@
import pathlib
import pandas as pd
def produce_csv(name, generator):
data_dir = pathlib.Path('data')
data_dir.mkdir(exist_ok=True)
data = []
for d in generator():
for key, value in list(d.items()):
if isinstance(value, pd.DataFrame):
if not value.empty:
df = value.describe()
for sub in ['min', '25%', '50%', '75%', 'max']:
d[f'{key} ({sub})'] = df[0][sub]
del d[key]
data.append(d)
df = pd.DataFrame(data)
with open(data_dir / f'{name}.csv', 'w') as fd:
df.to_csv(fd, sep=';')

88
cd06-audit/wcs-crawl.py Normal file
View File

@ -0,0 +1,88 @@
# https://dev.entrouvert.org/issues/63188#note-1
import datetime
import os
import ipdb
import pandas as pd
from quixote import get_publisher
from utils import produce_csv
from wcs.formdef import FormDef
from wcs.qommon.storage import NotEqual
pub = get_publisher()
tenant = os.path.basename(pub.app_dir)
print('tenant', tenant)
def hours(time):
return time.hour + time.minute / 60
# ventillation des demandes par formulaires, répartitions des fréquentations ...
def gen_formdef():
for formdef in FormDef.select():
count = formdef.data_class().count([NotEqual('status', 'draft')])
age = pd.DataFrame(
(
(datetime.datetime.now() - datetime.datetime(*formdata.receipt_time[:6])).total_seconds()
/ 86400
)
for formdata in formdef.data_class().select([NotEqual('status', 'draft')], iterator=True)
)
receipt_time = pd.DataFrame(
hours(datetime.datetime(*formdata.receipt_time[:6]).time())
for formdata in formdef.data_class().select([NotEqual('status', 'draft')], iterator=True)
)
seen_files = set()
disk_use = 0
for formdata in formdef.data_class().select([NotEqual('status', 'draft')], iterator=True):
for v in formdata.data.values():
if hasattr(v, 'qfilename'):
if v.qfilename not in seen_files:
seen_files.add(v.qfilename)
disk_use += os.path.getsize(v.get_fs_filename())
yield {
'Catégorie': formdef.category.name if formdef.category else '',
'Formulaire': formdef.name,
'Workflow': formdef.workflow.name,
'Nombre de statuts': len(formdef.workflow.possible_status),
'Nombre de champs': len(formdef.fields or []),
'Nombre de champs de traitement': len(formdef.workflow.get_backoffice_fields()),
'Nombre de champs avec conditions': len(
[field for field in formdef.fields or [] if field.condition]
),
'Nombre de pages': len([field for field in formdef.fields or [] if field.key == 'page']),
'Nombre de sauts sur expiration': len(
[
item
for status in formdef.workflow.possible_status
for item in status.items or []
if getattr(item, 'timeout', None)
]
),
'Nombre de sauts sur trigger': len(
[
item
for status in formdef.workflow.possible_status
for item in status.items or []
if getattr(item, 'trigger', None)
]
),
'Nombre de sauts sur condition': len(
[
item
for status in formdef.workflow.possible_status
for item in status.items or []
if item.condition
]
),
'Nombre de demandes': count,
'Âge': age,
'Heure de réception': receipt_time,
'Usage du disque (en Mo)': disk_use / (1024 * 1024),
}
with ipdb.launch_ipdb_on_exception():
produce_csv(f'wcs-{tenant}-formdefs', gen_formdef)

View File

@ -9,6 +9,10 @@ whitelist_externals =
uwsgi-core
deps =
django
uwsgidecorators
commands =
./install-uwsgi.sh
uwsgi-core -T -M --plugin python3 --http-socket :{env:PORT:3001} --wsgi-file app.py --mule=mule.py
mkdir -p spooler
# uwsgi-core -T -M --plugin python3 --spooler spooler --spooler-processes 3 --http-socket :{env:PORT:3001} --wsgi-file app.py --mule=mule.py --python-import uwsgi_spooler
uwsgi-core -T -M --plugin python3 --spooler spooler --spooler-processes 3 --http-socket :{env:PORT:3001} --wsgi-file app.py --spooler-quiet --python-import uwsgi_cron --spooler-python-import uwsgi_spooler
rm -rf spooler