示例#1
0
def dirbrowser_html(path):
    """Get the directory browser web page.

    Args:
        path: The directory path.

    Return:
        The HTML of the web page.
    """
    title = "Browse directory: {}".format(path)

    if is_root(path):
        parent = None
    else:
        parent = parent_dir(path)

    try:
        all_files = os.listdir(path)
    except OSError as e:
        html = jinja.render('error.html',
                            title="Error while reading directory",
                            url='file:///{}'.format(path), error=str(e))
        return html.encode('UTF-8', errors='xmlcharrefreplace')

    files = get_file_list(path, all_files, os.path.isfile)
    directories = get_file_list(path, all_files, os.path.isdir)
    html = jinja.render('dirbrowser.html', title=title, url=path,
                        parent=parent, files=files, directories=directories)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#2
0
def qute_history(url):
    """Handler for qute://history. Display and serve history."""
    if url.path() == '/data':
        # Use start_time in query or current time.
        try:
            start_time = QUrlQuery(url).queryItemValue("start_time")
            start_time = float(start_time) if start_time else time.time()
        except ValueError as e:
            raise QuteSchemeError("Query parameter start_time is invalid", e)

        return 'text/html', json.dumps(history_data(start_time))
    else:
        if (
            config.get('content', 'allow-javascript') and
            (objects.backend == usertypes.Backend.QtWebEngine or
             qtutils.is_qtwebkit_ng())
        ):
            return 'text/html', jinja.render(
                'history.html',
                title='History',
                session_interval=config.get('ui', 'history-session-interval')
            )
        else:
            # Get current date from query parameter, if not given choose today.
            curr_date = datetime.date.today()
            try:
                query_date = QUrlQuery(url).queryItemValue("date")
                if query_date:
                    curr_date = datetime.datetime.strptime(query_date,
                        "%Y-%m-%d").date()
            except ValueError:
                log.misc.debug("Invalid date passed to qute:history: " +
                    query_date)

            one_day = datetime.timedelta(days=1)
            next_date = curr_date + one_day
            prev_date = curr_date - one_day

            # start_time is the last second of curr_date
            start_time = time.mktime(next_date.timetuple()) - 1
            history = [
                (i["url"], i["title"],
                 datetime.datetime.fromtimestamp(i["time"]/1000),
                 QUrl(i["url"]).host())
                for i in history_data(start_time) if "next" not in i
            ]

            return 'text/html', jinja.render(
                'history_nojs.html',
                title='History',
                history=history,
                curr_date=curr_date,
                next_date=next_date,
                prev_date=prev_date,
                today=datetime.date.today(),
            )
示例#3
0
def qute_warning(url):
    """Handler for qute://warning."""
    path = url.path()
    if path == '/old-qt':
        src = jinja.render('warning-old-qt.html',
                           title='Old Qt warning',
                           qt_version=qVersion())
    elif path == '/webkit':
        src = jinja.render('warning-webkit.html',
                           title='QtWebKit backend warning')
    else:
        raise NotFoundError("Invalid warning page {}".format(path))
    return 'text/html', src
示例#4
0
def qute_help(url):
    """Handler for qute:help."""
    try:
        utils.read_file('html/doc/index.html')
    except OSError:
        html = jinja.render(
            'error.html',
            title="Error while loading documentation",
            url=url.toDisplayString(),
            error="This most likely means the documentation was not generated "
                  "properly. If you are running qutebrowser from the git "
                  "repository, please run scripts/asciidoc2html.py. "
                  "If you're running a released version this is a bug, please "
                  "use :report to report it.",
            icon='',
            qutescheme=True)
        return 'text/html', html
    urlpath = url.path()
    if not urlpath or urlpath == '/':
        urlpath = 'index.html'
    else:
        urlpath = urlpath.lstrip('/')
    if not docutils.docs_up_to_date(urlpath):
        message.error("Your documentation is outdated! Please re-run "
                      "scripts/asciidoc2html.py.")
    path = 'html/doc/{}'.format(urlpath)
    if urlpath.endswith('.png'):
        return 'image/png', utils.read_file(path, binary=True)
    else:
        data = utils.read_file(path)
        return 'text/html', data
示例#5
0
def qute_settings(url):
    """Handler for qute://settings. View/change qute configuration."""
    global csrf_token

    if url.path() == '/set':
        if url.password() != csrf_token:
            message.error("Invalid CSRF token for qute://settings!")
            raise RequestDeniedError("Invalid CSRF token!")
        return _qute_settings_set(url)

    # Requests to qute://settings/set should only be allowed from
    # qute://settings. As an additional security precaution, we generate a CSRF
    # token to use here.
    if secrets:
        csrf_token = secrets.token_urlsafe()
    else:
        # On Python < 3.6, from secrets.py
        token = base64.urlsafe_b64encode(os.urandom(32))
        csrf_token = token.rstrip(b'=').decode('ascii')

    src = jinja.render('settings.html', title='settings',
                       configdata=configdata,
                       confget=config.instance.get_str,
                       csrf_token=csrf_token)
    return 'text/html', src
