Skip to content

Commit

Permalink
add google analytics stats
Browse files Browse the repository at this point in the history
  • Loading branch information
Sispheor committed Sep 15, 2018
1 parent 383ab40 commit afe401c
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 8 deletions.
5 changes: 4 additions & 1 deletion Tests/settings/settings_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,7 @@ var_files:
options:
deaf: True
mute: False
energy_threshold: 3000
energy_threshold: 3000

# send hit to anonymously evaluate the global usage of Kalliope app by users
send_anonymous_usage_stats: False
11 changes: 7 additions & 4 deletions Tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ def test_Settings(self):
cache_path="/tmp/kalliope",
resources=resources,
variables={"key1": "val1"},
options=options)
options=options,
send_anonymous_usage_stats=0)
setting1.kalliope_version = "0.4.5"

setting2 = Settings(default_tts_name="pico2wav",
Expand All @@ -280,7 +281,8 @@ def test_Settings(self):
cache_path="/tmp/kalliope",
resources=resources,
variables={"key1": "val1"},
options=options)
options=options,
send_anonymous_usage_stats=0)

setting3 = Settings(default_tts_name="pico2wav",
default_stt_name="google",
Expand All @@ -294,10 +296,11 @@ def test_Settings(self):
cache_path="/tmp/kalliope",
resources=resources,
variables={"key1": "val1"},
options=options)
options=options,
send_anonymous_usage_stats=0)
setting3.kalliope_version = "0.4.5"

expected_result_serialize = {'default_tts_name': 'pico2wav', 'default_stt_name': 'google', 'default_trigger_name': 'swoyboy', 'default_player_name': 'mplayer', 'ttss': [{'name': 'tts1', 'parameters': {}}], 'stts': [{'name': 'stt1', 'parameters': {}}], 'triggers': [{'name': 'snowboy', 'parameters': {}}], 'players': [{'name': 'player1', 'parameters': None}], 'rest_api': {'password_protected': True, 'login': 'admin', 'password': 'password', 'active': True, 'port': 5000, 'allowed_cors_origin': '*'}, 'cache_path': '/tmp/kalliope', 'resources': {'neuron_folder': None, 'stt_folder': None, 'tts_folder': None, 'trigger_folder': None, 'signal_folder': None}, 'variables': {'key1': 'val1'}, 'machine': 'pumpkins', 'kalliope_version': '0.4.5', 'options': {'name': 'Options', 'energy_threshold': 4000, 'adjust_for_ambient_noise_second': 0, 'deaf': None, 'mute': None, 'stt_timeout': 0}, 'hooks': None}
expected_result_serialize = {'default_tts_name': 'pico2wav', 'default_stt_name': 'google', 'default_trigger_name': 'swoyboy', 'default_player_name': 'mplayer', 'ttss': [{'name': 'tts1', 'parameters': {}}], 'stts': [{'name': 'stt1', 'parameters': {}}], 'triggers': [{'name': 'snowboy', 'parameters': {}}], 'players': [{'name': 'player1', 'parameters': None}], 'rest_api': {'password_protected': True, 'login': 'admin', 'password': 'password', 'active': True, 'port': 5000, 'allowed_cors_origin': '*'}, 'cache_path': '/tmp/kalliope', 'resources': {'neuron_folder': None, 'stt_folder': None, 'tts_folder': None, 'trigger_folder': None, 'signal_folder': None}, 'variables': {'key1': 'val1'}, 'machine': 'pumpkins', 'kalliope_version': '0.4.5', 'options': {'name': 'Options', 'energy_threshold': 4000, 'adjust_for_ambient_noise_second': 0, 'deaf': None, 'mute': None, 'stt_timeout': 0}, 'hooks': None, 'send_anonymous_usage_stats': 0}

self.maxDiff = None
self.assertDictEqual(expected_result_serialize, setting1.serialize())
Expand Down
4 changes: 3 additions & 1 deletion Tests/test_settings_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def setUp(self):
'on_processed_synapses': None,
'on_start_speaking': None,
'on_stop_speaking': None
}
},
'send_anonymous_usage_stats': 0
}

# Init the folders, otherwise it raises an exceptions
Expand Down Expand Up @@ -146,6 +147,7 @@ def test_get_settings(self):
'on_start_speaking': None,
'on_stop_speaking': None,
}
settings_object.send_anonymous_usage_stats = 0

sl = SettingLoader(file_path=self.settings_file_to_test)

Expand Down
15 changes: 15 additions & 0 deletions docs/settings/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -577,3 +577,18 @@ options:
```

>**Note:** The number of second here represents the time between kalliope's awakening and the moment when you can give her your order.


## send_anonymous_usage_stats

This flag allow Kalliope to send some stats in order to anonymously evaluate the global usage of Kalliope app by users.

Syntax:
```yml
send_anonymous_usage_stats: <boolean>
```

E.g:
```yml
send_anonymous_usage_stats: False
```
22 changes: 22 additions & 0 deletions kalliope/core/ConfigurationManager/SettingLoader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import logging
import os
import uuid

from six import with_metaclass

from kalliope.core.Models.settings.Options import Options
Expand Down Expand Up @@ -113,6 +115,7 @@ def _get_settings(self):
variables = self._get_variables(settings)
options = self._get_options(settings)
hooks = self._get_hooks(settings)
send_anonymous_usage_stats = self._get_anonymous_usage_stats(settings)

# Load the setting singleton with the parameters
setting_object.default_tts_name = default_tts_name
Expand All @@ -129,6 +132,7 @@ def _get_settings(self):
setting_object.variables = variables
setting_object.options = options
setting_object.hooks = hooks
setting_object.send_anonymous_usage_stats = send_anonymous_usage_stats

return setting_object

Expand Down Expand Up @@ -685,3 +689,21 @@ def _get_hooks(settings):
hooks[key] = None

return hooks

def _get_anonymous_usage_stats(self, settings):

cid = uuid.uuid4().hex
try:
send_anonymous_usage_stats = settings["send_anonymous_usage_stats"]
bool_send_anonymous_usage_stats = Utils.str_to_bool(send_anonymous_usage_stats)
if bool_send_anonymous_usage_stats:
# generate a unique user ID
send_anonymous_usage_stats = cid
else: # the user choose to disable stats
send_anonymous_usage_stats = 0

except KeyError:
# if the user haven't set this flag
send_anonymous_usage_stats = cid
logger.debug("[SettingsLoader] send_anonymous_usage_stats: %s" % send_anonymous_usage_stats)
return send_anonymous_usage_stats
9 changes: 9 additions & 0 deletions kalliope/core/HookManager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from kalliope._version import version_str
from kalliope.core.ConfigurationManager import SettingLoader
import logging

from kalliope.core.Utils.google_tracking import GoogleTracking

logging.basicConfig()
logger = logging.getLogger("kalliope")

Expand All @@ -17,6 +20,12 @@ def on_waiting_for_trigger(cls):

@classmethod
def on_triggered(cls):
sl = SettingLoader()
gt = GoogleTracking(cid=sl.settings.send_anonymous_usage_stats,
kalliope_version=version_str,
category='synapse',
action='execute')
gt.start()
return cls.execute_synapses_in_hook_name("on_triggered")

@classmethod
Expand Down
7 changes: 5 additions & 2 deletions kalliope/core/Models/settings/Settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def __init__(self,
resources=None,
variables=None,
options=None,
hooks=None):
hooks=None,
send_anonymous_usage_stats=None):

self.default_tts_name = default_tts_name
self.default_stt_name = default_stt_name
Expand All @@ -40,6 +41,7 @@ def __init__(self,
self.kalliope_version = current_kalliope_version
self.options = options
self.hooks = hooks
self.send_anonymous_usage_stats = send_anonymous_usage_stats

def serialize(self):
"""
Expand All @@ -64,7 +66,8 @@ def serialize(self):
'machine': self.machine,
'kalliope_version': self.kalliope_version,
'options': self.options.serialize(),
'hooks': self.hooks
'hooks': self.hooks,
'send_anonymous_usage_stats': self.send_anonymous_usage_stats
}

def __str__(self):
Expand Down
56 changes: 56 additions & 0 deletions kalliope/core/Utils/google_tracking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import logging
from threading import Thread

import requests

GA_TRACKING_ID = "UA-124800612-1"

logging.basicConfig()
logger = logging.getLogger("kalliope")
logger.setLevel(logging.DEBUG)


class GoogleTracking(Thread):
"""
send hit to Google Analytics
allow to anonymously evaluate the global usage of Kalliope app by users
"""

def __init__(self, **kwargs):
super(GoogleTracking, self).__init__()
self.category = kwargs.get("category")
self.action = kwargs.get("action")
self.label = kwargs.get("label", None)
self.value = kwargs.get("value", 0)
self.kalliope_version = kwargs.get("kalliope_version", 0)

def run(self):
self.track_event(self.kalliope_version, self.category, self.action, self.label, self.value)

@staticmethod
def track_event(cid, kalliope_version, category, action, label=None, value=0):
# allowed parameters: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
data = {
'v': '1', # API Version.
'tid': GA_TRACKING_ID, # Tracking ID / Property ID.
'cid': cid, # unique user id
'an': "kalliope",
'av': kalliope_version,
'ds': 'api',
't': 'event', # Event hit type.
'ec': category, # Event category.
'ea': action, # Event action.
'el': label, # Event label.
'ev': value, # Event value, must be an integer
}
try:
response = requests.post(
'http://www.google-analytics.com/collect', data=data)

# If the request fails, this will raise a RequestException.
response.raise_for_status()

logger.debug("[GoogleTracking] hit sent: %s" % response.status_code)
except Exception as e:
logger.debug("[GoogleTracking] fail to send data: %s" % e)

3 changes: 3 additions & 0 deletions kalliope/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,6 @@ options:
# stt_timeout: 5 # Speech to text option
deaf: False
mute: False

# send hit to anonymously evaluate the global usage of Kalliope app by users
send_anonymous_usage_stats: False

0 comments on commit afe401c

Please sign in to comment.