Merge branch 'feature/directory-browser' of git://github.com/antoyo/qutebrowser into dirbrowser

This commit is contained in:
Florian Bruhin 2015-08-16 18:27:05 +02:00
commit fb1cffd158
11 changed files with 1425 additions and 25 deletions

View File

@ -2,6 +2,7 @@ global-exclude __pycache__ *.pyc *.pyo
recursive-include qutebrowser *.py
recursive-include qutebrowser/html *.html
recursive-include qutebrowser/img *.svg
recursive-include qutebrowser/test *.py
recursive-include qutebrowser/javascript *.js
graft icons

View File

@ -0,0 +1,124 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2015 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015 Antoni Boucher (antoyo) <bouanto@zoho.com>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
#
# pylint complains when using .render() on jinja templates, so we make it shut
# up for this whole module.
"""Handler functions for file:... pages."""
import os
from qutebrowser.browser.network import schemehandler, networkreply
from qutebrowser.utils import jinja
from qutebrowser.utils.utils import resource_filename
def get_file_list(basedir, all_files, filterfunc):
"""Get a list of files filtered by a filter function and sorted by name.
Args:
basedir: The parent directory of all files.
all_files: The list of files to filter and sort.
filterfunc: The filter function.
Return:
A list of dicts. Each dict contains the name and absname keys.
"""
items = []
for filename in all_files:
absname = os.path.join(basedir, filename)
if filterfunc(absname):
items.append({'name': filename, 'absname': absname})
return sorted(items, key=lambda v: v['name'].lower())
def is_root(directory):
"""Check if the directory is the root directory.
Args:
directory: The directory to check.
Return:
Whether the directory is a root directory or not.
"""
return os.path.dirname(directory) == directory
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)
template = jinja.env.get_template('dirbrowser.html')
# pylint: disable=no-member
# https://bitbucket.org/logilab/pylint/issue/490/
folder_icon = resource_filename('img/folder.svg')
file_icon = resource_filename('img/file.svg')
if is_root(path):
parent = None
else:
parent = os.path.dirname(path)
try:
all_files = os.listdir(path)
except OSError as e:
html = jinja.env.get_template('error.html').render(
title="Error while reading directory",
url='file://%s' % 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 = template.render(title=title, url=path, icon='',
parent=parent, files=files,
directories=directories, folder_icon=folder_icon,
file_icon=file_icon)
return html.encode('UTF-8', errors='xmlcharrefreplace')
class FileSchemeHandler(schemehandler.SchemeHandler):
"""Scheme handler for file: URLs."""
def createRequest(self, _op, request, _outgoing_data):
"""Create a new request.
Args:
request: const QNetworkRequest & req
_op: Operation op
_outgoing_data: QIODevice * outgoingData
Return:
A QNetworkReply for directories, None for files.
"""
path = request.url().toLocalFile()
if os.path.isdir(path):
data = dirbrowser_html(path)
return networkreply.FixedDataNetworkReply(
request, data, 'text/html', self.parent())

View File

@ -31,6 +31,7 @@ from qutebrowser.utils import (message, log, usertypes, utils, objreg, qtutils,
urlutils)
from qutebrowser.browser import cookies
from qutebrowser.browser.network import qutescheme, networkreply
from qutebrowser.browser.network import filescheme
HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%'
@ -97,6 +98,7 @@ class NetworkManager(QNetworkAccessManager):
self._requests = []
self._scheme_handlers = {
'qute': qutescheme.QuteSchemeHandler(win_id),
'file': filescheme.FileSchemeHandler(win_id),
}
self._set_cookiejar()
self._set_cache()
@ -295,6 +297,25 @@ class NetworkManager(QNetworkAccessManager):
download.destroyed.connect(self.on_adopted_download_destroyed)
download.do_retry.connect(self.adopt_download)
def set_referer(self, req, current_url):
"""Set the referer header."""
referer_header_conf = config.get('network', 'referer-header')
try:
if referer_header_conf == 'never':
# Note: using ''.encode('ascii') sends a header with no value,
# instead of no header at all
req.setRawHeader('Referer'.encode('ascii'), QByteArray())
elif (referer_header_conf == 'same-domain' and
not urlutils.same_domain(req.url(), current_url)):
req.setRawHeader('Referer'.encode('ascii'), QByteArray())
# If refer_header_conf is set to 'always', we leave the header
# alone as QtWebKit did set it.
except urlutils.InvalidUrlError:
# req.url() or current_url can be invalid - this happens on
# https://www.playstation.com/ for example.
pass
# WORKAROUND for:
# http://www.riverbankcomputing.com/pipermail/pyqt/2014-September/034806.html
#
@ -318,8 +339,10 @@ class NetworkManager(QNetworkAccessManager):
"""
scheme = req.url().scheme()
if scheme in self._scheme_handlers:
return self._scheme_handlers[scheme].createRequest(
result = self._scheme_handlers[scheme].createRequest(
op, req, outgoing_data)
if result is not None:
return result
host_blocker = objreg.get('host-blocker')
if (op == QNetworkAccessManager.GetOperation and
@ -344,22 +367,8 @@ class NetworkManager(QNetworkAccessManager):
webview = objreg.get('webview', scope='tab', window=self._win_id,
tab=self._tab_id)
current_url = webview.url()
referer_header_conf = config.get('network', 'referer-header')
try:
if referer_header_conf == 'never':
# Note: using ''.encode('ascii') sends a header with no value,
# instead of no header at all
req.setRawHeader('Referer'.encode('ascii'), QByteArray())
elif (referer_header_conf == 'same-domain' and
not urlutils.same_domain(req.url(), current_url)):
req.setRawHeader('Referer'.encode('ascii'), QByteArray())
# If refer_header_conf is set to 'always', we leave the header
# alone as QtWebKit did set it.
except urlutils.InvalidUrlError:
# req.url() or current_url can be invalid - this happens on
# https://www.playstation.com/ for example.
pass
self.set_referer(req, current_url)
accept_language = config.get('network', 'accept-language')
if accept_language is not None:

View File

@ -0,0 +1,67 @@
{% extends "base.html" %}
{% block style %}
{{ super() }}
#dirbrowserContainer {
background: #fff;
min-width: 35em;
max-width: 35em;
position: absolute;
top: 2em;
left: 1em;
padding: 10px;
border: 2px solid #eee;
-webkit-border-radius: 5px;
}
#dirbrowserTitleText {
font-size: 118%;
font-weight: bold;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul > li {
background-repeat: no-repeat;
background-size: 22px;
line-height: 22px;
padding-left: 25px;
}
ul > li {
background-image: url('{{folder_icon}}');
}
ul.files > li {
background-image: url('{{file_icon}}');
}
{% endblock %}
{% block content %}
<div id="dirbrowserContainer">
<div id="dirbrowserTitle">
<p id="dirbrowserTitleText">Browse directory: {{url}}</p>
</div>
{% if parent %}
<ul class="parent">
<li><a href="{{parent}}">..</a></li>
</ul>
{% endif %}
<ul class="folders">
{% for item in directories %}
<li><a href="file://{{item.absname}}">{{item.name}}</a></li>
{% endfor %}
</ul>
<ul class="files">
{% for item in files %}
<li><a href="file://{{item.absname}}">{{item.name}}</a></li>
{% endfor %}
</ul>
</div>
{% endblock %}

548
qutebrowser/img/file.svg Normal file
View File

@ -0,0 +1,548 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="240.00000"
inkscape:export-xdpi="240.00000"
inkscape:export-filename="/home/jimmac/gfx/novell/pdes/trunk/docs/BIGmime-text.png"
sodipodi:docname="text-x-generic.svg"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/mimetypes"
inkscape:version="0.46"
sodipodi:version="0.32"
id="svg249"
height="48.000000px"
width="48.000000px"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective78" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6719"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop5062" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5064" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6717"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient6715"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<linearGradient
inkscape:collect="always"
id="linearGradient4542">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4544" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4546" />
</linearGradient>
<linearGradient
id="linearGradient15662">
<stop
id="stop15664"
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
id="stop15666"
offset="1.0000000"
style="stop-color:#f8f8f8;stop-opacity:1.0000000;" />
</linearGradient>
<radialGradient
id="aigrd3"
cx="20.8921"
cy="64.5679"
r="5.257"
fx="20.8921"
fy="64.5679"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#F0F0F0"
id="stop15573" />
<stop
offset="1.0000000"
style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
id="stop15575" />
</radialGradient>
<radialGradient
id="aigrd2"
cx="20.8921"
cy="114.5684"
r="5.256"
fx="20.8921"
fy="114.5684"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#F0F0F0"
id="stop15566" />
<stop
offset="1.0000000"
style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
id="stop15568" />
</radialGradient>
<linearGradient
id="linearGradient269">
<stop
id="stop270"
offset="0.0000000"
style="stop-color:#a3a3a3;stop-opacity:1.0000000;" />
<stop
id="stop271"
offset="1.0000000"
style="stop-color:#4c4c4c;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient259">
<stop
id="stop260"
offset="0.0000000"
style="stop-color:#fafafa;stop-opacity:1.0000000;" />
<stop
id="stop261"
offset="1.0000000"
style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient269"
id="radialGradient15656"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
cx="8.8244190"
cy="3.7561285"
fx="8.8244190"
fy="3.7561285"
r="37.751713" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient259"
id="radialGradient15658"
gradientUnits="userSpaceOnUse"
gradientTransform="scale(0.960493,1.041132)"
cx="33.966679"
cy="35.736916"
fx="33.966679"
fy="35.736916"
r="86.708450" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient15662"
id="radialGradient15668"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
cx="8.1435566"
cy="7.2678967"
fx="8.1435566"
fy="7.2678967"
r="38.158695" />
<radialGradient
r="5.256"
fy="114.5684"
fx="20.8921"
cy="114.5684"
cx="20.8921"
gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
gradientUnits="userSpaceOnUse"
id="radialGradient2283"
xlink:href="#aigrd2"
inkscape:collect="always" />
<radialGradient
r="5.257"
fy="64.5679"
fx="20.8921"
cy="64.5679"
cx="20.8921"
gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
gradientUnits="userSpaceOnUse"
id="radialGradient2285"
xlink:href="#aigrd3"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4542"
id="radialGradient4548"
cx="24.306795"
cy="42.07798"
fx="24.306795"
fy="42.07798"
r="15.821514"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.284916,0.000000,30.08928)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
inkscape:window-y="160"
inkscape:window-x="343"
inkscape:window-height="688"
inkscape:window-width="872"
inkscape:document-units="px"
inkscape:grid-bbox="true"
showgrid="false"
inkscape:current-layer="layer6"
inkscape:cy="24.318443"
inkscape:cx="25.938708"
inkscape:zoom="5.6568542"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="0.25490196"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:showpageshadow="false" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Generic Text</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>text</rdf:li>
<rdf:li>plaintext</rdf:li>
<rdf:li>regular</rdf:li>
<rdf:li>document</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="Shadow">
<g
style="display:inline"
transform="matrix(2.105461e-2,0,0,2.086758e-2,42.85172,41.1536)"
id="g6707">
<rect
style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect6709"
width="1339.6335"
height="478.35718"
x="-1559.2523"
y="-150.69685" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
id="path6711"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
id="path6713"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
</g>
</g>
<g
style="display:inline"
inkscape:groupmode="layer"
inkscape:label="Base"
id="layer1">
<rect
style="color:#000000;fill:url(#radialGradient15658);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15656);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15391"
width="34.875000"
height="40.920494"
x="6.6035528"
y="3.6464462"
ry="1.1490486" />
<rect
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15668);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15660"
width="32.775887"
height="38.946384"
x="7.6660538"
y="4.5839462"
ry="0.14904857"
rx="0.14904857" />
<g
transform="translate(0.646447,-3.798933e-2)"
id="g2270">
<g
id="g1440"
style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4.0000000"
transform="matrix(0.229703,0.000000,0.000000,0.229703,4.967081,4.244972)">
<radialGradient
id="radialGradient1442"
cx="20.892099"
cy="114.56840"
r="5.2560000"
fx="20.892099"
fy="114.56840"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#F0F0F0"
id="stop1444" />
<stop
offset="1"
style="stop-color:#474747"
id="stop1446" />
</radialGradient>
<path
style="stroke:none"
d="M 23.428000,113.07000 C 23.428000,115.04300 21.828000,116.64200 19.855000,116.64200 C 17.881000,116.64200 16.282000,115.04200 16.282000,113.07000 C 16.282000,111.09600 17.882000,109.49700 19.855000,109.49700 C 21.828000,109.49700 23.428000,111.09700 23.428000,113.07000 z "
id="path1448" />
<radialGradient
id="radialGradient1450"
cx="20.892099"
cy="64.567902"
r="5.2570000"
fx="20.892099"
fy="64.567902"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#F0F0F0"
id="stop1452" />
<stop
offset="1"
style="stop-color:#474747"
id="stop1454" />
</radialGradient>
<path
style="stroke:none"
d="M 23.428000,63.070000 C 23.428000,65.043000 21.828000,66.643000 19.855000,66.643000 C 17.881000,66.643000 16.282000,65.043000 16.282000,63.070000 C 16.282000,61.096000 17.882000,59.497000 19.855000,59.497000 C 21.828000,59.497000 23.428000,61.097000 23.428000,63.070000 z "
id="path1456" />
</g>
<path
style="fill:url(#radialGradient2283);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
d="M 9.9950109,29.952326 C 9.9950109,30.405530 9.6274861,30.772825 9.1742821,30.772825 C 8.7208483,30.772825 8.3535532,30.405301 8.3535532,29.952326 C 8.3535532,29.498892 8.7210780,29.131597 9.1742821,29.131597 C 9.6274861,29.131597 9.9950109,29.499122 9.9950109,29.952326 z "
id="path15570" />
<path
style="fill:url(#radialGradient2285);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000"
d="M 9.9950109,18.467176 C 9.9950109,18.920380 9.6274861,19.287905 9.1742821,19.287905 C 8.7208483,19.287905 8.3535532,18.920380 8.3535532,18.467176 C 8.3535532,18.013742 8.7210780,17.646447 9.1742821,17.646447 C 9.6274861,17.646447 9.9950109,18.013972 9.9950109,18.467176 z "
id="path15577" />
</g>
<path
style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.98855311;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.017543854"
d="M 11.505723,5.4942766 L 11.505723,43.400869"
id="path15672"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.20467831"
d="M 12.500000,5.0205154 L 12.500000,43.038228"
id="path15674"
sodipodi:nodetypes="cc" />
</g>
<g
inkscape:groupmode="layer"
id="layer5"
inkscape:label="Text"
style="display:inline">
<g
transform="matrix(0.909091,0.000000,0.000000,1.000000,2.363628,0.000000)"
id="g2253">
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15686"
width="22.000004"
height="1.0000000"
x="15.000002"
y="9.0000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15688"
width="22.000004"
height="1.0000000"
x="15.000002"
y="11.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15690"
width="22.000004"
height="1.0000000"
x="15.000002"
y="13.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15692"
width="22.000004"
height="1.0000000"
x="15.000002"
y="15.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15694"
width="22.000004"
height="1.0000000"
x="15.000002"
y="17.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15696"
width="22.000004"
height="1.0000000"
x="15.000002"
y="19.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15698"
width="22.000004"
height="1.0000000"
x="15.000002"
y="21.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15700"
width="22.000004"
height="1.0000000"
x="15.000002"
y="23.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15732"
width="9.9000053"
height="1.0000000"
x="14.999992"
y="25.000000"
rx="0.068204239"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15736"
width="22.000004"
height="1.0000000"
x="14.999992"
y="29.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15738"
width="22.000004"
height="1.0000000"
x="14.999992"
y="31.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15740"
width="22.000004"
height="1.0000000"
x="14.999992"
y="33.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15742"
width="22.000004"
height="1.0000000"
x="14.999992"
y="35.000000"
rx="0.15156493"
ry="0.065390877" />
<rect
style="color:#000000;fill:#9b9b9b;fill-opacity:0.54970759;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.081871338;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible"
id="rect15744"
width="15.400014"
height="1.0000000"
x="14.999992"
y="37.000000"
rx="0.10609552"
ry="0.065390877" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

424
qutebrowser/img/folder.svg Normal file
View File

@ -0,0 +1,424 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48.000000px"
height="48.000000px"
id="svg97"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/places"
sodipodi:docname="folder.svg"
inkscape:export-filename="/home/jimmac/Desktop/horlander-style3.png"
inkscape:export-xdpi="90.000000"
inkscape:export-ydpi="90.000000"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 24 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="48 : 24 : 1"
inkscape:persp3d-origin="24 : 16 : 1"
id="perspective68" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6719"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop5062" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5064" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6717"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient6715"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<linearGradient
inkscape:collect="always"
id="linearGradient9806">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop9808" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop9810" />
</linearGradient>
<linearGradient
id="linearGradient9766">
<stop
style="stop-color:#6194cb;stop-opacity:1;"
offset="0"
id="stop9768" />
<stop
style="stop-color:#729fcf;stop-opacity:1;"
offset="1"
id="stop9770" />
</linearGradient>
<linearGradient
id="linearGradient3096">
<stop
id="stop3098"
offset="0"
style="stop-color:#424242;stop-opacity:1;" />
<stop
id="stop3100"
offset="1.0000000"
style="stop-color:#777777;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient319"
inkscape:collect="always">
<stop
id="stop320"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop321"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient1789">
<stop
style="stop-color:#202020;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop1790" />
<stop
style="stop-color:#b9b9b9;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop1791" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1789"
id="radialGradient238"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.055022,-2.734504e-2,0.177703,1.190929,-3.572177,-7.125301)"
cx="20.706017"
cy="37.517986"
fx="20.706017"
fy="37.517986"
r="30.905205" />
<linearGradient
id="linearGradient3983">
<stop
style="stop-color:#ffffff;stop-opacity:0.87628865;"
offset="0.0000000"
id="stop3984" />
<stop
style="stop-color:#fffffe;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop3985" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3983"
id="linearGradient491"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.516844,0.000000,0.000000,0.708978,-0.879573,-1.318166)"
x1="6.2297964"
y1="13.773066"
x2="9.8980894"
y2="66.834053" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="46.689312"
x2="12.853771"
y1="32.567184"
x1="13.035696"
gradientTransform="matrix(1.317489,0.000000,0.000000,0.816256,-0.879573,-1.318166)"
id="linearGradient322"
xlink:href="#linearGradient319"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="6.1802502"
x2="15.514889"
y1="31.367750"
x1="18.112709"
id="linearGradient3104"
xlink:href="#linearGradient3096"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient9766"
id="linearGradient9772"
x1="22.175976"
y1="36.987999"
x2="22.065331"
y2="32.050499"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient9806"
id="radialGradient9812"
cx="24.35099"
cy="41.591846"
fx="24.35099"
fy="41.591846"
r="19.136078"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.242494,1.565588e-16,31.50606)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
fill="#729fcf"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.10196078"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="54.359127"
inkscape:cy="-13.803699"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1026"
inkscape:window-height="818"
inkscape:window-x="169"
inkscape:window-y="30"
inkscape:showpageshadow="false"
stroke="#3465a4" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Folder Icon</dc:title>
<dc:date />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:source>http://jimmac.musichall.cz</dc:source>
<dc:subject>
<rdf:Bag>
<rdf:li>folder</rdf:li>
<rdf:li>directory</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Folder"
inkscape:groupmode="layer">
<g
style="display:inline"
transform="matrix(2.262383e-2,0,0,2.086758e-2,43.38343,36.36962)"
id="g6707">
<rect
style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect6709"
width="1339.6335"
height="478.35718"
x="-1559.2523"
y="-150.69685" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
id="path6711"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
id="path6713"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
</g>
<path
d="M 4.5217805,38.687417 C 4.5435766,39.103721 4.9816854,39.520026 5.3979900,39.520026 L 36.725011,39.520026 C 37.141313,39.520026 37.535823,39.103721 37.514027,38.687417 L 36.577584,11.460682 C 36.555788,11.044379 36.117687,10.628066 35.701383,10.628066 L 22.430510,10.628066 C 21.945453,10.628066 21.196037,10.312477 21.028866,9.5214338 L 20.417475,6.6283628 C 20.262006,5.8926895 19.535261,5.5904766 19.118957,5.5904766 L 4.3400975,5.5904766 C 3.9237847,5.5904766 3.5292767,6.0067807 3.5510726,6.4230849 L 4.5217805,38.687417 z "
id="path216"
style="fill:url(#radialGradient238);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient3104);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
sodipodi:nodetypes="ccccccssssccc" />
<path
sodipodi:nodetypes="cc"
id="path9788"
d="M 5.2265927,22.5625 L 35.492173,22.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cc"
id="path9784"
d="M 5.0421736,18.5625 L 35.489104,18.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 4.9806965,12.5625 L 35.488057,12.5625"
id="path9778"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.3861577,32.5625 L 35.494881,32.5625"
id="path9798"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path9800"
d="M 5.5091398,34.5625 L 35.496893,34.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.0421736,16.5625 L 35.489104,16.5625"
id="path9782"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path9780"
d="M 5.0114345,14.5625 L 35.48858,14.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cc"
id="path9776"
d="M 4.9220969,10.5625 L 20.202912,10.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 4.8737534,8.5624999 L 19.657487,8.5624999"
id="path9774"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.3246666,28.5625 L 35.493876,28.5625"
id="path9794"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path9792"
d="M 5.2880638,26.5625 L 35.493184,26.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.2265927,24.5625 L 35.492173,24.5625"
id="path9790"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.1958537,20.5625 L 35.491649,20.5625"
id="path9786"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path9796"
d="M 5.3246666,30.5625 L 35.493876,30.5625"
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.11363633;color:#000000;fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 5.5091398,36.5625 L 35.496893,36.5625"
id="path9802"
sodipodi:nodetypes="cc" />
<path
style="color:#000000;fill:url(#linearGradient491);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.2138050;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible;opacity:0.45142857"
d="M 6.0683430,38.864023 C 6.0846856,39.176251 5.8874317,39.384402 5.5697582,39.280326 L 5.5697582,39.280326 C 5.2520766,39.176251 5.0330270,38.968099 5.0166756,38.655870 L 4.0689560,6.5913839 C 4.0526131,6.2791558 4.2341418,6.0906134 4.5463699,6.0906134 L 18.968420,6.0429196 C 19.280648,6.0429196 19.900363,6.3433923 20.101356,7.3651014 L 20.674845,10.180636 C 20.247791,9.7153790 20.255652,9.7010175 20.037287,9.0239299 L 19.631192,7.7647478 C 19.412142,7.0371009 18.932991,6.9328477 18.620763,6.9328477 L 5.7329889,6.9328477 C 5.4207613,6.9328477 5.2235075,7.1409999 5.2398583,7.4532364 L 6.1778636,38.968099 L 6.0683430,38.864023 z "
id="path219"
sodipodi:nodetypes="cccccccccscccccc" />
<g
style="stroke-miterlimit:4.0000000;stroke-width:0.99946535;stroke:none;fill-rule:nonzero;fill-opacity:0.75706214;fill:#ffffff"
id="g220"
transform="matrix(1.040764,0.000000,5.449252e-2,1.040764,-8.670199,2.670594)"
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
inkscape:export-xdpi="74.800003"
inkscape:export-ydpi="74.800003">
<path
style="fill-opacity:0.50847459;fill:#ffffff"
d="M 42.417183,8.5151772 C 42.422267,8.4180642 42.289022,8.2681890 42.182066,8.2681716 L 29.150665,8.2660527 C 29.150665,8.2660527 30.062379,8.8540072 31.352477,8.8622963 L 42.405974,8.9333167 C 42.417060,8.7215889 42.408695,8.6772845 42.417183,8.5151772 z "
id="path221"
sodipodi:nodetypes="cscscs" />
</g>
<path
style="color:#000000;fill:url(#linearGradient9772);fill-opacity:1.0;fill-rule:nonzero;stroke:#3465a4;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1;visibility:visible;display:block"
d="M 39.783532,39.510620 C 40.927426,39.466556 41.746608,38.414321 41.830567,37.189615 C 42.622354,25.640928 43.489927,15.957666 43.489927,15.957666 C 43.562082,15.710182 43.322016,15.462699 43.009787,15.462699 L 8.6386304,15.462699 C 8.6386304,15.462699 6.7883113,37.329591 6.7883113,37.329591 C 6.6737562,38.311657 6.3223038,39.134309 5.2384755,39.513304 L 39.783532,39.510620 z "
id="path233"
sodipodi:nodetypes="cscccscc"
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/gnome-fs-directory.png"
inkscape:export-xdpi="74.800003"
inkscape:export-ydpi="74.800003" />
<path
sodipodi:nodetypes="ccsscsc"
id="path304"
d="M 9.6202444,16.463921 L 42.411343,16.528735 L 40.837297,36.530714 C 40.752975,37.602225 40.386619,37.958929 38.964641,37.958929 C 37.093139,37.958929 10.286673,37.926522 7.569899,37.926522 C 7.8034973,37.605711 7.9036547,36.937899 7.9049953,36.92191 L 9.6202444,16.463921 z "
style="opacity:0.46590909;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient322);stroke-width:0.99999970px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1.0000000" />
<path
sodipodi:nodetypes="ccccc"
id="path323"
d="M 9.6202481,16.223182 L 8.4536014,31.866453 C 8.4536014,31.866453 16.749756,27.718375 27.119949,27.718375 C 37.490142,27.718375 42.675239,16.223182 42.675239,16.223182 L 9.6202481,16.223182 z "
style="fill:#ffffff;fill-opacity:0.089285679;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="pattern" />
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -89,6 +89,20 @@ def read_file(filename, binary=False):
return data
def resource_filename(filename):
"""Get the absolute filename of a file contained with qutebrowser.
Args:
filename: The filename.
Return:
The absolute filename.
"""
if hasattr(sys, 'frozen'):
return os.path.join(os.path.dirname(sys.executable), filename)
return pkg_resources.resource_filename(qutebrowser.__name__, filename)
def actute_warning():
"""Display a warning about the dead_actute issue if needed."""
# WORKAROUND (remove this when we bump the requirements to 5.3.0)

View File

@ -40,6 +40,7 @@ PERFECT_FILES = [
'qutebrowser/browser/rfc6266.py',
'qutebrowser/browser/webelem.py',
'qutebrowser/browser/network/schemehandler.py',
'qutebrowser/browser/network/filescheme.py',
'qutebrowser/misc/readline.py',
'qutebrowser/misc/split.py',

View File

@ -0,0 +1,201 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015 Antoni Boucher (antoyo) <bouanto@zoho.com>
#
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Tests for qutebrowser.browser.network.filescheme."""
import os
import collections
import pytest
import bs4
from PyQt5.QtCore import QUrl
from PyQt5.QtNetwork import QNetworkRequest
from qutebrowser.browser.network import filescheme
@pytest.mark.parametrize('create_file, create_dir, filterfunc, expected', [
(True, False, os.path.isfile, True),
(True, False, os.path.isdir, False),
(False, True, os.path.isfile, False),
(False, True, os.path.isdir, True),
(False, False, os.path.isfile, False),
(False, False, os.path.isdir, False),
])
def test_get_file_list(tmpdir, create_file, create_dir, filterfunc, expected):
"""Test get_file_list."""
path = tmpdir / 'foo'
if create_file or create_dir:
path.ensure(dir=create_dir)
all_files = os.listdir(str(tmpdir))
result = filescheme.get_file_list(str(tmpdir), all_files, filterfunc)
item = {'name': 'foo', 'absname': str(path)}
assert (item in result) == expected
class TestIsRoot:
@pytest.mark.windows
@pytest.mark.parametrize('directory, is_root', [
('C:\\foo', False),
('C:\\', True)
])
def test_windows(self, directory, is_root):
assert filescheme.is_root(directory) == is_root
@pytest.mark.posix
@pytest.mark.parametrize('directory, is_root', [
('/foo', False),
('/', True)
])
def test_posix(self, directory, is_root):
assert filescheme.is_root(directory) == is_root
class TestDirbrowserHtml:
Parsed = collections.namedtuple('Parsed', 'parent, folders, files')
Item = collections.namedtuple('Item', 'link, text')
@pytest.fixture
def parser(self):
"""Provide a function to get a parsed dirbrowser document."""
def parse(path):
html = filescheme.dirbrowser_html(path)
soup = bs4.BeautifulSoup(html, 'html.parser')
print(soup.prettify())
container = soup('div', id='dirbrowserContainer')[0]
parent_elem = container('ul', class_='parent')
if len(parent_elem) == 0:
parent = None
else:
parent = parent_elem[0].li.a.string
folders = []
files = []
for li in container('ul', class_='folders')[0]('li'):
item = self.Item(link=li.a['href'], text=str(li.a.string))
folders.append(item)
for li in container('ul', class_='files')[0]('li'):
item = self.Item(link=li.a['href'], text=str(li.a.string))
files.append(item)
return self.Parsed(parent=parent, folders=folders, files=files)
return parse
def test_basic(self):
html = filescheme.dirbrowser_html(os.getcwd())
soup = bs4.BeautifulSoup(html, 'html.parser')
print(soup.prettify())
container = soup.div
assert container['id'] == 'dirbrowserContainer'
title_elem = container('div', id='dirbrowserTitle')[0]
title_text = title_elem('p', id='dirbrowserTitleText')[0].text
assert title_text == 'Browse directory: {}'.format(os.getcwd())
def test_empty(self, tmpdir, parser):
parsed = parser(str(tmpdir))
assert parsed.parent
assert not parsed.folders
assert not parsed.files
def test_files(self, tmpdir, parser):
foo_file = tmpdir / 'foo'
bar_file = tmpdir / 'bar'
foo_file.ensure()
bar_file.ensure()
parsed = parser(str(tmpdir))
assert parsed.parent
assert not parsed.folders
foo_item = self.Item('file://' + str(foo_file), foo_file.relto(tmpdir))
bar_item = self.Item('file://' + str(bar_file), bar_file.relto(tmpdir))
assert parsed.files == [bar_item, foo_item]
def test_dirs(self, tmpdir, parser):
foo_dir = tmpdir / 'foo'
bar_dir = tmpdir / 'bar'
foo_dir.ensure(dir=True)
bar_dir.ensure(dir=True)
parsed = parser(str(tmpdir))
assert parsed.parent
assert not parsed.files
foo_item = self.Item('file://' + str(foo_dir), foo_dir.relto(tmpdir))
bar_item = self.Item('file://' + str(bar_dir), bar_dir.relto(tmpdir))
assert parsed.folders == [bar_item, foo_item]
def test_mixed(self, tmpdir, parser):
foo_file = tmpdir / 'foo'
bar_dir = tmpdir / 'bar'
foo_file.ensure()
bar_dir.ensure(dir=True)
parsed = parser(str(tmpdir))
foo_item = self.Item('file://' + str(foo_file), foo_file.relto(tmpdir))
bar_item = self.Item('file://' + str(bar_dir), bar_dir.relto(tmpdir))
assert parsed.parent
assert parsed.files == [foo_item]
assert parsed.folders == [bar_item]
def test_root_dir(self, tmpdir, parser):
if os.name == 'nt':
root_dir = 'C:\\'
else:
root_dir = '/'
parsed = parser(root_dir)
assert not parsed.parent
def test_oserror(self, mocker):
m = mocker.patch('qutebrowser.browser.network.filescheme.os.listdir')
m.side_effect = OSError('Error message')
html = filescheme.dirbrowser_html('')
soup = bs4.BeautifulSoup(html, 'html.parser')
print(soup.prettify())
error_title = soup('p', id='errorTitleText')[0].string
error_msg = soup('p', id='errorMessageText')[0].string
assert error_title == 'Unable to load page'
assert error_msg == 'Error message'
class TestFileSchemeHandler:
def test_dir(self, tmpdir):
url = QUrl.fromLocalFile(str(tmpdir))
req = QNetworkRequest(url)
handler = filescheme.FileSchemeHandler(win_id=0)
reply = handler.createRequest(None, req, None)
assert reply.readAll() == filescheme.dirbrowser_html(str(tmpdir))
def test_file(self, tmpdir):
filename = tmpdir / 'foo'
filename.ensure()
url = QUrl.fromLocalFile(str(filename))
req = QNetworkRequest(url)
handler = filescheme.FileSchemeHandler(win_id=0)
reply = handler.createRequest(None, req, None)
assert reply is None

View File

@ -92,12 +92,8 @@ class TestEliding:
assert utils.elide(text, length) == expected
class TestReadFile:
"""Test read_file."""
@pytest.fixture(autouse=True, params=[True, False])
def freezer(self, request, monkeypatch):
@pytest.fixture(params=[True, False])
def freezer(request, monkeypatch):
if request.param and not getattr(sys, 'frozen', False):
monkeypatch.setattr(sys, 'frozen', True, raising=False)
monkeypatch.setattr('sys.executable', qutebrowser.__file__)
@ -105,6 +101,12 @@ class TestReadFile:
# Want to test unfrozen tests, but we are frozen
pytest.skip("Can't run with sys.frozen = True!")
@pytest.mark.usefixtures('freezer')
class TestReadFile:
"""Test read_file."""
def test_readfile(self):
"""Read a test file."""
content = utils.read_file(os.path.join('utils', 'testfile'))
@ -117,6 +119,14 @@ class TestReadFile:
assert content.splitlines()[0] == b"Hello World!"
@pytest.mark.usefixtures('freezer')
def test_resource_filename():
"""Read a test file."""
filename = utils.resource_filename(os.path.join('utils', 'testfile'))
with open(filename, 'r', encoding='utf-8') as f:
assert f.read().splitlines()[0] == "Hello World!"
class Patcher:
"""Helper for TestActuteWarning.

View File

@ -25,6 +25,7 @@ deps =
coverage==3.7.1
pytest-cov==2.0.0
cov-core==1.15.0
beautifulsoup4==4.4.0
commands =
{envpython} scripts/link_pyqt.py --tox {envdir}
{envpython} -m py.test --strict -rfEsw --cov qutebrowser --cov-report xml --cov-report= {posargs:tests}