First attempt at proper AboutSchemeHandler
This commit is contained in:
parent
ec1951c56c
commit
38ef8fe8c7
@ -17,8 +17,10 @@
|
||||
|
||||
"""Handler functions for different about:... pages."""
|
||||
|
||||
from qutebrowser.network.schemehandler import (SchemeHandler,
|
||||
SpecialNetworkReply)
|
||||
from qutebrowser.utils.version import version
|
||||
from qutebrowser.utils.url import is_about_url
|
||||
from qutebrowser.utils.url import is_about_url, urlstring
|
||||
|
||||
|
||||
_HTML_TEMPLATE = """
|
||||
@ -84,6 +86,30 @@ def _get_html(title, snippet):
|
||||
return _HTML_TEMPLATE.format(title=title, body=snippet).encode('UTF-8')
|
||||
|
||||
|
||||
class AboutSchemeHandler(SchemeHandler):
|
||||
|
||||
"""Scheme handler for about: URLs."""
|
||||
|
||||
def createRequest(self, op, request, outgoingData=None):
|
||||
"""Create a new request.
|
||||
|
||||
Args:
|
||||
op: Operation op
|
||||
req: const QNetworkRequest & req
|
||||
outgoing_data: QIODevice * outgoingData
|
||||
|
||||
Return:
|
||||
A QNetworkReply.
|
||||
|
||||
"""
|
||||
|
||||
# FIXME handle unknown pages
|
||||
# FIXME adjust URLutils based on handlers
|
||||
|
||||
data = handle(urlstring(request.url()))
|
||||
return SpecialNetworkReply(request, data, "text/html", self.parent())
|
||||
|
||||
|
||||
class AboutHandlers:
|
||||
|
||||
"""Handlers for about:... pages."""
|
||||
|
@ -17,20 +17,30 @@
|
||||
|
||||
"""Our own QNetworkAccessManager."""
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager
|
||||
|
||||
from qutebrowser.network.about import AboutSchemeHandler
|
||||
|
||||
|
||||
class NetworkManager(QNetworkAccessManager):
|
||||
|
||||
"""Our own QNetworkAccessManager.
|
||||
|
||||
Attributes:
|
||||
_requests: Pending requests.
|
||||
_scheme_handlers: A dictionary (scheme -> handler) of supported custom
|
||||
schemes.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
self._requests = {}
|
||||
super().__init__(parent)
|
||||
self._requests = {}
|
||||
self._scheme_handlers = {
|
||||
'about': AboutSchemeHandler,
|
||||
}
|
||||
|
||||
def abort_requests(self):
|
||||
"""Abort all running requests."""
|
||||
@ -41,7 +51,7 @@ class NetworkManager(QNetworkAccessManager):
|
||||
"""Return a new QNetworkReply object.
|
||||
|
||||
Extend QNetworkAccessManager::createRequest to save requests in
|
||||
self._requests.
|
||||
self._requests and handle custom schemes.
|
||||
|
||||
Args:
|
||||
op: Operation op
|
||||
@ -52,6 +62,13 @@ class NetworkManager(QNetworkAccessManager):
|
||||
A QNetworkReply.
|
||||
|
||||
"""
|
||||
scheme = req.url().scheme()
|
||||
logging.debug("new req, scheme {}, handlers {}".format(scheme,
|
||||
self._scheme_handlers))
|
||||
if scheme in self._scheme_handlers:
|
||||
reply = self._scheme_handlers[scheme].createRequest(
|
||||
op, req, outgoing_data)
|
||||
return reply
|
||||
reply = super().createRequest(op, req, outgoing_data)
|
||||
self._requests[id(reply)] = reply
|
||||
reply.destroyed.connect(lambda obj: self._requests.pop(id(obj)))
|
||||
|
118
qutebrowser/network/schemehandler.py
Normal file
118
qutebrowser/network/schemehandler.py
Normal file
@ -0,0 +1,118 @@
|
||||
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# Based on the Eric5 helpviewer,
|
||||
# Copyright (c) 2009 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
"""Base class for custom scheme handlers."""
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
|
||||
from PyQt5.QtCore import pyqtSlot, QObject, QIODevice, QByteArray
|
||||
|
||||
class SchemeHandler(QObject):
|
||||
|
||||
"""Abstract base class for custom scheme handlers."""
|
||||
|
||||
def createRequest(self, op, request, outgoingData=None):
|
||||
"""Create a new request.
|
||||
|
||||
Args:
|
||||
op: Operation op
|
||||
req: const QNetworkRequest & req
|
||||
outgoing_data: QIODevice * outgoingData
|
||||
|
||||
Return:
|
||||
A QNetworkReply.
|
||||
|
||||
Raise:
|
||||
NotImplementedError because this needs to be overwritten by
|
||||
subclasses.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
class SpecialNetworkReply(QNetworkReply):
|
||||
|
||||
"""QNetworkReply subclass for special data."""
|
||||
|
||||
def __init__(self, request, fileData, mimeType, parent=None):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
request: reference to the request object (QNetworkRequest)
|
||||
fileData: reference to the data buffer (QByteArray)
|
||||
mimeType: for the reply (string)
|
||||
parent: reference to the parent object (QObject)
|
||||
|
||||
Emit:
|
||||
metaDataChanged and readyRead after initializing.
|
||||
|
||||
"""
|
||||
super().__init__(parent)
|
||||
|
||||
self._data = fileData
|
||||
|
||||
self.setRequest(request)
|
||||
self.setOpenMode(QIODevice.ReadOnly)
|
||||
|
||||
self.setHeader(QNetworkRequest.ContentTypeHeader, mimeType)
|
||||
self.setHeader(QNetworkRequest.ContentLengthHeader,
|
||||
QByteArray.number(fileData.length()))
|
||||
self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200)
|
||||
self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, "OK")
|
||||
self.metaDataChanged.emit()
|
||||
self.readyRead.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
def abort(self):
|
||||
"""Abort the operation."""
|
||||
pass
|
||||
|
||||
def bytesAvailable(self):
|
||||
"""Determine the bytes available for being read.
|
||||
|
||||
Return:
|
||||
bytes available (int)
|
||||
|
||||
Emit:
|
||||
finished: if the data length is 0
|
||||
|
||||
"""
|
||||
if self._data.length() == 0:
|
||||
self.finished.emit()
|
||||
return self._data.length() + super().bytesAvailable()
|
||||
|
||||
def readData(self, maxlen):
|
||||
"""Retrieve data from the reply object.
|
||||
|
||||
Args:
|
||||
maxlen maximum number of bytes to read (int)
|
||||
|
||||
Return:
|
||||
bytestring containing the data
|
||||
|
||||
Emit:
|
||||
finished: if all data was read
|
||||
|
||||
"""
|
||||
len_ = min(maxlen, self._data.length())
|
||||
buf = bytes(self._data[:len_])
|
||||
self._data.remove(0, len_)
|
||||
if self._data.length() == 0:
|
||||
self.finished.emit()
|
||||
return buf
|
@ -36,7 +36,6 @@ from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.utils.config as config
|
||||
import qutebrowser.network.about as about
|
||||
from qutebrowser.widgets.tabbar import TabWidget
|
||||
from qutebrowser.network.networkmanager import NetworkManager
|
||||
from qutebrowser.utils.signals import SignalCache, dbg_signal
|
||||
@ -719,16 +718,7 @@ class BrowserTab(QWebView):
|
||||
logging.debug('New title: {}'.format(urlutils.urlstring(u)))
|
||||
self.titleChanged.emit(urlutils.urlstring(u))
|
||||
self.urlChanged.emit(urlutils.qurl(u))
|
||||
if urlutils.is_about_url(u):
|
||||
try:
|
||||
content = about.handle(urlutils.urlstring(u))
|
||||
except AttributeError:
|
||||
return self.load(u)
|
||||
else:
|
||||
self.setUrl(u)
|
||||
self.setContent(content, 'text/html')
|
||||
else:
|
||||
return self.load(u)
|
||||
return self.load(u)
|
||||
|
||||
def zoom(self, offset):
|
||||
"""Increase/Decrease the zoom level.
|
||||
|
Loading…
Reference in New Issue
Block a user