From db5fa1eda6888a48d77c3535b671ee82651d83f6 Mon Sep 17 00:00:00 2001 From: wielas Date: Fri, 17 Nov 2023 14:37:11 +0100 Subject: [PATCH] Survey and telemetry consent status reset on new session /w initialization method refactor --- .../core/config/__init__.py | 4 +- flask_monitoringdashboard/core/telemetry.py | 83 +++++++++++-------- .../js/controllers/telemetryController.js | 4 +- flask_monitoringdashboard/static/js/app.js | 2 +- flask_monitoringdashboard/views/telemetry.py | 2 +- 5 files changed, 55 insertions(+), 40 deletions(-) diff --git a/flask_monitoringdashboard/core/config/__init__.py b/flask_monitoringdashboard/core/config/__init__.py index 164acd1a..ccc9625d 100644 --- a/flask_monitoringdashboard/core/config/__init__.py +++ b/flask_monitoringdashboard/core/config/__init__.py @@ -206,7 +206,7 @@ def __init__(self): self.telemetry_consent = False self.telemetry_session = 0 self.telemetry_headers = { - 'X-Parse-Application-Id': 'zwfDL1t45KjnXSF5ELGQajShV6eJiaKVmRFaQjUb', - 'X-Parse-REST-API-Key': 'Kr9nhaAKx04hJypCJzz5BziqbKf9Yq5Q7HsWDpI9', + 'X-Parse-Application-Id': '4nHPABwkHqOZzNrFduzNyKH8q7wmPFdOWvajfWU2', + 'X-Parse-REST-API-Key': 'zjv0WLI2K3UvpfzrfG4sPA6EykYyzZM4KxQk07Hs', 'Content-Type': 'application/json' } diff --git a/flask_monitoringdashboard/core/telemetry.py b/flask_monitoringdashboard/core/telemetry.py index 4aba59cd..3dd24127 100644 --- a/flask_monitoringdashboard/core/telemetry.py +++ b/flask_monitoringdashboard/core/telemetry.py @@ -1,8 +1,6 @@ import datetime import requests -from collections import Counter - from sqlalchemy import func from sqlalchemy.exc import NoResultFound, MultipleResultsFound, SQLAlchemyError @@ -12,6 +10,7 @@ def get_telemetry_user(session): + """Return a telemetry user object""" try: return session.query(TelemetryUser).one() @@ -26,6 +25,41 @@ def get_telemetry_user(session): get_telemetry_user(session) +def collect_general_telemetry_data(session, telemetry_user): + """ + Collects telemetry data and posts it to the remote database + """ + # collect endpoint and blueprint data + endpoints = session.query(Endpoint.name).all() + blueprints = set(get_blueprint(endpoint) for endpoint, in endpoints) + no_of_endpoints = len(endpoints) + no_of_blueprints = len(blueprints) + + # collect monitoring levels + counts = ( + session.query(Endpoint.monitor_level, func.count(Endpoint.monitor_level)) + .group_by(Endpoint.monitor_level) + .all() + ) + counts_dict = dict(counts) + level_zeros_count = counts_dict.get(0, 0) + level_ones_count = counts_dict.get(1, 0) + level_twos_count = counts_dict.get(2, 0) + level_threes_count = counts_dict.get(3, 0) + + data = {'endpoints': no_of_endpoints, + 'blueprints': no_of_blueprints, + 'time_accessed': telemetry_user.last_accessed.strftime('%Y-%m-%d %H:%M:%S'), + 'monitoring_0': level_zeros_count, + 'monitoring_1': level_ones_count, + 'monitoring_2': level_twos_count, + 'monitoring_3': level_threes_count, + } + + # post user data + post_to_back('UserSession', **data) + + def initialize_telemetry_session(session): """ Initializes the monitoring session by creating or updating an entry @@ -42,6 +76,14 @@ def initialize_telemetry_session(session): telemetry_user.last_accessed = datetime.datetime.utcnow() session.commit() + # reset telemetry and survey prompt if declined in previous session + if telemetry_user.monitoring_consent == 2: + telemetry_user.monitoring_consent = 1 + session.commit() + if telemetry_user.survey_filled == 2: + telemetry_user.survey_filled = 1 + session.commit() + # check if telemetry's been agreed on telemetry_config.telemetry_consent = True if telemetry_user.monitoring_consent == 3 else False @@ -50,38 +92,8 @@ def initialize_telemetry_session(session): telemetry_config.telemetry_initialized = True telemetry_config.telemetry_session = telemetry_user.times_accessed - # collect user data - endpoints = session.query(Endpoint.name).all() - print(endpoints) - print(type(endpoints)) - print(type(endpoints[0])) - print(type(endpoints[0].name)) - blueprints = set(get_blueprint(endpoint) for endpoint, in endpoints) - no_of_endpoints = len(endpoints) - no_of_blueprints = len(blueprints) - counts = ( - session.query(Endpoint.monitor_level, func.count(Endpoint.monitor_level)) - .group_by(Endpoint.monitor_level) - .all() - ) - # collect monitoring levels - counts_dict = dict(counts) - level_zeros_count = counts_dict.get(0, 0) - level_ones_count = counts_dict.get(1, 0) - level_twos_count = counts_dict.get(2, 0) - level_threes_count = counts_dict.get(3, 0) - - data = {'endpoints': no_of_endpoints, - 'blueprints': no_of_blueprints, - 'time_accessed': telemetry_user.last_accessed.strftime('%Y-%m-%d %H:%M:%S'), - 'monitoring_0': level_zeros_count, - 'monitoring_1': level_ones_count, - 'monitoring_2': level_twos_count, - 'monitoring_3': level_threes_count, - } - - # post user data - post_to_back('UserSession', **data) + # collect the data and send it to the remote database + collect_general_telemetry_data(session, telemetry_user) except (MultipleResultsFound, NoResultFound) as e: print(e) @@ -94,6 +106,9 @@ def initialize_telemetry_session(session): def post_to_back(class_name='Endpoints', **kwargs): + """ + Function to send telemetry data to remote database + """ if telemetry_config.telemetry_consent: back4app_endpoint = f'https://parseapi.back4app.com/classes/{class_name}' diff --git a/flask_monitoringdashboard/frontend/js/controllers/telemetryController.js b/flask_monitoringdashboard/frontend/js/controllers/telemetryController.js index 5ac5835f..64aa6bdb 100644 --- a/flask_monitoringdashboard/frontend/js/controllers/telemetryController.js +++ b/flask_monitoringdashboard/frontend/js/controllers/telemetryController.js @@ -44,8 +44,8 @@ export function TelemetryController($scope, $http, $window) { // Configuration for HTTP requests to Back4App var config = { headers: { - 'X-Parse-Application-Id': 'zwfDL1t45KjnXSF5ELGQajShV6eJiaKVmRFaQjUb', - 'X-Parse-REST-API-Key': 'Kr9nhaAKx04hJypCJzz5BziqbKf9Yq5Q7HsWDpI9', + 'X-Parse-Application-Id': '4nHPABwkHqOZzNrFduzNyKH8q7wmPFdOWvajfWU2', + 'X-Parse-REST-API-Key': 'zjv0WLI2K3UvpfzrfG4sPA6EykYyzZM4KxQk07Hs', 'Content-Type': 'application/json' } }; diff --git a/flask_monitoringdashboard/static/js/app.js b/flask_monitoringdashboard/static/js/app.js index 79d8fcb8..fc543e5c 100644 --- a/flask_monitoringdashboard/static/js/app.js +++ b/flask_monitoringdashboard/static/js/app.js @@ -236,7 +236,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TelemetryController: () => (/* binding */ TelemetryController)\n/* harmony export */ });\nfunction TelemetryController($scope, $http, $window) {\r\n\r\n // Check if telemetry response is already stored in local storage\r\n const telemetryAnswered = $window.localStorage.getItem('telemetryAnswered') === 'true';\r\n\r\n // Control the visibility of the telemetry prompt based on previous response\r\n $scope.telemetryShow = !telemetryAnswered;\r\n $scope.followUpShow = false;\r\n\r\n // Function to fetch telemetry consent status from database \r\n $scope.fetchTelemetryConsent = function () {\r\n $http.get(`/dashboard/telemetry/get_is_telemetry_answered`)\r\n .then(function (response) {\r\n $scope.telemetryShow = !response.data.is_telemetry_answered;\r\n }, function (error) {\r\n console.error('Error fetching telemetry consent:', error);\r\n });\r\n };\r\n $scope.fetchTelemetryConsent();\r\n\r\n // Function to handle user response to telemetry prompt\r\n $scope.handleTelemetry = function (consent) {\r\n $scope.telemetryShow = false;\r\n $scope.followUpShow = !consent;\r\n\r\n $http.post('/dashboard/telemetry/accept_telemetry_consent', { 'consent': consent })\r\n .then(function (response) {\r\n $scope.telemetryShow = false;\r\n $window.localStorage.setItem('telemetryAnswered', 'true');\r\n }, function (error) {\r\n console.error('Error updating telemetry consent:', error);\r\n });\r\n };\r\n\r\n // Object to track reasons for declining telemetry\r\n $scope.reasons = {\r\n privacy: false,\r\n performance: false,\r\n trust: false,\r\n other: false\r\n };\r\n $scope.customReason = '';\r\n\r\n // Configuration for HTTP requests to Back4App\r\n var config = {\r\n headers: {\r\n 'X-Parse-Application-Id': 'zwfDL1t45KjnXSF5ELGQajShV6eJiaKVmRFaQjUb',\r\n 'X-Parse-REST-API-Key': 'Kr9nhaAKx04hJypCJzz5BziqbKf9Yq5Q7HsWDpI9',\r\n 'Content-Type': 'application/json'\r\n }\r\n };\r\n\r\n // Function to submit follow-up feedback\r\n $scope.submitFollowUp = function () {\r\n $scope.followUpShow = false;\r\n\r\n var feedback = [];\r\n for (var key in $scope.reasons) {\r\n if ($scope.reasons[key]) {\r\n if (key === 'other') {\r\n feedback.push(key);\r\n if ($scope.customReason.trim() !== '') {\r\n feedback.push({ other: $scope.customReason });\r\n }\r\n } else {\r\n feedback.push(key);\r\n }\r\n }\r\n }\r\n\r\n $http.post('https://parseapi.back4app.com/classes/FollowUp', { reasons: feedback }, config)\r\n .then(function (response) {\r\n }, function (error) {\r\n console.error('Error sending feedback:', error);\r\n });\r\n };\r\n}\n\n//# sourceURL=webpack://frontend/./js/controllers/telemetryController.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TelemetryController: () => (/* binding */ TelemetryController)\n/* harmony export */ });\nfunction TelemetryController($scope, $http, $window) {\r\n\r\n // Check if telemetry response is already stored in local storage\r\n const telemetryAnswered = $window.localStorage.getItem('telemetryAnswered') === 'true';\r\n\r\n // Control the visibility of the telemetry prompt based on previous response\r\n $scope.telemetryShow = !telemetryAnswered;\r\n $scope.followUpShow = false;\r\n\r\n // Function to fetch telemetry consent status from database \r\n $scope.fetchTelemetryConsent = function () {\r\n $http.get(`/dashboard/telemetry/get_is_telemetry_answered`)\r\n .then(function (response) {\r\n $scope.telemetryShow = !response.data.is_telemetry_answered;\r\n }, function (error) {\r\n console.error('Error fetching telemetry consent:', error);\r\n });\r\n };\r\n $scope.fetchTelemetryConsent();\r\n\r\n // Function to handle user response to telemetry prompt\r\n $scope.handleTelemetry = function (consent) {\r\n $scope.telemetryShow = false;\r\n $scope.followUpShow = !consent;\r\n\r\n $http.post('/dashboard/telemetry/accept_telemetry_consent', { 'consent': consent })\r\n .then(function (response) {\r\n $scope.telemetryShow = false;\r\n $window.localStorage.setItem('telemetryAnswered', 'true');\r\n }, function (error) {\r\n console.error('Error updating telemetry consent:', error);\r\n });\r\n };\r\n\r\n // Object to track reasons for declining telemetry\r\n $scope.reasons = {\r\n privacy: false,\r\n performance: false,\r\n trust: false,\r\n other: false\r\n };\r\n $scope.customReason = '';\r\n\r\n // Configuration for HTTP requests to Back4App\r\n var config = {\r\n headers: {\r\n 'X-Parse-Application-Id': '4nHPABwkHqOZzNrFduzNyKH8q7wmPFdOWvajfWU2',\r\n 'X-Parse-REST-API-Key': 'zjv0WLI2K3UvpfzrfG4sPA6EykYyzZM4KxQk07Hs',\r\n 'Content-Type': 'application/json'\r\n }\r\n };\r\n\r\n // Function to submit follow-up feedback\r\n $scope.submitFollowUp = function () {\r\n $scope.followUpShow = false;\r\n\r\n var feedback = [];\r\n for (var key in $scope.reasons) {\r\n if ($scope.reasons[key]) {\r\n if (key === 'other') {\r\n feedback.push(key);\r\n if ($scope.customReason.trim() !== '') {\r\n feedback.push({ other: $scope.customReason });\r\n }\r\n } else {\r\n feedback.push(key);\r\n }\r\n }\r\n }\r\n\r\n $http.post('https://parseapi.back4app.com/classes/FollowUp', { reasons: feedback }, config)\r\n .then(function (response) {\r\n }, function (error) {\r\n console.error('Error sending feedback:', error);\r\n });\r\n };\r\n}\n\n//# sourceURL=webpack://frontend/./js/controllers/telemetryController.js?"); /***/ }), diff --git a/flask_monitoringdashboard/views/telemetry.py b/flask_monitoringdashboard/views/telemetry.py index 5dbaa1c6..cca33acf 100644 --- a/flask_monitoringdashboard/views/telemetry.py +++ b/flask_monitoringdashboard/views/telemetry.py @@ -49,7 +49,7 @@ def survey_has_been_filled(): def get_is_telemetry_answered(): with session_scope() as session: telemetry_user = get_telemetry_user(session) - res = True if telemetry_user.monitoring_consent == 3 else False + res = True if telemetry_user.monitoring_consent == (2, 3) else False return {'is_telemetry_answered': res}