From dc27d873b3f068f9170bf9b2c70be38e29f53c64 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Thu, 15 Jun 2017 18:22:55 +0100 Subject: [PATCH] Fix metafile.makeinfo trying to decode pieces * The use of unicode_literals causes join to decode pieces if 'b' prefix not used. * Added test. * Fixed session_id keyerror when running with tests. --- deluge/metafile.py | 20 ++++++----- deluge/tests/test_metafile.py | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 deluge/tests/test_metafile.py diff --git a/deluge/metafile.py b/deluge/metafile.py index 7e0da8bd8..2d41955ab 100644 --- a/deluge/metafile.py +++ b/deluge/metafile.py @@ -20,6 +20,7 @@ from hashlib import sha1 as sha import deluge.component as component from deluge.bencode import bencode +from deluge.common import utf8_encode_structure from deluge.event import CreateTorrentProgressEvent log = logging.getLogger(__name__) @@ -69,11 +70,14 @@ def make_meta_file(path, url, piece_length, progress=None, title=None, comment=N f = target if progress is None: - session_id = component.get('RPCServer').get_session_id() - if not session_id: - progress = dummy + progress = dummy + try: + session_id = component.get('RPCServer').get_session_id() + except KeyError: + pass else: - progress = RemoteFileProgress(component.get('RPCServer').get_session_id()) + if session_id: + progress = RemoteFileProgress(session_id) info = makeinfo(path, piece_length, progress, name, content_type, private) @@ -110,7 +114,7 @@ def make_meta_file(path, url, piece_length, progress=None, title=None, comment=N data['encoding'] = 'UTF-8' - h.write(bencode(data)) + h.write(bencode(utf8_encode_structure(data))) h.close() @@ -173,7 +177,7 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private if not name: name = os.path.split(path)[1] - return {'pieces': ''.join(pieces), + return {'pieces': b''.join(pieces), 'piece length': piece_length, 'files': fs, 'name': name.encode('utf8'), @@ -199,12 +203,12 @@ def makeinfo(path, piece_length, progress, name=None, content_type=None, private h.close() name = os.path.split(path)[1].encode('utf8') if content_type is not None: - return {'pieces': ''.join(pieces), + return {'pieces': b''.join(pieces), 'piece length': piece_length, 'length': size, 'name': name, 'content_type': content_type, 'private': private} - return {'pieces': ''.join(pieces), + return {'pieces': b''.join(pieces), 'piece length': piece_length, 'length': size, 'name': name, 'private': private} diff --git a/deluge/tests/test_metafile.py b/deluge/tests/test_metafile.py new file mode 100644 index 000000000..0558a097a --- /dev/null +++ b/deluge/tests/test_metafile.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with +# the additional special exception to link portions of this program with the OpenSSL library. +# See LICENSE for more details. +# + +from __future__ import unicode_literals + +import os +import tempfile + +from twisted.trial import unittest + +from deluge import metafile + + +def check_torrent(filename): + # Test loading with libtorrent to make sure it's valid + from deluge._libtorrent import lt + lt.torrent_info(filename) + + # Test loading with our internal TorrentInfo class + from deluge.ui.common import TorrentInfo + TorrentInfo(filename) + + +class MetafileTestCase(unittest.TestCase): + def test_save_multifile(self): + # Create a temporary folder for torrent creation + tmp_path = tempfile.mkdtemp() + with open(os.path.join(tmp_path, 'file_A'), 'wb') as tmp_file: + tmp_file.write('a' * (312 * 1024)) + with open(os.path.join(tmp_path, 'file_B'), 'wb') as tmp_file: + tmp_file.write('b' * (2354 * 1024)) + with open(os.path.join(tmp_path, 'file_C'), 'wb') as tmp_file: + tmp_file.write('c' * (11 * 1024)) + + tmp_fd, tmp_file = tempfile.mkstemp('.torrent') + metafile.make_meta_file(tmp_path, '', 32768, target=tmp_file) + + check_torrent(tmp_file) + + os.remove(os.path.join(tmp_path, 'file_A')) + os.remove(os.path.join(tmp_path, 'file_B')) + os.remove(os.path.join(tmp_path, 'file_C')) + os.rmdir(tmp_path) + os.close(tmp_fd) + os.remove(tmp_file) + + def test_save_singlefile(self): + tmp_path = tempfile.mkstemp('testdata')[1] + with open(tmp_path, 'wb') as tmp_file: + tmp_file.write('a' * (2314 * 1024)) + + tmp_fd, tmp_file = tempfile.mkstemp('.torrent') + metafile.make_meta_file(tmp_path, '', 32768, target=tmp_file) + + check_torrent(tmp_file) + + os.remove(tmp_path) + os.close(tmp_fd) + os.remove(tmp_file)