/usr/share/pyshared/chirpui/reporting.py is in chirp 0.3.1-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | # Copyright 2011 Dan Smith <dsmith@danplanet.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# README:
#
# I know that collecting data is not very popular. I don't like it
# either. However, it's hard to tell what drivers people are using
# and I think it would be helpful if I had that information. This is
# completely optional, so you can turn it off if you want. It doesn't
# report anything other than version and model usage information. The
# code below is very conservative, and will disable itself if reporting
# fails even once or takes too long to perform. It's run in a thread
# so that the user shouldn't even notice it's happening.
#
import threading
import os
import time
from chirp import CHIRP_VERSION, platform
REPORT_URL = "http://chirp.danplanet.com/report/report.php?do_report"
ENABLED = True
DEBUG = os.getenv("CHIRP_DEBUG") == "y"
THREAD_SEM = threading.Semaphore(10) # Maximum number of outstanding threads
LAST = 0
LAST_TYPE = None
try:
# Don't let failure to import any of these modules cause trouble
from chirpui import config
import xmlrpclib
except:
ENABLED = False
def debug(string):
if DEBUG:
print string
def should_report():
if not ENABLED:
debug("Not reporting due to recent failure")
return False
conf = config.get()
if conf.get_bool("no_report"):
debug("Reporting disabled")
return False
return True
def _report_model_usage(model, direction, success):
global ENABLED
if direction not in ["live", "download", "upload", "import", "export", "importsrc"]:
print "Invalid direction `%s'" % direction
return True # This is a bug, but not fatal
model = "%s_%s" % (model.VENDOR, model.MODEL)
data = "%s,%s,%s" % (model, direction, success)
debug("Reporting model usage: %s" % data)
proxy = xmlrpclib.ServerProxy(REPORT_URL)
id = proxy.report_stats(CHIRP_VERSION,
platform.get_platform().os_version_string(),
"model_use",
data)
# If the server returns zero, it wants us to shut up
return id != 0
def _report_exception(stack):
global ENABLED
debug("Reporting exception")
proxy = xmlrpclib.ServerProxy(REPORT_URL)
id = proxy.report_exception(CHIRP_VERSION,
platform.get_platform().os_version_string(),
"exception",
stack)
# If the server returns zero, it wants us to shut up
return id != 0
def _report_misc_error(module, data):
global ENABLED
debug("Reporting misc error with %s" % module)
proxy = xmlrpclib.ServerProxy(REPORT_URL)
id = proxy.report_misc_error(CHIRP_VERSION,
platform.get_platform().os_version_string(),
module, data)
# If the server returns zero, it wants us to shut up
return id != 0
def _check_for_updates(callback):
debug("Checking for updates")
proxy = xmlrpclib.ServerProxy(REPORT_URL)
ver = proxy.check_for_updates(CHIRP_VERSION,
platform.get_platform().os_version_string())
debug("Server reports version %s is latest" % ver)
callback(ver)
return True
class ReportThread(threading.Thread):
def __init__(self, func, *args):
threading.Thread.__init__(self)
self.__func = func
self.__args = args
def _run(self):
try:
return self.__func(*self.__args)
except Exception, e:
debug("Failed to report: %s" % e)
return False
def run(self):
start = time.time()
result = self._run()
if not result:
# Reporting failed
ENABLED = False
elif (time.time() - start) > 15:
# Reporting took too long
debug("Time to report was %.2f sec -- Disabling" % \
(time.time()-start))
ENABLED = False
THREAD_SEM.release()
def dispatch_thread(func, *args):
global LAST
global LAST_TYPE
# If reporting is disabled or failing, bail
if not should_report():
debug("Reporting is disabled")
return
# If the time between now and the last report is less than 5 seconds, bail
delta = time.time() - LAST
if delta < 5 and func == LAST_TYPE:
debug("Throttling...")
return
LAST = time.time()
LAST_TYPE = func
# If there are already too many threads running, bail
if not THREAD_SEM.acquire(False):
debug("Too many threads already running")
return
t = ReportThread(func, *args)
t.start()
def report_model_usage(model, direction, success):
dispatch_thread(_report_model_usage, model, direction, success)
def report_exception(stack):
dispatch_thread(_report_exception, stack)
def report_misc_error(module, data):
dispatch_thread(_report_misc_error, module, data)
# Calls callback with the latest version
def check_for_updates(callback):
dispatch_thread(_check_for_updates, callback)
|