diff --git a/deluge/common.py b/deluge/common.py index dd0a86e02..c188bbb5e 100644 --- a/deluge/common.py +++ b/deluge/common.py @@ -68,6 +68,7 @@ if not hasattr(json, "dumps"): import pkg_resources import gettext import locale +import sys from deluge.error import * @@ -751,3 +752,39 @@ def setup_translations(setup_pygtk=False): log.exception(e) import __builtin__ __builtin__.__dict__["_"] = lambda x: x + +def unicode_argv(): + """ Gets sys.argv as list of unicode objects on any platform.""" + if windows_check(): + # Versions 2.x of Python don't support Unicode in sys.argv on + # Windows, with the underlying Windows API instead replacing multi-byte + # characters with '?'. + from ctypes import POINTER, byref, cdll, c_int, windll + from ctypes.wintypes import LPCWSTR, LPWSTR + + GetCommandLineW = cdll.kernel32.GetCommandLineW + GetCommandLineW.argtypes = [] + GetCommandLineW.restype = LPCWSTR + + CommandLineToArgvW = windll.shell32.CommandLineToArgvW + CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] + CommandLineToArgvW.restype = POINTER(LPWSTR) + + cmd = GetCommandLineW() + argc = c_int(0) + argv = CommandLineToArgvW(cmd, byref(argc)) + if argc.value > 0: + # Remove Python executable and commands if present + start = argc.value - len(sys.argv) + return [argv[i] for i in + xrange(start, argc.value)] + else: + # On other platforms, we have to find the likely encoding of the args and decode + # First check if sys.stdout or stdin have encoding set + encoding = getattr(sys.stdout, "encoding") or getattr(sys.stdin, "encoding") + # If that fails, check what the locale is set to + encoding = encoding or locale.getpreferredencoding() + # As a last resort, just default to utf-8 + encoding = encoding or "utf-8" + + return [arg.decode(encoding) for arg in sys.argv] diff --git a/deluge/main.py b/deluge/main.py index a966356de..422b661fe 100644 --- a/deluge/main.py +++ b/deluge/main.py @@ -86,7 +86,7 @@ def start_ui(): help="Rotate logfiles.", action="store_true", default=False) # Get the options and args from the OptionParser - (options, args) = parser.parse_args() + (options, args) = parser.parse_args(deluge.common.unicode_argv()[1:]) if options.quiet: options.loglevel = "none" diff --git a/deluge/ui/ui.py b/deluge/ui/ui.py index c10a2c323..46a597a5f 100644 --- a/deluge/ui/ui.py +++ b/deluge/ui/ui.py @@ -64,35 +64,6 @@ if 'dev' not in deluge.common.get_version(): import warnings warnings.filterwarnings('ignore', category=DeprecationWarning, module='twisted') -def win32_unicode_argv(): - """Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode - strings. - - Versions 2.x of Python don't support Unicode in sys.argv on - Windows, with the underlying Windows API instead replacing multi-byte - characters with '?'. - """ - - from ctypes import POINTER, byref, cdll, c_int, windll - from ctypes.wintypes import LPCWSTR, LPWSTR - - GetCommandLineW = cdll.kernel32.GetCommandLineW - GetCommandLineW.argtypes = [] - GetCommandLineW.restype = LPCWSTR - - CommandLineToArgvW = windll.shell32.CommandLineToArgvW - CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] - CommandLineToArgvW.restype = POINTER(LPWSTR) - - cmd = GetCommandLineW() - argc = c_int(0) - argv = CommandLineToArgvW(cmd, byref(argc)) - if argc.value > 0: - # Remove Python executable and commands if present - start = argc.value - len(sys.argv) - return [argv[i] for i in - xrange(start, argc.value)] - class _UI(object): def __init__(self, name="gtk"): @@ -137,10 +108,7 @@ class _UI(object): def start(self): # Make sure all arguments are unicode - if deluge.common.windows_check(): - argv = win32_unicode_argv()[1:] - else: - argv = [arg.decode(sys.stdin.encoding) for arg in sys.argv[1:]] + argv = deluge.common.unicode_argv()[1:] (self.__options, self.__args) = self.__parser.parse_args(argv) if self.__options.quiet: