[38962] | 1 | # -*- coding: utf-8 -*- |
---|
| 2 | # ------------------------------------------------------------ |
---|
| 3 | # pelisalacarta - XBMC Plugin |
---|
| 4 | # Conector for openload.io |
---|
| 5 | # http://blog.tvalacarta.info/plugin-xbmc/pelisalacarta/ |
---|
| 6 | # by DrZ3r0 |
---|
| 7 | # ------------------------------------------------------------ |
---|
| 8 | # Modified by Shani |
---|
| 9 | import re |
---|
[38996] | 10 | #from urlresolver import common |
---|
[38962] | 11 | |
---|
| 12 | |
---|
| 13 | class AADecoder(object): |
---|
| 14 | def __init__(self, aa_encoded_data): |
---|
| 15 | self.encoded_str = aa_encoded_data.replace('/*´∇`*/', '') |
---|
| 16 | |
---|
| 17 | self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)", |
---|
| 18 | "(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))", |
---|
| 19 | "((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ", |
---|
| 20 | "(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"] |
---|
| 21 | |
---|
| 22 | def is_aaencoded(self): |
---|
| 23 | idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ") |
---|
| 24 | if idx == -1: |
---|
| 25 | return False |
---|
| 26 | |
---|
| 27 | is_encoded = self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) != -1 |
---|
| 28 | return is_encoded |
---|
| 29 | |
---|
| 30 | def base_repr(self, number, base=2, padding=0): |
---|
| 31 | digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
---|
| 32 | if base > len(digits): |
---|
| 33 | base = len(digits) |
---|
| 34 | |
---|
| 35 | num = abs(number) |
---|
| 36 | res = [] |
---|
| 37 | while num: |
---|
| 38 | res.append(digits[num % base]) |
---|
| 39 | num //= base |
---|
| 40 | if padding: |
---|
| 41 | res.append('0' * padding) |
---|
| 42 | if number < 0: |
---|
| 43 | res.append('-') |
---|
| 44 | return ''.join(reversed(res or '0')) |
---|
| 45 | |
---|
| 46 | def decode_char(self, enc_char, radix): |
---|
| 47 | end_char = "+ " |
---|
| 48 | str_char = "" |
---|
| 49 | while enc_char != '': |
---|
| 50 | found = False |
---|
| 51 | # for i in range(len(self.b)): |
---|
| 52 | # print self.b[i], enc_char.find(self.b[i]) |
---|
| 53 | # if enc_char.find(self.b[i]) == 0: |
---|
| 54 | # str_char += self.base_repr(i, radix) |
---|
| 55 | # enc_char = enc_char[len(self.b[i]):] |
---|
| 56 | # found = True |
---|
| 57 | # break |
---|
| 58 | |
---|
| 59 | # print 'found', found, enc_char |
---|
| 60 | if not found: |
---|
| 61 | for i in range(len(self.b)): |
---|
| 62 | enc_char = enc_char.replace(self.b[i], str(i)) |
---|
| 63 | # enc_char = enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3') |
---|
| 64 | # print 'enc_char', enc_char |
---|
| 65 | startpos = 0 |
---|
| 66 | findClose = True |
---|
| 67 | balance = 1 |
---|
| 68 | result = [] |
---|
| 69 | if enc_char.startswith('('): |
---|
| 70 | l = 0 |
---|
| 71 | |
---|
| 72 | for t in enc_char[1:]: |
---|
| 73 | l += 1 |
---|
| 74 | # print 'looping', findClose, startpos, t, balance |
---|
| 75 | if findClose and t == ')': |
---|
| 76 | balance -= 1 |
---|
| 77 | if balance == 0: |
---|
| 78 | result += [enc_char[startpos:l + 1]] |
---|
| 79 | findClose = False |
---|
| 80 | continue |
---|
| 81 | elif not findClose and t == '(': |
---|
| 82 | startpos = l |
---|
| 83 | findClose = True |
---|
| 84 | balance = 1 |
---|
| 85 | continue |
---|
| 86 | elif t == '(': |
---|
| 87 | balance += 1 |
---|
| 88 | |
---|
| 89 | if result is None or len(result) == 0: |
---|
| 90 | return "" |
---|
| 91 | else: |
---|
| 92 | for r in result: |
---|
| 93 | value = self.decode_digit(r, radix) |
---|
| 94 | # print 'va', value |
---|
| 95 | str_char += value |
---|
| 96 | if value == "": |
---|
| 97 | return "" |
---|
| 98 | |
---|
| 99 | return str_char |
---|
| 100 | |
---|
| 101 | enc_char = enc_char[len(end_char):] |
---|
| 102 | |
---|
| 103 | return str_char |
---|
| 104 | |
---|
| 105 | def parseJSString(self, s): |
---|
| 106 | try: |
---|
| 107 | # print s |
---|
| 108 | # offset = 1 if s[0] == '+' else 0 |
---|
| 109 | tmp = (s.replace('!+[]', '1').replace('!![]', '1').replace('[]', '0')) # .replace('(','str(')[offset:]) |
---|
| 110 | val = int(eval(tmp)) |
---|
| 111 | return val |
---|
| 112 | except: |
---|
| 113 | pass |
---|
| 114 | |
---|
| 115 | def decode_digit(self, enc_int, radix): |
---|
| 116 | # enc_int = enc_int.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3') |
---|
| 117 | # print 'enc_int before', enc_int |
---|
| 118 | # for i in range(len(self.b)): |
---|
| 119 | # print self.b[i], enc_char.find(self.b[i]) |
---|
| 120 | # if enc_char.find(self.b[i]) > 0: |
---|
| 121 | # str_char += self.base_repr(i, radix) |
---|
| 122 | # enc_char = enc_char[len(self.b[i]):] |
---|
| 123 | # found = True |
---|
| 124 | # break |
---|
| 125 | # enc_int=enc_int.replace(self.b[i], str(i)) |
---|
| 126 | # print 'enc_int before', enc_int |
---|
| 127 | |
---|
| 128 | try: |
---|
| 129 | return str(eval(enc_int)) |
---|
| 130 | except: pass |
---|
| 131 | rr = '(\(.+?\)\))\+' |
---|
| 132 | rerr = enc_int.split('))+') # re.findall(rr, enc_int) |
---|
| 133 | v = "" |
---|
| 134 | # print rerr |
---|
| 135 | for c in rerr: |
---|
| 136 | if len(c) > 0: |
---|
| 137 | # print 'v', c |
---|
| 138 | if c.strip().endswith('+'): |
---|
| 139 | c = c.strip()[:-1] |
---|
| 140 | # print 'v', c |
---|
| 141 | startbrackets = len(c) - len(c.replace('(', '')) |
---|
| 142 | endbrackets = len(c) - len(c.replace(')', '')) |
---|
| 143 | if startbrackets > endbrackets: |
---|
| 144 | c += ')' * (startbrackets - endbrackets) |
---|
| 145 | if '[' in c: |
---|
| 146 | v += str(self.parseJSString(c)) |
---|
| 147 | else: |
---|
| 148 | # print c |
---|
| 149 | v += str(eval(c)) |
---|
| 150 | return v |
---|
| 151 | |
---|
| 152 | # unreachable code |
---|
| 153 | # mode 0=+, 1=- |
---|
| 154 | # mode = 0 |
---|
| 155 | # value = 0 |
---|
| 156 | |
---|
| 157 | # while enc_int != '': |
---|
| 158 | # found = False |
---|
| 159 | # for i in range(len(self.b)): |
---|
| 160 | # if enc_int.find(self.b[i]) == 0: |
---|
| 161 | # if mode == 0: |
---|
| 162 | # value += i |
---|
| 163 | # else: |
---|
| 164 | # value -= i |
---|
| 165 | # enc_int = enc_int[len(self.b[i]):] |
---|
| 166 | # found = True |
---|
| 167 | # break |
---|
| 168 | |
---|
| 169 | # if not found: |
---|
| 170 | # return "" |
---|
| 171 | |
---|
| 172 | # enc_int = re.sub('^\s+|\s+$', '', enc_int) |
---|
| 173 | # if enc_int.find("+") == 0: |
---|
| 174 | # mode = 0 |
---|
| 175 | # else: |
---|
| 176 | # mode = 1 |
---|
| 177 | |
---|
| 178 | # enc_int = enc_int[1:] |
---|
| 179 | # enc_int = re.sub('^\s+|\s+$', '', enc_int) |
---|
| 180 | |
---|
| 181 | # return self.base_repr(value, radix) |
---|
| 182 | |
---|
| 183 | def decode(self): |
---|
| 184 | self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str) |
---|
| 185 | |
---|
| 186 | # get data |
---|
| 187 | pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)") |
---|
| 188 | result = re.search(pattern, self.encoded_str, re.DOTALL) |
---|
| 189 | if result is None: |
---|
[38996] | 190 | # common.log_utils.log_debug("AADecoder: data not found") |
---|
[38962] | 191 | return False |
---|
| 192 | |
---|
| 193 | data = result.group(1) |
---|
| 194 | |
---|
| 195 | # hex decode string |
---|
| 196 | begin_char = "(゚Д゚)[゚ε゚]+" |
---|
| 197 | alt_char = "(o゚ー゚o)+ " |
---|
| 198 | |
---|
| 199 | out = '' |
---|
| 200 | # print data |
---|
| 201 | while data != '': |
---|
| 202 | # Check new char |
---|
| 203 | if data.find(begin_char) != 0: |
---|
[38996] | 204 | # common.log_utils.log_debug("AADecoder: data not found") |
---|
[38962] | 205 | return False |
---|
| 206 | |
---|
| 207 | data = data[len(begin_char):] |
---|
| 208 | |
---|
| 209 | # Find encoded char |
---|
| 210 | enc_char = "" |
---|
| 211 | if data.find(begin_char) == -1: |
---|
| 212 | enc_char = data |
---|
| 213 | data = "" |
---|
| 214 | else: |
---|
| 215 | enc_char = data[:data.find(begin_char)] |
---|
| 216 | data = data[len(enc_char):] |
---|
| 217 | |
---|
| 218 | radix = 8 |
---|
| 219 | # Detect radix 16 for utf8 char |
---|
| 220 | if enc_char.find(alt_char) == 0: |
---|
| 221 | enc_char = enc_char[len(alt_char):] |
---|
| 222 | radix = 16 |
---|
| 223 | |
---|
| 224 | # print repr(enc_char), radix |
---|
| 225 | # print enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3') |
---|
| 226 | |
---|
| 227 | # print 'The CHAR', enc_char, radix |
---|
| 228 | str_char = self.decode_char(enc_char, radix) |
---|
| 229 | |
---|
| 230 | if str_char == "": |
---|
[38996] | 231 | # common.log_utils.log_debug("no match : ") |
---|
| 232 | # common.log_utils.log_debug(data + "\nout = " + out + "\n") |
---|
[38962] | 233 | return False |
---|
| 234 | # print 'sofar', str_char, radix,out |
---|
| 235 | |
---|
| 236 | out += chr(int(str_char, radix)) |
---|
| 237 | # print 'sfar', chr(int(str_char, radix)), out |
---|
| 238 | |
---|
| 239 | if out == "": |
---|
[38996] | 240 | # common.log_utils.log_debug("no match : " + data) |
---|
[38962] | 241 | return False |
---|
| 242 | |
---|
| 243 | return out |
---|