示例#6
0
 def _on_proxy_authentication_required(self, url, authenticator,
                                       proxy_host):
     """Called when a proxy needs authentication."""
     msg = "<b>{}</b> requires a username and password.".format(
         html_utils.escape(proxy_host))
     answer = message.ask(
         title="Proxy authentication required", text=msg,
         mode=usertypes.PromptMode.user_pwd,
         abort_on=[self.shutting_down, self.load_started])
     if answer is not None:
         authenticator.setUser(answer.user)
         authenticator.setPassword(answer.password)
     else:
         try:
             # pylint: disable=no-member, useless-suppression
             sip.assign(authenticator, QAuthenticator())
             # pylint: enable=no-member, useless-suppression
         except AttributeError:
             url_string = url.toDisplayString()
             error_page = jinja.render(
                 'error.html',
                 title="Error loading page: {}".format(url_string),
                 url=url_string, error="Proxy authentication required",
                 icon='')
             self.set_html(error_page)
示例#7
0
def qute_help(win_id, request):
    """Handler for qute:help. Return HTML content as bytes."""
    try:
        utils.read_file('html/doc/index.html')
    except OSError:
        html = jinja.render(
            'error.html',
            title="Error while loading documentation",
            url=request.url().toDisplayString(),
            error="This most likely means the documentation was not generated "
                  "properly. If you are running qutebrowser from the git "
                  "repository, please run scripts/asciidoc2html.py. "
                  "If you're running a released version this is a bug, please "
                  "use :report to report it.",
            icon='')
        return html.encode('UTF-8', errors='xmlcharrefreplace')
    urlpath = request.url().path()
    if not urlpath or urlpath == '/':
        urlpath = 'index.html'
    else:
        urlpath = urlpath.lstrip('/')
    if not docutils.docs_up_to_date(urlpath):
        message.error(win_id, "Your documentation is outdated! Please re-run "
                      "scripts/asciidoc2html.py.")
    path = 'html/doc/{}'.format(urlpath)
    if urlpath.endswith('.png'):
        return utils.read_file(path, binary=True)
    else:
        data = utils.read_file(path)
        return data.encode('UTF-8', errors='xmlcharrefreplace')
示例#8
0
def test_data_url():
    """Test data_url() which can be used from templates."""
    data = jinja.render('test3.html')
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert data == 'data:text/plain;base64,Zm9v'  # 'foo'
示例#9
0
def generate_pdfjs_page(filename, url):
    """Return the html content of a page that displays a file with pdfjs.

    Returns a string.

    Args:
        filename: The filename of the PDF to open.
        url: The URL being opened.
    """
    if not is_available():
        pdfjs_dir = os.path.join(standarddir.data(), 'pdfjs')
        return jinja.render('no_pdfjs.html',
                            url=url.toDisplayString(),
                            title="PDF.js not found",
                            pdfjs_dir=pdfjs_dir)
    html = get_pdfjs_res('web/viewer.html').decode('utf-8')

    script = _generate_pdfjs_script(filename)
    html = html.replace('</body>',
                        '</body><script>{}</script>'.format(script))
    # WORKAROUND for the fact that PDF.js tries to use the Fetch API even with
    # qute:// URLs.
    pdfjs_script = '<script src="../build/pdf.js"></script>'
    html = html.replace(pdfjs_script,
                        '<script>window.Response = undefined;</script>\n' +
                        pdfjs_script)
    return html
示例#10
0
    def _on_renderer_process_terminated(self, tab, status, code):
        """Show an error when a renderer process terminated."""
        if status == browsertab.TerminationStatus.normal:
            return

        messages = {
            browsertab.TerminationStatus.abnormal:
                "Renderer process exited with status {}".format(code),
            browsertab.TerminationStatus.crashed:
                "Renderer process crashed",
            browsertab.TerminationStatus.killed:
                "Renderer process was killed",
            browsertab.TerminationStatus.unknown:
                "Renderer process did not start",
        }
        msg = messages[status]

        def show_error_page(html):
            tab.set_html(html)
            log.webview.error(msg)

        if qtutils.version_check('5.9', compiled=False):
            url_string = tab.url(requested=True).toDisplayString()
            error_page = jinja.render(
                'error.html', title="Error loading {}".format(url_string),
                url=url_string, error=msg)
            QTimer.singleShot(100, lambda: show_error_page(error_page))
        else:
            # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-58698
            message.error(msg)
            self._remove_tab(tab, crashed=True)
            if self.count() == 0:
                self.tabopen(QUrl('about:blank'))
