diff options
| author | jvoisin | 2014-06-08 13:39:18 +0200 |
|---|---|---|
| committer | jvoisin | 2014-06-08 13:39:18 +0200 |
| commit | af36529554c39a2eefcc2c8723715e2d25b401b8 (patch) | |
| tree | f54b964520bab44d1dfac725086211eaf22d3763 /libmat/bencode | |
| parent | ef5a32cfd3c0555ffe5ddf413eeaae61622ebb4b (diff) | |
Rename the MAT folder to libmat.
This commit fixes some issues for dump operating
systems who doesn't handle capitalization.
Diffstat (limited to 'libmat/bencode')
| -rw-r--r-- | libmat/bencode/__init__.py | 1 | ||||
| -rw-r--r-- | libmat/bencode/bencode.py | 143 |
2 files changed, 144 insertions, 0 deletions
diff --git a/libmat/bencode/__init__.py b/libmat/bencode/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/libmat/bencode/__init__.py | |||
| @@ -0,0 +1 @@ | |||
diff --git a/libmat/bencode/bencode.py b/libmat/bencode/bencode.py new file mode 100644 index 0000000..a0cc99a --- /dev/null +++ b/libmat/bencode/bencode.py | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | # Copyright 2007 by Petru Paler | ||
| 2 | # Copyright 2011 by Julien (jvoisin) Voisin | ||
| 3 | # | ||
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 5 | # of this software and associated documentation files (the "Software"), to deal | ||
| 6 | # in the Software without restriction, including without limitation the rights | ||
| 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 8 | # copies of the Software, and to permit persons to whom the Software is | ||
| 9 | # furnished to do so, subject to the following conditions: | ||
| 10 | # | ||
| 11 | # The above copyright notice and this permission notice shall be included in | ||
| 12 | # all copies or substantial portions of the Software. | ||
| 13 | # | ||
| 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 19 | # FROM, | ||
| 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 21 | # THE SOFTWARE. | ||
| 22 | # | ||
| 23 | |||
| 24 | ''' | ||
| 25 | A quick (and also nice) lib to bencode/bdecode torrent files | ||
| 26 | ''' | ||
| 27 | |||
| 28 | |||
| 29 | class BTFailure(Exception): | ||
| 30 | '''Custom Exception''' | ||
| 31 | pass | ||
| 32 | |||
| 33 | |||
| 34 | class Bencached(object): | ||
| 35 | '''Custom type : cached string''' | ||
| 36 | __slots__ = ['bencoded'] | ||
| 37 | |||
| 38 | def __init__(self, string): | ||
| 39 | self.bencoded = string | ||
| 40 | |||
| 41 | |||
| 42 | def decode_int(x, f): | ||
| 43 | '''decode an int''' | ||
| 44 | f += 1 | ||
| 45 | newf = x.index('e', f) | ||
| 46 | if x[f:f+1] == '-0': | ||
| 47 | raise ValueError | ||
| 48 | elif x[f] == '0' and newf != f + 1: | ||
| 49 | raise ValueError | ||
| 50 | return int(x[f:newf]), newf + 1 | ||
| 51 | |||
| 52 | |||
| 53 | def decode_string(x, f): | ||
| 54 | '''decode a string''' | ||
| 55 | colon = x.index(':', f) | ||
| 56 | if x[f] == '0' and colon != f + 1: | ||
| 57 | raise ValueError | ||
| 58 | n = int(x[f:colon]) | ||
| 59 | colon += 1 | ||
| 60 | return x[colon:colon + n], colon + n | ||
| 61 | |||
| 62 | |||
| 63 | def decode_list(x, f): | ||
| 64 | '''decode a list''' | ||
| 65 | result = [] | ||
| 66 | f += 1 | ||
| 67 | while x[f] != 'e': | ||
| 68 | v, f = DECODE_FUNC[x[f]](x, f) | ||
| 69 | result.append(v) | ||
| 70 | return result, f + 1 | ||
| 71 | |||
| 72 | |||
| 73 | def decode_dict(x, f): | ||
| 74 | '''decode a dict''' | ||
| 75 | result = {} | ||
| 76 | f += 1 | ||
| 77 | while x[f] != 'e': | ||
| 78 | k, f = decode_string(x, f) | ||
| 79 | result[k], f = DECODE_FUNC[x[f]](x, f) | ||
| 80 | return result, f + 1 | ||
| 81 | |||
| 82 | |||
| 83 | def encode_bool(x, r): | ||
| 84 | '''bencode a boolean''' | ||
| 85 | encode_int(1 if r else 0, r) | ||
| 86 | |||
| 87 | |||
| 88 | def encode_int(x, r): | ||
| 89 | '''bencode an integer/float''' | ||
| 90 | r.extend(('i', str(x), 'e')) | ||
| 91 | |||
| 92 | |||
| 93 | def encode_list(x, r): | ||
| 94 | '''bencode a list/tuple''' | ||
| 95 | r.append('l') | ||
| 96 | [ENCODE_FUNC[type(item)](item, r) for item in x] | ||
| 97 | r.append('e') | ||
| 98 | |||
| 99 | |||
| 100 | def encode_dict(x, result): | ||
| 101 | '''bencode a dict''' | ||
| 102 | result.append('d') | ||
| 103 | ilist = list(x.items()) | ||
| 104 | ilist.sort() | ||
| 105 | for k, v in ilist: | ||
| 106 | result.extend((str(len(k)), ':', k)) | ||
| 107 | ENCODE_FUNC[type(v)](v, result) | ||
| 108 | result.append('e') | ||
| 109 | |||
| 110 | |||
| 111 | DECODE_FUNC = {str(x):decode_string for x in range(9)} | ||
| 112 | DECODE_FUNC['l'] = decode_list | ||
| 113 | DECODE_FUNC['d'] = decode_dict | ||
| 114 | DECODE_FUNC['i'] = decode_int | ||
| 115 | |||
| 116 | |||
| 117 | ENCODE_FUNC = {} | ||
| 118 | ENCODE_FUNC[Bencached] = lambda x, r: r.append(x.bencoded) | ||
| 119 | ENCODE_FUNC[int] = encode_int | ||
| 120 | ENCODE_FUNC[int] = encode_int | ||
| 121 | ENCODE_FUNC[bytes] = lambda x, r: r.extend((str(len(x)), ':', x)) | ||
| 122 | ENCODE_FUNC[list] = encode_list | ||
| 123 | ENCODE_FUNC[tuple] = encode_list | ||
| 124 | ENCODE_FUNC[dict] = encode_dict | ||
| 125 | ENCODE_FUNC[bool] = encode_bool | ||
| 126 | |||
| 127 | |||
| 128 | def bencode(string): | ||
| 129 | '''bencode $string''' | ||
| 130 | table = [] | ||
| 131 | ENCODE_FUNC[type(string)](string, table) | ||
| 132 | return ''.join(table) | ||
| 133 | |||
| 134 | |||
| 135 | def bdecode(string): | ||
| 136 | '''decode $string''' | ||
| 137 | try: | ||
| 138 | result, lenght = DECODE_FUNC[string[0]](string, 0) | ||
| 139 | except (IndexError, KeyError, ValueError): | ||
| 140 | raise BTFailure('Not a valid bencoded string') | ||
| 141 | if lenght != len(string): | ||
| 142 | raise BTFailure('Invalid bencoded value (data after valid prefix)') | ||
| 143 | return result | ||
