Refactor utils.url.

This commit is contained in:
Florian Bruhin 2014-02-07 19:20:57 +01:00
parent a4a2832f8e
commit b50eba38d3

View File

@ -3,7 +3,6 @@
import re import re
import socket import socket
import logging import logging
import ipaddress
import urllib.parse import urllib.parse
from PyQt5.QtCore import QUrl from PyQt5.QtCore import QUrl
@ -13,32 +12,41 @@ import qutebrowser.utils.config as config
def qurl(url): def qurl(url):
"""Get a QUrl from an url string.""" """Get a QUrl from an url string."""
if isinstance(url, QUrl): return url if isinstance(url, QUrl) else QUrl(url)
logging.debug("url is already a qurl")
return url
return QUrl.fromUserInput(url) def urlstring(url):
"""Return an QUrl as string.
qurl -- URL as string or QUrl.
"""
return url.url() if isinstance(url, QUrl) else url
def fuzzy_url(url): def fuzzy_url(url):
"""Returns a QUrl based on an user input which is URL or search term.""" """Return a QUrl based on an user input which is URL or search term.
u = url.toString() if isinstance(url, QUrl) else url
url -- URL to load as QUrl or string.
"""
u = qurl(url)
urlstr = urlstring(url)
if is_url(u): if is_url(u):
# probably an address # probably an address
logging.debug("url is a fuzzy address") logging.debug("url is a fuzzy address")
newurl = QUrl.fromUserInput(u) newurl = QUrl.fromUserInput(urlstr)
else: # probably a search term else: # probably a search term
logging.debug("url is a fuzzy search term") logging.debug("url is a fuzzy search term")
try: try:
newurl = QUrl.fromUserInput(_get_search_url(u)) newurl = _get_search_url(urlstr)
except ValueError: except ValueError: # invalid search engine
newurl = QUrl.fromUserInput(u) newurl = QUrl.fromUserInput(urlstr)
logging.debug('Converting fuzzy term {} to url -> {}'.format( logging.debug('Converting fuzzy term {} to url -> {}'.format(urlstr,
u, newurl.url())) newurl.url()))
return newurl return newurl
def _get_search_url(txt): def _get_search_url(txt):
"""Get a search engine URL for a text.""" """Return a search engine URL (QUrl) for a text."""
logging.debug('Finding search engine for "{}"'.format(txt)) logging.debug('Finding search engine for "{}"'.format(txt))
r = re.compile(r'(^|\s+)!(\w+)($|\s+)') r = re.compile(r'(^|\s+)!(\w+)($|\s+)')
m = r.search(txt) m = r.search(txt)
@ -55,67 +63,48 @@ def _get_search_url(txt):
logging.debug('engine: default, term "{}"'.format(txt)) logging.debug('engine: default, term "{}"'.format(txt))
if template is None or not term: if template is None or not term:
raise ValueError raise ValueError
return template.format(urllib.parse.quote(term)) return QUrl.fromUserInput(template.format(urllib.parse.quote(term)))
def is_about_url(url): def is_about_url(url):
"""Return True if url is an about:... or other special URL.""" """Return True if url (QUrl) is an about:... or other special URL."""
u = url.toString() if isinstance(url, QUrl) else url return urlstring(url).replace('http://', '').startswith('about:')
return u.replace('http://', '').startswith('about:')
def is_url(url): def is_url(url):
"""Return True if url seems to be a valid URL.""" """Return True if url (QUrl) seems to be a valid URL."""
logging.debug('Checking if "{}" is an URL'.format(url)) logging.debug('Checking if "{}" is an URL'.format(url.url()))
if ' ' in url: if ' ' in urlstring(url):
# An URL will never contain a space # An URL will never contain a space
logging.debug('Contains space -> no url') logging.debug('Contains space -> no url')
return False return False
elif config.config.getboolean('general', 'addressbar_dns_lookup'): elif config.config.getboolean('general', 'addressbar_dns_lookup'):
logging.debug('Checking via DNS') logging.debug('Checking via DNS')
return _is_url_dns(url) return _is_url_dns(QUrl.fromUserInput(urlstring(url)))
else: else:
logging.debug('Checking via naive check') logging.debug('Checking via naive check')
return _is_url_naive(url) return _is_url_naive(url)
def _is_url_naive(url): def _is_url_naive(url):
"""Naive check if given url string is really an url.""" """Naive check if given url (QUrl) is really an url."""
PROTOCOLS = ['http://', 'https://'] PROTOCOLS = ['http://', 'https://']
ip = _get_netloc(url) u = urlstring(url)
if not ip: return (any([u.startswith(proto) for proto in PROTOCOLS]) or '.' in u or
is_ip = False is_about_url(url) or u == 'localhost')
else:
try:
ipaddress.ip_address(ip)
except ValueError:
is_ip = False
else:
is_ip = True
return (any([url.startswith(proto) for proto in PROTOCOLS]) or
'.' in url or is_about_url(url) or url == 'localhost'
or is_ip)
def _is_url_dns(url): def _is_url_dns(url):
"""Check if an url string is really an url via DNS.""" """Check if an url (QUrl) is really an url via DNS."""
# FIXME we could probably solve this in a nicer way by attempting to open # FIXME we could probably solve this in a nicer way by attempting to open
# the page in the webview, and then open the search if that fails. # the page in the webview, and then open the search if that fails.
netloc = _get_netloc(url) host = url.host()
if not netloc: logging.debug("DNS request for {}".format(host))
if not host:
return False return False
try: try:
socket.gethostbyname(netloc) socket.gethostbyname(host)
except socket.gaierror: except socket.gaierror:
return False return False
else: else:
return True return True
def _get_netloc(url):
"""Gets the host part of an url."""
# FIXME better way to do this?
if '://' in url:
return urllib.parse.urlsplit(url).netloc
else:
return urllib.parse.urlsplit('http://' + url).netloc