Use of dataclass ¶
See also
1 """Calcul des statistiques journalière d'utilisation des programmes.
2
3
4 Exemples d'appel
5 =================
6
7 ::
8
9 python manage_dev.py update_stats_day
10
11
12 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:59] update_stats_day()
13 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='XXXXXXXXXXXXXXXXXX' stat_product_name.nb_total_logs=7
14 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.9.7' version.nb_logs=3 (42.86%)
15 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.0' version.nb_logs=2 (28.57%)
16 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.6.1' version.nb_logs=2 (28.57%)
17 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='YYYYYYYYYYYYYYYYYY' stat_product_name.nb_total_logs=2
18 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.9.7' version.nb_logs=1 (50.00%)
19 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.0' version.nb_logs=1 (50.00%)
20 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='ZZZZZZZZZZZZZZZZ' stat_product_name.nb_total_logs=1
21 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.2' version.nb_logs=1 (100.00%)
22 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='AAAAAAAAAAAAAAAAa' stat_product_name.nb_total_logs=1
23 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.0.0' version.nb_logs=1 (100.00%)
24 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='BBBBBBBBBBBBBBBBBBB' stat_product_name.nb_total_logs=1
25 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='1.3.38' version.nb_logs=1 (100.00%)
26
27
28 """
29
30
31 import logging
32 import pendulum
33 from typing import List, Dict
34
35 from django.core.management.base import BaseCommand
36
37 from programs.models import Program
38 from logs.models import LogHardwareId
39
40 logger = logging.getLogger(__name__)
41
42 from dataclasses import dataclass, field
43
44
45 @dataclass
46 class StatsProductNameVersion:
47 product_name: str
48 version: str = ""
49 nb_logs: int = 0
50 stats_product_name: "StatsProductName" = None
51
52 @property
53 def percent_logs(self):
54 percent = ""
55 p = self.nb_logs / self.stats_product_name.nb_total_logs
56 percent = f"({p:.2%})"
57 return percent
58
59 @dataclass
60 class StatsProductName:
61 product_name: str
62 nb_total_logs: int = 0
63 versions: List[StatsProductNameVersion] = field(default_factory=list)
64
65 logger = logging.getLogger(__name__)
66
67
68 class Command(BaseCommand):
69 """Calcul des statistiques journalières d'utilisation des programmes."""
70
71 def add_arguments(self, parser):
72 """
73 - https://docs.python.org/3/library/argparse.html
74 """
75
76 def handle(self, *args, **options):
77 logger.info("update_stats_day()")
78 now = pendulum.now()
79 list_stats_product_name = []
80 for product_name in Program.objects.filter(version_is_ready=True).values_list("product_name", flat=True).distinct():
81 stats_product_name = StatsProductName(product_name=product_name)
82 logs_hardware = LogHardwareId.objects.filter(
83 date_connexion__year=now.year,
84 date_connexion__month=now.month,
85 date_connexion__day=now.day,
86 product_name=product_name,
87 ).order_by("product_name", "-version")
88 if logs_hardware.exists():
89 # il existe des logs hardware pour ce programme (product_name)
90 list_stats_product_name.append(stats_product_name)
91 stats_product_name.nb_total_logs = len(logs_hardware)
92 current_version = None
93 for log in logs_hardware:
94 if current_version is None or current_version != log.version:
95 # nouvelle version ou changement de version
96 product_name_version = StatsProductNameVersion(product_name=product_name, version=log.version, stats_product_name=stats_product_name)
97 current_version = log.version
98 stats_product_name.versions.append(product_name_version)
99
100 product_name_version.nb_logs = product_name_version.nb_logs + 1
101
102 for stat_product_name in list_stats_product_name:
103 logger.info(f"{stat_product_name.product_name=} {stat_product_name.nb_total_logs=}")
104 for version in stat_product_name.versions:
105
106 logger.info(f" - {version.version=} {version.nb_logs=} {version.percent_logs}")