[Core] Fixup maketorrent for unicode_literals

* Added a new convert_to_utf8 function to common that is handy for
   any nested dictionaries etc.
 * Small refactor to get rid of duplicate code and comment will be
   encoded by convert_to_utf8 function.
 * Passes test_maketorrent.
This commit is contained in:
Calum Lind 2017-02-12 11:26:31 +00:00
commit 1d9733014a
3 changed files with 37 additions and 19 deletions

View file

@ -839,6 +839,29 @@ def utf8_encoded(s, encoding='utf8'):
return s return s
def convert_to_utf8(data):
"""Recursively convert all unicode keys and values in a data structure to utf8.
e.g. converting keys and values for a dict with nested dicts and lists etc.
Args:
data (any): This can be any structure, dict, list or tuple.
Returns:
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)):
return type(data)(map(convert_to_utf8, data))
elif isinstance(data, dict):
return dict(map(convert_to_utf8, data.items()))
else:
return data
@functools.total_ordering @functools.total_ordering
class VersionSplit(object): class VersionSplit(object):
""" """

View file

@ -19,7 +19,7 @@ from twisted.python.failure import Failure
from twisted.web import client, http from twisted.web import client, http
from twisted.web.error import PageRedirect from twisted.web.error import PageRedirect
from deluge.common import get_version from deluge.common import convert_to_utf8, get_version
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -175,8 +175,8 @@ def _download_file(url, filename, callback=None, headers=None, force_filename=Fa
url = url.encode('utf8') url = url.encode('utf8')
filename = filename.encode('utf8') filename = filename.encode('utf8')
if headers: headers = convert_to_utf8(headers) if headers else headers
headers = {k.encode('utf8'): v.encode('utf8') for k, v in headers.items()} factory = HTTPDownloader(url, filename, callback, headers, force_filename, allow_compression)
# In Twisted 13.1.0 _parse() function replaced by _URI class. # In Twisted 13.1.0 _parse() function replaced by _URI class.
# In Twisted 15.0.0 _URI class renamed to URI. # In Twisted 15.0.0 _URI class renamed to URI.
@ -187,13 +187,12 @@ def _download_file(url, filename, callback=None, headers=None, force_filename=Fa
from twisted.web.client import _URI as URI from twisted.web.client import _URI as URI
except ImportError: except ImportError:
from twisted.web.client import URI from twisted.web.client import URI
finally:
uri = URI.fromBytes(url)
scheme = uri.scheme
host = uri.host
port = uri.port
uri = URI.fromBytes(url)
scheme = uri.scheme
host = uri.host
port = uri.port
factory = HTTPDownloader(url, filename, callback, headers, force_filename, allow_compression)
if scheme == 'https': if scheme == 'https':
from twisted.internet import ssl from twisted.internet import ssl
# ClientTLSOptions in Twisted >= 14, see ticket #2765 for details on this addition. # ClientTLSOptions in Twisted >= 14, see ticket #2765 for details on this addition.

View file

@ -14,7 +14,7 @@ import sys
from hashlib import sha1 as sha from hashlib import sha1 as sha
from deluge.bencode import bencode from deluge.bencode import bencode
from deluge.common import get_path_size from deluge.common import convert_to_utf8, get_path_size
class InvalidPath(Exception): class InvalidPath(Exception):
@ -72,7 +72,7 @@ class TorrentMetadata(object):
} }
if self.comment: if self.comment:
torrent['comment'] = self.comment.encode('UTF-8') torrent['comment'] = self.comment
if self.private: if self.private:
torrent['info']['private'] = True torrent['info']['private'] = True
@ -113,10 +113,10 @@ class TorrentMetadata(object):
num_pieces += 1 num_pieces += 1
torrent['info']['piece length'] = piece_size torrent['info']['piece length'] = piece_size
torrent['info']['name'] = os.path.split(self.data_path)[1]
# Create the info # Create the info
if os.path.isdir(self.data_path): if os.path.isdir(self.data_path):
torrent['info']['name'] = os.path.split(self.data_path)[1]
files = [] files = []
padding_count = 0 padding_count = 0
# Collect a list of file paths and add padding files if necessary # Collect a list of file paths and add padding files if necessary
@ -170,18 +170,14 @@ class TorrentMetadata(object):
else: else:
break break
r = _file.read(piece_size - len(buf)) r = _file.read(piece_size - len(buf))
torrent['info']['files'] = fs
if buf: if buf:
pieces.append(sha(buf).digest()) pieces.append(sha(buf).digest())
if progress: if progress:
progress(len(pieces), num_pieces) progress(len(pieces), num_pieces)
buf = '' buf = ''
torrent['info']['pieces'] = ''.join(pieces)
torrent['info']['files'] = fs
elif os.path.isfile(self.data_path): elif os.path.isfile(self.data_path):
torrent['info']['name'] = os.path.split(self.data_path)[1]
torrent['info']['length'] = get_path_size(self.data_path) torrent['info']['length'] = get_path_size(self.data_path)
pieces = [] pieces = []
@ -194,11 +190,11 @@ class TorrentMetadata(object):
r = _file.read(piece_size) r = _file.read(piece_size)
torrent['info']['pieces'] = ''.join(pieces) torrent['info']['pieces'] = b''.join(pieces)
# Write out the torrent file # Write out the torrent file
with open(torrent_path, 'wb') as _file: with open(torrent_path, 'wb') as _file:
_file.write(bencode(torrent)) _file.write(bencode(convert_to_utf8(torrent)))
def get_data_path(self): def get_data_path(self):
"""Get the path to the files that the torrent will contain. """Get the path to the files that the torrent will contain.