OpenShot Video Editor  2.0.0
metrics.py
Go to the documentation of this file.
1 ##
2 #
3 # @file
4 # @brief This file sends anonymous application metrics and errors over HTTP
5 # @author Jonathan Thomas <jonathan@openshot.org>
6 #
7 # @section LICENSE
8 #
9 # Copyright (c) 2008-2018 OpenShot Studios, LLC
10 # (http://www.openshotstudios.com). This file is part of
11 # OpenShot Video Editor (http://www.openshot.org), an open-source project
12 # dedicated to delivering high quality video editing and animation solutions
13 # to the world.
14 #
15 # OpenShot Video Editor is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation, either version 3 of the License, or
18 # (at your option) any later version.
19 #
20 # OpenShot Video Editor is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
27 #
28 
29 # idna encoding import required to prevent bug (unknown encoding: idna)
30 import encodings.idna
31 import requests
32 import platform
33 import threading
34 import urllib.parse
35 from copy import deepcopy
36 from classes import info
37 from classes import language
38 from classes.logger import log
39 from classes import settings
40 import openshot
41 
42 from PyQt5.QtCore import QT_VERSION_STR
43 from PyQt5.Qt import PYQT_VERSION_STR
44 
45 
46 # Get libopenshot version
47 libopenshot_version = openshot.GetVersion()
48 
49 # Get settings
51 
52 # Determine OS version
53 os_version = "X11; Linux %s" % platform.machine()
54 linux_distro = "None"
55 try:
56  if platform.system() == "Darwin":
57  v = platform.mac_ver()
58  os_version = "Macintosh; Intel Mac OS X %s" % v[0].replace(".", "_")
59  linux_distro = "OS X %s" % v[0]
60 
61  elif platform.system() == "Windows":
62  v = platform.win32_ver()
63  # TODO: Upgrade windows python (on build server) version to 3.5, so it correctly identifies Windows 10
64  os_version = "Windows NT %s; %s" % (v[0], v[1])
65  linux_distro = "Windows %s" % "-".join(platform.win32_ver())
66 
67  elif platform.system() == "Linux":
68  # Get the distro name and version (if any)
69  linux_distro = "-".join(platform.linux_distribution())
70 
71 except Exception as Ex:
72  log.error("Error determining OS version in metrics.py")
73 
74 # Build user-agent
75 user_agent = "Mozilla/5.0 (%s) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36" % os_version
76 
77 params = {
78  "cid" : s.get("unique_install_id"), # Unique install ID
79  "v" : 1, # Google Measurement API version
80  "tid" : "UA-4381101-5", # Google Analytic Tracking ID
81  "an" : info.PRODUCT_NAME, # App Name
82  "aip" : 1, # Anonymize IP
83  "aid" : "org.openshot.%s" % info.NAME, # App ID
84  "av" : info.VERSION, # App Version
85  "ul" : language.get_current_locale().replace('_','-').lower(), # Current Locale
86  "ua" : user_agent, # Custom User Agent (for OS, Processor, and OS version)
87  "cd1" : libopenshot_version.ToString(), # Dimension 1: libopenshot version
88  "cd2" : platform.python_version(), # Dimension 2: python version (i.e. 3.4.3)
89  "cd3" : QT_VERSION_STR, # Dimension 3: qt5 version (i.e. 5.2.1)
90  "cd4" : PYQT_VERSION_STR, # Dimension 4: pyqt5 version (i.e. 5.2.1)
91  "cd5" : linux_distro
92 }
93 
94 ##
95 # Track a GUI screen being shown
96 def track_metric_screen(screen_name):
97  metric_params = deepcopy(params)
98  metric_params["t"] = "screenview"
99  metric_params["cd"] = screen_name
100  metric_params["cid"] = s.get("unique_install_id")
101 
102  t = threading.Thread(target=send_metric, args=[metric_params])
103  t.start()
104 
105 ##
106 # Track a GUI screen being shown
107 def track_metric_event(event_action, event_label, event_category="General", event_value=0):
108  metric_params = deepcopy(params)
109  metric_params["t"] = "event"
110  metric_params["ec"] = event_category
111  metric_params["ea"] = event_action
112  metric_params["el"] = event_label
113  metric_params["ev"] = event_value
114  metric_params["cid"] = s.get("unique_install_id")
115 
116  t = threading.Thread(target=send_metric, args=[metric_params])
117  t.start()
118 
119 ##
120 # Track an error has occurred
121 def track_metric_error(error_name, is_fatal=False):
122  metric_params = deepcopy(params)
123  metric_params["t"] = "exception"
124  metric_params["exd"] = error_name
125  metric_params["exf"] = 0
126  if is_fatal:
127  metric_params["exf"] = 1
128 
129  t = threading.Thread(target=send_metric, args=[metric_params])
130  t.start()
131 
132 ##
133 # Track an exception/stacktrace has occurred
134 def track_exception_stacktrace(stacktrace, source):
135  t = threading.Thread(target=send_exception, args=[stacktrace, source])
136  t.start()
137 
138 ##
139 # Track a GUI screen being shown
140 def track_metric_session(is_start=True):
141  metric_params = deepcopy(params)
142  metric_params["t"] = "screenview"
143  metric_params["sc"] = "start"
144  metric_params["cd"] = "launch-app"
145  metric_params["cid"] = s.get("unique_install_id")
146  if not is_start:
147  metric_params["sc"] = "end"
148  metric_params["cd"] = "close-app"
149 
150  t = threading.Thread(target=send_metric, args=[metric_params])
151  t.start()
152 
153 ##
154 # Send anonymous metric over HTTP for tracking
155 def send_metric(params):
156  # Check if the user wants to send metrics and errors
157  if s.get("send_metrics"):
158 
159  url_params = urllib.parse.urlencode(params)
160  url = "http://www.google-analytics.com/collect?%s" % url_params
161 
162  # Send metric HTTP data
163  try:
164  r = requests.get(url, headers={"user-agent": user_agent}, verify=False)
165  log.info("Track metric: [%s] %s | (%s bytes)" % (r.status_code, r.url, len(r.content)))
166 
167  except Exception as Ex:
168  log.error("Failed to Track metric: %s" % (Ex))
169 
170 ##
171 # Send exception stacktrace over HTTP for tracking
172 def send_exception(stacktrace, source):
173  # Check if the user wants to send metrics and errors
174  if s.get("send_metrics"):
175 
176  data = urllib.parse.urlencode({ "stacktrace": stacktrace,
177  "platform": platform.system(),
178  "version": info.VERSION,
179  "source": source,
180  "unique_install_id": s.get("unique_install_id" )})
181  url = "http://www.openshot.org/exception/json/"
182 
183  # Send exception HTTP data
184  try:
185  r = requests.post(url, data=data, headers={"user-agent": user_agent, "content-type": "application/x-www-form-urlencoded"}, verify=False)
186  log.info("Track exception: [%s] %s | %s" % (r.status_code, r.url, r.text))
187 
188  except Exception as Ex:
189  log.error("Failed to Track exception: %s" % (Ex))
def track_exception_stacktrace(stacktrace, source)
Track an exception/stacktrace has occurred.
Definition: metrics.py:134
def send_metric(params)
Send anonymous metric over HTTP for tracking.
Definition: metrics.py:155
def track_metric_session(is_start=True)
Track a GUI screen being shown.
Definition: metrics.py:140
def send_exception(stacktrace, source)
Send exception stacktrace over HTTP for tracking.
Definition: metrics.py:172
def get_current_locale()
Get the current locale name from the current system.
Definition: language.py:111
def track_metric_event(event_action, event_label, event_category="General", event_value=0)
Track a GUI screen being shown.
Definition: metrics.py:107
def get_settings()
Get the current QApplication&#39;s settings instance.
Definition: settings.py:44
def track_metric_screen(screen_name)
Track a GUI screen being shown.
Definition: metrics.py:96
def track_metric_error(error_name, is_fatal=False)
Track an error has occurred.
Definition: metrics.py:121