Exemple #1
0
def error_handler(cls, err, tb, action=""):
    title = "Application aborted"
    if action:
        title += f" while {action}"
    msg = f"{cls.__name__}: {err}"
    # Try writing traceback to stderr
    try:
        tb_info = "".join(traceback.format_list(traceback.extract_tb(tb)))
        write(f"{title}\n{msg}\n{tb_info}")
    except Exception:
        pass
    # Use dialite to show error in modal window
    if not TESTING:
        dialite.fail(title, msg)
Exemple #2
0
def test_unsupported_platform1():
    """ Unsupported platform, fallback to terminal. """

    o_platform = sys.platform
    o_stdin = sys.stdin
    o_app = dialite._the_app

    sys.platform = 'meh'

    sys.stdin = FakeStdin()

    try:

        app = dialite._get_app(True)
        assert app.works()
        assert isinstance(app, TerminalApp)

        assert dialite.is_supported()

        with capture_log('info') as log:
            dialite.inform()
        assert len(log) == 1 and 'Info: ' in log[0]

        with capture_log('info') as log:
            dialite.warn()  # no problem
        assert len(log) == 1 and 'Warning: ' in log[0]

        with capture_log('info') as log:
            dialite.fail()
        assert len(log) == 1 and 'Error: ' in log[0]

        assert dialite.ask_ok()
        assert dialite.ask_retry()
        assert dialite.ask_yesno()

        sys.stdin.answer = 'no'
        assert not dialite.ask_ok()
        assert not dialite.ask_retry()
        assert not dialite.ask_yesno()

    finally:
        sys.platform = o_platform
        sys.stdin = o_stdin
        dialite._the_app = o_app
Exemple #3
0
def test_unsupported_platform2():
    """ Unsupported platform, and also no terminal. """

    o_platform = sys.platform
    o_stdin = sys.stdin
    o_app = dialite._the_app
    o_open = webbrowser.open

    sys.platform = 'meh'
    sys.stdin = None
    webbrowser.open = lambda x: None

    try:

        app = dialite._get_app(True)
        assert app.works()
        assert isinstance(app, StubApp)

        assert not dialite.is_supported()

        dialite.inform()  # no problem

        dialite.warn()  # no problem

        dialite.fail()  # no problem
        # with raises(SystemExit):
        #     dialite.fail()

        with raises(SystemExit):
            dialite.ask_ok()

        with raises(SystemExit):
            dialite.ask_retry()

        with raises(SystemExit):
            dialite.ask_yesno()

    finally:
        sys.platform = o_platform
        sys.stdin = o_stdin
        dialite._the_app = o_app
        webbrowser.open = o_open
Exemple #4
0
def test_osx():
    """ Pretend that this is OS X. """

    o_platform = sys.platform
    o_app = dialite._the_app
    sys.platform = 'darwin'

    try:

        app = FakeOSXApp()
        # assert app.works()
        assert isinstance(app, OSXApp)
        dialite._the_app = app

        assert dialite.is_supported()

        dialite.inform()
        assert len(app._messages) == 1

        dialite.warn()
        assert len(app._messages) == 2

        dialite.fail()
        assert len(app._messages) == 3

        assert dialite.ask_ok()
        assert len(app._messages) == 4

        assert dialite.ask_retry()
        assert len(app._messages) == 5

        assert dialite.ask_yesno()
        assert len(app._messages) == 6

    finally:
        sys.platform = o_platform
        dialite._the_app = o_app
Exemple #5
0
def test_linux():
    """ Pretend that this is Linux. """

    o_platform = sys.platform
    o_app = dialite._the_app
    sys.platform = 'linux'

    try:

        app = FakeLinuxApp()
        # assert app.works()
        assert isinstance(app, LinuxApp)
        dialite._the_app = app

        assert dialite.is_supported()

        dialite.inform()
        assert len(app._messages) == 1 and 'info' in app._messages[-1]

        dialite.warn()
        assert len(app._messages) == 2 and 'warn' in app._messages[-1]

        dialite.fail()
        assert len(app._messages) == 3 and 'error' in app._messages[-1]

        assert dialite.ask_ok()
        assert len(app._messages) == 4 and 'question' in app._messages[-1]

        assert dialite.ask_retry()
        assert len(app._messages) == 5 and 'question' in app._messages[-1]

        assert dialite.ask_yesno()
        assert len(app._messages) == 6 and 'question' in app._messages[-1]

    finally:
        sys.platform = o_platform
        dialite._the_app = o_app
Exemple #6
0
assert res is True

# Three message boxes

res = dialite.inform(
    PREFIX + "info",
    "Awesome! "
    "We will now show three dialogs: info, warn, error. "
    "This is the first one; an info dialog.",
)
assert res is None

res = dialite.warn(PREFIX + "warn", "This is the second one; a warning.")
assert res is None

res = dialite.fail(PREFIX + "error", "This is the third one; an error.")
assert res is None

# Check results

res = dialite.ask_yesno(
    PREFIX + "check",
    "Did the past three boxes look something like an info, "
    "warning, and error dialog, and have only an OK option?",
)
assert res is True

# Check confirm

