From 6c66b66a0c967a7d33e5864a0c826500a4e11553 Mon Sep 17 00:00:00 2001 From: Anastasiia Pnevskaia Date: Fri, 4 Jul 2025 15:29:44 +0200 Subject: [PATCH 1/5] Usage group event, OS info. --- src/backend/backend_ga4.py | 1 + src/main.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/backend/backend_ga4.py b/src/backend/backend_ga4.py index 65eff7f..eb6c49a 100644 --- a/src/backend/backend_ga4.py +++ b/src/backend/backend_ga4.py @@ -56,6 +56,7 @@ def __init__(self, tid: str = None, app_name: str = None, app_version: str = Non self.default_message_attrs = { 'app_name': self.app_name, 'app_version': self.app_version, + 'os': system(), } self.stats = {} diff --git a/src/main.py b/src/main.py index 445a33f..ea2eb53 100644 --- a/src/main.py +++ b/src/main.py @@ -305,7 +305,21 @@ def get_stats(self): usage_count += 1 else: usage_count = 1 + if usage_count is None or usage_count <= 0: + log.warning("Invalid usage count.") + return data data["usage_count"] = usage_count + if usage_count == 1: + data["usage_group"] = "first_usage" + elif usage_count <= 100: + data["usage_group"] = "1-100_usages" + elif usage_count <= 1000: + data["usage_group"] = "101-1000_usages" + elif usage_count <= 5000: + data["usage_group"] = "1001-5000_usages" + else: + data["usage_group"] = "5000+_usages" + stats.update_stats(data) return data From f5b9c9427622a47c2c3ab30d70fe83c3893bbfed Mon Sep 17 00:00:00 2001 From: Anastasiia Pnevskaia Date: Fri, 4 Jul 2025 16:56:37 +0200 Subject: [PATCH 2/5] Test updated. --- src/main_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main_test.py b/src/main_test.py index 9622095..c9395d8 100644 --- a/src/main_test.py +++ b/src/main_test.py @@ -74,7 +74,8 @@ def make_message(self, client_id, app_name, app_version, category, action, label 'app_name': app_name, 'app_version': app_version, 'usage_count': 1, - 'docker': 'False'} + 'docker': 'False', + 'usage_group': 'first_usage'} } ]} From 63f16be5b340d09c16b71450e84e0f47a2559203 Mon Sep 17 00:00:00 2001 From: Anastasiia Pnevskaia Date: Fri, 4 Jul 2025 17:03:39 +0200 Subject: [PATCH 3/5] Update test. --- src/main_test.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main_test.py b/src/main_test.py index c9395d8..e3d50a9 100644 --- a/src/main_test.py +++ b/src/main_test.py @@ -4,6 +4,7 @@ import os import unittest import uuid +from platform import system from tempfile import TemporaryDirectory from unittest.mock import MagicMock, call, patch @@ -73,8 +74,9 @@ def make_message(self, client_id, app_name, app_version, category, action, label 'session_id': session_id, 'app_name': app_name, 'app_version': app_version, - 'usage_count': 1, + 'os': system(), 'docker': 'False', + 'usage_count': 1, 'usage_group': 'first_usage'} } ]} From 1a3607f8d2c4da3183cb36b08aeed4e9fe398600 Mon Sep 17 00:00:00 2001 From: Anastasiia Pnevskaia Date: Mon, 7 Jul 2025 10:51:30 +0200 Subject: [PATCH 4/5] Fixed errors. --- src/main.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.py b/src/main.py index ea2eb53..aade9ad 100644 --- a/src/main.py +++ b/src/main.py @@ -57,6 +57,11 @@ def __init__(self, app_name: str = None, app_version: str = None, tid: str = Non self.init(app_name, app_version, tid, backend, enable_opt_in_dialog, disable_in_ci) + if self.consent: + data = self.get_stats() + if data is not None and isinstance(data, dict): + self.backend.set_stats(data) + def init(self, app_name: str = None, app_version: str = None, tid: str = None, backend: [str, None] = 'ga', enable_opt_in_dialog=True, disable_in_ci=False): opt_in_checker = OptInChecker() @@ -77,11 +82,6 @@ def init(self, app_name: str = None, app_version: str = None, tid: str = None, if self.consent and not self.backend.cid_file_initialized(): self.backend.generate_new_cid_file() - if self.consent: - data = self.get_stats() - if data is not None and isinstance(data, dict): - self.backend.set_stats(data) - if not enable_opt_in_dialog and self.consent: # Try to create directory for client ID if it does not exist if not opt_in_checker.create_or_check_consent_dir(): @@ -301,14 +301,15 @@ def get_stats(self): return None if "usage_count" in data: usage_count = data["usage_count"] + if usage_count is None or not isinstance(usage_count, int) or usage_count <= 0: + log.warning("Invalid usage count.") + return data if usage_count < sys.maxsize: usage_count += 1 else: usage_count = 1 - if usage_count is None or usage_count <= 0: - log.warning("Invalid usage count.") - return data data["usage_count"] = usage_count + stats.update_stats(data) if usage_count == 1: data["usage_group"] = "first_usage" elif usage_count <= 100: @@ -320,7 +321,6 @@ def get_stats(self): else: data["usage_group"] = "5000+_usages" - stats.update_stats(data) return data @staticmethod From 0089029e15b8867dbd4ebdecfca9fba5d5f1d300 Mon Sep 17 00:00:00 2001 From: Anastasiia Pnevskaia Date: Mon, 7 Jul 2025 11:56:52 +0200 Subject: [PATCH 5/5] Fixed error. --- src/main.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.py b/src/main.py index aade9ad..25372b1 100644 --- a/src/main.py +++ b/src/main.py @@ -55,15 +55,10 @@ def __init__(self, app_name: str = None, app_version: str = None, tid: str = Non 'application name, version and TID.') return - self.init(app_name, app_version, tid, backend, enable_opt_in_dialog, disable_in_ci) - - if self.consent: - data = self.get_stats() - if data is not None and isinstance(data, dict): - self.backend.set_stats(data) + self.init(app_name, app_version, tid, backend, enable_opt_in_dialog, disable_in_ci, True) def init(self, app_name: str = None, app_version: str = None, tid: str = None, - backend: [str, None] = 'ga', enable_opt_in_dialog=True, disable_in_ci=False): + backend: [str, None] = 'ga', enable_opt_in_dialog=True, disable_in_ci=False, increment_stats=False): opt_in_checker = OptInChecker() opt_in_check_result = opt_in_checker.check(enable_opt_in_dialog, disable_in_ci) if enable_opt_in_dialog: @@ -82,6 +77,11 @@ def init(self, app_name: str = None, app_version: str = None, tid: str = None, if self.consent and not self.backend.cid_file_initialized(): self.backend.generate_new_cid_file() + if self.consent: + data = self.get_stats(increment_stats) + if data is not None and isinstance(data, dict): + self.backend.set_stats(data) + if not enable_opt_in_dialog and self.consent: # Try to create directory for client ID if it does not exist if not opt_in_checker.create_or_check_consent_dir(): @@ -291,7 +291,7 @@ def send_opt_in_event(self, new_state: OptInStatus, prev_state: OptInStatus = Op label = "{{prev_state:{}, new_state: {}}}".format(prev_state.value, new_state.value) self.send_event("opt_in", new_state.value, label, force_send=force_send) - def get_stats(self): + def get_stats(self, update_usage_num: bool): stats = StatsProcessor() file_exists, data = stats.get_stats() if not file_exists: @@ -304,7 +304,7 @@ def get_stats(self): if usage_count is None or not isinstance(usage_count, int) or usage_count <= 0: log.warning("Invalid usage count.") return data - if usage_count < sys.maxsize: + if usage_count < sys.maxsize and update_usage_num: usage_count += 1 else: usage_count = 1