From 14ae308279214cee62e06a3355bf94f2d677e074 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 8 Aug 2015 15:16:48 -0400 Subject: [PATCH] Added a file:// scheme. --- qutebrowser/browser/dirbrowser.py | 73 ------------ qutebrowser/browser/network/filescheme.py | 110 ++++++++++++++++++ qutebrowser/browser/network/networkmanager.py | 2 + qutebrowser/browser/webpage.py | 7 -- tests/browser/test_dirbrowser.py | 2 +- 5 files changed, 113 insertions(+), 81 deletions(-) delete mode 100644 qutebrowser/browser/dirbrowser.py create mode 100644 qutebrowser/browser/network/filescheme.py diff --git a/qutebrowser/browser/dirbrowser.py b/qutebrowser/browser/dirbrowser.py deleted file mode 100644 index 61c3e4bd6..000000000 --- a/qutebrowser/browser/dirbrowser.py +++ /dev/null @@ -1,73 +0,0 @@ -# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: - -# Copyright 2015 Antoni Boucher (antoyo) -# -# 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 . - -"""The directory browser page.""" - -import os - -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 = [{'name': filename, 'absname': - os.path.abspath(os.path.join(basedir, filename))} - for filename in all_files - if filterfunc(os.path.join(basedir, filename))] - return sorted(items, key=lambda v: v['name'].lower()) - - -def dirbrowser(urlstring): - """Get the directory browser web page. - - Args: - urlstring: The directory path. - - Return: - The HTML of the web page. - """ - title = "Browse directory: {}".format(urlstring) - template = jinja.env.get_template('dirbrowser.html') - # pylint: disable=no-member - # https://bitbucket.org/logilab/pylint/issue/490/ - - folder = resource_filename('img/folder.svg') - file = resource_filename('img/file.svg') - - if os.path.dirname(urlstring) == urlstring: - parent = None - else: - parent = os.path.dirname(urlstring) - all_files = os.listdir(urlstring) - files = get_file_list(urlstring, all_files, os.path.isfile) - directories = get_file_list(urlstring, all_files, os.path.isdir) - html = template.render(title=title, url=urlstring, icon='', parent=parent, - files=files, directories=directories, folder=folder, - file=file) - return html diff --git a/qutebrowser/browser/network/filescheme.py b/qutebrowser/browser/network/filescheme.py new file mode 100644 index 000000000..c86b283c0 --- /dev/null +++ b/qutebrowser/browser/network/filescheme.py @@ -0,0 +1,110 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2014-2015 Florian Bruhin (The Compiler) +# +# 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 . +# +# pylint complains when using .render() on jinja templates, so we make it shut +# up for this whole module. + +# pylint: disable=no-member +# https://bitbucket.org/logilab/pylint/issue/490/ + +"""Handler functions for different qute:... pages. + +Module attributes: + pyeval_output: The output of the last :pyeval command. +""" + +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 = [{'name': filename, 'absname': + os.path.abspath(os.path.join(basedir, filename))} + for filename in all_files + if filterfunc(os.path.join(basedir, filename))] + return sorted(items, key=lambda v: v['name'].lower()) + + +def dirbrowser(urlstring): + """Get the directory browser web page. + + Args: + urlstring: The directory path. + + Return: + The HTML of the web page. + """ + if os.path.isdir(urlstring): + title = "Browse directory: {}".format(urlstring) + template = jinja.env.get_template('dirbrowser.html') + # pylint: disable=no-member + # https://bitbucket.org/logilab/pylint/issue/490/ + + folder = resource_filename('img/folder.svg') + file = resource_filename('img/file.svg') + + if os.path.dirname(urlstring) == urlstring: + parent = None + else: + parent = os.path.dirname(urlstring) + all_files = os.listdir(urlstring) + files = get_file_list(urlstring, all_files, os.path.isfile) + directories = get_file_list(urlstring, all_files, os.path.isdir) + html = template.render(title=title, url=urlstring, icon='', + parent=parent, files=files, + directories=directories, folder=folder, + file=file) + html = html.encode('UTF-8', errors='xmlcharrefreplace') + else: + with open(urlstring, 'rb') as f: + html = f.read() + return html + + +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. + """ + data = dirbrowser(request.url().toLocalFile()) + return networkreply.FixedDataNetworkReply( + request, data, 'text/html', self.parent()) diff --git a/qutebrowser/browser/network/networkmanager.py b/qutebrowser/browser/network/networkmanager.py index 1e0049684..e2119c460 100644 --- a/qutebrowser/browser/network/networkmanager.py +++ b/qutebrowser/browser/network/networkmanager.py @@ -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() diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index f5d6fe675..16460eaad 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -31,7 +31,6 @@ from PyQt5.QtWebKitWidgets import QWebPage from qutebrowser.config import config from qutebrowser.browser import http, tabhistory -from qutebrowser.browser.dirbrowser import dirbrowser from qutebrowser.browser.network import networkmanager from qutebrowser.utils import (message, usertypes, log, jinja, qtutils, utils, objreg, debug) @@ -159,12 +158,6 @@ class BrowserPage(QWebPage): if QUrl(elem.attribute('src')) == info.url: elem.setAttribute('style', 'display: none') return False - elif (error_str.endswith('Path is a directory') and - info.url.scheme() == 'file'): - html = dirbrowser(info.url.toLocalFile()) - errpage.content = html.encode('utf-8') - errpage.encoding = 'utf-8' - return True else: self._ignore_load_started = True self.error_occurred = True diff --git a/tests/browser/test_dirbrowser.py b/tests/browser/test_dirbrowser.py index ebfee4bc0..80a04499a 100644 --- a/tests/browser/test_dirbrowser.py +++ b/tests/browser/test_dirbrowser.py @@ -21,7 +21,7 @@ import os -from qutebrowser.browser.dirbrowser import get_file_list +from qutebrowser.browser.network.filescheme import get_file_list class TestFileList: