Exemple #1
0
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)
Exemple #2
0
    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(' ', '&nbsp;')),
                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()