[Py2to3] Refactor out usage of unicode and basestring
- Python 3 renames `unicode` type to `str` and introduces `bytes` type. - Python 2.7 has `bytes` but is only an alias for `str` so restricted to comparisons but helps keep compatibility. - To test for unicode string on Py2 and Py3 uses the "''.__class__" type. - Remove usage of utf8encode and just encode, problems with bytes being passed in code will be picked up faster. - Where possible refactor out isinstance for try..except duck-typing.
This commit is contained in:
parent
52a85cb91c
commit
b2db96e4df
|
@ -241,7 +241,7 @@ def show_file(path, timestamp=None):
|
|||
timestamp = int(time.time())
|
||||
startup_id = '%s_%u_%s-dbus_TIME%d' % (os.path.basename(sys.argv[0]), os.getpid(), os.uname()[1], timestamp)
|
||||
if DBUS_FILEMAN:
|
||||
paths = [urlparse.urljoin('file:', urllib.pathname2url(utf8_encoded(path)))]
|
||||
paths = [urlparse.urljoin('file:', urllib.pathname2url(path))]
|
||||
DBUS_FILEMAN.ShowItems(paths, startup_id, dbus_interface='org.freedesktop.FileManager1')
|
||||
else:
|
||||
env = os.environ.copy()
|
||||
|
@ -518,12 +518,16 @@ def parse_human_size(size):
|
|||
if len(tokens) == 1:
|
||||
return int(tokens[0])
|
||||
# Otherwise we expect to find two tokens: A number and a unit.
|
||||
if len(tokens) == 2 and isinstance(tokens[1], basestring):
|
||||
normalized_unit = tokens[1].lower()
|
||||
# Try to match the first letter of the unit.
|
||||
for unit in size_units:
|
||||
if normalized_unit.startswith(unit['prefix'].lower()):
|
||||
return int(tokens[0] * unit['divider'])
|
||||
if len(tokens) == 2:
|
||||
try:
|
||||
normalized_unit = tokens[1].lower()
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
# Try to match the first letter of the unit.
|
||||
for unit in size_units:
|
||||
if normalized_unit.startswith(unit['prefix'].lower()):
|
||||
return int(tokens[0] * unit['divider'])
|
||||
# We failed to parse the size specification.
|
||||
msg = 'Failed to parse size! (input %r was tokenized as %r)'
|
||||
raise InvalidSize(msg % (size, tokens))
|
||||
|
@ -801,7 +805,7 @@ def decode_bytes(byte_str, encoding='utf8'):
|
|||
"""
|
||||
if not byte_str:
|
||||
return ''
|
||||
elif isinstance(byte_str, unicode):
|
||||
elif not isinstance(byte_str, bytes):
|
||||
return byte_str
|
||||
|
||||
encodings = [lambda: ('utf8', 'strict'),
|
||||
|
@ -820,25 +824,6 @@ def decode_bytes(byte_str, encoding='utf8'):
|
|||
return ''
|
||||
|
||||
|
||||
def utf8_encoded(s, encoding='utf8'):
|
||||
"""
|
||||
Returns a utf8 encoded string of s
|
||||
|
||||
:param s: (unicode) string to (re-)encode
|
||||
:type s: basestring
|
||||
:param encoding: the encoding to use in the decoding
|
||||
:type encoding: string
|
||||
:returns: a utf8 encoded string of s
|
||||
:rtype: str
|
||||
|
||||
"""
|
||||
if isinstance(s, str):
|
||||
s = decode_bytes(s, encoding).encode('utf8')
|
||||
elif isinstance(s, unicode):
|
||||
s = s.encode('utf8')
|
||||
return s
|
||||
|
||||
|
||||
def utf8_encode_structure(data):
|
||||
"""Recursively convert all unicode keys and values in a data structure to utf8.
|
||||
|
||||
|
@ -851,14 +836,16 @@ def utf8_encode_structure(data):
|
|||
input type: The data with unicode keys and values converted to utf8.
|
||||
|
||||
"""
|
||||
if isinstance(data, unicode):
|
||||
return data.encode('utf8')
|
||||
elif isinstance(data, (list, tuple)):
|
||||
if isinstance(data, (list, tuple)):
|
||||
return type(data)(map(utf8_encode_structure, data))
|
||||
elif isinstance(data, dict):
|
||||
return dict(map(utf8_encode_structure, data.items()))
|
||||
else:
|
||||
return data
|
||||
elif not isinstance(data, bytes):
|
||||
try:
|
||||
return data.encode('utf8')
|
||||
except AttributeError:
|
||||
pass
|
||||
return data
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
|
@ -993,7 +980,11 @@ def set_env_variable(name, value):
|
|||
http://sourceforge.net/p/gramps/code/HEAD/tree/branches/maintenance/gramps32/src/TransUtils.py
|
||||
'''
|
||||
# Update Python's copy of the environment variables
|
||||
os.environ[name] = value
|
||||
try:
|
||||
os.environ[name] = value
|
||||
except UnicodeEncodeError:
|
||||
# Python 2
|
||||
os.environ[name] = value.encode('utf8')
|
||||
|
||||
if windows_check():
|
||||
from ctypes import windll
|
||||
|
|
|
@ -307,7 +307,7 @@ class ComponentRegistry(object):
|
|||
# Start all the components if names is empty
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif isinstance(names, basestring):
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
names = [names]
|
||||
|
||||
def on_depends_started(result, name):
|
||||
|
@ -341,7 +341,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif isinstance(names, basestring):
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
names = [names]
|
||||
|
||||
def on_dependents_stopped(result, name):
|
||||
|
@ -379,7 +379,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif isinstance(names, basestring):
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
names = [names]
|
||||
|
||||
deferreds = []
|
||||
|
@ -405,7 +405,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif isinstance(names, basestring):
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
names = [names]
|
||||
|
||||
deferreds = []
|
||||
|
|
|
@ -47,7 +47,7 @@ import logging
|
|||
import os
|
||||
import shutil
|
||||
|
||||
from deluge.common import decode_bytes, get_default_config_dir, utf8_encoded
|
||||
from deluge.common import get_default_config_dir
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
callLater = None # Necessary for the config tests
|
||||
|
@ -172,8 +172,10 @@ class Config(object):
|
|||
5
|
||||
|
||||
"""
|
||||
if isinstance(value, basestring):
|
||||
value = utf8_encoded(value)
|
||||
try:
|
||||
value = value.encode('utf8')
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if key not in self.__config:
|
||||
self.__config[key] = value
|
||||
|
@ -188,10 +190,7 @@ class Config(object):
|
|||
self.__config[key], type(None)) and not isinstance(self.__config[key], type(value)):
|
||||
try:
|
||||
oldtype = type(self.__config[key])
|
||||
if isinstance(self.__config[key], unicode):
|
||||
value = oldtype(value, 'utf8')
|
||||
else:
|
||||
value = oldtype(value)
|
||||
value = oldtype(value)
|
||||
except ValueError:
|
||||
log.warning('Value Type "%s" invalid for key: %s', type(value), key)
|
||||
raise
|
||||
|
@ -244,9 +243,9 @@ class Config(object):
|
|||
5
|
||||
|
||||
"""
|
||||
if isinstance(self.__config[key], basestring):
|
||||
return decode_bytes(self.__config[key])
|
||||
else:
|
||||
try:
|
||||
return self.__config[key].decode('utf8')
|
||||
except AttributeError:
|
||||
return self.__config[key]
|
||||
|
||||
def get(self, key, default=None):
|
||||
|
|
|
@ -710,7 +710,7 @@ class Core(component.Component):
|
|||
if 'owner' in options and not self.core.authmanager.has_account(options['owner']):
|
||||
raise DelugeError('Username "%s" is not known.' % options['owner'])
|
||||
|
||||
if isinstance(torrent_ids, basestring):
|
||||
if not isinstance(torrent_ids, (list, tuple)):
|
||||
torrent_ids = [torrent_ids]
|
||||
|
||||
for torrent_id in torrent_ids:
|
||||
|
|
|
@ -133,7 +133,7 @@ class FilterManager(component.Component):
|
|||
|
||||
# Sanitize input: filter-value must be a list of strings
|
||||
for key, value in filter_dict.items():
|
||||
if isinstance(value, basestring):
|
||||
if not isinstance(value, (list, tuple)):
|
||||
filter_dict[key] = [value]
|
||||
|
||||
# Optimized filter for id
|
||||
|
|
|
@ -26,7 +26,7 @@ from twisted.internet.defer import Deferred, DeferredList
|
|||
|
||||
import deluge.component as component
|
||||
from deluge._libtorrent import lt
|
||||
from deluge.common import decode_bytes, utf8_encoded
|
||||
from deluge.common import decode_bytes
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
|
||||
from deluge.decorators import deprecated
|
||||
|
@ -1126,12 +1126,12 @@ class Torrent(object):
|
|||
return False
|
||||
|
||||
try:
|
||||
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
||||
# lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string.
|
||||
# Keyword argument flags=2 (dont_replace) dont overwrite target files but delete source.
|
||||
try:
|
||||
self.handle.move_storage(dest, flags=2)
|
||||
self.handle.move_storage(dest.encode('utf8'), flags=2)
|
||||
except TypeError:
|
||||
self.handle.move_storage(utf8_encoded(dest), flags=2)
|
||||
self.handle.move_storage(dest, flags=2)
|
||||
except RuntimeError as ex:
|
||||
log.error('Error calling libtorrent move_storage: %s', ex)
|
||||
return False
|
||||
|
@ -1252,13 +1252,13 @@ class Torrent(object):
|
|||
filenames (list): A list of (index, filename) pairs.
|
||||
"""
|
||||
for index, filename in filenames:
|
||||
# Make sure filename is a unicode object
|
||||
# Make sure filename is a sanitized unicode string.
|
||||
filename = sanitize_filepath(decode_bytes(filename))
|
||||
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
||||
# lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string.
|
||||
try:
|
||||
self.handle.rename_file(index, filename)
|
||||
self.handle.rename_file(index, filename.encode('utf8'))
|
||||
except TypeError:
|
||||
self.handle.rename_file(index, utf8_encoded(filename))
|
||||
self.handle.rename_file(index, filename)
|
||||
|
||||
def rename_folder(self, folder, new_folder):
|
||||
"""Renames a folder within a torrent.
|
||||
|
@ -1292,9 +1292,9 @@ class Torrent(object):
|
|||
)
|
||||
new_path = _file['path'].replace(folder, new_folder, 1)
|
||||
try:
|
||||
self.handle.rename_file(_file['index'], new_path)
|
||||
self.handle.rename_file(_file['index'], new_path.encode('utf8'))
|
||||
except TypeError:
|
||||
self.handle.rename_file(_file['index'], utf8_encoded(new_path))
|
||||
self.handle.rename_file(_file['index'], new_path)
|
||||
|
||||
def on_folder_rename_complete(dummy_result, torrent, folder, new_folder):
|
||||
"""Folder rename complete"""
|
||||
|
|
|
@ -24,7 +24,7 @@ from twisted.internet.task import LoopingCall
|
|||
|
||||
import deluge.component as component
|
||||
from deluge._libtorrent import lt
|
||||
from deluge.common import decode_bytes, get_magnet_info, utf8_encoded
|
||||
from deluge.common import decode_bytes, get_magnet_info
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
|
||||
from deluge.core.torrent import Torrent, TorrentOptions, sanitize_filepath
|
||||
|
@ -332,10 +332,9 @@ class TorrentManager(component.Component):
|
|||
add_torrent_params['name'] = name
|
||||
torrent_id = str(torrent_info.info_hash())
|
||||
elif magnet:
|
||||
magnet = utf8_encoded(magnet)
|
||||
magnet_info = get_magnet_info(magnet)
|
||||
if magnet_info:
|
||||
add_torrent_params['url'] = magnet
|
||||
add_torrent_params['url'] = magnet.encode('utf8')
|
||||
add_torrent_params['name'] = magnet_info['name']
|
||||
torrent_id = magnet_info['info_hash']
|
||||
else:
|
||||
|
@ -362,9 +361,9 @@ class TorrentManager(component.Component):
|
|||
if log.isEnabledFor(logging.DEBUG):
|
||||
log.debug('renaming file index %s to %s', index, fname)
|
||||
try:
|
||||
torrent_info.rename_file(index, fname)
|
||||
torrent_info.rename_file(index, fname.encode('utf8'))
|
||||
except TypeError:
|
||||
torrent_info.rename_file(index, utf8_encoded(fname))
|
||||
torrent_info.rename_file(index, fname)
|
||||
add_torrent_params['ti'] = torrent_info
|
||||
|
||||
if not options['owner']:
|
||||
|
@ -376,7 +375,7 @@ class TorrentManager(component.Component):
|
|||
log.debug('options: %s', options)
|
||||
|
||||
# Fill in the rest of the add_torrent_params dictionary.
|
||||
add_torrent_params['save_path'] = utf8_encoded(options['download_location'])
|
||||
add_torrent_params['save_path'] = options['download_location'].encode('utf8')
|
||||
if options['name']:
|
||||
add_torrent_params['name'] = options['name']
|
||||
if options['pre_allocate_storage']:
|
||||
|
|
|
@ -15,7 +15,6 @@ from __future__ import division, unicode_literals
|
|||
|
||||
import logging
|
||||
import os.path
|
||||
import sys
|
||||
import time
|
||||
from hashlib import sha1 as sha
|
||||
|
||||
|
@ -40,22 +39,6 @@ def gmtime():
|
|||
return time.mktime(time.gmtime())
|
||||
|
||||
|
||||
def get_filesystem_encoding():
|
||||
return sys.getfilesystemencoding()
|
||||
|
||||
|
||||
def decode_from_filesystem(path):
|
||||
encoding = get_filesystem_encoding()
|
||||
if encoding is None:
|
||||
assert isinstance(path, unicode), 'Path should be unicode not %s' % type(path)
|
||||
decoded_path = path
|
||||
else:
|
||||
assert isinstance(path, str), 'Path should be str not %s' % type(path)
|
||||
decoded_path = path.decode(encoding)
|
||||
|
||||
return decoded_path
|
||||
|
||||
|
||||
def dummy(*v):
|
||||
pass
|
||||
|
||||
|
@ -140,23 +123,6 @@ def calcsize(path):
|
|||
|
||||
def makeinfo(path, piece_length, progress, name=None, content_type=None, private=False):
|
||||
# HEREDAVE. If path is directory, how do we assign content type?
|
||||
def to_utf8(name):
|
||||
if isinstance(name, unicode):
|
||||
u = name
|
||||
else:
|
||||
try:
|
||||
u = decode_from_filesystem(name)
|
||||
except Exception:
|
||||
raise Exception('Could not convert file/directory name %r to '
|
||||
'Unicode. Either the assumed filesystem '
|
||||
'encoding "%s" is wrong or the filename contains '
|
||||
'illegal bytes.' % (name, get_filesystem_encoding()))
|
||||
|
||||
if u.translate(noncharacter_translate) != u:
|
||||
raise Exception('File/directory name "%s" contains reserved '
|
||||
'unicode values that do not correspond to '
|
||||
'characters.' % name)
|
||||
return u.encode('utf-8')
|
||||
path = os.path.abspath(path)
|
||||
piece_count = 0
|
||||
if os.path.isdir(path):
|
||||
|
@ -178,7 +144,7 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
|
|||
for p, f in subs:
|
||||
pos = 0
|
||||
size = os.path.getsize(f)
|
||||
p2 = [to_utf8(n) for n in p]
|
||||
p2 = [n.encode('utf8') for n in p]
|
||||
if content_type:
|
||||
fs.append({'length': size, 'path': p2,
|
||||
'content_type': content_type}) # HEREDAVE. bad for batch!
|
||||
|
@ -204,16 +170,13 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
|
|||
piece_count += 1
|
||||
progress(piece_count, num_pieces)
|
||||
|
||||
if name is not None:
|
||||
assert isinstance(name, unicode)
|
||||
name = to_utf8(name)
|
||||
else:
|
||||
name = to_utf8(os.path.split(path)[1])
|
||||
if not name:
|
||||
name = os.path.split(path)[1]
|
||||
|
||||
return {'pieces': ''.join(pieces),
|
||||
'piece length': piece_length,
|
||||
'files': fs,
|
||||
'name': name,
|
||||
'name': name.encode('utf8'),
|
||||
'private': private}
|
||||
else:
|
||||
size = os.path.getsize(path)
|
||||
|
@ -234,15 +197,16 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private
|
|||
p = size
|
||||
progress(piece_count, num_pieces)
|
||||
h.close()
|
||||
name = os.path.split(path)[1].encode('utf8')
|
||||
if content_type is not None:
|
||||
return {'pieces': ''.join(pieces),
|
||||
'piece length': piece_length, 'length': size,
|
||||
'name': to_utf8(os.path.split(path)[1]),
|
||||
'name': name,
|
||||
'content_type': content_type,
|
||||
'private': private}
|
||||
return {'pieces': ''.join(pieces),
|
||||
'piece length': piece_length, 'length': size,
|
||||
'name': to_utf8(os.path.split(path)[1]),
|
||||
'name': name,
|
||||
'private': private}
|
||||
|
||||
|
||||
|
|
|
@ -394,8 +394,8 @@ class Core(CorePluginBase):
|
|||
def _make_unicode(self, options):
|
||||
opts = {}
|
||||
for key in options:
|
||||
if isinstance(options[key], str):
|
||||
options[key] = unicode(options[key], 'utf8')
|
||||
if isinstance(options[key], bytes):
|
||||
options[key] = options[key].decode('utf8')
|
||||
opts[key] = options[key]
|
||||
return opts
|
||||
|
||||
|
|
|
@ -145,17 +145,17 @@ class IP(object):
|
|||
# return IP(q1, q2, q3, q4)
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, basestring):
|
||||
if isinstance(other, ''.__class__):
|
||||
other = IP.parse(other)
|
||||
return self.long < other.long
|
||||
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, basestring):
|
||||
if isinstance(other, ''.__class__):
|
||||
other = IP.parse(other)
|
||||
return self.long > other.long
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, basestring):
|
||||
if isinstance(other, ''.__class__):
|
||||
other = IP.parse(other)
|
||||
return self.long == other.long
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import time
|
|||
from twisted.internet.utils import getProcessOutputAndValue
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import utf8_encoded, windows_check
|
||||
from deluge.common import windows_check
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.core.rpcserver import export
|
||||
from deluge.event import DelugeEvent
|
||||
|
@ -85,8 +85,7 @@ class Core(CorePluginBase):
|
|||
# Get and store the torrent info before it is removed
|
||||
torrent = component.get('TorrentManager').torrents[torrent_id]
|
||||
info = torrent.get_status(['name', 'download_location'])
|
||||
self.preremoved_cache[torrent_id] = [utf8_encoded(torrent_id), utf8_encoded(info['name']),
|
||||
utf8_encoded(info['download_location'])]
|
||||
self.preremoved_cache[torrent_id] = [torrent_id, info['name'], info['download_location']]
|
||||
|
||||
def execute_commands(self, torrent_id, event, *arg):
|
||||
if event == 'added' and arg[0]:
|
||||
|
@ -99,9 +98,8 @@ class Core(CorePluginBase):
|
|||
info = torrent.get_status(['name', 'download_location'])
|
||||
# Grab the torrent name and download location
|
||||
# getProcessOutputAndValue requires args to be str
|
||||
torrent_id = utf8_encoded(torrent_id)
|
||||
torrent_name = utf8_encoded(info['name'])
|
||||
download_location = utf8_encoded(info['download_location'])
|
||||
torrent_name = info['name']
|
||||
download_location = info['download_location']
|
||||
|
||||
log.debug('Running commands for %s', event)
|
||||
|
||||
|
@ -120,7 +118,8 @@ class Core(CorePluginBase):
|
|||
command = os.path.expandvars(command[EXECUTE_COMMAND])
|
||||
command = os.path.expanduser(command)
|
||||
|
||||
cmd_args = [torrent_id, torrent_name, download_location]
|
||||
cmd_args = [torrent_id.encode('utf8'), torrent_name.encode('utf8'),
|
||||
download_location.encode('utf8')]
|
||||
if windows_check():
|
||||
# Escape ampersand on windows (see #2784)
|
||||
cmd_args = [cmd_arg.replace('&', '^^^&') for cmd_arg in cmd_args]
|
||||
|
|
|
@ -151,7 +151,7 @@ class GtkUiNotifications(CustomNotifications):
|
|||
'handler was: %s' % result)
|
||||
|
||||
def handle_custom_sound_notification(self, result, eventtype):
|
||||
if isinstance(result, basestring):
|
||||
if isinstance(result, ''.__class__):
|
||||
if not result and eventtype in self.config['custom_sounds']:
|
||||
return defer.maybeDeferred(
|
||||
self.__play_sound, self.config['custom_sounds'][eventtype])
|
||||
|
|
|
@ -47,7 +47,7 @@ class ConfigTestCase(unittest.TestCase):
|
|||
self.assertEquals(config['unicode'], 'ВИДЕОФИЛЬМЫ')
|
||||
|
||||
config['unicode'] = b'foostring'
|
||||
self.assertTrue(isinstance(config.get_item('unicode'), unicode))
|
||||
self.assertFalse(isinstance(config.get_item('unicode'), bytes))
|
||||
|
||||
config._save_timer.cancel()
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ class PluginManagerBaseTestCase(BaseTestCase):
|
|||
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
||||
for p in pm.get_available_plugins():
|
||||
for key, value in pm.get_plugin_info(p).items():
|
||||
self.assertTrue(isinstance('%s: %s' % (key, value), basestring))
|
||||
self.assertTrue(isinstance('%s: %s' % (key, value), ''.__class__))
|
||||
|
||||
def test_get_plugin_info_invalid_name(self):
|
||||
pm = PluginManagerBase('core.conf', 'deluge.plugin.core')
|
||||
|
|
|
@ -212,9 +212,6 @@ class Command(BaseCommand):
|
|||
def tlen(string):
|
||||
return strwidth(format_utils.remove_formatting(string))
|
||||
|
||||
if not isinstance(col_filename, unicode):
|
||||
col_filename = unicode(col_filename, 'utf-8')
|
||||
|
||||
col_all_info = col_size + col_progress + col_priority
|
||||
# Check how much space we've got left after writing all the info
|
||||
space_left = cols - tlen(col_all_info)
|
||||
|
|
|
@ -371,8 +371,7 @@ Please use commands from the command line, e.g.:\n
|
|||
no matches are found.
|
||||
|
||||
"""
|
||||
if not isinstance(string, unicode):
|
||||
string = unicode(string, self.encoding)
|
||||
deluge.common.decode_bytes(string, self.encoding)
|
||||
|
||||
if string == '*' or string == '':
|
||||
return [tid for tid, name in self.torrents]
|
||||
|
@ -387,8 +386,7 @@ Please use commands from the command line, e.g.:\n
|
|||
|
||||
matches = []
|
||||
for tid, name in self.torrents:
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name, self.encoding)
|
||||
deluge.common.decode_bytes(name, self.encoding)
|
||||
if getattr(tid, match_func, None)(string) or getattr(name, match_func, None)(string):
|
||||
matches.append(tid)
|
||||
return matches
|
||||
|
@ -423,7 +421,7 @@ Please use commands from the command line, e.g.:\n
|
|||
component.get('CmdLine').add_line(s, False)
|
||||
self.events.append(s)
|
||||
else:
|
||||
print(colors.strip_colors(deluge.common.utf8_encoded(s)))
|
||||
print(colors.strip_colors(s.encode('utf8')))
|
||||
|
||||
def write_event(self, s):
|
||||
if self.interactive:
|
||||
|
@ -434,7 +432,7 @@ Please use commands from the command line, e.g.:\n
|
|||
component.get('CmdLine').add_line(s, False)
|
||||
self.events.append(s)
|
||||
else:
|
||||
print(colors.strip_colors(deluge.common.utf8_encoded(s)))
|
||||
print(colors.strip_colors(s.encode('utf8')))
|
||||
|
||||
def _migrate_config_1_to_2(self, config):
|
||||
"""Create better structure by moving most settings out of dict root
|
||||
|
|
|
@ -417,10 +417,7 @@ class CmdLine(BaseMode, Commander):
|
|||
|
||||
# Write the line
|
||||
with open(self.history_file[active_file], 'a', encoding='utf8') as _file:
|
||||
if isinstance(text, unicode):
|
||||
text = text.encode(self.encoding)
|
||||
_file.write(text)
|
||||
_file.write(os.linesep)
|
||||
_file.write(text + '\n')
|
||||
|
||||
# And increment line counter
|
||||
self._hf_lines[active_file] += 1
|
||||
|
|
|
@ -131,17 +131,14 @@ def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
|
|||
for field in torrent_options:
|
||||
caption = '{!info!}' + TORRENT_DATA_FIELD[field]['name']
|
||||
value = options[field]
|
||||
field_type = type(value)
|
||||
if field_type in [str, unicode]:
|
||||
if not isinstance(value, basestring):
|
||||
value = str(value)
|
||||
if isinstance(value, ''.__class__):
|
||||
option_popup.add_text_input(field, caption, value)
|
||||
elif field_type == bool:
|
||||
choices = (['Yes', 'No'], [True, False], [True, False].index(options[field]))
|
||||
elif isinstance(value, bool):
|
||||
choices = (['Yes', 'No'], [True, False], [True, False].index(value))
|
||||
option_popup.add_select_input(field, caption, choices[0], choices[1], choices[2])
|
||||
elif field_type == float:
|
||||
elif isinstance(value, float):
|
||||
option_popup.add_float_spin_input(field, caption, value=value, min_val=-1)
|
||||
elif field_type == int:
|
||||
elif isinstance(value, int):
|
||||
option_popup.add_int_spin_input(field, caption, value=value, min_val=-1)
|
||||
|
||||
mode.push_popup(option_popup)
|
||||
|
|
|
@ -237,18 +237,15 @@ class TorrentView(InputKeyHandler):
|
|||
# and if it's a string
|
||||
first_element = state[state.keys()[0]]
|
||||
if field in first_element:
|
||||
is_string = isinstance(first_element[field], basestring)
|
||||
|
||||
def sort_key(s):
|
||||
return state.get(s)[field]
|
||||
try:
|
||||
# Sort case-insensitively but preserve A>a order.
|
||||
return state.get(s)[field].lower()
|
||||
except AttributeError:
|
||||
# Not a string.
|
||||
return state.get(s)[field]
|
||||
|
||||
def sort_key2(s):
|
||||
return state.get(s)[field].lower()
|
||||
|
||||
# If it's a string, sort case-insensitively but preserve A>a order
|
||||
to_sort = sorted(to_sort, _queue_sort, sort_key, reverse)
|
||||
if is_string:
|
||||
to_sort = sorted(to_sort, _queue_sort, sort_key2, reverse)
|
||||
|
||||
if field == 'eta':
|
||||
to_sort = sorted(to_sort, key=lambda s: state.get(s)['eta'] == 0)
|
||||
|
|
|
@ -131,7 +131,7 @@ def strip_colors(line):
|
|||
return line
|
||||
|
||||
|
||||
def get_line_length(line, encoding='UTF-8'):
|
||||
def get_line_length(line):
|
||||
"""
|
||||
Returns the string length without the color formatting.
|
||||
|
||||
|
@ -139,9 +139,6 @@ def get_line_length(line, encoding='UTF-8'):
|
|||
if line.count('{!') != line.count('!}'):
|
||||
raise BadColorString('Number of {! is not equal to number of !}')
|
||||
|
||||
if isinstance(line, unicode):
|
||||
line = line.encode(encoding, 'replace')
|
||||
|
||||
# Remove all the color tags
|
||||
line = strip_colors(line)
|
||||
|
||||
|
@ -150,7 +147,7 @@ def get_line_length(line, encoding='UTF-8'):
|
|||
return len(line)
|
||||
|
||||
|
||||
def get_line_width(line, encoding='UTF-8'):
|
||||
def get_line_width(line):
|
||||
"""
|
||||
Get width of string considering double width characters
|
||||
|
||||
|
@ -158,9 +155,6 @@ def get_line_width(line, encoding='UTF-8'):
|
|||
if line.count('{!') != line.count('!}'):
|
||||
raise BadColorString('Number of {! is not equal to number of !}')
|
||||
|
||||
if isinstance(line, unicode):
|
||||
line = line.encode(encoding, 'replace')
|
||||
|
||||
# Remove all the color tags
|
||||
line = strip_colors(line)
|
||||
|
||||
|
@ -180,9 +174,6 @@ def parse_color_string(s, encoding='UTF-8'):
|
|||
if s.count('{!') != s.count('!}'):
|
||||
raise BadColorString('Number of {! is not equal to number of !}')
|
||||
|
||||
if isinstance(s, unicode):
|
||||
s = s.encode(encoding, 'replace')
|
||||
|
||||
ret = []
|
||||
last_color_attr = None
|
||||
# Keep track of where the strings
|
||||
|
|
|
@ -11,8 +11,7 @@ from __future__ import unicode_literals
|
|||
|
||||
import re
|
||||
from collections import deque
|
||||
from unicodedata import normalize as ud_normalize
|
||||
from unicodedata import east_asian_width
|
||||
from unicodedata import east_asian_width, normalize
|
||||
|
||||
import deluge.common
|
||||
from deluge.ui.common import FILE_PRIORITY
|
||||
|
@ -88,7 +87,7 @@ def trim_string(string, w, have_dbls):
|
|||
idx = 0
|
||||
while width < w:
|
||||
chrs.append(string[idx])
|
||||
if east_asian_width(string[idx]) in ['W', 'F']:
|
||||
if east_asian_width(string[idx]) in 'WF':
|
||||
width += 2
|
||||
else:
|
||||
width += 1
|
||||
|
@ -102,14 +101,13 @@ def trim_string(string, w, have_dbls):
|
|||
|
||||
|
||||
def format_column(col, lim):
|
||||
dbls = 0
|
||||
# Chosen over isinstance(col, unicode) and col.__class__ == unicode
|
||||
# for speed - it's ~3 times faster for non-unicode strings and ~1.5
|
||||
# for unicode strings.
|
||||
if col.__class__ is unicode:
|
||||
try:
|
||||
# might have some double width chars
|
||||
col = ud_normalize('NFC', col)
|
||||
col = normalize('NFC', col)
|
||||
dbls = sum(east_asian_width(c) in 'WF' for c in col)
|
||||
except TypeError:
|
||||
dbls = 0
|
||||
|
||||
size = len(col) + dbls
|
||||
if size >= lim - 1:
|
||||
return trim_string(col, lim, dbls > 0)
|
||||
|
@ -239,8 +237,6 @@ def strwidth(string):
|
|||
"""
|
||||
Measure width of a string considering asian double width characters
|
||||
"""
|
||||
if not isinstance(string, unicode):
|
||||
string = unicode(string, 'utf-8')
|
||||
return sum([1 + (east_asian_width(char) in ['W', 'F']) for char in string])
|
||||
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ class BaseInputPane(InputKeyHandler):
|
|||
|
||||
if ipt.default_col != -1:
|
||||
default_col = int(ipt.default_col)
|
||||
if isinstance(ipt.default_col, basestring) and ipt.default_col[0] in ['+', '-']:
|
||||
if isinstance(ipt.default_col, ''.__class__) and ipt.default_col[0] in ['+', '-']:
|
||||
col += default_col
|
||||
cursor_offset += default_col
|
||||
field_width -= default_col # Increase to col must be reflected here
|
||||
|
|
|
@ -15,6 +15,7 @@ import gtk
|
|||
from gobject import SIGNAL_RUN_LAST, TYPE_NONE, signal_new
|
||||
from gtk.gdk import Event # pylint: disable=ungrouped-imports
|
||||
|
||||
from deluge.common import decode_bytes
|
||||
from deluge.ui.gtkui.common import load_pickled_state_file, save_pickled_state_file
|
||||
|
||||
signal_new('button-press-event', gtk.TreeViewColumn, SIGNAL_RUN_LAST, TYPE_NONE, (Event,))
|
||||
|
@ -320,7 +321,7 @@ class ListView(object):
|
|||
try:
|
||||
self.columns[name].column.set_visible(widget.get_active())
|
||||
except KeyError:
|
||||
self.columns[unicode(name)].column.set_visible(widget.get_active())
|
||||
self.columns[decode_bytes(name)].column.set_visible(widget.get_active())
|
||||
return
|
||||
|
||||
def on_treeview_header_right_clicked(self, column, event):
|
||||
|
|
|
@ -401,20 +401,20 @@ class Preferences(component.Component):
|
|||
# Update the widgets accordingly
|
||||
for key in core_widgets:
|
||||
modifier = core_widgets[key][0]
|
||||
if isinstance(key, basestring):
|
||||
try:
|
||||
widget = self.builder.get_object(key)
|
||||
else:
|
||||
except TypeError:
|
||||
widget = key
|
||||
|
||||
widget.set_sensitive(self.is_connected)
|
||||
|
||||
if self.is_connected:
|
||||
value = core_widgets[key][1]
|
||||
from types import FunctionType
|
||||
if isinstance(value, FunctionType):
|
||||
value = value()
|
||||
elif isinstance(value, basestring):
|
||||
try:
|
||||
value = self.core_config[value]
|
||||
except KeyError:
|
||||
if callable(value):
|
||||
value = value()
|
||||
elif modifier:
|
||||
value = {'active': False, 'not_active': False, 'value': 0, 'text': '', 'path_chooser': ''}[modifier]
|
||||
|
||||
|
@ -433,9 +433,9 @@ class Preferences(component.Component):
|
|||
|
||||
if self.is_connected:
|
||||
for key in core_widgets:
|
||||
if isinstance(key, basestring):
|
||||
try:
|
||||
widget = self.builder.get_object(key)
|
||||
else:
|
||||
except TypeError:
|
||||
widget = key
|
||||
# Update the toggle status if necessary
|
||||
self.on_toggle(widget)
|
||||
|
|
|
@ -70,7 +70,6 @@ def set_language(lang):
|
|||
:param lang: the language, e.g. "en", "de" or "en_GB"
|
||||
:type lang: str
|
||||
"""
|
||||
lang = str(lang)
|
||||
# Necessary to set these environment variables for GtkBuilder
|
||||
deluge.common.set_env_variable('LANGUAGE', lang) # Windows/Linux
|
||||
deluge.common.set_env_variable('LANG', lang) # For OSX
|
||||
|
|
|
@ -18,8 +18,6 @@ from email.utils import formatdate
|
|||
|
||||
from twisted.internet.task import LoopingCall
|
||||
|
||||
from deluge.common import utf8_encoded
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -143,7 +141,7 @@ class Auth(JSONComponent):
|
|||
log.debug('Received a password via the 1.2-dev auth method')
|
||||
m = hashlib.md5()
|
||||
m.update(config['pwd_salt'])
|
||||
m.update(utf8_encoded(password))
|
||||
m.update(password.encode('utf8'))
|
||||
if m.hexdigest() == config['pwd_md5']:
|
||||
# We want to move the password over to sha1 and remove
|
||||
# the old passwords from the config file.
|
||||
|
@ -163,7 +161,7 @@ class Auth(JSONComponent):
|
|||
from base64 import decodestring
|
||||
m = hashlib.md5()
|
||||
m.update(decodestring(config['old_pwd_salt']))
|
||||
m.update(utf8_encoded(password))
|
||||
m.update(password.encode('utf8'))
|
||||
if m.digest() == decodestring(config['old_pwd_md5']):
|
||||
|
||||
# We want to move the password over to sha1 and remove
|
||||
|
@ -179,7 +177,7 @@ class Auth(JSONComponent):
|
|||
log.debug('Received a password via the 1.2 auth method')
|
||||
s = hashlib.sha1()
|
||||
s.update(config['pwd_salt'])
|
||||
s.update(utf8_encoded(password))
|
||||
s.update(password.encode('utf8'))
|
||||
if s.hexdigest() == config['pwd_sha1']:
|
||||
return True
|
||||
|
||||
|
@ -249,7 +247,7 @@ class Auth(JSONComponent):
|
|||
log.debug('Changing password')
|
||||
salt = hashlib.sha1(os.urandom(32)).hexdigest()
|
||||
s = hashlib.sha1(salt)
|
||||
s.update(utf8_encoded(new_password))
|
||||
s.update(new_password.encode('utf8'))
|
||||
self.config['pwd_salt'] = salt
|
||||
self.config['pwd_sha1'] = s.hexdigest()
|
||||
return True
|
||||
|
|
|
@ -897,8 +897,6 @@ class WebApi(JSONComponent):
|
|||
if key in ['sessions', 'pwd_salt', 'pwd_sha1']:
|
||||
log.warn('Ignored attempt to overwrite web config key: %s', key)
|
||||
continue
|
||||
if isinstance(config[key], basestring):
|
||||
config[key] = config[key].encode('utf8')
|
||||
web_config[key] = config[key]
|
||||
|
||||
@export
|
||||
|
|
Loading…
Reference in New Issue