Merge branch 'master' of ssh://lupin/qutebrowser

This commit is contained in:
Florian Bruhin 2014-06-10 12:02:17 +02:00
commit 2bcbfce8f9
4 changed files with 130 additions and 70 deletions

View File

@ -54,7 +54,8 @@ from qutebrowser.config.iniparsers import ReadWriteConfigParser
from qutebrowser.config.lineparser import LineConfigParser
from qutebrowser.browser.cookies import CookieJar
from qutebrowser.utils.message import MessageBridge
from qutebrowser.utils.misc import get_standard_dir, actute_warning
from qutebrowser.utils.misc import (get_standard_dir, actute_warning,
get_qt_args)
from qutebrowser.utils.readline import ReadlineBridge
from qutebrowser.utils.debug import set_trace # pylint: disable=unused-import
@ -94,7 +95,9 @@ class Application(QApplication):
Args:
Argument namespace from argparse.
"""
super().__init__(self._get_qt_args(args))
qt_args = get_qt_args(args)
log.init.debug("Qt arguments: {}, based on {}".format(qt_args, args))
super().__init__(get_qt_args(args))
self._quit_status = {
'crash': True,
'tabs': False,
@ -146,31 +149,6 @@ class Application(QApplication):
if self._crashdlg is not None:
self._crashdlg.raise_()
def _get_qt_args(self, namespace):
"""Get the Qt QApplication arguments based on an argparse namespace.
Args:
namespace: The argparse namespace.
Return:
The argv list to be passed to Qt.
"""
argv = [sys.argv[0]]
qt_args = ('style', 'stylesheet', 'widget-count', 'reverse',
'qmljsdebugger')
for argname in qt_args:
val = getattr(namespace, 'qt_' + argname, None)
if val is None:
# flag/argument not given
continue
elif val is True:
argv.append('-' + argname)
else:
argv.append('-' + argname)
argv.append(val)
log.init.debug("Qt arguments: {}, based on {}".format(argv, namespace))
return argv
def _init_config(self):
"""Inizialize and read the config."""
if self._args.confdir is None:

View File

@ -22,6 +22,7 @@
import os
import sys
import shutil
import argparse
import unittest
import os.path
import subprocess
@ -379,5 +380,61 @@ class GetStandardDirWindowsTests(TestCase):
self.app.quit()
class GetQtArgsTests(TestCase):
"""Tests for get_qt_args."""
def setUp(self):
self.parser = argparse.ArgumentParser()
def _namespace(self, cmdline, flags=None, args=None):
"""Get an argparse namespace object based on arguments given.
Args:
cmdline: The given commandline.
flags: A list of strings (argument names) for flags without an
argument.
args: A list of arguemnt names for flags with an argument.
"""
if flags is not None:
for e in flags:
self.parser.add_argument(e, action='store_true')
if args is not None:
for e in args:
self.parser.add_argument(e, nargs=1)
return self.parser.parse_args(cmdline)
def test_no_qt_args(self):
"""Test commandline with no Qt arguments given."""
ns = self._namespace(['--foo'], flags=['--foo'])
self.assertEqual(utils.get_qt_args(ns), [sys.argv[0]])
def test_qt_flag(self):
"""Test commandline with a Qt flag."""
ns = self._namespace(['--foo', '--qt-reverse', '--bar'],
flags=['--foo', '--qt-reverse', '--bar'])
self.assertEqual(utils.get_qt_args(ns), [sys.argv[0], '-reverse'])
def test_qt_arg(self):
"""Test commandline with a Qt argument."""
ns = self._namespace(['--qt-stylesheet', 'foobar'],
args=['--qt-stylesheet'])
self.assertEqual(utils.get_qt_args(ns), [sys.argv[0], '-stylesheet',
'foobar'])
def test_qt_both(self):
"""Test commandline with a Qt argument and flag."""
ns = self._namespace(['--qt-stylesheet', 'foobar', '--qt-reverse'],
flags=['--qt-reverse'], args=['--qt-stylesheet'])
self.assertEqual(utils.get_qt_args(ns), [sys.argv[0],
'-stylesheet', 'foobar',
'-reverse'])
def test_qt_unknown(self):
"""Test commandline with unknown Qt argument."""
ns = self._namespace(['--qt-foo'], flags=['--qt-foo'])
self.assertEqual(utils.get_qt_args(ns), [sys.argv[0]])
if __name__ == '__main__':
unittest.main()

View File

@ -260,3 +260,28 @@ def actute_warning():
"https://bugs.freedesktop.org/show_bug.cgi?id=69476 for "
"details.")
break
def get_qt_args(namespace):
"""Get the Qt QApplication arguments based on an argparse namespace.
Args:
namespace: The argparse namespace.
Return:
The argv list to be passed to Qt.
"""
argv = [sys.argv[0]]
qt_args = ('style', 'stylesheet', 'widget-count', 'reverse',
'qmljsdebugger')
for argname in qt_args:
val = getattr(namespace, 'qt_' + argname, None)
if val is None:
# flag/argument not given
continue
elif val is True:
argv.append('-' + argname)
else:
argv.append('-' + argname)
argv.append(val[0])
return argv

View File

@ -26,12 +26,17 @@ import contextlib
from distutils import log
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
try:
from site import USER_SITE
except ImportError:
USER_SITE = None
DEFAULT_VERSION = "3.4.4"
DEFAULT_VERSION = "4.0.1"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
@ -64,17 +69,24 @@ def _build_egg(egg, archive_filename, to_dir):
raise IOError('Could not build the egg.')
def get_zip_class():
class ContextualZipFile(zipfile.ZipFile):
"""
Supplement ZipFile class to support context manager for Python 2.6
"""
class ContextualZipFile(zipfile.ZipFile):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close
return zipfile.ZipFile if hasattr(zipfile.ZipFile, '__exit__') else \
ContextualZipFile
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
def __new__(cls, *args, **kwargs):
"""
Construct a ZipFile or ContextualZipFile as appropriate
"""
if hasattr(zipfile.ZipFile, '__exit__'):
return zipfile.ZipFile(*args, **kwargs)
return super(ContextualZipFile, cls).__new__(cls)
@contextlib.contextmanager
@ -85,7 +97,7 @@ def archive_context(filename):
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
with get_zip_class()(filename) as archive:
with ContextualZipFile(filename) as archive:
archive.extractall()
# going in the directory
@ -166,10 +178,16 @@ def download_file_powershell(url, target):
trust). Raise an exception if the command cannot complete.
"""
target = os.path.abspath(target)
ps_cmd = (
"[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
"[System.Net.CredentialCache]::DefaultCredentials; "
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)"
% vars()
)
cmd = [
'powershell',
'-Command',
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(),
ps_cmd,
]
_clean_check(cmd, target)
@ -177,14 +195,11 @@ def has_powershell():
if platform.system() != 'Windows':
return False
cmd = ['powershell', '-Command', 'echo test']
devnull = open(os.path.devnull, 'wb')
try:
with open(os.path.devnull, 'wb') as devnull:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except Exception:
return False
finally:
devnull.close()
return True
download_file_powershell.viable = has_powershell
@ -195,14 +210,11 @@ def download_file_curl(url, target):
def has_curl():
cmd = ['curl', '--version']
devnull = open(os.path.devnull, 'wb')
try:
with open(os.path.devnull, 'wb') as devnull:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except Exception:
return False
finally:
devnull.close()
return True
download_file_curl.viable = has_curl
@ -213,14 +225,11 @@ def download_file_wget(url, target):
def has_wget():
cmd = ['wget', '--version']
devnull = open(os.path.devnull, 'wb')
try:
with open(os.path.devnull, 'wb') as devnull:
try:
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
except Exception:
return False
finally:
devnull.close()
return True
download_file_wget.viable = has_wget
@ -230,37 +239,28 @@ def download_file_insecure(url, target):
Use Python to download the file, even though it cannot authenticate the
connection.
"""
src = urlopen(url)
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
src = dst = None
try:
src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
# Read all the data in one block.
data = src.read()
dst = open(target, "wb")
dst.write(data)
finally:
if src:
src.close()
if dst:
dst.close()
src.close()
# Write all the data in one block to avoid creating a partial file.
with open(target, "wb") as dst:
dst.write(data)
download_file_insecure.viable = lambda: True
def get_best_downloader():
downloaders = [
downloaders = (
download_file_powershell,
download_file_curl,
download_file_wget,
download_file_insecure,
]
for dl in downloaders:
if dl.viable():
return dl
)
viable_downloaders = (dl for dl in downloaders if dl.viable())
return next(viable_downloaders, None)
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader):