Remove urlutils.{urlstring,qurl}.
The idea of treating an URL-string and a QUrl as essentially the same data type got us into all kinds of problems. Now we use QUrl everywhere except at the borders to the user interface.
This commit is contained in:
parent
9b77efb50c
commit
0fd64419da
@ -30,7 +30,7 @@ from base64 import b64encode
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||
from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths,
|
||||
qInstallMessageHandler, QObject)
|
||||
qInstallMessageHandler, QObject, QUrl)
|
||||
|
||||
import qutebrowser
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
@ -42,6 +42,8 @@ import qutebrowser.network.proxy as proxy
|
||||
import qutebrowser.browser.quickmarks as quickmarks
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.version as version
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.network.networkmanager import NetworkManager
|
||||
from qutebrowser.config.config import ConfigManager
|
||||
from qutebrowser.keyinput.modeman import ModeManager
|
||||
@ -55,7 +57,6 @@ from qutebrowser.config.iniparsers import ReadWriteConfigParser
|
||||
from qutebrowser.config.lineparser import LineConfigParser
|
||||
from qutebrowser.browser.cookies import CookieJar
|
||||
from qutebrowser.browser.downloads import DownloadManager
|
||||
from qutebrowser.utils.message import MessageBridge
|
||||
from qutebrowser.utils.misc import (get_standard_dir, actute_warning,
|
||||
get_qt_args)
|
||||
from qutebrowser.utils.readline import ReadlineBridge
|
||||
@ -83,7 +84,7 @@ class Application(QApplication):
|
||||
_timers: List of used QTimers so they don't get GCed.
|
||||
_shutting_down: True if we're currently shutting down.
|
||||
_quit_status: The current quitting status.
|
||||
_opened_urls: List of opened URLs.
|
||||
_opened_urls: List of opened URLs, string as passed to the application.
|
||||
_crashdlg: The crash dialog currently open.
|
||||
_crashlogfile: A file handler to the fatal crash logfile.
|
||||
"""
|
||||
@ -220,7 +221,7 @@ class Application(QApplication):
|
||||
self.setOrganizationName("qutebrowser")
|
||||
self.setApplicationName("qutebrowser")
|
||||
self.setApplicationVersion(qutebrowser.__version__)
|
||||
self.messagebridge = MessageBridge(self)
|
||||
self.messagebridge = message.MessageBridge(self)
|
||||
self.rl_bridge = ReadlineBridge()
|
||||
|
||||
def _handle_segfault(self):
|
||||
@ -284,19 +285,30 @@ class Application(QApplication):
|
||||
self.processEvents(QEventLoop.ExcludeUserInputEvents |
|
||||
QEventLoop.ExcludeSocketNotifiers)
|
||||
|
||||
for e in self.args.command:
|
||||
if e.startswith(':'):
|
||||
log.init.debug("Startup cmd {}".format(e))
|
||||
self.commandmanager.run_safely_init(e.lstrip(':'))
|
||||
for cmd in self.args.command:
|
||||
if cmd.startswith(':'):
|
||||
log.init.debug("Startup cmd {}".format(cmd))
|
||||
self.commandmanager.run_safely_init(cmd.lstrip(':'))
|
||||
else:
|
||||
log.init.debug("Startup URL {}".format(e))
|
||||
self._opened_urls.append(e)
|
||||
self.mainwindow.tabs.tabopen(e)
|
||||
log.init.debug("Startup URL {}".format(cmd))
|
||||
self._opened_urls.append(cmd)
|
||||
try:
|
||||
url = urlutils.fuzzy_url(cmd)
|
||||
except urlutils.SearchEngineError as e:
|
||||
message.error("Error in startup argument '{}': {}".format(
|
||||
cmd, e))
|
||||
else:
|
||||
self.mainwindow.tabs.tabopen(url)
|
||||
|
||||
if self.mainwindow.tabs.count() == 0:
|
||||
log.init.debug("Opening startpage")
|
||||
for url in self.config.get('general', 'startpage'):
|
||||
self.mainwindow.tabs.tabopen(url)
|
||||
for urlstr in self.config.get('general', 'startpage'):
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.SearchEngineError as e:
|
||||
message.error("Error when opening startpage: {}".format(e))
|
||||
else:
|
||||
self.mainwindow.tabs.tabopen(url)
|
||||
|
||||
def _python_hacks(self):
|
||||
"""Get around some PyQt-oddities by evil hacks.
|
||||
@ -548,9 +560,9 @@ class Application(QApplication):
|
||||
# if pages is None:
|
||||
# pages = []
|
||||
# for tab in self.mainwindow.tabs.widgets:
|
||||
# url = tab.url().toString()
|
||||
# if url:
|
||||
# pages.append(url)
|
||||
# urlstr = tab.url().toString()
|
||||
# if urlstr:
|
||||
# pages.append(urlstr)
|
||||
# pythonpath = os.pathsep.join(sys.path)
|
||||
# os.environ['PYTHONPATH'] = pythonpath
|
||||
# argv = sys.argv[:]
|
||||
@ -582,7 +594,7 @@ class Application(QApplication):
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
out = ': '.join([e.__class__.__name__, str(e)])
|
||||
qutescheme.pyeval_output = out
|
||||
self.mainwindow.tabs.cmd.openurl('qute:pyeval')
|
||||
self.mainwindow.tabs.openurl(QUrl('qute:pyeval'), newtab=True)
|
||||
|
||||
@pyqtSlot()
|
||||
def shutdown(self):
|
||||
|
@ -24,7 +24,7 @@ import subprocess
|
||||
from functools import partial
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtCore import Qt, QUrl
|
||||
from PyQt5.QtGui import QClipboard
|
||||
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
|
||||
from PyQt5.QtWebKitWidgets import QWebInspector
|
||||
@ -32,11 +32,11 @@ from PyQt5.QtWebKitWidgets import QWebInspector
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.browser.hints as hints
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
import qutebrowser.browser.quickmarks as quickmarks
|
||||
import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.url as urlutils
|
||||
from qutebrowser.utils.misc import (check_overflow, shell_escape,
|
||||
check_print_compat)
|
||||
from qutebrowser.utils.editor import ExternalEditor
|
||||
@ -152,14 +152,18 @@ class CommandDispatcher:
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', name='open',
|
||||
split=False)
|
||||
def openurl(self, url, count=None):
|
||||
def openurl(self, urlstr, count=None):
|
||||
"""Open a URL in the current/[count]th tab.
|
||||
|
||||
Args:
|
||||
url: The URL to open.
|
||||
urlstr: The URL to open, as string.
|
||||
count: The tab index to open the URL in, or None.
|
||||
"""
|
||||
tab = self._tabs.cntwidget(count)
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.SearchEngineError as e:
|
||||
raise CommandError(e)
|
||||
if tab is None:
|
||||
if count is None:
|
||||
# We want to open a URL in the current tab, but none exists
|
||||
@ -352,15 +356,15 @@ class CommandDispatcher:
|
||||
Args:
|
||||
sel: True to use primary selection, False to use clipboard
|
||||
"""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
urlstr = self._tabs.currentWidget().url().toString(QUrl.FullyEncoded)
|
||||
if sel:
|
||||
mode = QClipboard.Selection
|
||||
target = "primary selection"
|
||||
else:
|
||||
mode = QClipboard.Clipboard
|
||||
target = "clipboard"
|
||||
log.misc.debug("Yanking to {}: '{}'".format(target, url))
|
||||
QApplication.clipboard().setText(url, mode)
|
||||
log.misc.debug("Yanking to {}: '{}'".format(target, urlstr))
|
||||
QApplication.clipboard().setText(urlstr, mode)
|
||||
message.info("URL yanked to {}".format(target))
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
@ -425,32 +429,40 @@ class CommandDispatcher:
|
||||
self._tabs.close_tab(tab)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', split=False)
|
||||
def open_tab(self, url):
|
||||
def open_tab(self, urlstr):
|
||||
"""Open a new tab with a given url."""
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.SearchEngineError as e:
|
||||
raise CommandError(e)
|
||||
self._tabs.tabopen(url, background=False)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', split=False)
|
||||
def open_tab_bg(self, url):
|
||||
def open_tab_bg(self, urlstr):
|
||||
"""Open a new tab in background."""
|
||||
try:
|
||||
url = urlutils.fuzzy_url(urlstr)
|
||||
except urlutils.SearchEngineError as e:
|
||||
raise CommandError(e)
|
||||
self._tabs.tabopen(url, background=True)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', hide=True)
|
||||
def open_tab_cur(self):
|
||||
"""Set the statusbar to :tabopen and the current URL."""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
message.set_cmd_text(':open-tab ' + url)
|
||||
urlstr = self._tabs.currentWidget().url().toString()
|
||||
message.set_cmd_text(':open-tab ' + urlstr)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', hide=True)
|
||||
def open_cur(self):
|
||||
"""Set the statusbar to :open and the current URL."""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
message.set_cmd_text(':open ' + url)
|
||||
urlstr = self._tabs.currentWidget().url().toString()
|
||||
message.set_cmd_text(':open ' + urlstr)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', hide=True)
|
||||
def open_tab_bg_cur(self):
|
||||
"""Set the statusbar to :tabopen-bg and the current URL."""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
message.set_cmd_text(':open-tab-bg ' + url)
|
||||
urlstr = self._tabs.currentWidget().url().toString()
|
||||
message.set_cmd_text(':open-tab-bg ' + urlstr)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def undo(self):
|
||||
@ -499,10 +511,14 @@ class CommandDispatcher:
|
||||
tab: True to open in a new tab.
|
||||
"""
|
||||
mode = QClipboard.Selection if sel else QClipboard.Clipboard
|
||||
url = QApplication.clipboard().text(mode)
|
||||
if not url:
|
||||
text = QApplication.clipboard().text(mode)
|
||||
if not text:
|
||||
raise CommandError("Clipboard is empty.")
|
||||
log.misc.debug("Clipboard contained: '{}'".format(url))
|
||||
log.misc.debug("Clipboard contained: '{}'".format(text))
|
||||
try:
|
||||
url = urlutils.fuzzy_url(text)
|
||||
except urlutils.SearchEngineError as e:
|
||||
raise CommandError(e)
|
||||
if tab:
|
||||
self._tabs.tabopen(url)
|
||||
else:
|
||||
@ -591,8 +607,8 @@ class CommandDispatcher:
|
||||
Args:
|
||||
cmd: The command to execute.
|
||||
"""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
cmd = cmd.replace('{}', shell_escape(url))
|
||||
urlstr = self._tabs.currentWidget().url().toString(QUrl.FullyEncoded)
|
||||
cmd = cmd.replace('{}', shell_escape(urlstr))
|
||||
log.procs.debug("Executing: {}".format(cmd))
|
||||
subprocess.Popen(cmd, shell=True)
|
||||
|
||||
@ -604,10 +620,10 @@ class CommandDispatcher:
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def run_userscript(self, cmd, *args):
|
||||
"""Run an userscript given as argument."""
|
||||
url = urlutils.urlstring(self._tabs.currentWidget().url())
|
||||
urlstr = self._tabs.currentWidget().url().toString(QUrl.FullyEncoded)
|
||||
runner = UserscriptRunner(self._tabs)
|
||||
runner.got_cmd.connect(self._tabs.got_cmd)
|
||||
runner.run(cmd, *args, env={'QUTE_URL': url})
|
||||
runner.run(cmd, *args, env={'QUTE_URL': urlstr})
|
||||
self._userscript_runners.append(runner)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
@ -656,8 +672,7 @@ class CommandDispatcher:
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd')
|
||||
def download_page(self):
|
||||
"""Download the current page."""
|
||||
widget = self._tabs.currentWidget()
|
||||
url = urlutils.urlstring(widget.url())
|
||||
url = self._tabs.currentWidget().url()
|
||||
QApplication.instance().downloadmanager.get(url)
|
||||
|
||||
@cmdutils.register(instance='mainwindow.tabs.cmd', modes=['insert'],
|
||||
|
@ -31,7 +31,6 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.utils.log import downloads as logger
|
||||
from qutebrowser.utils.log import fix_rfc2622
|
||||
@ -360,13 +359,13 @@ class DownloadManager(QObject):
|
||||
filename = 'qutebrowser-download'
|
||||
return os.path.basename(filename)
|
||||
|
||||
def get(self, link):
|
||||
def get(self, url):
|
||||
"""Start a download with a link URL.
|
||||
|
||||
Args:
|
||||
link: The link URL as a string.
|
||||
url: The URL to get, as QUrl
|
||||
"""
|
||||
req = QNetworkRequest(urlutils.qurl(link))
|
||||
req = QNetworkRequest(url)
|
||||
reply = QCoreApplication.instance().networkmanager.get(req)
|
||||
self.fetch(reply)
|
||||
|
||||
|
@ -22,14 +22,13 @@
|
||||
import math
|
||||
from collections import namedtuple
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent, Qt, QUrl
|
||||
from PyQt5.QtGui import QMouseEvent, QClipboard
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.utils.webelem as webelem
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
@ -294,23 +293,24 @@ class HintManager(QObject):
|
||||
for evt in events:
|
||||
self.mouse_event.emit(evt)
|
||||
|
||||
def _yank(self, link):
|
||||
def _yank(self, url):
|
||||
"""Yank an element to the clipboard or primary selection.
|
||||
|
||||
Args:
|
||||
link: The URL to open.
|
||||
url: The URL to open as a QURL.
|
||||
"""
|
||||
sel = self._context.target == Target.yank_primary
|
||||
mode = QClipboard.Selection if sel else QClipboard.Clipboard
|
||||
QApplication.clipboard().setText(urlutils.urlstring(link), mode)
|
||||
urlstr = url.toString(QUrl.FullyEncoded)
|
||||
QApplication.clipboard().setText(urlstr, mode)
|
||||
message.info("URL yanked to {}".format("primary selection" if sel
|
||||
else "clipboard"))
|
||||
|
||||
def _preset_cmd_text(self, link):
|
||||
def _preset_cmd_text(self, url):
|
||||
"""Preset a commandline text based on a hint URL.
|
||||
|
||||
Args:
|
||||
link: The link to open.
|
||||
url: The URL to open as a QUrl.
|
||||
"""
|
||||
commands = {
|
||||
Target.cmd: 'open',
|
||||
@ -318,36 +318,36 @@ class HintManager(QObject):
|
||||
Target.cmd_tab_bg: 'open-tab-bg',
|
||||
}
|
||||
message.set_cmd_text(':{} {}'.format(commands[self._context.target],
|
||||
urlutils.urlstring(link)))
|
||||
url.toString(QUrl.FullyEncoded)))
|
||||
|
||||
def _download(self, link):
|
||||
def _download(self, url):
|
||||
"""Download a hint URL.
|
||||
|
||||
Args:
|
||||
link: The link to download.
|
||||
url: The URL to download, as a QUrl.
|
||||
"""
|
||||
QApplication.instance().downloadmanager.get(link)
|
||||
QApplication.instance().downloadmanager.get(url)
|
||||
|
||||
def _resolve_link(self, elem, baseurl=None):
|
||||
"""Resolve a link and check if we want to keep it.
|
||||
def _resolve_url(self, elem, baseurl=None):
|
||||
"""Resolve a URL and check if we want to keep it.
|
||||
|
||||
Args:
|
||||
elem: The QWebElement to get the link of.
|
||||
elem: The QWebElement to get the URL of.
|
||||
baseurl: The baseurl of the current tab (overrides baseurl from
|
||||
self._context).
|
||||
|
||||
Return:
|
||||
A QUrl with the absolute link, or None.
|
||||
A QUrl with the absolute URL, or None.
|
||||
"""
|
||||
link = elem.attribute('href')
|
||||
if not link:
|
||||
text = elem.attribute('href')
|
||||
if not text:
|
||||
return None
|
||||
if baseurl is None:
|
||||
baseurl = self._context.baseurl
|
||||
link = urlutils.qurl(link)
|
||||
if link.isRelative():
|
||||
link = baseurl.resolved(link)
|
||||
return link
|
||||
url = QUrl(text)
|
||||
if url.isRelative():
|
||||
url = baseurl.resolved(url)
|
||||
return url
|
||||
|
||||
def _find_prevnext(self, frame, prev=False):
|
||||
"""Find a prev/next element in frame."""
|
||||
@ -399,11 +399,11 @@ class HintManager(QObject):
|
||||
if elem is None:
|
||||
raise CommandError("No {} links found!".format(
|
||||
"prev" if prev else "forward"))
|
||||
link = self._resolve_link(elem, baseurl)
|
||||
if link is None:
|
||||
url = self._resolve_url(elem, baseurl)
|
||||
if url is None:
|
||||
raise CommandError("No {} links found!".format(
|
||||
"prev" if prev else "forward"))
|
||||
self.openurl.emit(link, newtab)
|
||||
self.openurl.emit(url, newtab)
|
||||
|
||||
def start(self, mainframe, baseurl, group=webelem.Group.all,
|
||||
target=Target.normal):
|
||||
@ -508,8 +508,8 @@ class HintManager(QObject):
|
||||
Target.tab_bg: self._click,
|
||||
Target.rapid: self._click,
|
||||
}
|
||||
# Handlers which take a link string
|
||||
link_handlers = {
|
||||
# Handlers which take a QUrl
|
||||
url_handlers = {
|
||||
Target.yank: self._yank,
|
||||
Target.yank_primary: self._yank,
|
||||
Target.cmd: self._preset_cmd_text,
|
||||
@ -520,11 +520,11 @@ class HintManager(QObject):
|
||||
elem = self._context.elems[keystr].elem
|
||||
if self._context.target in elem_handlers:
|
||||
elem_handlers[self._context.target](elem)
|
||||
elif self._context.target in link_handlers:
|
||||
link = self._resolve_link(elem)
|
||||
if link is None:
|
||||
elif self._context.target in url_handlers:
|
||||
url = self._resolve_url(elem)
|
||||
if url is None:
|
||||
raise CommandError("No suitable link found for this element.")
|
||||
link_handlers[self._context.target](link)
|
||||
url_handlers[self._context.target](url)
|
||||
else:
|
||||
raise ValueError("No suitable handler found!")
|
||||
if self._context.target != Target.rapid:
|
||||
|
@ -22,14 +22,13 @@
|
||||
from functools import partial
|
||||
from collections import OrderedDict
|
||||
|
||||
from PyQt5.QtCore import QStandardPaths
|
||||
from PyQt5.QtCore import QStandardPaths, QUrl
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.utils.usertypes import PromptMode
|
||||
from qutebrowser.config.lineparser import LineConfigParser
|
||||
from qutebrowser.utils.misc import get_standard_dir
|
||||
from qutebrowser.utils.url import urlstring
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
|
||||
|
||||
@ -54,9 +53,14 @@ def save():
|
||||
|
||||
|
||||
def prompt_save(url):
|
||||
"""Prompt for a new quickmark name to be added and add it."""
|
||||
"""Prompt for a new quickmark name to be added and add it.
|
||||
|
||||
Args:
|
||||
url: The quickmark url as a QUrl.
|
||||
"""
|
||||
urlstr = url.toString(QUrl.FullyEncoded)
|
||||
message.question("Add quickmark:", PromptMode.text,
|
||||
partial(quickmark_add, url))
|
||||
partial(quickmark_add, urlstr))
|
||||
|
||||
|
||||
@cmdutils.register()
|
||||
@ -64,7 +68,7 @@ def quickmark_add(url, name):
|
||||
"""Add a new quickmark.
|
||||
|
||||
Args:
|
||||
url: The url to add as quickmark.
|
||||
url: The url to add as quickmark, as QUrl.
|
||||
name: The name for the new quickmark.
|
||||
"""
|
||||
if not name:
|
||||
@ -74,7 +78,7 @@ def quickmark_add(url, name):
|
||||
|
||||
def set_mark():
|
||||
"""Really set the quickmark."""
|
||||
marks[name] = urlstring(url)
|
||||
marks[name] = url
|
||||
|
||||
if name in marks:
|
||||
message.confirm_action("Override existing quickmark?", set_mark,
|
||||
|
@ -28,7 +28,6 @@ from PyQt5.QtPrintSupport import QPrintDialog
|
||||
from PyQt5.QtWebKitWidgets import QWebPage
|
||||
|
||||
import qutebrowser.utils.message as message
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.log as log
|
||||
from qutebrowser.utils.misc import read_file, check_print_compat
|
||||
@ -104,7 +103,7 @@ class BrowserPage(QWebPage):
|
||||
info = sip.cast(opt, QWebPage.ErrorPageExtensionOption)
|
||||
errpage = sip.cast(out, QWebPage.ErrorPageExtensionReturn)
|
||||
errpage.baseUrl = info.url
|
||||
urlstr = urlutils.urlstring(info.url)
|
||||
urlstr = info.url.toString()
|
||||
if (info.domain, info.error) in ignored_errors:
|
||||
log.webview.debug("Ignored error on {}: {} (error domain: {}, "
|
||||
"error code: {})".format(
|
||||
|
@ -31,7 +31,6 @@ import qutebrowser.utils.log as log
|
||||
import qutebrowser.utils.version as version
|
||||
from qutebrowser.network.schemehandler import (SchemeHandler,
|
||||
SpecialNetworkReply)
|
||||
from qutebrowser.utils.url import urlstring
|
||||
from qutebrowser.utils.misc import read_file
|
||||
|
||||
|
||||
@ -70,17 +69,6 @@ class QuteSchemeHandler(SchemeHandler):
|
||||
|
||||
"""Scheme handler for qute: URLs."""
|
||||
|
||||
def _transform_url(self, url):
|
||||
"""Transform a special URL to an QuteHandlers method name.
|
||||
|
||||
Args:
|
||||
url: The URL as string.
|
||||
|
||||
Return:
|
||||
The method name qute_*
|
||||
"""
|
||||
return url.replace('http://', '').replace('qute:', 'qute_')
|
||||
|
||||
def createRequest(self, _op, request, _outgoing_data):
|
||||
"""Create a new request.
|
||||
|
||||
@ -92,10 +80,12 @@ class QuteSchemeHandler(SchemeHandler):
|
||||
Return:
|
||||
A QNetworkReply.
|
||||
"""
|
||||
log.misc.debug("request: {}".format(request))
|
||||
url = urlstring(request.url())
|
||||
path = request.url().path()
|
||||
# An url like "qute:foo" is split as "scheme:path", not "scheme:host".
|
||||
log.misc.debug("url: {}, path: {}".format(request.url().toString(),
|
||||
path))
|
||||
try:
|
||||
handler = getattr(QuteHandlers, self._transform_url(url))
|
||||
handler = getattr(QuteHandlers, path)
|
||||
except AttributeError:
|
||||
data = bytes()
|
||||
else:
|
||||
@ -108,13 +98,13 @@ class QuteHandlers:
|
||||
"""Handlers for qute:... pages."""
|
||||
|
||||
@classmethod
|
||||
def qute_pyeval(cls):
|
||||
def pyeval(cls):
|
||||
"""Handler for qute:pyeval. Return HTML content as bytes."""
|
||||
text = cgi.escape(pyeval_output)
|
||||
return _get_html('pyeval', '<pre>{}</pre>'.format(text))
|
||||
|
||||
@classmethod
|
||||
def qute_version(cls):
|
||||
def version(cls):
|
||||
"""Handler for qute:version. Return HTML content as bytes."""
|
||||
text = cgi.escape(version.version())
|
||||
html = '<h1>Version info</h1>'
|
||||
@ -125,7 +115,7 @@ class QuteHandlers:
|
||||
return _get_html('Version', html)
|
||||
|
||||
@classmethod
|
||||
def qute_log(cls):
|
||||
def log(cls):
|
||||
"""Handler for qute:log. Return HTML content as bytes."""
|
||||
if log.ram_handler is None:
|
||||
text = "Log output was disabled."
|
||||
@ -134,6 +124,6 @@ class QuteHandlers:
|
||||
return _get_html('log', '<pre>{}</pre>'.format(text))
|
||||
|
||||
@classmethod
|
||||
def qute_gpl(cls):
|
||||
def gpl(cls):
|
||||
"""Handler for qute:gpl. Return HTML content as bytes."""
|
||||
return read_file('html/COPYING.html').encode('ASCII')
|
||||
|
@ -24,8 +24,6 @@
|
||||
import unittest
|
||||
from unittest import TestCase
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
|
||||
|
||||
@ -64,41 +62,6 @@ class ConfigStub:
|
||||
raise self.NoOptionError
|
||||
|
||||
|
||||
class ConversionTests(TestCase):
|
||||
|
||||
"""Test conversions between QUrl and url string.
|
||||
|
||||
Attributes:
|
||||
URL: The URL to check conversion with.
|
||||
"""
|
||||
|
||||
URL = 'http://www.qutebrowser.org/'
|
||||
|
||||
def test_qurl2qurl(self):
|
||||
"""Test converting a QUrl to a QUrl."""
|
||||
q = urlutils.qurl(QUrl(self.URL))
|
||||
self.assertIsInstance(q, QUrl)
|
||||
self.assertFalse(q.isEmpty())
|
||||
|
||||
def test_str2qurl(self):
|
||||
"""Test converting a string to a QUrl."""
|
||||
q = urlutils.qurl(self.URL)
|
||||
self.assertIsInstance(q, QUrl)
|
||||
self.assertFalse(q.isEmpty())
|
||||
|
||||
def test_str2str(self):
|
||||
"""Test converting a string to a string."""
|
||||
s = urlutils.urlstring(self.URL)
|
||||
self.assertIsInstance(s, str)
|
||||
self.assertEqual(s, self.URL)
|
||||
|
||||
def test_qurl2str(self):
|
||||
"""Test converting a QUrl to a string."""
|
||||
s = urlutils.urlstring(QUrl(self.URL))
|
||||
self.assertIsInstance(s, str)
|
||||
self.assertEqual(s, self.URL)
|
||||
|
||||
|
||||
class SpecialURLTests(TestCase):
|
||||
|
||||
"""Test is_special_url.
|
||||
|
@ -66,38 +66,34 @@ def _get_search_url(txt):
|
||||
return QUrl.fromUserInput(template.format(urllib.parse.quote(term)))
|
||||
|
||||
|
||||
def _is_url_naive(url):
|
||||
def _is_url_naive(urlstr):
|
||||
"""Naive check if given URL is really a URL.
|
||||
|
||||
Args:
|
||||
url: The URL to check for.
|
||||
urlstr: The URL to check for, as string.
|
||||
|
||||
Return:
|
||||
True if the URL really is a URL, False otherwise.
|
||||
"""
|
||||
protocols = ('http', 'https')
|
||||
u = qurl(url)
|
||||
urlstr = urlstring(url)
|
||||
if isinstance(url, QUrl):
|
||||
u = url
|
||||
else:
|
||||
u = QUrl.fromUserInput(url)
|
||||
# We don't use u here because fromUserInput appends http:// automatically.
|
||||
if any(urlstr.startswith(proto) for proto in protocols):
|
||||
schemes = ('http', 'https')
|
||||
url = QUrl.fromUserInput(urlstr)
|
||||
# We don't use url here because fromUserInput appends http://
|
||||
# automatically.
|
||||
if QUrl(urlstr).scheme() in schemes:
|
||||
return True
|
||||
elif '.' in u.host():
|
||||
elif '.' in url.host():
|
||||
return True
|
||||
elif u.host() == 'localhost':
|
||||
elif url.host() == 'localhost':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _is_url_dns(url):
|
||||
"""Check if a URL (QUrl) is really a URL via DNS.
|
||||
"""Check if a URL is really a URL via DNS.
|
||||
|
||||
Args:
|
||||
url: The URL to check for.
|
||||
url: The URL to check for as QUrl, ideally via QUrl::fromUserInput.
|
||||
|
||||
Return:
|
||||
True if the URL really is a URL, False otherwise.
|
||||
@ -110,66 +106,41 @@ def _is_url_dns(url):
|
||||
return not info.error()
|
||||
|
||||
|
||||
def qurl(url):
|
||||
"""Get a QUrl from a URL string.
|
||||
|
||||
Args:
|
||||
The URL as string or QUrl.
|
||||
|
||||
Return:
|
||||
The URL as string.
|
||||
"""
|
||||
return url if isinstance(url, QUrl) else QUrl(url)
|
||||
|
||||
|
||||
def urlstring(url):
|
||||
"""Get an QUrl as string.
|
||||
|
||||
Args:
|
||||
qurl: URL as string or QUrl.
|
||||
|
||||
Return:
|
||||
The URL as string
|
||||
"""
|
||||
return url.toString() if isinstance(url, QUrl) else url
|
||||
|
||||
|
||||
def fuzzy_url(url):
|
||||
def fuzzy_url(urlstr):
|
||||
"""Get a QUrl based on an user input which is URL or search term.
|
||||
|
||||
Args:
|
||||
url: URL to load as QUrl or string.
|
||||
urlstr: URL to load as a string.
|
||||
|
||||
Return:
|
||||
A target QUrl to a searchpage or the original URL.
|
||||
"""
|
||||
urlstr = urlstring(url)
|
||||
if is_url(urlstr):
|
||||
# probably an address
|
||||
logger.debug("URL is a fuzzy address")
|
||||
newurl = QUrl.fromUserInput(urlstr)
|
||||
url = QUrl.fromUserInput(urlstr)
|
||||
else: # probably a search term
|
||||
logger.debug("URL is a fuzzy search term")
|
||||
try:
|
||||
newurl = _get_search_url(urlstr)
|
||||
url = _get_search_url(urlstr)
|
||||
except ValueError: # invalid search engine
|
||||
newurl = QUrl.fromUserInput(urlstr)
|
||||
url = QUrl.fromUserInput(urlstr)
|
||||
logger.debug("Converting fuzzy term {} to URL -> {}".format(
|
||||
urlstr, urlstring(newurl)))
|
||||
return newurl
|
||||
urlstr, url.toString()))
|
||||
return url
|
||||
|
||||
|
||||
def is_special_url(url):
|
||||
"""Return True if url is an about:... or other special URL."""
|
||||
special_schemes = ('about', 'qute', 'file')
|
||||
return qurl(url).scheme() in special_schemes
|
||||
return QUrl(url).scheme() in special_schemes
|
||||
|
||||
|
||||
def is_url(url):
|
||||
def is_url(urlstr):
|
||||
"""Check if url seems to be a valid URL.
|
||||
|
||||
Args:
|
||||
url: The URL as QUrl or string.
|
||||
urlstr: The URL as string.
|
||||
|
||||
Return:
|
||||
True if it is a valid URL, False otherwise.
|
||||
@ -177,8 +148,6 @@ def is_url(url):
|
||||
Raise:
|
||||
ValueError if the autosearch config value is invalid.
|
||||
"""
|
||||
urlstr = urlstring(url)
|
||||
|
||||
autosearch = config.get('general', 'auto-search')
|
||||
|
||||
logger.debug("Checking if '{}' is a URL (autosearch={}).".format(
|
||||
@ -192,19 +161,21 @@ def is_url(url):
|
||||
# A URL will never contain a space
|
||||
logger.debug("Contains space -> no URL")
|
||||
return False
|
||||
elif is_special_url(url):
|
||||
elif is_special_url(QUrl(urlstr)):
|
||||
# Special URLs are always URLs, even with autosearch=False
|
||||
logger.debug("Is an special URL.")
|
||||
return True
|
||||
elif os.path.exists(url):
|
||||
elif os.path.exists(urlstr):
|
||||
# local file
|
||||
return True
|
||||
elif autosearch == 'dns':
|
||||
logger.debug("Checking via DNS")
|
||||
# We want to use fromUserInput here, as the user might enter "foo.de"
|
||||
# and that should be treated as URL here.
|
||||
return _is_url_dns(QUrl.fromUserInput(urlstr))
|
||||
elif autosearch == 'naive':
|
||||
logger.debug("Checking via naive check")
|
||||
return _is_url_naive(url)
|
||||
return _is_url_naive(urlstr)
|
||||
else:
|
||||
raise ValueError("Invalid autosearch value")
|
||||
|
||||
|
@ -27,10 +27,9 @@ Module attributes:
|
||||
without "href".
|
||||
"""
|
||||
|
||||
from PyQt5.QtCore import QRect
|
||||
from PyQt5.QtCore import QRect, QUrl
|
||||
from PyQt5.QtWebKit import QWebElement
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
|
||||
|
||||
@ -57,7 +56,7 @@ SELECTORS[Group.editable_focused] = ', '.join(
|
||||
|
||||
FILTERS = {
|
||||
Group.links: (lambda e: e.hasAttribute('href') and
|
||||
urlutils.qurl(e.attribute('href')).scheme() != 'javascript'),
|
||||
QUrl(e.attribute('href')).scheme() != 'javascript'),
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,7 +24,6 @@ from functools import partial
|
||||
from PyQt5.QtWidgets import QSizePolicy
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QSize
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
@ -160,7 +159,7 @@ class TabbedBrowser(TabWidget):
|
||||
self._filter.create(self.cur_load_status_changed))
|
||||
# hintmanager
|
||||
tab.hintmanager.hint_strings_updated.connect(self.hint_strings_updated)
|
||||
tab.hintmanager.openurl.connect(self.cmd.openurl)
|
||||
tab.hintmanager.openurl.connect(self.openurl)
|
||||
# downloads
|
||||
tab.page().unsupportedContent.connect(self.start_download)
|
||||
tab.page().start_download.connect(self.start_download)
|
||||
@ -244,7 +243,7 @@ class TabbedBrowser(TabWidget):
|
||||
"""Open a URL, used as a slot.
|
||||
|
||||
Args:
|
||||
url: The URL to open.
|
||||
url: The URL to open as QUrl.
|
||||
newtab: True to open URL in a new tab, False otherwise.
|
||||
"""
|
||||
if newtab:
|
||||
@ -262,7 +261,7 @@ class TabbedBrowser(TabWidget):
|
||||
"""Close a tab with a widget given."""
|
||||
self.close_tab(widget)
|
||||
|
||||
@pyqtSlot(str, bool)
|
||||
@pyqtSlot('QUrl', bool)
|
||||
def tabopen(self, url=None, background=None):
|
||||
"""Open a new tab with a given URL.
|
||||
|
||||
@ -270,7 +269,7 @@ class TabbedBrowser(TabWidget):
|
||||
Also connect all the signals we need to _filter_signals.
|
||||
|
||||
Args:
|
||||
url: The URL to open.
|
||||
url: The URL to open as QUrl or None for an empty tab.
|
||||
background: Whether to open the tab in the background.
|
||||
if None, the background-tabs setting decides.
|
||||
|
||||
@ -283,7 +282,6 @@ class TabbedBrowser(TabWidget):
|
||||
self._tabs.append(tab)
|
||||
self.addTab(tab, "")
|
||||
if url is not None:
|
||||
url = urlutils.qurl(url)
|
||||
tab.openurl(url)
|
||||
if background is None:
|
||||
background = config.get('general', 'background-tabs')
|
||||
|
@ -21,12 +21,11 @@
|
||||
|
||||
import functools
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtWebKit import QWebSettings
|
||||
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
||||
|
||||
import qutebrowser.utils.url as urlutils
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.utils.message as message
|
||||
@ -122,8 +121,7 @@ class WebView(QWebView):
|
||||
# FIXME find some way to hide scrollbars without setScrollBarPolicy
|
||||
|
||||
def __repr__(self):
|
||||
return "WebView(url='{}')".format(
|
||||
elide(urlutils.urlstring(self.url()), 50))
|
||||
return "WebView(url='{}')".format(elide(self.url().toString(), 50))
|
||||
|
||||
@property
|
||||
def load_status(self):
|
||||
@ -284,7 +282,7 @@ class WebView(QWebView):
|
||||
"""Open a URL in the browser.
|
||||
|
||||
Args:
|
||||
url: The URL to load, as string or QUrl.
|
||||
url: The URL to load as QUrl
|
||||
|
||||
Return:
|
||||
Return status of self.load
|
||||
@ -292,14 +290,11 @@ class WebView(QWebView):
|
||||
Emit:
|
||||
titleChanged
|
||||
"""
|
||||
try:
|
||||
u = urlutils.fuzzy_url(url)
|
||||
except urlutils.SearchEngineError as e:
|
||||
raise CommandError(e)
|
||||
log.webview.debug("New title: {}".format(urlutils.urlstring(u)))
|
||||
self.titleChanged.emit(urlutils.urlstring(u))
|
||||
self.url_text = urlutils.urlstring(u)
|
||||
return self.load(u)
|
||||
urlstr = url.toString()
|
||||
log.webview.debug("New title: {}".format(urlstr))
|
||||
self.titleChanged.emit(urlstr)
|
||||
self.url_text = urlstr
|
||||
return self.load(url)
|
||||
|
||||
def zoom_perc(self, perc, fuzzyval=True):
|
||||
"""Zoom to a given zoom percentage.
|
||||
@ -381,18 +376,19 @@ class WebView(QWebView):
|
||||
@pyqtSlot('QUrl')
|
||||
def on_url_changed(self, url):
|
||||
"""Update url_text when URL has changed."""
|
||||
self.url_text = urlutils.urlstring(url)
|
||||
self.url_text = url.toString()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def on_link_clicked(self, url):
|
||||
def on_link_clicked(self, urlstr):
|
||||
"""Handle a link.
|
||||
|
||||
Called from the linkClicked signal. Checks if it should open it in a
|
||||
tab (middle-click or control) or not, and does so.
|
||||
|
||||
Args:
|
||||
url: The URL to handle, as string or QUrl.
|
||||
urlstr: The URL to handle, as string.
|
||||
"""
|
||||
url = QUrl(urlstr)
|
||||
if self._open_target == Target.tab:
|
||||
self.tabbedbrowser.tabopen(url, False)
|
||||
elif self._open_target == Target.tab_bg:
|
||||
|
Loading…
Reference in New Issue
Block a user