Merge branch 'meles5-jinja'
This commit is contained in:
commit
d862821552
@ -45,6 +45,7 @@ Changed
|
|||||||
relative paths in `~/.local/share/qutebrowser/userscripts` or
|
relative paths in `~/.local/share/qutebrowser/userscripts` or
|
||||||
`$XDG_DATA_DIR`. Using a binary in `$PATH` won't work anymore with
|
`$XDG_DATA_DIR`. Using a binary in `$PATH` won't work anymore with
|
||||||
`--userscript`.
|
`--userscript`.
|
||||||
|
- New design for error pages
|
||||||
|
|
||||||
Fixed
|
Fixed
|
||||||
~~~~~
|
~~~~~
|
||||||
|
@ -2,7 +2,7 @@ global-exclude __pycache__ *.pyc *.pyo
|
|||||||
|
|
||||||
recursive-include qutebrowser *.py
|
recursive-include qutebrowser *.py
|
||||||
recursive-include qutebrowser/html *.html
|
recursive-include qutebrowser/html *.html
|
||||||
recursive-include qutebrowser/img *.svg
|
recursive-include qutebrowser/img *.svg *.png
|
||||||
recursive-include qutebrowser/test *.py
|
recursive-include qutebrowser/test *.py
|
||||||
recursive-include qutebrowser/javascript *.js
|
recursive-include qutebrowser/javascript *.js
|
||||||
graft icons
|
graft icons
|
||||||
|
@ -148,6 +148,7 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Artur Shaik
|
* Artur Shaik
|
||||||
* Thorsten Wißmann
|
* Thorsten Wißmann
|
||||||
* Alexey "Averrin" Nabrodov
|
* Alexey "Averrin" Nabrodov
|
||||||
|
* meles5
|
||||||
* ZDarian
|
* ZDarian
|
||||||
* John ShaggyTwoDope Jenkins
|
* John ShaggyTwoDope Jenkins
|
||||||
* Peter Vilim
|
* Peter Vilim
|
||||||
@ -173,7 +174,6 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Fritz V155 Reichwald
|
* Fritz V155 Reichwald
|
||||||
* Franz Fellner
|
* Franz Fellner
|
||||||
* zwarag
|
* zwarag
|
||||||
* meles5
|
|
||||||
* error800
|
* error800
|
||||||
* Tim Harder
|
* Tim Harder
|
||||||
* Thiago Barroso Perrotta
|
* Thiago Barroso Perrotta
|
||||||
|
@ -25,10 +25,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PyQt5.QtCore import QUrl
|
|
||||||
|
|
||||||
from qutebrowser.browser.network import schemehandler, networkreply
|
from qutebrowser.browser.network import schemehandler, networkreply
|
||||||
from qutebrowser.utils import utils, jinja
|
from qutebrowser.utils import jinja
|
||||||
|
|
||||||
|
|
||||||
def get_file_list(basedir, all_files, filterfunc):
|
def get_file_list(basedir, all_files, filterfunc):
|
||||||
@ -76,12 +74,6 @@ def dirbrowser_html(path):
|
|||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
# https://bitbucket.org/logilab/pylint/issue/490/
|
# https://bitbucket.org/logilab/pylint/issue/490/
|
||||||
|
|
||||||
folder_icon = utils.resource_filename('img/folder.svg')
|
|
||||||
file_icon = utils.resource_filename('img/file.svg')
|
|
||||||
|
|
||||||
folder_url = QUrl.fromLocalFile(folder_icon).toString(QUrl.FullyEncoded)
|
|
||||||
file_url = QUrl.fromLocalFile(file_icon).toString(QUrl.FullyEncoded)
|
|
||||||
|
|
||||||
if is_root(path):
|
if is_root(path):
|
||||||
parent = None
|
parent = None
|
||||||
else:
|
else:
|
||||||
@ -101,8 +93,7 @@ def dirbrowser_html(path):
|
|||||||
directories = get_file_list(path, all_files, os.path.isdir)
|
directories = get_file_list(path, all_files, os.path.isdir)
|
||||||
html = template.render(title=title, url=path, icon='',
|
html = template.render(title=title, url=path, icon='',
|
||||||
parent=parent, files=files,
|
parent=parent, files=files,
|
||||||
directories=directories, folder_url=folder_url,
|
directories=directories)
|
||||||
file_url=file_url)
|
|
||||||
return html.encode('UTF-8', errors='xmlcharrefreplace')
|
return html.encode('UTF-8', errors='xmlcharrefreplace')
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ ul > li {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul > li {
|
ul > li {
|
||||||
background-image: url('{{folder_url}}');
|
background-image: url('{{ resource_url('img/folder.svg') }}');
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.files > li {
|
ul.files > li {
|
||||||
background-image: url('{{file_url}}');
|
background-image: url('{{ resource_url('img/file.svg') }}');
|
||||||
}
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -1,25 +1,59 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block style %}
|
{% block style %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
#errorContainer {
|
* {
|
||||||
background: #fff;
|
margin: 0px 0px;
|
||||||
min-width: 35em;
|
padding: 0px 0px;
|
||||||
max-width: 35em;
|
|
||||||
position: absolute;
|
|
||||||
top: 2em;
|
|
||||||
left: 1em;
|
|
||||||
padding: 10px;
|
|
||||||
border: 2px solid #eee;
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#errorTitleText {
|
body {
|
||||||
font-size: 118%;
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
font-weight: bold;
|
-webkit-text-size-adjust: none;
|
||||||
|
color: #333333;
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#errorMessageText {
|
#error-container {
|
||||||
font-size: 80%;
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
border: 1px solid #CCCCCC;
|
||||||
|
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.20);
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
border-bottom: 1px solid #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qutebrowser-broken {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: normal;
|
||||||
|
color: #1e89c6;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -35,19 +69,22 @@ function searchFor(uri) {
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="errorContainer">
|
<div id="error-container">
|
||||||
<div id="errorTitle">
|
<table>
|
||||||
<p id="errorTitleText">Unable to load page</p>
|
<tr>
|
||||||
</div>
|
<td style="width: 10%; vertical-align: top;">
|
||||||
<div id="errorMessage">
|
<img style="width: 100%; display: block; max-width: 256px;" src="{{ resource_url('img/broken_qutebrowser_logo.png') }}" />
|
||||||
<p>Problem occurred while loading the URL {{ url }}</p>
|
</td>
|
||||||
<p id="errorMessageText">{{ error }}</p>
|
<td style="padding-left: 40px;">
|
||||||
</p>
|
<h1>Unable to load page</h1>
|
||||||
</div>
|
Error while opening {{ url }}: <br>
|
||||||
|
<p id="error-message-text" style="color: #a31a1a;">{{ error }}</p><br><br>
|
||||||
|
|
||||||
<form name="bl">
|
<form name="bl">
|
||||||
<input type="button" value="Try again" onclick="javascript:tryagain()" />
|
<input type="button" value="Try again" onclick="javascript:tryagain()" />
|
||||||
<!--<input type="button" value="Search" style="visibility:%s" onclick="javascript:searchFor('%s')" />-->
|
|
||||||
</form>
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
BIN
qutebrowser/img/broken_qutebrowser_logo.png
Normal file
BIN
qutebrowser/img/broken_qutebrowser_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
@ -19,12 +19,15 @@
|
|||||||
|
|
||||||
"""Utilities related to jinja2."""
|
"""Utilities related to jinja2."""
|
||||||
|
|
||||||
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
from qutebrowser.utils import utils
|
from qutebrowser.utils import utils
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QUrl
|
||||||
|
|
||||||
|
|
||||||
class Loader(jinja2.BaseLoader):
|
class Loader(jinja2.BaseLoader):
|
||||||
|
|
||||||
@ -59,4 +62,14 @@ def _guess_autoescape(template_name):
|
|||||||
return ext in ('html', 'htm', 'xml')
|
return ext in ('html', 'htm', 'xml')
|
||||||
|
|
||||||
|
|
||||||
|
def resource_url(path):
|
||||||
|
"""Load images from a relative path (to qutebrowser).
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
path: The relative path to the image
|
||||||
|
"""
|
||||||
|
image = utils.resource_filename(path)
|
||||||
|
return QUrl.fromLocalFile(image).toString(QUrl.FullyEncoded)
|
||||||
|
|
||||||
env = jinja2.Environment(loader=Loader('html'), autoescape=_guess_autoescape)
|
env = jinja2.Environment(loader=Loader('html'), autoescape=_guess_autoescape)
|
||||||
|
env.globals['resource_url'] = resource_url
|
||||||
|
@ -120,7 +120,7 @@ class TestDirbrowserHtml:
|
|||||||
def test_icons(self, monkeypatch):
|
def test_icons(self, monkeypatch):
|
||||||
"""Make sure icon paths are correct file:// URLs."""
|
"""Make sure icon paths are correct file:// URLs."""
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
'qutebrowser.browser.network.filescheme.utils.resource_filename',
|
'qutebrowser.utils.jinja.utils.resource_filename',
|
||||||
lambda name: '/test path/foo.svg')
|
lambda name: '/test path/foo.svg')
|
||||||
|
|
||||||
html = filescheme.dirbrowser_html(os.getcwd())
|
html = filescheme.dirbrowser_html(os.getcwd())
|
||||||
@ -198,9 +198,7 @@ class TestDirbrowserHtml:
|
|||||||
html = filescheme.dirbrowser_html('')
|
html = filescheme.dirbrowser_html('')
|
||||||
soup = bs4.BeautifulSoup(html, 'html.parser')
|
soup = bs4.BeautifulSoup(html, 'html.parser')
|
||||||
print(soup.prettify())
|
print(soup.prettify())
|
||||||
error_title = soup('p', id='errorTitleText')[0].string
|
error_msg = soup('p', id='error-message-text')[0].string
|
||||||
error_msg = soup('p', id='errorMessageText')[0].string
|
|
||||||
assert error_title == 'Unable to load page'
|
|
||||||
assert error_msg == 'Error message'
|
assert error_msg == 'Error message'
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
"""Tests for qutebrowser.utils.jinja."""
|
"""Tests for qutebrowser.utils.jinja."""
|
||||||
|
|
||||||
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import jinja2
|
import jinja2
|
||||||
|
from PyQt5.QtCore import QUrl
|
||||||
|
|
||||||
from qutebrowser.utils import jinja
|
from qutebrowser.utils import jinja
|
||||||
|
|
||||||
@ -34,6 +36,8 @@ 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'):
|
||||||
|
return """{{ resource_url('utils/testfile') }}"""
|
||||||
else:
|
else:
|
||||||
raise IOError("Invalid path {}!".format(path))
|
raise IOError("Invalid path {}!".format(path))
|
||||||
|
|
||||||
@ -48,6 +52,25 @@ def test_simple_template():
|
|||||||
assert data == "Hello World"
|
assert data == "Hello World"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resource_url():
|
||||||
|
"""Test resource_url() which can be used from templates."""
|
||||||
|
template = jinja.env.get_template('test2.html')
|
||||||
|
data = template.render() # pylint: disable=no-member
|
||||||
|
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!"
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
Loading…
Reference in New Issue
Block a user