diff options
Diffstat (limited to 'lib/bencode/bencode.py')
| -rw-r--r-- | lib/bencode/bencode.py | 142 |
1 files changed, 0 insertions, 142 deletions
diff --git a/lib/bencode/bencode.py b/lib/bencode/bencode.py deleted file mode 100644 index 4acf788..0000000 --- a/lib/bencode/bencode.py +++ /dev/null | |||
| @@ -1,142 +0,0 @@ | |||
| 1 | # The contents of this file are subject to the BitTorrent Open Source License | ||
| 2 | # Version 1.1 (the License). You may not copy or use this file, in either | ||
| 3 | # source code or executable form, except in compliance with the License. You | ||
| 4 | # may obtain a copy of the License at http://www.bittorrent.com/license/. | ||
| 5 | # | ||
| 6 | # Software distributed under the License is distributed on an AS IS basis, | ||
| 7 | # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | ||
| 8 | # for the specific language governing rights and limitations under the | ||
| 9 | # License. | ||
| 10 | |||
| 11 | # Written by Petru Paler | ||
| 12 | # Modified by Julien (jvoisin) Voisin | ||
| 13 | |||
| 14 | ''' | ||
| 15 | A quick (and also nice) lib to bencode/bdecode torrent files | ||
| 16 | ''' | ||
| 17 | |||
| 18 | |||
| 19 | import types | ||
| 20 | |||
| 21 | |||
| 22 | class BTFailure(Exception): | ||
| 23 | '''Custom Exception''' | ||
| 24 | pass | ||
| 25 | |||
| 26 | |||
| 27 | class Bencached(object): | ||
| 28 | '''Custom type : cached string''' | ||
| 29 | __slots__ = ['bencoded'] | ||
| 30 | |||
| 31 | def __init__(self, string): | ||
| 32 | self.bencoded = string | ||
| 33 | |||
| 34 | |||
| 35 | def decode_int(x, f): | ||
| 36 | '''decode an int''' | ||
| 37 | f += 1 | ||
| 38 | newf = x.index('e', f) | ||
| 39 | n = int(x[f:newf]) | ||
| 40 | if x[f] == '-': | ||
| 41 | if x[f + 1] == '0': | ||
| 42 | raise ValueError | ||
| 43 | elif x[f] == '0' and newf != f + 1: | ||
| 44 | raise ValueError | ||
| 45 | return (n, newf + 1) | ||
| 46 | |||
| 47 | |||
| 48 | def decode_string(x, f): | ||
| 49 | '''decode a string''' | ||
| 50 | colon = x.index(':', f) | ||
| 51 | n = int(x[f:colon]) | ||
| 52 | if x[f] == '0' and colon != f + 1: | ||
| 53 | raise ValueError | ||
| 54 | colon += 1 | ||
| 55 | return (x[colon:colon + n], colon + n) | ||
| 56 | |||
| 57 | |||
| 58 | def decode_list(x, f): | ||
| 59 | '''decode a list''' | ||
| 60 | result = [] | ||
| 61 | f += 1 | ||
| 62 | while x[f] != 'e': | ||
| 63 | v, f = DECODE_FUNC[x[f]](x, f) | ||
| 64 | result.append(v) | ||
| 65 | return (result, f + 1) | ||
| 66 | |||
| 67 | |||
| 68 | def decode_dict(x, f): | ||
| 69 | '''decode a dict''' | ||
| 70 | result = {} | ||
| 71 | f += 1 | ||
| 72 | while x[f] != 'e': | ||
| 73 | k, f = decode_string(x, f) | ||
| 74 | result[k], f = DECODE_FUNC[x[f]](x, f) | ||
| 75 | return (result, f + 1) | ||
| 76 | |||
| 77 | |||
| 78 | def encode_bool(x, r): | ||
| 79 | '''bencode a boolean''' | ||
| 80 | if x: | ||
| 81 | encode_int(1, r) | ||
| 82 | else: | ||
| 83 | encode_int(0, r) | ||
| 84 | |||
| 85 | |||
| 86 | def encode_int(x, r): | ||
| 87 | '''bencode an integer/float''' | ||
| 88 | r.extend(('i', str(x), 'e')) | ||
| 89 | |||
| 90 | |||
| 91 | def encode_list(x, r): | ||
| 92 | '''bencode a list/tuple''' | ||
| 93 | r.append('l') | ||
| 94 | [ENCODE_FUNC[type(item)](item, r) for item in x] | ||
| 95 | r.append('e') | ||
| 96 | |||
| 97 | |||
| 98 | def encode_dict(x, result): | ||
| 99 | '''bencode a dict''' | ||
| 100 | result.append('d') | ||
| 101 | ilist = x.items() | ||
| 102 | ilist.sort() | ||
| 103 | for k, v in ilist: | ||
| 104 | result.extend((str(len(k)), ':', k)) | ||
| 105 | ENCODE_FUNC[type(v)](v, result) | ||
| 106 | result.append('e') | ||
| 107 | |||
| 108 | |||
| 109 | DECODE_FUNC = {} | ||
| 110 | DECODE_FUNC.update(dict([(str(x), decode_string) for x in xrange(9)])) | ||
| 111 | DECODE_FUNC['l'] = decode_list | ||
| 112 | DECODE_FUNC['d'] = decode_dict | ||
| 113 | DECODE_FUNC['i'] = decode_int | ||
| 114 | |||
| 115 | |||
| 116 | ENCODE_FUNC = {} | ||
| 117 | ENCODE_FUNC[Bencached] = lambda x, r: r.append(x.bencoded) | ||
| 118 | ENCODE_FUNC[types.IntType] = encode_int | ||
| 119 | ENCODE_FUNC[types.LongType] = encode_int | ||
| 120 | ENCODE_FUNC[types.StringType] = lambda x, r: r.extend((str(len(x)), ':', x)) | ||
| 121 | ENCODE_FUNC[types.ListType] = encode_list | ||
| 122 | ENCODE_FUNC[types.TupleType] = encode_list | ||
| 123 | ENCODE_FUNC[types.DictType] = encode_dict | ||
| 124 | ENCODE_FUNC[types.BooleanType] = encode_bool | ||
| 125 | |||
| 126 | |||
| 127 | def bencode(string): | ||
| 128 | '''bencode $string''' | ||
| 129 | table = [] | ||
| 130 | ENCODE_FUNC[type(string)](string, table) | ||
| 131 | return ''.join(table) | ||
| 132 | |||
| 133 | |||
| 134 | def bdecode(string): | ||
| 135 | '''decode $string''' | ||
| 136 | try: | ||
| 137 | result, lenght = DECODE_FUNC[string[0]](string, 0) | ||
| 138 | except (IndexError, KeyError, ValueError): | ||
| 139 | raise BTFailure('Not a valid bencoded string') | ||
| 140 | if lenght != len(string): | ||
| 141 | raise BTFailure('Invalid bencoded value (data after valid prefix)') | ||
| 142 | return result | ||
