Merge branch 'dev'

dev
7sDream 2017-06-20 15:42:07 +08:00
commit 29b4caccec
No known key found for this signature in database
GPG Key ID: 72A6D9FCEDDAB75D
3 changed files with 27 additions and 22 deletions

18
test.py
View File

@ -26,24 +26,18 @@ class Test(unittest.TestCase):
def test_parse_correctness(self):
data = parse_torrent_file(self.TEST_FILENAME)
self.assertIn(['udp://p4p.arenabg.ch:1337/announce'],
self.assertIn(['udp://tracker.publicbt.com:80/announce'],
data['announce-list'])
self.assertEqual(data['comment'],
'Torrent downloaded from https://rarbg.to')
self.assertEqual(data['creation date'], 1472762993)
self.assertEqual(data['creation date'], 1409254242)
def test_parse_two_times(self):
with open(self.TEST_FILENAME, 'rb') as fp:
parser = TorrentFileParser(fp)
data = parser.parse()
self.assertIn(['udp://p4p.arenabg.ch:1337/announce'],
self.assertIn(['udp://tracker.publicbt.com:80/announce'],
data['announce-list'])
self.assertEqual(data['comment'],
'Torrent downloaded from https://rarbg.to')
self.assertEqual(data['creation date'], 1472762993)
self.assertEqual(data['creation date'], 1409254242)
data = parser.parse()
self.assertIn(['udp://p4p.arenabg.ch:1337/announce'],
self.assertIn(['udp://tracker.publicbt.com:80/announce'],
data['announce-list'])
self.assertEqual(data['comment'],
'Torrent downloaded from https://rarbg.to')
self.assertEqual(data['creation date'], 1472762993)
self.assertEqual(data['creation date'], 1409254242)

Binary file not shown.

View File

@ -7,9 +7,9 @@ A .torrent file parser for both Python 2 and 3
Usage:
data = parse_torrent_file(filename)
# or
with open(filename, 'rb') as f: # the binary mode 'b' is necessary
data = TorrentFileParser(f).parse()
"""
@ -62,7 +62,7 @@ class TorrentFileParser(object):
def __init__(self, fp, use_ordered_dict=False, encoding='utf-8'):
"""
:param fp: a **binary** file-like object to parse,
:param fp: a **binary** file-like object to parse,
which means need 'b' mode when use built-in open function
:param encoding: file content encoding, default utf-8
:param use_ordered_dict: Use collections.OrderedDict as dict container
@ -126,7 +126,11 @@ class TorrentFileParser(object):
except InvalidTorrentFileException:
return
if k == 'pieces':
v = self._pieces()
v = self._next_hash()
elif k == 'ed2k':
v = self._next_hash(16, False)
elif k == 'filehash':
v = self._next_hash(20, False)
else:
v = self._next_element()
if k == 'encoding':
@ -173,14 +177,19 @@ class TorrentFileParser(object):
def __to_hex(v):
return hex(ord(v) if isinstance(v, str) else v)[2:].rjust(2, str(0))
def _pieces(self):
def _next_hash(self, p_len=20, need_list=True):
raw = self._next_string(decode=False)
if len(raw) % 20 != 0:
if len(raw) % p_len != 0:
raise InvalidTorrentFileException(self._pos)
return [
res = [
''.join([self.__to_hex(c) for c in h])
for h in (raw[x:x+20] for x in range(0, len(raw), 20))
for h in (raw[x:x+p_len] for x in range(0, len(raw), p_len))
]
if len(res) == 0 and not need_list:
return ''
if len(res) == 1 and not need_list:
return res[0]
return res
def _next_end(self):
raise InvalidTorrentFileException(self._pos)
@ -206,7 +215,7 @@ class TorrentFileParser(object):
def parse_torrent_file(filename, use_ordered_dict=False):
"""
Shortcut function for parse torrent object use TorrentFileParser
:param string filename: torrent filename
:param bool use_ordered_dict: see :any:`TorrentFileParser.__init__`
:rtype: dict if ``use_ordered_dict`` is false,
@ -229,6 +238,8 @@ def __main():
parser.add_argument('--ascii', '-a', action='store_true', default=False,
help='ensure output json use ascii char, '
'escape other char use \\u')
parser.add_argument('--coding', '-c', default='utf-8',
help='string encoding, default utf-8')
parser.add_argument('--version', '-v', action='store_true', default=False,
help='print version and exit')
args = parser.parse_args()
@ -249,7 +260,7 @@ def __main():
exit(1)
# noinspection PyUnboundLocalVariable
data = TorrentFileParser(target_file, not args.dict).parse()
data = TorrentFileParser(target_file, not args.dict, args.coding).parse()
data = json.dumps(
data, ensure_ascii=args.ascii,