Serve broken qutebrowser logo via qute:resources

This is needed when we want to display an error page after the user
requested a qute:// URL, as qute:// URLs can't access file:// content
with QtWebEngine.
This commit is contained in:
Florian Bruhin 2016-09-15 16:01:56 +02:00
parent 8bdcd49626
commit 37fa7431b0
6 changed files with 44 additions and 12 deletions

View File

@ -24,6 +24,7 @@ Module attributes:
_HANDLERS: The handlers registered via decorators. _HANDLERS: The handlers registered via decorators.
""" """
import mimetypes
import urllib.parse import urllib.parse
import qutebrowser import qutebrowser
@ -102,7 +103,7 @@ class add_handler: # pylint: disable=invalid-name
url=url.toDisplayString(), url=url.toDisplayString(),
error='{} is not available with this ' error='{} is not available with this '
'backend'.format(url.toDisplayString()), 'backend'.format(url.toDisplayString()),
icon='') icon='', qutescheme=True)
return 'text/html', html return 'text/html', html
@ -237,7 +238,8 @@ def qute_help(url):
"repository, please run scripts/asciidoc2html.py. " "repository, please run scripts/asciidoc2html.py. "
"If you're running a released version this is a bug, please " "If you're running a released version this is a bug, please "
"use :report to report it.", "use :report to report it.",
icon='') icon='',
qutescheme=True)
return 'text/html', html return 'text/html', html
urlpath = url.path() urlpath = url.path()
if not urlpath or urlpath == '/': if not urlpath or urlpath == '/':
@ -253,3 +255,11 @@ def qute_help(url):
else: else:
data = utils.read_file(path) data = utils.read_file(path)
return 'text/html', data return 'text/html', data
@add_handler('resource')
def qute_resource(url):
data = utils.read_file(url.path(), binary=True)
mimetype, _encoding = mimetypes.guess_type(url.fileName())
assert mimetype is not None, url
return mimetype, data

View File

@ -102,7 +102,7 @@ def dirbrowser_html(path):
html = jinja.render('error.html', html = jinja.render('error.html',
title="Error while reading directory", title="Error while reading directory",
url='file:///{}'.format(path), error=str(e), url='file:///{}'.format(path), error=str(e),
icon='') icon='', qutescheme=False)
return html.encode('UTF-8', errors='xmlcharrefreplace') return html.encode('UTF-8', errors='xmlcharrefreplace')
files = get_file_list(path, all_files, os.path.isfile) files = get_file_list(path, all_files, os.path.isfile)

View File

@ -170,7 +170,8 @@ class BrowserPage(QWebPage):
title = "Error loading page: {}".format(urlstr) title = "Error loading page: {}".format(urlstr)
html = jinja.render( html = jinja.render(
'error.html', 'error.html',
title=title, url=urlstr, error=error_str, icon='') title=title, url=urlstr, error=error_str, icon='',
qutescheme=False)
errpage.content = html.encode('utf-8') errpage.content = html.encode('utf-8')
errpage.encoding = 'utf-8' errpage.encoding = 'utf-8'
return True return True

View File

@ -73,7 +73,7 @@ function searchFor(uri) {
<table> <table>
<tr> <tr>
<td style="width: 10%; vertical-align: top;"> <td style="width: 10%; vertical-align: top;">
<img style="width: 100%; display: block; max-width: 256px;" src="{{ resource_url('img/broken_qutebrowser_logo.png') }}" /> <img style="width: 100%; display: block; max-width: 256px;" src="{{ resource_url('img/broken_qutebrowser_logo.png', qutescheme) }}" />
</td> </td>
<td style="padding-left: 40px;"> <td style="padding-left: 40px;">
<h1>Unable to load page</h1> <h1>Unable to load page</h1>

View File

@ -26,7 +26,7 @@ import traceback
import jinja2 import jinja2
import jinja2.exceptions import jinja2.exceptions
from qutebrowser.utils import utils, urlutils, log from qutebrowser.utils import utils, urlutils, log, qtutils
from PyQt5.QtCore import QUrl from PyQt5.QtCore import QUrl
@ -64,14 +64,25 @@ def _guess_autoescape(template_name):
return ext in ['html', 'htm', 'xml'] return ext in ['html', 'htm', 'xml']
def resource_url(path): def resource_url(path, qutescheme):
"""Load images from a relative path (to qutebrowser). """Load images from a relative path (to qutebrowser).
Arguments: Arguments:
path: The relative path to the image path: The relative path to the image
qutescheme: If the logo needs to be served via a qute:// scheme.
This is the case when we want to show an error page from
there.
""" """
image = utils.resource_filename(path) if qutescheme:
return QUrl.fromLocalFile(image).toString(QUrl.FullyEncoded) url = QUrl()
url.setScheme('qute')
url.setHost('resource')
url.setPath('/' + path)
qtutils.ensure_valid(url)
return url.toString(QUrl.FullyEncoded)
else:
full_path = utils.resource_filename(path)
return QUrl.fromLocalFile(full_path).toString(QUrl.FullyEncoded)
def render(template, **kwargs): def render(template, **kwargs):

View File

@ -39,8 +39,10 @@ def patch_read_file(monkeypatch):
"""A read_file which returns a simple template if the path is right.""" """A read_file which returns a simple template if the path is right."""
if path == os.path.join('html', 'test.html'): if path == os.path.join('html', 'test.html'):
return """Hello {{var}}""" return """Hello {{var}}"""
elif path == os.path.join('html', 'test2.html'): elif path == os.path.join('html', 'resource_url.html'):
return """{{ resource_url('utils/testfile') }}""" return """{{ resource_url('utils/testfile', False) }}"""
elif path == os.path.join('html', 'resource_url_qute.html'):
return """{{ resource_url('utils/testfile', True) }}"""
elif path == os.path.join('html', 'undef.html'): elif path == os.path.join('html', 'undef.html'):
return """{{ does_not_exist() }}""" return """{{ does_not_exist() }}"""
elif path == os.path.join('html', 'undef_error.html'): elif path == os.path.join('html', 'undef_error.html'):
@ -59,7 +61,7 @@ def test_simple_template():
def test_resource_url(): def test_resource_url():
"""Test resource_url() which can be used from templates.""" """Test resource_url() which can be used from templates."""
data = jinja.render('test2.html') data = jinja.render('resource_url.html')
print(data) print(data)
url = QUrl(data) url = QUrl(data)
assert url.isValid() assert url.isValid()
@ -75,6 +77,14 @@ def test_resource_url():
assert f.read().splitlines()[0] == "Hello World!" assert f.read().splitlines()[0] == "Hello World!"
def test_resource_url_qutescheme():
"""Test resource_url() which can be used from templates."""
data = jinja.render('resource_url_qute.html')
print(data)
url = QUrl(data)
assert url == QUrl('qute://resource/utils/testfile')
def test_not_found(): def test_not_found():
"""Test with a template which does not exist.""" """Test with a template which does not exist."""
with pytest.raises(jinja2.TemplateNotFound) as excinfo: with pytest.raises(jinja2.TemplateNotFound) as excinfo: