diff options
Diffstat (limited to 'src/torrent.py')
| -rw-r--r-- | src/torrent.py | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/src/torrent.py b/src/torrent.py index bdf83ce..cb4b5e3 100644 --- a/src/torrent.py +++ b/src/torrent.py | |||
| @@ -11,7 +11,7 @@ class TorrentParser(abstract.AbstractParser): | |||
| 11 | d = _BencodeHandler().bdecode(f.read()) | 11 | d = _BencodeHandler().bdecode(f.read()) |
| 12 | if d is None: | 12 | if d is None: |
| 13 | return {'Unknown meta': 'Unable to parse torrent file "%s".' % self.filename} | 13 | return {'Unknown meta': 'Unable to parse torrent file "%s".' % self.filename} |
| 14 | for k,v in d.items(): | 14 | for k, v in d.items(): |
| 15 | if k not in self.whitelist: | 15 | if k not in self.whitelist: |
| 16 | metadata[k.decode('utf-8')] = v | 16 | metadata[k.decode('utf-8')] = v |
| 17 | return metadata | 17 | return metadata |
| @@ -23,7 +23,7 @@ class TorrentParser(abstract.AbstractParser): | |||
| 23 | d = _BencodeHandler().bdecode(f.read()) | 23 | d = _BencodeHandler().bdecode(f.read()) |
| 24 | if d is None: | 24 | if d is None: |
| 25 | return False | 25 | return False |
| 26 | for k,v in d.items(): | 26 | for k, v in d.items(): |
| 27 | if k in self.whitelist: | 27 | if k in self.whitelist: |
| 28 | cleaned[k] = v | 28 | cleaned[k] = v |
| 29 | with open(self.output_filename, 'wb') as f: | 29 | with open(self.output_filename, 'wb') as f: |
| @@ -39,21 +39,22 @@ class _BencodeHandler(object): | |||
| 39 | """ | 39 | """ |
| 40 | def __init__(self): | 40 | def __init__(self): |
| 41 | self.__decode_func = { | 41 | self.__decode_func = { |
| 42 | ord('d'): self.__decode_dict, | 42 | ord('d'): self.__decode_dict, |
| 43 | ord('i'): self.__decode_int, | 43 | ord('i'): self.__decode_int, |
| 44 | ord('l'): self.__decode_list, | 44 | ord('l'): self.__decode_list, |
| 45 | } | 45 | } |
| 46 | for i in range(0, 10): | 46 | for i in range(0, 10): |
| 47 | self.__decode_func[ord(str(i))] = self.__decode_string | 47 | self.__decode_func[ord(str(i))] = self.__decode_string |
| 48 | 48 | ||
| 49 | self.__encode_func = { | 49 | self.__encode_func = { |
| 50 | bytes: self.__encode_string, | 50 | bytes: self.__encode_string, |
| 51 | dict: self.__encode_dict, | 51 | dict: self.__encode_dict, |
| 52 | int: self.__encode_int, | 52 | int: self.__encode_int, |
| 53 | list: self.__encode_list, | 53 | list: self.__encode_list, |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | def __decode_int(self, s:str) -> (int, str): | 56 | @staticmethod |
| 57 | def __decode_int(s: str) -> (int, str): | ||
| 57 | s = s[1:] | 58 | s = s[1:] |
| 58 | next_idx = s.index(b'e') | 59 | next_idx = s.index(b'e') |
| 59 | if s.startswith(b'-0'): | 60 | if s.startswith(b'-0'): |
| @@ -62,7 +63,8 @@ class _BencodeHandler(object): | |||
| 62 | raise ValueError # no leading zero except for zero itself | 63 | raise ValueError # no leading zero except for zero itself |
| 63 | return int(s[:next_idx]), s[next_idx+1:] | 64 | return int(s[:next_idx]), s[next_idx+1:] |
| 64 | 65 | ||
| 65 | def __decode_string(self, s:str) -> (str, str): | 66 | @staticmethod |
| 67 | def __decode_string(s: str) -> (str, str): | ||
| 66 | sep = s.index(b':') | 68 | sep = s.index(b':') |
| 67 | str_len = int(s[:sep]) | 69 | str_len = int(s[:sep]) |
| 68 | if str_len < 0: | 70 | if str_len < 0: |
| @@ -72,7 +74,7 @@ class _BencodeHandler(object): | |||
| 72 | s = s[1:] | 74 | s = s[1:] |
| 73 | return s[sep:sep+str_len], s[sep+str_len:] | 75 | return s[sep:sep+str_len], s[sep+str_len:] |
| 74 | 76 | ||
| 75 | def __decode_list(self, s:str) -> (list, str): | 77 | def __decode_list(self, s: str) -> (list, str): |
| 76 | r = list() | 78 | r = list() |
| 77 | s = s[1:] # skip leading `l` | 79 | s = s[1:] # skip leading `l` |
| 78 | while s[0] != ord('e'): | 80 | while s[0] != ord('e'): |
| @@ -80,7 +82,7 @@ class _BencodeHandler(object): | |||
| 80 | r.append(v) | 82 | r.append(v) |
| 81 | return r, s[1:] | 83 | return r, s[1:] |
| 82 | 84 | ||
| 83 | def __decode_dict(self, s:str) -> (dict, str): | 85 | def __decode_dict(self, s: str) -> (dict, str): |
| 84 | r = dict() | 86 | r = dict() |
| 85 | s = s[1:] # skip leading `d` | 87 | s = s[1:] # skip leading `d` |
| 86 | while s[0] != ord(b'e'): | 88 | while s[0] != ord(b'e'): |
| @@ -89,30 +91,30 @@ class _BencodeHandler(object): | |||
| 89 | return r, s[1:] | 91 | return r, s[1:] |
| 90 | 92 | ||
| 91 | @staticmethod | 93 | @staticmethod |
| 92 | def __encode_int(x:str) -> bytes: | 94 | def __encode_int(x: str) -> bytes: |
| 93 | return b'i' + bytes(str(x), 'utf-8') + b'e' | 95 | return b'i' + bytes(str(x), 'utf-8') + b'e' |
| 94 | 96 | ||
| 95 | @staticmethod | 97 | @staticmethod |
| 96 | def __encode_string(x:str) -> bytes: | 98 | def __encode_string(x: str) -> bytes: |
| 97 | return bytes((str(len(x))), 'utf-8') + b':' + x | 99 | return bytes((str(len(x))), 'utf-8') + b':' + x |
| 98 | 100 | ||
| 99 | def __encode_list(self, x:str) -> bytes: | 101 | def __encode_list(self, x: str) -> bytes: |
| 100 | ret = b'' | 102 | ret = b'' |
| 101 | for i in x: | 103 | for i in x: |
| 102 | ret += self.__encode_func[type(i)](i) | 104 | ret += self.__encode_func[type(i)](i) |
| 103 | return b'l' + ret + b'e' | 105 | return b'l' + ret + b'e' |
| 104 | 106 | ||
| 105 | def __encode_dict(self, x:str) -> bytes: | 107 | def __encode_dict(self, x: str) -> bytes: |
| 106 | ret = b'' | 108 | ret = b'' |
| 107 | for k, v in sorted(x.items()): | 109 | for k, v in sorted(x.items()): |
| 108 | ret += self.__encode_func[type(k)](k) | 110 | ret += self.__encode_func[type(k)](k) |
| 109 | ret += self.__encode_func[type(v)](v) | 111 | ret += self.__encode_func[type(v)](v) |
| 110 | return b'd' + ret + b'e' | 112 | return b'd' + ret + b'e' |
| 111 | 113 | ||
| 112 | def bencode(self, s:str) -> bytes: | 114 | def bencode(self, s: str) -> bytes: |
| 113 | return self.__encode_func[type(s)](s) | 115 | return self.__encode_func[type(s)](s) |
| 114 | 116 | ||
| 115 | def bdecode(self, s:str): | 117 | def bdecode(self, s: str): |
| 116 | try: | 118 | try: |
| 117 | r, l = self.__decode_func[s[0]](s) | 119 | r, l = self.__decode_func[s[0]](s) |
| 118 | except (IndexError, KeyError, ValueError) as e: | 120 | except (IndexError, KeyError, ValueError) as e: |