示例#11
0
    def certificateError(self, error):
        """Handle certificate errors coming from Qt."""
        self.certificate_error.emit()
        url = error.url()
        error = certificateerror.CertificateErrorWrapper(error)
        log.webview.debug("Certificate error: {}".format(error))

        url_string = url.toDisplayString()
        error_page = jinja.render(
            'error.html', title="Error loading page: {}".format(url_string),
            url=url_string, error=str(error), icon='')

        if error.is_overridable():
            ignore = shared.ignore_certificate_errors(
                url, [error], abort_on=[self.loadStarted, self.shutting_down])
        else:
            log.webview.error("Non-overridable certificate error: "
                              "{}".format(error))
            ignore = False

        # We can't really know when to show an error page, as the error might
        # have happened when loading some resource.
        # However, self.url() is not available yet and self.requestedUrl()
        # might not match the URL we get from the error - so we just apply a
        # heuristic here.
        # See https://bugreports.qt.io/browse/QTBUG-56207
        log.webview.debug("ignore {}, URL {}, requested {}".format(
            ignore, url, self.requestedUrl()))
        if not ignore and url.matches(self.requestedUrl(), QUrl.RemoveScheme):
            self.setHtml(error_page)

        return ignore
示例#12
0
def qute_plainlog(_win_id, _request):
    """Handler for qute:plainlog. Return HTML content as bytes."""
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        text = log.ram_handler.dump_log()
    html = jinja.render('pre.html', title='log', content=text)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#13
0
def test_not_found(caplog):
    """Test with a template which does not exist."""
    with caplog.at_level(logging.ERROR):
        data = jinja.render('does_not_exist.html')
    assert "The does_not_exist.html template could not be found!" in data

    assert caplog.records[0].msg.startswith("The does_not_exist.html template"
                                            " could not be loaded from")
示例#14
0
 def wrong_backend_handler(self, url):
     """Show an error page about using the invalid backend."""
     html = jinja.render('error.html',
                         title="Error while opening qute://url",
                         url=url.toDisplayString(),
                         error='{} is not available with this '
                               'backend'.format(url.toDisplayString()))
     return 'text/html', html
示例#15
0
def qute_log(_win_id, _request):
    """Handler for qute:log. Return HTML content as bytes."""
    if log.ram_handler is None:
        html_log = None
    else:
        html_log = log.ram_handler.dump_log(html=True)
    html = jinja.render('log.html', title='log', content=html_log)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#16
0
def qute_backend_warning(_url):
    """Handler for qute://backend-warning."""
    html = jinja.render('backend-warning.html',
                        distribution=version.distribution(),
                        Distribution=version.Distribution,
                        version=pkg_resources.parse_version,
                        title="Legacy backend warning")
    return 'text/html', html
示例#17
0
def qute_back(url):
    """Handler for qute://back.

    Simple page to free ram / lazy load a site, goes back on focusing the tab.
    """
    src = jinja.render(
        'back.html',
        title='Suspended: ' + urllib.parse.unquote(url.fragment()))
    return 'text/html', src
示例#18
0
 def _show_error_page(self, url, error):
     """Show an error page in the tab."""
     log.misc.debug("Showing error page for {}".format(error))
     url_string = url.toDisplayString()
     error_page = jinja.render(
         'error.html',
         title="Error loading page: {}".format(url_string),
         url=url_string, error=error)
     self.set_html(error_page)
示例#19
0
def qute_settings(url):
    """Handler for qute://settings. View/change qute configuration."""
    if url.path() == '/set':
        return _qute_settings_set(url)

    html = jinja.render('settings.html', title='settings',
                        configdata=configdata,
                        confget=config.instance.get_str)
    return 'text/html', html
示例#20
0
 def _show_source_fallback(self, source: str) -> None:
     """Show source with pygments unavailable."""
     html = jinja.render(
         'pre.html',
         title='Source',
         content=source,
         preamble="Note: The optional Pygments dependency wasn't found - "
         "showing unhighlighted source.",
     )
     self._show_html_source(html)
示例#21
0
 def _show_error_page(self, url, error):
     """Show an error page in the tab."""
     log.misc.debug("Showing error page for {}".format(error))
     url_string = url.toDisplayString()
     error_page = jinja.render(
         'error.html',
         title="Error loading page: {}".format(url_string),
         url=url_string,
         error=error)
     self.set_html(error_page)
示例#22
0
def test_utf8():
    """Test rendering with an UTF8 template.

    This was an attempt to get a failing test case for #127 but it seems
    the issue is elsewhere.

    https://github.com/The-Compiler/qutebrowser/issues/127
    """
    data = jinja.render('test.html', var='\u2603')
    assert data == "Hello \u2603"
示例#23
0
 def _show_pdfjs(self, reply):
     """Show the reply with pdfjs."""
     try:
         page = pdfjs.generate_pdfjs_page(reply.url())
     except pdfjs.PDFJSNotFound:
         page = jinja.render('no_pdfjs.html',
                             url=reply.url().toDisplayString())
     self.mainFrame().setContent(page.encode('utf-8'), 'text/html',
                                 reply.url())
     reply.deleteLater()
示例#24
0
def test_utf8():
    """Test rendering with an UTF8 template.

    This was an attempt to get a failing test case for #127 but it seems
    the issue is elsewhere.

    https://github.com/The-Compiler/qutebrowser/issues/127
    """
    data = jinja.render('test.html', var='\u2603')
    assert data == "Hello \u2603"
示例#25
0
 def _show_pdfjs(self, reply):
     """Show the reply with pdfjs."""
     try:
         page = pdfjs.generate_pdfjs_page(reply.url())
     except pdfjs.PDFJSNotFound:
         page = jinja.render('no_pdfjs.html',
                             url=reply.url().toDisplayString())
     self.mainFrame().setContent(page.encode('utf-8'), 'text/html',
                                 reply.url())
     reply.deleteLater()
示例#26
0
def test_undefined_function(caplog):
    """Make sure we don't crash if an undefined function is called."""
    with caplog.at_level(logging.ERROR):
        data = jinja.render('undef.html')
    assert 'There was an error while rendering undef.html' in data
    assert "'does_not_exist' is undefined" in data
    assert data.startswith('<!DOCTYPE html>')

    assert len(caplog.records) == 1
    assert caplog.records[0].msg == "UndefinedError while rendering undef.html"
示例#27
0
def qute_bookmarks(_win_id, _request):
    """Handler for qute:bookmarks. Display all quickmarks / bookmarks."""
    bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
                       key=lambda x: x[1])  # Sort by title
    quickmarks = sorted(objreg.get('quickmark-manager').marks.items(),
                        key=lambda x: x[0])  # Sort by name

    html = jinja.render('bookmarks.html',
                        title='Bookmarks',
                        bookmarks=bookmarks,
                        quickmarks=quickmarks)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#28
0
def qute_bookmarks(_url):
    """Handler for qute://bookmarks. Display all quickmarks / bookmarks."""
    bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
                       key=lambda x: x[1])  # Sort by title
    quickmarks = sorted(objreg.get('quickmark-manager').marks.items(),
                        key=lambda x: x[0])  # Sort by name

    src = jinja.render('bookmarks.html',
                       title='Bookmarks',
                       bookmarks=bookmarks,
                       quickmarks=quickmarks)
    return 'text/html', src
示例#29
0
def qute_bindings(_url):
    """Handler for qute://bindings. View keybindings."""
    bindings = {}
    defaults = config.val.bindings.default
    modes = set(defaults.keys()).union(config.val.bindings.commands)
    modes.remove('normal')
    modes = ['normal'] + sorted(list(modes))
    for mode in modes:
        bindings[mode] = config.key_instance.get_bindings_for(mode)

    src = jinja.render('bindings.html', title='Bindings', bindings=bindings)
    return 'text/html', src
示例#30
0
def qute_bookmarks(_url):
    """Handler for qute:bookmarks. Display all quickmarks / bookmarks."""
    bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
                       key=lambda x: x[1])  # Sort by title
    quickmarks = sorted(objreg.get('quickmark-manager').marks.items(),
                        key=lambda x: x[0])  # Sort by name

    html = jinja.render('bookmarks.html',
                        title='Bookmarks',
                        bookmarks=bookmarks,
                        quickmarks=quickmarks)
    return 'text/html', html
示例#31
0
def qute_bindings(_url):
    """Handler for qute://bindings. View keybindings."""
    bindings = {}
    defaults = config.val.bindings.default
    modes = set(defaults.keys()).union(config.val.bindings.commands)
    modes.remove('normal')
    modes = ['normal'] + sorted(list(modes))
    for mode in modes:
        bindings[mode] = config.key_instance.get_bindings_for(mode)

    src = jinja.render('bindings.html', title='Bindings',
                       bindings=bindings)
    return 'text/html', src
示例#32
0
def qute_start(_url: QUrl) -> _HandlerRet:
    """Handler for qute://start."""
    bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
                       key=lambda x: x[1])  # Sort by title
    quickmarks = sorted(objreg.get('quickmark-manager').marks.items(),
                        key=lambda x: x[0])  # Sort by name
    searchurl = config.val.url.searchengines['DEFAULT']
    page = jinja.render('startpage.html',
                        title='Welcome to qutebrowser',
                        bookmarks=bookmarks,
                        search_url=searchurl,
                        quickmarks=quickmarks)
    return 'text/html', page
示例#33
0
 def _on_authentication_required(self, url, authenticator):
     # FIXME:qtwebengine support .netrc
     answer = shared.authentication_required(
         url, authenticator, abort_on=[self.shutting_down,
                                       self.load_started])
     if answer is None:
         # WORKAROUND for
         # https://www.riverbankcomputing.com/pipermail/pyqt/2016-December/038400.html
         url_string = url.toDisplayString()
         error_page = jinja.render(
             'error.html',
             title="Error loading page: {}".format(url_string),
             url=url_string, error="Authentication required", icon='')
         self.set_html(error_page)
