Merge branch 'dev'
commit
29b4caccec
18
test.py
18
test.py
|
@ -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)
|
||||
|
|
BIN
test.torrent
BIN
test.torrent
Binary file not shown.
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue