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:
Florian Bruhin 2014-06-20 16:33:01 +02:00
parent 9b77efb50c
commit 0fd64419da
12 changed files with 165 additions and 219 deletions

View File

@ -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):

View File

@ -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'],

View File

@ -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)

View File

@ -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:

View File

@ -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,

View File

@ -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(

View File

@ -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')

View File

@ -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.

View File

@ -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")

View File

@ -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'),
}

View File

@ -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')

View File

@ -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: