def open_link(url: QUrl): if url.scheme() == "orange": # define custom actions within Orange here if url.host() == "enable-statistics": settings = QSettings() settings.setValue("reporting/send-statistics", True) UsageStatistics.set_enabled(True) if not settings.contains('reporting/machine-id'): settings.setValue('reporting/machine-id', str(uuid.uuid4())) else: QDesktopServices.openUrl(url)
def send_statistics(url): """Send the statistics to the remote at `url`""" import json import requests settings = QSettings() if not settings.value( "error-reporting/send-statistics", False, type=bool): log.info("Not sending usage statistics (preferences setting).") return if not UsageStatistics.is_enabled(): log.info("Not sending usage statistics (disabled).") return if settings.contains('error-reporting/machine-id'): machine_id = settings.value('error-reporting/machine-id') else: machine_id = uuid.uuid4() settings.setValue('error-reporting/machine-id', machine_id) is_anaconda = 'Continuum' in sys.version or 'conda' in sys.version usage = UsageStatistics() data = usage.load() for d in data: d["Orange Version"] = d.pop("Application Version", "") d["Anaconda"] = is_anaconda d["UUID"] = machine_id try: r = requests.post(url, files={'file': json.dumps(data)}) if r.status_code != 200: log.warning( "Error communicating with server while attempting to send " "usage statistics.") return # success - wipe statistics file log.info("Usage statistics sent.") with open(usage.filename(), 'w', encoding="utf-8") as f: json.dump([], f) except (ConnectionError, requests.exceptions.RequestException): log.warning( "Connection error while attempting to send usage statistics.") except Exception: # pylint: disable=broad-except log.warning("Failed to send usage statistics.", exc_info=True)
def handle_exception(cls, exc): etype, evalue, tb = exc exception = traceback.format_exception_only(etype, evalue)[-1].strip() stacktrace = ''.join(traceback.format_exception(etype, evalue, tb)) def _find_last_frame(tb): if not tb: return None while tb.tb_next: tb = tb.tb_next return tb err_locals, err_module, frame = None, None, _find_last_frame(tb) if frame: err_module = '{}:{}'.format( frame.tb_frame.f_globals.get( '__name__', frame.tb_frame.f_code.co_filename), frame.tb_lineno) err_locals = OrderedDict(sorted(frame.tb_frame.f_locals.items())) err_locals = try_(lambda: pformat(err_locals), try_(lambda: str(err_locals))) def _find_widget_frame(tb): while tb: if isinstance(tb.tb_frame.f_locals.get('self'), OWBaseWidget): return tb tb = tb.tb_next widget_module = widget_class = widget = workflow = None frame = _find_widget_frame(tb) if frame is not None: widget = frame.tb_frame.f_locals['self'] # type: OWBaseWidget widget_class = widget.__class__ widget_module = '{}:{}'.format(widget_class.__module__, frame.tb_lineno) if widget is not None: try: workflow = widget.signalManager.parent() if not isinstance(workflow, WidgetsScheme): raise TypeError except Exception: workflow = None packages = ', '.join(sorted(get_installed_distributions())) settings = QSettings() if settings.contains('error-reporting/machine-id'): machine_id = settings.value('error-reporting/machine-id') else: machine_id = str(uuid.uuid4()) settings.setValue('error-reporting/machine-id', machine_id) # If this exact error was already reported in this session, # just warn about it # or if computer not connected to the internet if (err_module, widget_module) in cls._cache or not internet_on(): QMessageBox( QMessageBox.Warning, 'Error Encountered', 'Error encountered{}:<br><br><tt>{}</tt>'.format( (' in widget <b>{}</b>'.format(widget_class.name) if widget_class else ''), stacktrace.replace('\n', '<br>').replace(' ', ' ')), QMessageBox.Ignore).exec() return F = cls.DataField data = OrderedDict() data[F.EXCEPTION] = exception data[F.MODULE] = err_module if widget_class is not None: data[F.WIDGET_NAME] = widget_class.name data[F.WIDGET_MODULE] = widget_module if workflow is not None \ and QSettings().value('reporting/add-scheme', True, type=bool): fd, filename = mkstemp(prefix='ows-', suffix='.ows.xml') os.close(fd) try: with open(filename, "wb") as f: workflow.save_to(f, pretty=True, pickle_fallback=True) with open(filename, encoding='utf-8') as f: data[F.WIDGET_SCHEME] = f.read() except Exception: pass data[F.VERSION] = QApplication.applicationVersion() data[F.ENVIRONMENT] = 'Python {} on {} {} {} {}'.format( platform.python_version(), platform.system(), platform.release(), platform.version(), platform.machine()) data[F.INSTALLED_PACKAGES] = packages data[F.MACHINE_ID] = machine_id data[F.STACK_TRACE] = stacktrace if err_locals: data[F.LOCALS] = err_locals cls(data=data).exec()