示例#34
0
def dirbrowser_html(path):
    """Get the directory browser web page.

    Args:
        path: The directory path.

    Return:
        The HTML of the web page.
    """
    title = "Browse directory: {}".format(path)

    if is_root(path):
        parent = None
    else:
        parent = parent_dir(path)

    try:
        all_files = os.listdir(path)
    except OSError as e:
        html = jinja.render('error.html',
                            title="Error while reading directory",
                            url='file:///{}'.format(path),
                            error=str(e),
                            icon='')
        return html.encode('UTF-8', errors='xmlcharrefreplace')

    files = get_file_list(path, all_files, os.path.isfile)
    directories = get_file_list(path, all_files, os.path.isdir)
    html = jinja.render('dirbrowser.html',
                        title=title,
                        url=path,
                        icon='',
                        parent=parent,
                        files=files,
                        directories=directories)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#35
0
    def _on_renderer_process_terminated(self, tab, status, code):
        """Show an error when a renderer process terminated."""
        if status == browsertab.TerminationStatus.normal:
            return

        messages = {
            browsertab.TerminationStatus.abnormal: "Renderer process exited",
            browsertab.TerminationStatus.crashed: "Renderer process crashed",
            browsertab.TerminationStatus.killed: "Renderer process was killed",
            browsertab.TerminationStatus.unknown:
            "Renderer process did not start",
        }
        msg = messages[status] + f" (status {code})"

        # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-91715
        versions = version.qtwebengine_versions()
        is_qtbug_91715 = (status == browsertab.TerminationStatus.unknown
                          and code == 1002
                          and versions.webengine == utils.VersionNumber(
                              5, 15, 3))

        def show_error_page(html):
            tab.set_html(html)
            log.webview.error(msg)

        if is_qtbug_91715:
            log.webview.error(msg)
            log.webview.error('')
            log.webview.error(
                'NOTE: If you see this and "Network service crashed, restarting '
                'service.", please see:')
            log.webview.error(
                'https://github.com/qutebrowser/qutebrowser/issues/6235')
            log.webview.error(
                'You can set the "qt.workarounds.locale" setting in qutebrowser to '
                'work around the issue.')
            log.webview.error(
                'A proper fix is likely available in QtWebEngine soon (which is why '
                'the workaround is disabled by default).')
            log.webview.error('')
        else:
            url_string = tab.url(requested=True).toDisplayString()
            error_page = jinja.render(
                'error.html',
                title="Error loading {}".format(url_string),
                url=url_string,
                error=msg)
            QTimer.singleShot(100, lambda: show_error_page(error_page))
示例#36
0
def qute_tabs(_url):
    """Handler for qute://tabs. Display information about all open tabs."""
    tabs = collections.defaultdict(list)
    for win_id, window in objreg.window_registry.items():
        if sip.isdeleted(window):
            continue
        tabbed_browser = objreg.get('tabbed-browser',
                                    scope='window',
                                    window=win_id)
        for tab in tabbed_browser.widgets():
            if tab.url() not in [QUrl("qute://tabs/"), QUrl("qute://tabs")]:
                urlstr = tab.url().toDisplayString()
                tabs[str(win_id)].append((tab.title(), urlstr))

    src = jinja.render('tabs.html', title='Tabs', tab_list_by_window=tabs)
    return 'text/html', src
示例#37
0
def test_resource_url():
    """Test resource_url() which can be used from templates."""
    data = jinja.render('resource_url.html')
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert url.scheme() == 'file'

    path = url.path()

    if os.name == "nt":
        path = path.lstrip('/')
        path = path.replace('/', os.sep)

    with open(path, 'r', encoding='utf-8') as f:
        assert f.read().splitlines()[0] == "Hello World!"
示例#38
0
def test_resource_url():
    """Test resource_url() which can be used from templates."""
    data = jinja.render('test2.html')
    print(data)
    url = QUrl(data)
    assert url.isValid()
    assert url.scheme() == 'file'

    path = url.path()

    if os.name == "nt":
        path = path.lstrip('/')
        path = path.replace('/', os.sep)

    with open(path, 'r', encoding='utf-8') as f:
        assert f.read().splitlines()[0] == "Hello World!"
示例#39
0
def qute_plainlog(url):
    """Handler for qute://plainlog.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        level = QUrlQuery(url).queryItemValue('level')
        if not level:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    src = jinja.render('pre.html', title='log', content=text)
    return 'text/html', src
示例#40
0
def qute_plainlog(url):
    """Handler for qute://plainlog.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        level = QUrlQuery(url).queryItemValue('level')
        if not level:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    src = jinja.render('pre.html', title='log', content=text)
    return 'text/html', src
示例#41
0
def qute_plainlog(_win_id, request):
    """Handler for qute:plainlog. Return HTML content as bytes.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        try:
            level = urllib.parse.parse_qs(request.url().query())['level'][0]
        except KeyError:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    html = jinja.render('pre.html', title='log', content=text)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#42
0
def qute_plainlog(url):
    """Handler for qute:plainlog.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        try:
            level = urllib.parse.parse_qs(url.query())['level'][0]
        except KeyError:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    html = jinja.render('pre.html', title='log', content=text)
    return 'text/html', html
示例#43
0
def qute_log(url):
    """Handler for qute://log.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        html_log = None
    else:
        level = QUrlQuery(url).queryItemValue('level')
        if not level:
            level = 'vdebug'
        html_log = log.ram_handler.dump_log(html=True, level=level)

    html = jinja.render('log.html', title='log', content=html_log)
    return 'text/html', html
示例#44
0
 def _on_authentication_required(self, url, authenticator):
     # FIXME:qtwebengine support .netrc
     answer = shared.authentication_required(
         url,
         authenticator,
         abort_on=[self.shutting_down, self.load_started])
     if answer is None:
         # WORKAROUND for
         # https://www.riverbankcomputing.com/pipermail/pyqt/2016-December/038400.html
         url_string = url.toDisplayString()
         error_page = jinja.render(
             'error.html',
             title="Error loading page: {}".format(url_string),
             url=url_string,
             error="Authentication required",
             icon='')
         self.set_html(error_page)
示例#45
0
def qute_plainlog(_win_id, request):
    """Handler for qute:plainlog. Return HTML content as bytes.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        try:
            level = urllib.parse.parse_qs(request.url().query())['level'][0]
        except KeyError:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    html = jinja.render('pre.html', title='log', content=text)
    return html.encode('UTF-8', errors='xmlcharrefreplace')
示例#46
0
def qute_plainlog(url):
    """Handler for qute:plainlog.

    An optional query parameter specifies the minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.
    """
    if log.ram_handler is None:
        text = "Log output was disabled."
    else:
        try:
            level = urllib.parse.parse_qs(url.query())['level'][0]
        except KeyError:
            level = 'vdebug'
        text = log.ram_handler.dump_log(html=False, level=level)
    html = jinja.render('pre.html', title='log', content=text)
    return 'text/html', html
示例#47
0
def qute_process(url: QUrl) -> _HandlerRet:
    """Handler for qute://process."""
    path = url.path()[1:]
    try:
        pid = int(path)
    except ValueError:
        raise UrlInvalidError(f"Invalid PID {path}")

    try:
        proc = guiprocess.all_processes[pid]
    except KeyError:
        raise NotFoundError(f"No process {pid}")

    if proc is None:
        raise NotFoundError(f"Data for process {pid} got cleaned up.")

    src = jinja.render('process.html', title=f'Process {pid}', proc=proc)
    return 'text/html', src
示例#48
0
def generate_pdfjs_page(filename, url):
    """Return the html content of a page that displays a file with pdfjs.

    Returns a string.

    Args:
        filename: The filename of the PDF to open.
        url: The URL being opened.
    """
    if not is_available():
        return jinja.render('no_pdfjs.html',
                            url=url.toDisplayString(),
                            title="PDF.js not found")
    viewer = get_pdfjs_res('web/viewer.html').decode('utf-8')
    script = _generate_pdfjs_script(filename)
    html_page = viewer.replace('</body>',
                               '</body><script>{}</script>'.format(script))
    return html_page
示例#49
0
 def _on_authentication_required(self, url, authenticator):
     # FIXME:qtwebengine support .netrc
     answer = shared.authentication_required(
         url, authenticator, abort_on=[self.shutting_down,
                                       self.load_started])
     if answer is None:
         try:
             # pylint: disable=no-member, useless-suppression
             sip.assign(authenticator, QAuthenticator())
         except AttributeError:
             # WORKAROUND for
             # https://www.riverbankcomputing.com/pipermail/pyqt/2016-December/038400.html
             url_string = url.toDisplayString()
             error_page = jinja.render(
                 'error.html',
                 title="Error loading page: {}".format(url_string),
                 url=url_string, error="Authentication required")
             self.set_html(error_page)
示例#50
0
def qute_settings(url: QUrl) -> _HandlerRet:
    """Handler for qute://settings. View/change qute configuration."""
    global csrf_token

    if url.path() == '/set':
        if url.password() != csrf_token:
            message.error("Invalid CSRF token for qute://settings!")
            raise RequestDeniedError("Invalid CSRF token!")
        return _qute_settings_set(url)

    # Requests to qute://settings/set should only be allowed from
    # qute://settings. As an additional security precaution, we generate a CSRF
    # token to use here.
    csrf_token = secrets.token_urlsafe()

    src = jinja.render('settings.html', title='settings',
                       configdata=configdata,
                       confget=config.instance.get_str,
                       csrf_token=csrf_token)
    return 'text/html', src
