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 *.py
recursive-include qutebrowser/html *.html recursive-include qutebrowser/html *.html
recursive-include qutebrowser/img *.svg
recursive-include qutebrowser/test *.py recursive-include qutebrowser/test *.py
recursive-include qutebrowser/javascript *.js recursive-include qutebrowser/javascript *.js
graft icons 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) urlutils)
from qutebrowser.browser import cookies from qutebrowser.browser import cookies
from qutebrowser.browser.network import qutescheme, networkreply from qutebrowser.browser.network import qutescheme, networkreply
from qutebrowser.browser.network import filescheme
HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%' HOSTBLOCK_ERROR_STRING = '%HOSTBLOCK%'
@ -97,6 +98,7 @@ class NetworkManager(QNetworkAccessManager):
self._requests = [] self._requests = []
self._scheme_handlers = { self._scheme_handlers = {
'qute': qutescheme.QuteSchemeHandler(win_id), 'qute': qutescheme.QuteSchemeHandler(win_id),
'file': filescheme.FileSchemeHandler(win_id),
} }
self._set_cookiejar() self._set_cookiejar()
self._set_cache() self._set_cache()
@ -295,6 +297,25 @@ class NetworkManager(QNetworkAccessManager):
download.destroyed.connect(self.on_adopted_download_destroyed) download.destroyed.connect(self.on_adopted_download_destroyed)
download.do_retry.connect(self.adopt_download) 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: # WORKAROUND for:
# http://www.riverbankcomputing.com/pipermail/pyqt/2014-September/034806.html # http://www.riverbankcomputing.com/pipermail/pyqt/2014-September/034806.html
# #
@ -318,8 +339,10 @@ class NetworkManager(QNetworkAccessManager):
""" """
scheme = req.url().scheme() scheme = req.url().scheme()
if scheme in self._scheme_handlers: if scheme in self._scheme_handlers:
return self._scheme_handlers[scheme].createRequest( result = self._scheme_handlers[scheme].createRequest(
op, req, outgoing_data) op, req, outgoing_data)
if result is not None:
return result
host_blocker = objreg.get('host-blocker') host_blocker = objreg.get('host-blocker')
if (op == QNetworkAccessManager.GetOperation and if (op == QNetworkAccessManager.GetOperation and
@ -344,22 +367,8 @@ class NetworkManager(QNetworkAccessManager):
webview = objreg.get('webview', scope='tab', window=self._win_id, webview = objreg.get('webview', scope='tab', window=self._win_id,
tab=self._tab_id) tab=self._tab_id)
current_url = webview.url() current_url = webview.url()
referer_header_conf = config.get('network', 'referer-header')
try: self.set_referer(req, current_url)
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
accept_language = config.get('network', 'accept-language') accept_language = config.get('network', 'accept-language')
if accept_language is not None: 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 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(): def actute_warning():
"""Display a warning about the dead_actute issue if needed.""" """Display a warning about the dead_actute issue if needed."""
# WORKAROUND (remove this when we bump the requirements to 5.3.0) # 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/rfc6266.py',
'qutebrowser/browser/webelem.py', 'qutebrowser/browser/webelem.py',
'qutebrowser/browser/network/schemehandler.py', 'qutebrowser/browser/network/schemehandler.py',
'qutebrowser/browser/network/filescheme.py',
'qutebrowser/misc/readline.py', 'qutebrowser/misc/readline.py',
'qutebrowser/misc/split.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,19 +92,21 @@ class TestEliding:
assert utils.elide(text, length) == expected assert utils.elide(text, length) == expected
@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__)
elif not request.param and getattr(sys, 'frozen', False):
# Want to test unfrozen tests, but we are frozen
pytest.skip("Can't run with sys.frozen = True!")
@pytest.mark.usefixtures('freezer')
class TestReadFile: class TestReadFile:
"""Test read_file.""" """Test read_file."""
@pytest.fixture(autouse=True, params=[True, False])
def freezer(self, request, monkeypatch):
if request.param and not getattr(sys, 'frozen', False):
monkeypatch.setattr(sys, 'frozen', True, raising=False)
monkeypatch.setattr('sys.executable', qutebrowser.__file__)
elif not request.param and getattr(sys, 'frozen', False):
# Want to test unfrozen tests, but we are frozen
pytest.skip("Can't run with sys.frozen = True!")
def test_readfile(self): def test_readfile(self):
"""Read a test file.""" """Read a test file."""
content = utils.read_file(os.path.join('utils', 'testfile')) content = utils.read_file(os.path.join('utils', 'testfile'))
@ -117,6 +119,14 @@ class TestReadFile:
assert content.splitlines()[0] == b"Hello World!" 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: class Patcher:
"""Helper for TestActuteWarning. """Helper for TestActuteWarning.

View File

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