res = dialite.ask_ok(
    PREFIX + "confirm",
Exemple #7
0
def launch(url, runtime=None, **kwargs):
    """ Launch a web runtime in a new process.
    
    Parameters:
        url (str): The url to open, e.g. ``'http://python.org'``. To open a
            local file use ``'file://...'``.
        runtime (str) : The runtime(s) to use. E.g. 'app' will open in a
            desktop-app-like runtime, 'browser' in a browser runtime. One can
            target specific runtimes, e.g. 'nw-app' or 'edge-browser', or
            a selection, e.g. 'chrome-browser or firefox-browser'. Default
            is ``'app or browser'``.
            See below for more information on available runtimes.
        kwargs: addition arguments specific to the runtime. See the
            docs of the runtime classes.
    
    Returns:
        BaseRuntime: An object that represents the runtime. For
        Desktop runtimes it can be used to close the runtime.
    
    Browser runtimes:
    
    * browser: open in a browser. Firefox, Chrome and Edge are prefered over
      the default browser.
    * default-browser: open in the system default browser.
    * firefox-browser: open in Firefox browser.
    * chrome-browser: open in Chrome/Chromium browser.
    * googlechrome-browser or chromium-browser: like chrome-browser, but specific.
    * edge-browser: open in Microsoft Edge browser.
    * ie-browser: open in Microsoft Internet Explorer browser.
    * xx-browser: use webbrowser module to open in browser "xx".
    
    App runtimes:
    
    * app: open as desktop app, using firefox-app or nw-app
      (and chrome-app on Windows).
    * firerox-app: open as desktop app, using Firefox' app framework (Xul).
    * nw-app: open as desktop app using NW.js.
    * chrome-app: open as desktop-like app via Chrome/Chromium (only works well
      on Windows).
    * pyqt-app: open as desktop-like app using PyQt/PySide.
    
    The most developed app runtimes are Firefox and NW. The former requires
    the user to have Firefox installed. The latter can be installed by the user
    simply by downloading the archive. Firefox is lighter (memory-wise), while
    NW is based on Chromium, making it heavier. The other
    app runtimes are useful for testing or development, but should generally be
    avoided when distributing apps.
    
    """

    # Resolve backward compat names, and select default runtime if not given
    if runtime in _aliases_compat:
        logger.warn('Runtime name %s is deprecated, use %s instead.' %
                    (runtime, _aliases_compat[runtime]))
        runtime = _aliases_compat[runtime]
    if not runtime:
        runtime = 'app or browser'
    given_runtime = runtime

    # Normalize runtime, apply aliases
    runtimes = _expand_runtime_name(runtime)
    tried_runtimes = []
    errors = []

    # Attempt to launch runtimes, one by one
    for runtime in runtimes:
        rt, launched, err = _launch(url, runtime, **kwargs)
        if rt and launched:
            return rt  # Hooray!
        if rt:
            tried_runtimes.append(rt)
        if err:
            errors.append(str(err).strip())

    # We end up here only when no suitable runtime was found.
    # Note that default-browser will always work, so by default we wont
    # end up here. We can well get here when runtime is 'app' though.

    # Show dialog to the user with information on how to install a runtime.
    # It is important that this is a dialog and not printed to stdout for
    # cases where an app is frozen (e.g. with cx_Freeze), because there is
    # no stdout in that case. Dialite will fallback to stdout if there is no
    # way to create a dialog, and if there is a tty, and attempt to show a
    # webpage with an error message otherwise.
    messages = []
    if not tried_runtimes:
        messages.append('Given runtime name "%s" does '
                        'not resolve to any known runtimes.' % given_runtime)
    elif len(tried_runtimes) == 1:
        # This app needs exactly this runtime
        rt = tried_runtimes[0]
        name = given_runtime if given_runtime.endswith(
            '-browser') else rt.get_name()
        msg = 'Could not run app, because runtime %s ' % name
        msg += 'could not be used.' if errors else 'is not available.'
        messages.append(msg)
        if rt._get_install_instuctions():
            messages.append(rt._get_install_instuctions())
    else:
        # User has options
        seen = set()
        messages.append('Could not find a suitable runtime to run app. '
                        'Available options:')
        for c, rt in zip('ABCDEFGHIJK', tried_runtimes):
            if rt.get_name() in seen or not rt._get_install_instuctions():
                continue
            seen.add(rt.get_name())
            messages.append(c + ': ' + rt._get_install_instuctions())
    if errors:
        messages.append('Errors:')
        messages.extend(errors)
    messages = '\n\n'.join(messages)

    dialite.fail('Webruntime - No suitable runtime available', messages)

    raise ValueError('Could not detect a suitable backend among %r.' %
                     runtimes)
Exemple #8
0
    PREFIX + 'unicode', u'Do you see "double quotes", \'single quotes\', '
    u'a euro symbol (€), pi symbol (π), an A with a roof (Â)?')
assert res is True

# Three message boxes

res = dialite.inform(
    PREFIX + 'info', 'Awesome! '
    'We will now show three dialogs: info, warn, error. '
    'This is the first one; an info dialog.')
assert res is None

res = dialite.warn(PREFIX + 'warn', 'This is the second one; a warning.')
assert res is None

res = dialite.fail(PREFIX + 'error', 'This is the third one; an error.')
assert res is None

# Check results

res = dialite.ask_yesno(
    PREFIX + 'check', 'Did the past three boxes look something like an info, '
    'warning, and error dialog, and have only an OK option?')
assert res is True

# Check confirm

res = dialite.ask_ok(
    PREFIX + 'confirm', 'Great, I am going to asume all tests passed then!'
    'Press OK to continue.')
assert res is True