diff options
author | Calum Lind <calumlind+deluge@gmail.com> | 2019-05-20 15:31:26 +0100 |
---|---|---|
committer | Calum Lind <calumlind+deluge@gmail.com> | 2019-05-20 16:49:25 +0100 |
commit | c6b6902e9f3e37f5b15184eb509b48b43817a331 (patch) | |
tree | 6494447c1daab80e2b3eeb8291b7b4019234cf92 /deluge/ui/common.py | |
parent | 6a5bb44d5b20c1404237bab5d5051a7ff8a26a65 (diff) | |
download | deluge-c6b6902e9f3e37f5b15184eb509b48b43817a331.tar.gz deluge-c6b6902e9f3e37f5b15184eb509b48b43817a331.tar.bz2 deluge-c6b6902e9f3e37f5b15184eb509b48b43817a331.zip |
[Core] Fix prefetch magnets missing trackers
When adding magnets that have been prefetched the tracker details were
lost. A result of returning only the lt.torrent_info.metadata which
does not contain full torrent details, such as trackers.
- Modified torrentmanager prefetch_metadata to return dict instead of
base64 encoded bencoded metadata dict...
- Used a namedtuple to ease identifying tuple contents.
- Updated tests to reflect changes with mock trackers added to
test_torrent.file.torrent.
- Refactor TorrentInfo to accept dict instead of bytes and add
a class method to accept metadata dict with lists of trackers.
- Rename class arg from metainfo to torrent_file, matching
lt.torrent_info.
- Rename metadata property to correct name; metainfo.
- Simplify class variable naming with _filedata and _metainfo for
torrent file contents encoded and decoded respectively.
- Update GTK Add torrent dialog to pass trackers to TorrentInfo.
Diffstat (limited to 'deluge/ui/common.py')
-rw-r--r-- | deluge/ui/common.py | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/deluge/ui/common.py b/deluge/ui/common.py index 38c27d8cf..21bcafd5f 100644 --- a/deluge/ui/common.py +++ b/deluge/ui/common.py @@ -173,38 +173,36 @@ class TorrentInfo(object): """Collects information about a torrent file. Args: - filename (str): The path to the .torrent file. + filename (str, optional): The path to the .torrent file. filetree (int, optional): The version of filetree to create (defaults to 1). - metainfo (bytes, optional): A bencoded filedump from a .torrent file. - metadata (bytes, optional): A bencoded metadata info_dict. + torrent_file (dict, optional): A bdecoded .torrent file contents. """ - def __init__(self, filename='', filetree=1, metainfo=None, metadata=None): - # Get the torrent metainfo from the torrent file - if metadata: - self._metainfo_dict = {b'info': bencode.bdecode(metadata)} - - self._metainfo = bencode.bencode(self._metainfo_dict) - else: - self._metainfo = metainfo - if filename and not self._metainfo: - log.debug('Attempting to open %s.', filename) - try: - with open(filename, 'rb') as _file: - self._metainfo = _file.read() - except IOError as ex: - log.warning('Unable to open %s: %s', filename, ex) - return + def __init__(self, filename='', filetree=1, torrent_file=None): + self._filedata = None + if torrent_file: + self._metainfo = torrent_file + elif filename: + log.debug('Attempting to open %s.', filename) + try: + with open(filename, 'rb') as _file: + self._filedata = _file.read() + except IOError as ex: + log.warning('Unable to open %s: %s', filename, ex) + return try: - self._metainfo_dict = bencode.bdecode(self._metainfo) + self._metainfo = bencode.bdecode(self._filedata) except bencode.BTFailure as ex: log.warning('Failed to decode %s: %s', filename, ex) return + else: + log.warning('Requires valid arguments.') + return - # info_dict with keys decoded. - info_dict = {k.decode(): v for k, v in self._metainfo_dict[b'info'].items()} + # info_dict with keys decoded to unicode. + info_dict = {k.decode(): v for k, v in self._metainfo[b'info'].items()} self._info_hash = sha(bencode.bencode(info_dict)).hexdigest() # Get encoding from torrent file if available @@ -299,6 +297,25 @@ class TorrentInfo(object): else: self._files_tree = {self._name: (0, info_dict['length'], True)} + @classmethod + def from_metadata(cls, metadata, trackers=None): + """Create a TorrentInfo from metadata and trackers + + Args: + metadata (dict): A bdecoded info section of torrent file. + trackers (list of lists, optional): The trackers to include. + + """ + if not isinstance(metadata, dict): + return + + metainfo = {b'info': metadata} + if trackers: + metainfo[b'announce'] = trackers[0][0].encode('utf-8') + trackers_utf8 = [[t.encode('utf-8') for t in tier] for tier in trackers] + metainfo[b'announce-list'] = trackers_utf8 + return cls(torrent_file=metainfo) + def as_dict(self, *keys): """The torrent info as a dictionary, filtered by keys. @@ -358,24 +375,28 @@ class TorrentInfo(object): return self._files_tree @property - def metadata(self): - """The torrents metainfo dictionary. + def metainfo(self): + """Returns the torrent metainfo dictionary. + + This is the bdecoded torrent file contents. Returns: - dict: The bdecoded metainfo dictionary. + dict: The metainfo dictionary. """ - return self._metainfo_dict + return self._metainfo @property def filedata(self): """The contents of the .torrent file. Returns: - str: The metainfo bencoded dictionary from a torrent file. + bytes: The bencoded metainfo. """ - return self._metainfo + if not self._filedata: + self._filedata = bencode.bencode(self._metainfo) + return self._filedata class FileTree2(object): |