示例#51
0
def qute_history(url):
    """Handler for qute://history. Display and serve history."""
    if url.path() == '/data':
        try:
            offset = QUrlQuery(url).queryItemValue("offset")
            offset = int(offset) if offset else None
        except ValueError:
            raise UrlInvalidError("Query parameter offset is invalid")
        # Use start_time in query or current time.
        try:
            start_time = QUrlQuery(url).queryItemValue("start_time")
            start_time = float(start_time) if start_time else time.time()
        except ValueError:
            raise UrlInvalidError("Query parameter start_time is invalid")

        return 'text/html', json.dumps(history_data(start_time, offset))
    else:
        return 'text/html', jinja.render(
            'history.html',
            title='History',
            gap_interval=config.val.history_gap_interval)
示例#52
0
def qute_log(url: QUrl) -> _HandlerRet:
    """Handler for qute://log.

    There are three query parameters:

    - level: The minimum log level to print.
    For example, qute://log?level=warning prints warnings and errors.
    Level can be one of: vdebug, debug, info, warning, error, critical.

    - plain: If given (and not 'false'), plaintext is shown.

    - logfilter: A filter string like the --logfilter commandline argument
      accepts.
    """
    query = QUrlQuery(url)
    plain = (query.hasQueryItem('plain')
             and query.queryItemValue('plain').lower() != 'false')

    if log.ram_handler is None:
        content = "Log output was disabled." if plain else None
    else:
        level = query.queryItemValue('level')
        if not level:
            level = 'vdebug'

        filter_str = query.queryItemValue('logfilter')

        try:
            logfilter = (log.LogFilter.parse(filter_str, only_debug=False)
                         if filter_str else None)
        except log.InvalidLogFilterError as e:
            raise UrlInvalidError(e)

        content = log.ram_handler.dump_log(html=not plain,
                                           level=level,
                                           logfilter=logfilter)

    template = 'pre.html' if plain else 'log.html'
    src = jinja.render(template, title='log', content=content)
    return 'text/html', src
示例#53
0
def qute_history(url):
    """Handler for qute://history. Display and serve history."""
    if url.path() == '/data':
        try:
            offset = QUrlQuery(url).queryItemValue("offset")
            offset = int(offset) if offset else None
        except ValueError as e:
            raise QuteSchemeError("Query parameter offset is invalid", e)
        # Use start_time in query or current time.
        try:
            start_time = QUrlQuery(url).queryItemValue("start_time")
            start_time = float(start_time) if start_time else time.time()
        except ValueError as e:
            raise QuteSchemeError("Query parameter start_time is invalid", e)

        return 'text/html', json.dumps(history_data(start_time, offset))
    else:
        if not config.val.content.javascript.enabled:
            return 'text/plain', b'JavaScript is required for qute://history'
        return 'text/html', jinja.render(
            'history.html',
            title='History',
            gap_interval=config.val.history_gap_interval)
示例#54
0
 def _on_authentication_required(self, url, authenticator):
     netrc_success = False
     if not self.data.netrc_used:
         self.data.netrc_used = True
         netrc_success = shared.netrc_authentication(url, authenticator)
     if not netrc_success:
         abort_on = [self.shutting_down, self.load_started]
         answer = shared.authentication_required(url, authenticator,
                                                 abort_on)
     if not netrc_success and answer is None:
         try:
             # pylint: disable=no-member, useless-suppression
             sip.assign(authenticator, QAuthenticator())
             # pylint: enable=no-member, useless-suppression
         except AttributeError:
             # WORKAROUND for
             # https://www.riverbankcomputing.com/pipermail/pyqt/2016-December/038400.html
             url_string = url.toDisplayString()
             error_page = jinja.render(
                 'error.html',
                 title="Error loading page: {}".format(url_string),
                 url=url_string,
                 error="Authentication required")
             self.set_html(error_page)
示例#55
0
 def _on_proxy_authentication_required(self, url, authenticator,
                                       proxy_host):
     """Called when a proxy needs authentication."""
     msg = "<b>{}</b> requires a username and password.".format(
         html_utils.escape(proxy_host))
     answer = message.ask(
         title="Proxy authentication required", text=msg,
         mode=usertypes.PromptMode.user_pwd,
         abort_on=[self.shutting_down, self.load_started])
     if answer is not None:
         authenticator.setUser(answer.user)
         authenticator.setPassword(answer.password)
     else:
         try:
             # pylint: disable=no-member, useless-suppression
             sip.assign(authenticator, QAuthenticator())
         except AttributeError:
             url_string = url.toDisplayString()
             error_page = jinja.render(
                 'error.html',
                 title="Error loading page: {}".format(url_string),
                 url=url_string, error="Proxy authentication required",
                 icon='')
             self.set_html(error_page)
