# -*- coding: utf-8 -*-
"""
openload.io urlresolver plugin
Copyright (C) 2015 tknorris
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
import urllib
import re
import urllib2
from HTMLParser import HTMLParser
import requests
#from lib.net import Net
#from urlresolver import common
#from urlresolver.resolver import ResolverError
#net = Net() #III
SIZE_LIMIT = 32 * 1024 * 1024
def caesar_shift(s, shift=13):
s2 = ''
for c in s:
if c.isalpha():
limit = 90 if c <= 'Z' else 122
new_code = ord(c) + shift
if new_code > limit:
new_code -= 26
s2 += chr(new_code)
else:
s2 += c
return s2
def unpack(html):
strings = re.findall('{\s*var\s+a\s*=\s*"([^"]+)', html)
shifts = re.findall('\)\);}\((\d+)\)', html)
for s, shift in zip(strings, shifts):
s = caesar_shift(s, int(shift))
s = urllib.unquote(s)
for i, replace in enumerate(['j', '_', '__', '___']):
s = s.replace(str(i), replace)
html += '' % (s)
return html
def get_media_url(url):
try:
HTTP_HEADER = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Accept-Encoding': 'none',
'Accept-Language': 'en-US,en;q=0.8',
'Referer': url} # 'Connection': 'keep-alive'
#html = net.http_GET(url, headers=HTTP_HEADER).content
html = requests.get(url, headers=HTTP_HEADER).content
try: html = html.encode('utf-8')
except: pass
html = unpack(html)
match = re.search('''>([^<]+)\s*]*>(.*?)', html, re.DOTALL):
encoded = match.group(1)
match = re.search("(゚ω゚ノ.*?\('_'\);)", encoded, re.DOTALL)
if match:
decodes.append(AADecoder(match.group(1)).decode())
match = re.search('(.=~\[\].*\(\);)', encoded, re.DOTALL)
if match:
decodes.append(JJDecoder(match.group(1)).decode())
if not decodes:
raise ResolverError('No Encoded Section Found. Deleted?')
magic_number = 0
for decode in decodes:
match = re.search('charCodeAt\(\d+\)\s*\+\s*(\d+)\)', decode, re.DOTALL | re.I)
if match:
magic_number = match.group(1)
break
s = []
for idx, i in enumerate(hiddenurl):
j = ord(i)
if (j >= 33 & j <= 126):
j = 33 + ((j + 14) % 94)
if idx == len(hiddenurl) - 1:
j += int(magic_number)
s.append(chr(j))
res = ''.join(s)
videoUrl = 'https://openload.co/stream/{0}?mime=true'.format(res)
dtext = videoUrl.replace('https', 'http')
headers = {'User-Agent': HTTP_HEADER['User-Agent']}
req = urllib2.Request(dtext, None, headers)
res = urllib2.urlopen(req)
videourl = res.geturl()
if int(res.headers['Content-Length']) < SIZE_LIMIT:
raise ResolverError('Openload.co resolve failed. Pigeons?')
res.close()
return videourl
except Exception as e:
print 'Exception during openload resolve parse: %s' % e
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# pelisalacarta - XBMC Plugin
# Conector for openload.io
# http://blog.tvalacarta.info/plugin-xbmc/pelisalacarta/
# by DrZ3r0
# ------------------------------------------------------------
# Modified by Shani
import re
#from urlresolver import common
#import common
class AADecoder(object):
def __init__(self, aa_encoded_data):
self.encoded_str = aa_encoded_data.replace('/*´∇`*/', '')
self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)",
"(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))",
"((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ",
"(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"]
def is_aaencoded(self):
idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ")
if idx == -1:
return False
is_encoded = self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) != -1
return is_encoded
def base_repr(self, number, base=2, padding=0):
digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
if base > len(digits):
base = len(digits)
num = abs(number)
res = []
while num:
res.append(digits[num % base])
num //= base
if padding:
res.append('0' * padding)
if number < 0:
res.append('-')
return ''.join(reversed(res or '0'))
def decode_char(self, enc_char, radix):
end_char = "+ "
str_char = ""
while enc_char != '':
found = False
# for i in range(len(self.b)):
# print self.b[i], enc_char.find(self.b[i])
# if enc_char.find(self.b[i]) == 0:
# str_char += self.base_repr(i, radix)
# enc_char = enc_char[len(self.b[i]):]
# found = True
# break
# print 'found', found, enc_char
if not found:
for i in range(len(self.b)):
enc_char = enc_char.replace(self.b[i], str(i))
# enc_char = enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
# print 'enc_char', enc_char
startpos = 0
findClose = True
balance = 1
result = []
if enc_char.startswith('('):
l = 0
for t in enc_char[1:]:
l += 1
# print 'looping', findClose, startpos, t, balance
if findClose and t == ')':
balance -= 1
if balance == 0:
result += [enc_char[startpos:l + 1]]
findClose = False
continue
elif not findClose and t == '(':
startpos = l
findClose = True
balance = 1
continue
elif t == '(':
balance += 1
if result is None or len(result) == 0:
return ""
else:
for r in result:
value = self.decode_digit(r, radix)
# print 'va', value
str_char += value
if value == "":
return ""
return str_char
enc_char = enc_char[len(end_char):]
return str_char
def parseJSString(self, s):
try:
# print s
# offset = 1 if s[0] == '+' else 0
tmp = (s.replace('!+[]', '1').replace('!![]', '1').replace('[]', '0')) # .replace('(','str(')[offset:])
val = int(eval(tmp))
return val
except:
pass
def decode_digit(self, enc_int, radix):
# enc_int = enc_int.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
# print 'enc_int before', enc_int
# for i in range(len(self.b)):
# print self.b[i], enc_char.find(self.b[i])
# if enc_char.find(self.b[i]) > 0:
# str_char += self.base_repr(i, radix)
# enc_char = enc_char[len(self.b[i]):]
# found = True
# break
# enc_int=enc_int.replace(self.b[i], str(i))
# print 'enc_int before', enc_int
try:
return str(eval(enc_int))
except: pass
rr = '(\(.+?\)\))\+'
rerr = enc_int.split('))+') # re.findall(rr, enc_int)
v = ""
# print rerr
for c in rerr:
if len(c) > 0:
# print 'v', c
if c.strip().endswith('+'):
c = c.strip()[:-1]
# print 'v', c
startbrackets = len(c) - len(c.replace('(', ''))
endbrackets = len(c) - len(c.replace(')', ''))
if startbrackets > endbrackets:
c += ')' * (startbrackets - endbrackets)
if '[' in c:
v += str(self.parseJSString(c))
else:
# print c
v += str(eval(c))
return v
# unreachable code
# mode 0=+, 1=-
# mode = 0
# value = 0
# while enc_int != '':
# found = False
# for i in range(len(self.b)):
# if enc_int.find(self.b[i]) == 0:
# if mode == 0:
# value += i
# else:
# value -= i
# enc_int = enc_int[len(self.b[i]):]
# found = True
# break
# if not found:
# return ""
# enc_int = re.sub('^\s+|\s+$', '', enc_int)
# if enc_int.find("+") == 0:
# mode = 0
# else:
# mode = 1
# enc_int = enc_int[1:]
# enc_int = re.sub('^\s+|\s+$', '', enc_int)
# return self.base_repr(value, radix)
def decode(self):
self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str)
# get data
pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)")
result = re.search(pattern, self.encoded_str, re.DOTALL)
if result is None:
#common.log_utils.log_debug("AADecoder: data not found")
print "AADecoder: data not foun"
return False
data = result.group(1)
# hex decode string
begin_char = "(゚Д゚)[゚ε゚]+"
alt_char = "(o゚ー゚o)+ "
out = ''
# print data
while data != '':
# Check new char
if data.find(begin_char) != 0:
common.log_utils.log_debug("AADecoder: data not found")
return False
data = data[len(begin_char):]
# Find encoded char
enc_char = ""
if data.find(begin_char) == -1:
enc_char = data
data = ""
else:
enc_char = data[:data.find(begin_char)]
data = data[len(enc_char):]
radix = 8
# Detect radix 16 for utf8 char
if enc_char.find(alt_char) == 0:
enc_char = enc_char[len(alt_char):]
radix = 16
# print repr(enc_char), radix
# print enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
# print 'The CHAR', enc_char, radix
str_char = self.decode_char(enc_char, radix)
if str_char == "":
#common.log_utils.log_debug("no match : "),
print "no match : "
#common.log_utils.log_debug(data + "\nout = " + out + "\n")
print data + "\nout = " + out + "\n"
return False
# print 'sofar', str_char, radix,out
out += chr(int(str_char, radix))
# print 'sfar', chr(int(str_char, radix)), out
if out == "":
#common.log_utils.log_debug("no match : " + data)
print "no match : " + data
return False
return out
#
# Python version of the jjdecode function written by Syed Zainudeen
# http://csc.cs.utm.my/syed/images/files/jjdecode/jjdecode.html
#
# +NCR/CRC! [ReVeRsEr] - crackinglandia@gmail.com
# Thanks to Jose Miguel Esparza (@EternalTodo) for the final push to make it work!
#
class JJDecoder(object):
def __init__(self, jj_encoded_data):
self.encoded_str = jj_encoded_data
def clean(self):
return re.sub('^\s+|\s+$', '', self.encoded_str)
def checkPalindrome(self, Str):
startpos = -1
endpos = -1
gv, gvl = -1, -1
index = Str.find('"\'\\"+\'+",')
if index == 0:
startpos = Str.find('$$+"\\""+') + 8
endpos = Str.find('"\\"")())()')
gv = Str[Str.find('"\'\\"+\'+",') + 9:Str.find('=~[]')]
gvl = len(gv)
else:
gv = Str[0:Str.find('=')]
gvl = len(gv)
startpos = Str.find('"\\""+') + 5
endpos = Str.find('"\\"")())()')
return (startpos, endpos, gv, gvl)
def decode(self):
self.encoded_str = self.clean()
startpos, endpos, gv, gvl = self.checkPalindrome(self.encoded_str)
if startpos == endpos:
raise Exception('No data!')
data = self.encoded_str[startpos:endpos]
b = ['___+', '__$+', '_$_+', '_$$+', '$__+', '$_$+', '$$_+', '$$$+', '$___+', '$__$+', '$_$_+', '$_$$+', '$$__+', '$$_$+', '$$$_+', '$$$$+']
str_l = '(![]+"")[' + gv + '._$_]+'
str_o = gv + '._$+'
str_t = gv + '.__+'
str_u = gv + '._+'
str_hex = gv + '.'
str_s = '"'
gvsig = gv + '.'
str_quote = '\\\\\\"'
str_slash = '\\\\\\\\'
str_lower = '\\\\"+'
str_upper = '\\\\"+' + gv + '._+'
str_end = '"+'
out = ''
while data != '':
# l o t u
if data.find(str_l) == 0:
data = data[len(str_l):]
out += 'l'
continue
elif data.find(str_o) == 0:
data = data[len(str_o):]
out += 'o'
continue
elif data.find(str_t) == 0:
data = data[len(str_t):]
out += 't'
continue
elif data.find(str_u) == 0:
data = data[len(str_u):]
out += 'u'
continue
# 0123456789abcdef
if data.find(str_hex) == 0:
data = data[len(str_hex):]
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
out += '%x' % i
break
continue
# start of s block
if data.find(str_s) == 0:
data = data[len(str_s):]
# check if "R
if data.find(str_upper) == 0: # r4 n >= 128
data = data[len(str_upper):] # skip sig
ch_str = ''
for i in range(2): # shouldn't be more than 2 hex chars
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
data = data[len(gvsig):]
for k in range(len(b)): # for every entry in b
if data.find(b[k]) == 0:
data = data[len(b[k]):]
ch_str = '%x' % k
break
else:
break
out += chr(int(ch_str, 16))
continue
elif data.find(str_lower) == 0: # r3 check if "R // n < 128
data = data[len(str_lower):] # skip sig
ch_str = ''
ch_lotux = ''
temp = ''
b_checkR1 = 0
for j in range(3): # shouldn't be more than 3 octal chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
temp = data[len(gvsig):]
for k in range(8): # for every entry in b octal
if temp.find(b[k]) == 0:
if int(ch_str + str(k), 8) > 128:
b_checkR1 = 1
break
ch_str += str(k)
data = data[len(gvsig):] # skip gvsig
data = data[len(b[k]):]
break
if b_checkR1 == 1:
if data.find(str_hex) == 0: # 0123456789abcdef
data = data[len(str_hex):]
# check every element of hex decode string for a match
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
ch_lotux = '%x' % i
break
break
else:
break
out += chr(int(ch_str, 8)) + ch_lotux
continue
else: # "S ----> "SR or "S+
# if there is, loop s until R 0r +
# if there is no matching s block, throw error
match = 0
n = None
# searching for matching pure s block
while True:
n = ord(data[0])
if data.find(str_quote) == 0:
data = data[len(str_quote):]
out += '"'
match += 1
continue
elif data.find(str_slash) == 0:
data = data[len(str_slash):]
out += '\\'
match += 1
continue
elif data.find(str_end) == 0: # reached end off S block ? +
if match == 0:
raise '+ no match S block: ' + data
data = data[len(str_end):]
break # step out of the while loop
elif data.find(str_upper) == 0: # r4 reached end off S block ? - check if "R n >= 128
if match == 0:
raise 'no match S block n>128: ' + data
data = data[len(str_upper):] # skip sig
ch_str = ''
ch_lotux = ''
for j in range(10): # shouldn't be more than 10 hex chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
data = data[len(gvsig):] # skip gvsig
for k in range(len(b)): # for every entry in b
if data.find(b[k]) == 0:
data = data[len(b[k]):]
ch_str += '%x' % k
break
else:
break # done
out += chr(int(ch_str, 16))
break # step out of the while loop
elif data.find(str_lower) == 0: # r3 check if "R // n < 128
if match == 0:
raise 'no match S block n<128: ' + data
data = data[len(str_lower):] # skip sig
ch_str = ''
ch_lotux = ''
temp = ''
b_checkR1 = 0
for j in range(3): # shouldn't be more than 3 octal chars
if j > 1: # lotu check
if data.find(str_l) == 0:
data = data[len(str_l):]
ch_lotux = 'l'
break
elif data.find(str_o) == 0:
data = data[len(str_o):]
ch_lotux = 'o'
break
elif data.find(str_t) == 0:
data = data[len(str_t):]
ch_lotux = 't'
break
elif data.find(str_u) == 0:
data = data[len(str_u):]
ch_lotux = 'u'
break
# gv + "."+b[ c ]
if data.find(gvsig) == 0:
temp = data[len(gvsig):]
for k in range(8): # for every entry in b octal
if temp.find(b[k]) == 0:
if int(ch_str + str(k), 8) > 128:
b_checkR1 = 1
break
ch_str += str(k)
data = data[len(gvsig):] # skip gvsig
data = data[len(b[k]):]
break
if b_checkR1 == 1:
if data.find(str_hex) == 0: # 0123456789abcdef
data = data[len(str_hex):]
# check every element of hex decode string for a match
for i in range(len(b)):
if data.find(b[i]) == 0:
data = data[len(b[i]):]
ch_lotux = '%x' % i
break
else:
break
out += chr(int(ch_str, 8)) + ch_lotux
break # step out of the while loop
elif (0x21 <= n and n <= 0x2f) or (0x3A <= n and n <= 0x40) or (0x5b <= n and n <= 0x60) or (0x7b <= n and n <= 0x7f):
out += data[0]
data = data[1:]
match += 1
continue
print 'No match : ' + data
break
return out