summaryrefslogtreecommitdiffstats
path: root/deluge/ui/common.py
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2017-06-29 12:13:35 +0100
committerCalum Lind <calumlind+deluge@gmail.com>2018-06-19 09:12:57 +0100
commit63b25311f53e4e089d335858f749fe40423e8529 (patch)
tree81f126dc693396406e743b892fcfd49c4f6ef727 /deluge/ui/common.py
parentd45dbfe064e2c974663bab59d52b80dbe19fd35d (diff)
downloaddeluge-63b25311f53e4e089d335858f749fe40423e8529.tar.gz
deluge-63b25311f53e4e089d335858f749fe40423e8529.tar.bz2
deluge-63b25311f53e4e089d335858f749fe40423e8529.zip
[UI] Refactor TorrentInfo and add functionality
Make a clearer distinction about torrent metainfo and metadata and allow passing these to TorrentInfo.
Diffstat (limited to 'deluge/ui/common.py')
-rw-r--r--deluge/ui/common.py190
1 files changed, 101 insertions, 89 deletions
diff --git a/deluge/ui/common.py b/deluge/ui/common.py
index 71bbd0468..ac3a18904 100644
--- a/deluge/ui/common.py
+++ b/deluge/ui/common.py
@@ -183,60 +183,67 @@ DISK_CACHE_KEYS = [
class TorrentInfo(object):
- """
- Collects information about a torrent file.
+ """Collects information about a torrent file.
- :param filename: The path to the torrent
- :type filename: string
+ Args:
+ filename (str): 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.
"""
- def __init__(self, filename, filetree=1):
- # Get the torrent data from the torrent file
- try:
- log.debug('Attempting to open %s.', filename)
- with open(filename, 'rb') as _file:
- self.__m_filedata = _file.read()
- except IOError as ex:
- log.warning('Unable to open %s: %s', filename, ex)
- raise ex
- try:
- self.__m_metadata = bencode.bdecode(self.__m_filedata)
- except bencode.BTFailure as ex:
- log.warning('Failed to decode %s: %s', filename, ex)
- raise ex
-
- self.__m_info_hash = sha(bencode.bencode(self.__m_metadata['info'])).hexdigest()
+ def __init__(self, filename='', filetree=1, metainfo=None, metadata=None):
+ # Get the torrent metainfo from the torrent file
+ if metadata:
+ self._metainfo_dict = {'info': bencode.bdecode(metadata)}
+ 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
+
+ try:
+ self._metainfo_dict = bencode.bdecode(self._metainfo)
+ except bencode.BTFailure as ex:
+ log.warning('Failed to decode %s: %s', filename, ex)
+ return
+
+ info_dict = self._metainfo_dict['info']
+ self._info_hash = sha(bencode.bencode(info_dict)).hexdigest()
# Get encoding from torrent file if available
- self.encoding = None
- if 'encoding' in self.__m_metadata:
- self.encoding = self.__m_metadata['encoding']
- elif 'codepage' in self.__m_metadata:
- self.encoding = str(self.__m_metadata['codepage'])
- if not self.encoding:
- self.encoding = 'UTF-8'
-
- # Check if 'name.utf-8' is in the torrent and if not try to decode the string
- # using the encoding found.
- if 'name.utf-8' in self.__m_metadata['info']:
- self.__m_name = decode_bytes(self.__m_metadata['info']['name.utf-8'])
+ encoding = self._metainfo_dict.get('encoding', None)
+ codepage = self._metainfo_dict.get('codepage', None)
+ if not encoding:
+ encoding = codepage if codepage else 'UTF-8'
+
+ # Decode 'name' with encoding unless 'name.utf-8' found.
+ if 'name.utf-8' in info_dict:
+ self._name = decode_bytes(info_dict['name.utf-8'])
else:
- self.__m_name = decode_bytes(self.__m_metadata['info']['name'], self.encoding)
+ self._name = decode_bytes(info_dict['name'], encoding)
# Get list of files from torrent info
- paths = {}
- dirs = {}
- if 'files' in self.__m_metadata['info']:
- prefix = ''
- if len(self.__m_metadata['info']['files']) > 1:
- prefix = self.__m_name
+ if 'files' in info_dict:
+ paths = {}
+ dirs = {}
+ prefix = self._name if len(info_dict['files']) > 1 else ''
- for index, f in enumerate(self.__m_metadata['info']['files']):
+ for index, f in enumerate(info_dict['files']):
if 'path.utf-8' in f:
- path = decode_bytes(os.path.join(prefix, *f['path.utf-8']))
+ path = decode_bytes(os.path.join(*f['path.utf-8']))
del f['path.utf-8']
else:
- path = os.path.join(prefix, decode_bytes(os.path.join(*f['path']), self.encoding))
+ path = decode_bytes(os.path.join(*f['path']), encoding)
+
+ if prefix:
+ path = os.path.join(prefix, path)
+
f['path'] = path
f['index'] = index
if 'sha1' in f and len(f['sha1']) == 20:
@@ -270,84 +277,86 @@ class TorrentInfo(object):
file_tree = FileTree(paths)
file_tree.walk(walk)
- self.__m_files_tree = file_tree.get_tree()
+ self._files_tree = file_tree.get_tree()
else:
if filetree == 2:
- self.__m_files_tree = {
+ self._files_tree = {
'contents': {
- self.__m_name: {
+ self._name: {
'type': 'file',
'index': 0,
- 'length': self.__m_metadata['info']['length'],
+ 'length': info_dict['length'],
'download': True,
- },
- },
+ }
+ }
}
else:
- self.__m_files_tree = {
- self.__m_name: (0, self.__m_metadata['info']['length'], True),
+ self._files_tree = {
+ self._name: (0, info_dict['length'], True),
}
- self.__m_files = []
- if 'files' in self.__m_metadata['info']:
+ self._files = []
+ if 'files' in info_dict:
prefix = ''
- if len(self.__m_metadata['info']['files']) > 1:
- prefix = self.__m_name
+ if len(info_dict['files']) > 1:
+ prefix = self._name
- for f in self.__m_metadata['info']['files']:
- self.__m_files.append({
+ for f in info_dict['files']:
+ self._files.append({
'path': f['path'],
'size': f['length'],
'download': True,
})
else:
- self.__m_files.append({
- 'path': self.__m_name,
- 'size': self.__m_metadata['info']['length'],
+ self._files.append({
+ 'path': self._name,
+ 'size': info_dict['length'],
'download': True,
})
def as_dict(self, *keys):
- """
- Return the torrent info as a dictionary, only including the passed in
- keys.
+ """The torrent info as a dictionary, filtered by keys.
+
+ Args:
+ keys (str): A space-separated string of keys.
- :param keys: a number of key strings
- :type keys: string
+ Returns:
+ dict: The torrent info dict with specified keys.
"""
return {key: getattr(self, key) for key in keys}
@property
def name(self):
- """
- The name of the torrent.
+ """The name of the torrent.
+
+ Returns:
+ str: The torrent name.
- :rtype: string
"""
- return self.__m_name
+ return self._name
@property
def info_hash(self):
- """
- The torrents info_hash
+ """The calculated torrent info_hash.
- :rtype: string
+ Returns:
+ str: The torrent info_hash.
"""
- return self.__m_info_hash
+ return self._info_hash
@property
def files(self):
- """
- A list of the files that the torrent contains.
+ """The files that the torrent contains.
+
+ Returns:
+ list: The list of torrent files.
- :rtype: list
"""
- return self.__m_files
+ return self._files
@property
def files_tree(self):
- """
- A dictionary based tree of the files.
+ """A tree of the files the torrent contains.
::
@@ -357,28 +366,31 @@ class TorrentInfo(object):
}
}
- :rtype: dictionary
+ Returns:
+ dict: The tree of files.
+
"""
- return self.__m_files_tree
+ return self._files_tree
@property
def metadata(self):
- """
- The torrents metadata.
+ """The torrents metainfo dictionary.
+
+ Returns:
+ dict: The bdecoded metainfo dictionary.
- :rtype: dictionary
"""
- return self.__m_metadata
+ return self._metainfo_dict
@property
def filedata(self):
- """
- The torrents file data. This will be the bencoded dictionary read
- from the torrent file.
+ """The contents of the .torrent file.
+
+ Returns:
+ str: The metainfo bencoded dictionary from a torrent file.
- :rtype: string
"""
- return self.__m_filedata
+ return self._metainfo
class FileTree2(object):