示例#56
0
def generate_pdfjs_page(filename, url):
    """Return the html content of a page that displays a file with pdfjs.

    Returns a string.

    Args:
        filename: The filename of the PDF to open.
        url: The URL being opened.
    """
    if not is_available():
        return jinja.render('no_pdfjs.html',
                            url=url.toDisplayString(),
                            title="PDF.js not found")
    html = get_pdfjs_res('web/viewer.html').decode('utf-8')

    script = _generate_pdfjs_script(filename)
    html = html.replace('</body>', '</body><script>{}</script>'.format(script))
    # WORKAROUND for the fact that PDF.js tries to use the Fetch API even with
    # qute:// URLs.
    pdfjs_script = '<script src="../build/pdf.js"></script>'
    html = html.replace(
        pdfjs_script,
        '<script>window.Response = undefined;</script>\n' + pdfjs_script)
    return html
示例#57
0
    def _on_renderer_process_terminated(self, tab, status, code):
        """Show an error when a renderer process terminated."""
        if status == browsertab.TerminationStatus.normal:
            return

        messages = {
            browsertab.TerminationStatus.abnormal: "Renderer process exited",
            browsertab.TerminationStatus.crashed: "Renderer process crashed",
            browsertab.TerminationStatus.killed: "Renderer process was killed",
            browsertab.TerminationStatus.unknown:
            "Renderer process did not start",
        }
        msg = messages[status] + f" (status {code})"

        def show_error_page(html):
            tab.set_html(html)
            log.webview.error(msg)

        url_string = tab.url(requested=True).toDisplayString()
        error_page = jinja.render('error.html',
                                  title="Error loading {}".format(url_string),
                                  url=url_string,
                                  error=msg)
        QTimer.singleShot(100, lambda: show_error_page(error_page))
示例#58
0
    def _handle_errorpage(self, info, errpage):
        """Display an error page if needed.

        Loosely based on Helpviewer/HelpBrowserWV.py from eric5
        (line 260 @ 5d937eb378dd)

        Args:
            info: The QWebPage.ErrorPageExtensionOption instance.
            errpage: The QWebPage.ErrorPageExtensionReturn instance, where the
                     error page will get written to.

        Return:
            False if no error page should be displayed, True otherwise.
        """
        ignored_errors = [
            (QWebPage.QtNetwork, QNetworkReply.OperationCanceledError),
            # "Loading is handled by the media engine"
            (QWebPage.WebKit, 203),
            # "Frame load interrupted by policy change"
            (QWebPage.WebKit, 102),
        ]
        errpage.baseUrl = info.url
        urlstr = info.url.toDisplayString()
        if (info.domain, info.error) == (QWebPage.QtNetwork,
                                         QNetworkReply.ProtocolUnknownError):
            # For some reason, we get a segfault when we use
            # QDesktopServices::openUrl with info.url directly - however it
            # works when we construct a copy of it.
            url = QUrl(info.url)
            scheme = url.scheme()
            message.confirm_async(
                title="Open external application for {}-link?".format(scheme),
                text="URL: <b>{}</b>".format(html.escape(
                    url.toDisplayString())),
                yes_action=functools.partial(QDesktopServices.openUrl, url))
            return True
        elif (info.domain, info.error) in ignored_errors:
            log.webview.debug("Ignored error on {}: {} (error domain: {}, "
                              "error code: {})".format(urlstr,
                                                       info.errorString,
                                                       info.domain,
                                                       info.error))
            return False
        else:
            error_str = info.errorString
            if error_str == networkmanager.HOSTBLOCK_ERROR_STRING:
                # We don't set error_occurred in this case.
                error_str = "Request blocked by host blocker."
                main_frame = info.frame.page().mainFrame()
                if info.frame != main_frame:
                    # Content in an iframe -> Hide the frame so it doesn't use
                    # any space. We can't hide the frame's documentElement
                    # directly though.
                    for elem in main_frame.documentElement().findAll('iframe'):
                        if QUrl(elem.attribute('src')) == info.url:
                            elem.setAttribute('style', 'display: none')
                    return False
            else:
                self._ignore_load_started = True
                self.error_occurred = True
            log.webview.error("Error while loading {}: {}".format(
                urlstr, error_str))
            log.webview.debug("Error domain: {}, error code: {}".format(
                info.domain, info.error))
            title = "Error loading page: {}".format(urlstr)
            error_html = jinja.render('error.html',
                                      title=title,
                                      url=urlstr,
                                      error=error_str)
            errpage.content = error_html.encode('utf-8')
            errpage.encoding = 'utf-8'
            return True
示例#59
0
def qute_spawn_output(_url):
    """Handler for qute://spawn-output."""
    src = jinja.render('pre.html', title='spawn output', content=spawn_output)
    return 'text/html', src