1 | # -*- coding: utf-8 -*- |
---|
2 | # Based on (root)/trunk/xbmc-addons/src/plugin.video.polishtv.live/hosts/ @ 419 - Wersja 636 |
---|
3 | # encoding=utf8 |
---|
4 | import sys |
---|
5 | |
---|
6 | reload(sys) |
---|
7 | sys.setdefaultencoding('utf8') |
---|
8 | |
---|
9 | import os |
---|
10 | import hashlib |
---|
11 | import sys |
---|
12 | from lib.net import Net |
---|
13 | import re |
---|
14 | import lib.ol_gmu as ol_gmu |
---|
15 | import lib.common as common |
---|
16 | import json |
---|
17 | from lib import jsunpack |
---|
18 | |
---|
19 | ################################################### |
---|
20 | import re |
---|
21 | import time |
---|
22 | import urllib |
---|
23 | import socket |
---|
24 | import string |
---|
25 | import base64 |
---|
26 | import math |
---|
27 | import lib.jjdecode as JJDecoder |
---|
28 | |
---|
29 | #OL_SOURCE = 'https://offshoregit.com/tvaresolvers/ol_gmu.py' |
---|
30 | OL_PATH = '' |
---|
31 | |
---|
32 | API_BASE_URL = 'https://api.openload.co/1' |
---|
33 | INFO_URL = API_BASE_URL + '/streaming/info' |
---|
34 | GET_URL = API_BASE_URL + '/streaming/get?file={media_id}' |
---|
35 | #OL_PATH = os.path.join(common.plugins_path, 'ol_gmu.py') |
---|
36 | |
---|
37 | |
---|
38 | import urllib |
---|
39 | import urllib2 |
---|
40 | try: import ssl |
---|
41 | except Exception: pass |
---|
42 | import re |
---|
43 | import string |
---|
44 | import time |
---|
45 | import htmlentitydefs |
---|
46 | import cookielib |
---|
47 | import unicodedata |
---|
48 | #import urllib2_ssl |
---|
49 | #try: import json |
---|
50 | #except Exception: import simplejson as json |
---|
51 | #try: |
---|
52 | # try: from cStringIO import StringIO |
---|
53 | # except Exception: from StringIO import StringIO |
---|
54 | # import gzip |
---|
55 | |
---|
56 | class OpenLoadResolver(object): |
---|
57 | name = "openload" |
---|
58 | # domains = ["openload.io", "openload.co"] |
---|
59 | # pattern = '(?://|\.)(openload\.(?:io|co))/(?:embed|f)/([0-9a-zA-Z-_]+)' |
---|
60 | domains = ["openload.io", "openload.co", "oload.tv", "oload.stream"] |
---|
61 | pattern = '(?://|\.)(o(?:pen)??load\.(?:io|co|tv|stream))/(?:embed|f)/([0-9a-zA-Z-_]+)' |
---|
62 | |
---|
63 | def __init__(self): |
---|
64 | self.net = Net(cookie_file='/mnt/network/cookies', cloudflare=True) |
---|
65 | self.headers = {'User-Agent': common.ANDROID_USER_AGENT} |
---|
66 | url = str(sys.argv[1]) |
---|
67 | host = self.get_host_and_id(url)[0] |
---|
68 | media_id = self.get_host_and_id(url)[1] |
---|
69 | |
---|
70 | return self.get_media_url(host, media_id) |
---|
71 | |
---|
72 | def get_host_and_id(self, url): |
---|
73 | r = re.search(self.pattern, url, re.I) |
---|
74 | if r: |
---|
75 | return r.groups() |
---|
76 | else: |
---|
77 | return False |
---|
78 | |
---|
79 | def i18n(string_id): |
---|
80 | try: |
---|
81 | return addon.getLocalizedString(strings.STRINGS[string_id]).encode('utf-8', 'ignore') |
---|
82 | except Exception as e: |
---|
83 | # log_utils.log('Failed String Lookup: %s (%s)' % (string_id, e)) |
---|
84 | return string_id |
---|
85 | |
---|
86 | def get_ol_code(self): |
---|
87 | try: |
---|
88 | new_py = self.net.http_GET(OL_SOURCE).content |
---|
89 | # common.log_utils.log('new_py: %s' % (new_pya)) |
---|
90 | |
---|
91 | if new_py: |
---|
92 | with open(OL_PATH, 'w') as f: |
---|
93 | f.write(new_py) |
---|
94 | except Exception as e: |
---|
95 | print 'errormsg=Exception during openload code retrieve:' |
---|
96 | # common.log_utils.log_warning('Exception during openload code retrieve: %s' % e) |
---|
97 | |
---|
98 | def decode1(self, encoded): |
---|
99 | tab = encoded.split('\\') |
---|
100 | ret = '' |
---|
101 | for item in tab: |
---|
102 | try: ret += chr(int(item, 8)) |
---|
103 | except Exception: |
---|
104 | ret += item |
---|
105 | return ret |
---|
106 | |
---|
107 | def base10toN(self, num,n): |
---|
108 | num_rep={10:'a', 11:'b',12:'c',13:'d',14:'e',15:'f',16:'g',17:'h',18:'i',19:'j',20:'k',21:'l',22:'m',23:'n',24:'o',25:'p',26:'q',27:'r',28:'s',29:'t',30:'u',31:'v',32:'w',33:'x',34:'y',35:'z'} |
---|
109 | new_num_string='' |
---|
110 | current=num |
---|
111 | while current!=0: |
---|
112 | remainder=current%n |
---|
113 | if 36>remainder>9: |
---|
114 | remainder_string=num_rep[remainder] |
---|
115 | elif remainder>=36: |
---|
116 | remainder_string='('+str(remainder)+')' |
---|
117 | else: |
---|
118 | remainder_string=str(remainder) |
---|
119 | new_num_string=remainder_string+new_num_string |
---|
120 | current=current/n |
---|
121 | return new_num_string |
---|
122 | |
---|
123 | def decodeOpenLoad(self, aastring): |
---|
124 | # decodeOpenLoad made by mortael, please leave this line for proper credit :) |
---|
125 | #aastring = re.search(r"<video(?:.|\s)*?<script\s[^>]*?>((?:.|\s)*?)</script", html, re.DOTALL | re.IGNORECASE).group(1) |
---|
126 | |
---|
127 | aastring = aastring.replace("(゚Д゚)[゚ε゚]+(o゚ー゚o)+ ((c^_^o)-(c^_^o))+ (-~0)+ (゚Д゚) ['c']+ (-~-~1)+","") |
---|
128 | aastring = aastring.replace("((゚ー゚) + (゚ー゚) + (゚Θ゚))", "9") |
---|
129 | aastring = aastring.replace("((゚ー゚) + (゚ー゚))","8") |
---|
130 | aastring = aastring.replace("((゚ー゚) + (o^_^o))","7") |
---|
131 | aastring = aastring.replace("((c^_^o)-(c^_^o))","0") |
---|
132 | aastring = aastring.replace("((゚ー゚) + (゚Θ゚))","5") |
---|
133 | aastring = aastring.replace("(゚ー゚)","4") |
---|
134 | aastring = aastring.replace("((o^_^o) - (゚Θ゚))","2") |
---|
135 | aastring = aastring.replace("(o^_^o)","3") |
---|
136 | aastring = aastring.replace("(゚Θ゚)","1") |
---|
137 | aastring = aastring.replace("(+!+[])","1") |
---|
138 | aastring = aastring.replace("(c^_^o)","0") |
---|
139 | aastring = aastring.replace("(0+0)","0") |
---|
140 | aastring = aastring.replace("(゚Д゚)[゚ε゚]","\\") |
---|
141 | aastring = aastring.replace("(3 +3 +0)","6") |
---|
142 | aastring = aastring.replace("(3 - 1 +0)","2") |
---|
143 | aastring = aastring.replace("(!+[]+!+[])","2") |
---|
144 | aastring = aastring.replace("(-~-~2)","4") |
---|
145 | aastring = aastring.replace("(-~-~1)","3") |
---|
146 | aastring = aastring.replace("(-~0)","1") |
---|
147 | aastring = aastring.replace("(-~1)","2") |
---|
148 | aastring = aastring.replace("(-~3)","4") |
---|
149 | aastring = aastring.replace("(0-0)","0") |
---|
150 | |
---|
151 | aastring = aastring.replace("(゚Д゚).゚ω゚ノ","10") |
---|
152 | aastring = aastring.replace("(゚Д゚).゚Θ゚ノ","11") |
---|
153 | aastring = aastring.replace("(゚Д゚)[\'c\']","12") |
---|
154 | aastring = aastring.replace("(゚Д゚).゚ー゚ノ","13") |
---|
155 | aastring = aastring.replace("(゚Д゚).゚Д゚ノ","14") |
---|
156 | aastring = aastring.replace("(゚Д゚)[゚Θ゚]","15") |
---|
157 | # print "aastring", aastring |
---|
158 | decodestring = re.search(r"\\\+([^(]+)", aastring, re.DOTALL | re.IGNORECASE).group(1) |
---|
159 | # decodestring = re.search(r"\\\+([^(]+)", aastring, re.DOTALL | re.IGNORECASE) |
---|
160 | decodestring = "\\+"+ decodestring |
---|
161 | decodestring = decodestring.replace("+","") |
---|
162 | decodestring = decodestring.replace(" ","") |
---|
163 | |
---|
164 | decodestring = self.decode1(decodestring) |
---|
165 | decodestring = decodestring.replace("\\/","/") |
---|
166 | |
---|
167 | if 'toString' in decodestring: |
---|
168 | base = re.compile(r"toString\(a\+(\d+)", re.DOTALL | re.IGNORECASE).findall(decodestring)[0] |
---|
169 | base = int(base) |
---|
170 | match = re.compile(r"(\(\d[^)]+\))", re.DOTALL | re.IGNORECASE).findall(decodestring) |
---|
171 | for repl in match: |
---|
172 | match1 = re.compile(r"(\d+),(\d+)", re.DOTALL | re.IGNORECASE).findall(repl) |
---|
173 | base2 = base + int(match1[0][0]) |
---|
174 | repl2 = self.base10toN(int(match1[0][1]),base2) |
---|
175 | decodestring = decodestring.replace(repl,repl2) |
---|
176 | decodestring = decodestring.replace("+","") |
---|
177 | decodestring = decodestring.replace("\"","") |
---|
178 | print "decodestring", decodestring |
---|
179 | return decodestring |
---|
180 | |
---|
181 | # def OPENLOADIO_decryptPlayerParams(p, a, c, k, e, d): |
---|
182 | def decryptPlayerParams(self, p, a, c, k, e, d): |
---|
183 | def e1(c): |
---|
184 | return c |
---|
185 | def e2(t=None): |
---|
186 | return '\\w+' |
---|
187 | def k1(matchobj): |
---|
188 | return d[int(matchobj.group(0))] |
---|
189 | e = e1 |
---|
190 | if True: |
---|
191 | while c != 0: |
---|
192 | c -= 1 |
---|
193 | d[c] = k[c] |
---|
194 | if c < len(k): |
---|
195 | d[c] = k[c] |
---|
196 | else: |
---|
197 | d[c] = c |
---|
198 | c = 1 |
---|
199 | k = [k1] |
---|
200 | e = e2 |
---|
201 | while c != 0: |
---|
202 | c -= 1 |
---|
203 | if k[c]: |
---|
204 | reg = '\\b' + e(c) + '\\b' |
---|
205 | p = re.sub(reg, k[c], p) |
---|
206 | return p |
---|
207 | |
---|
208 | def getAllItemsBeetwenNodes(self, data, node1, node2, withNodes=True, numNodes=-1, caseSensitive=True): |
---|
209 | if len(node1) < 2 or len(node2) < 2: |
---|
210 | return [] |
---|
211 | itemsTab = [] |
---|
212 | n1S = node1[0] |
---|
213 | n1E = node1[1] |
---|
214 | if len(node1) > 2: n1P = node1[2] |
---|
215 | else: n1P = None |
---|
216 | n2S = node2[0] |
---|
217 | n2E = node2[1] |
---|
218 | if len(node2) > 2: n2P = node2[2] |
---|
219 | else: n2P = None |
---|
220 | lastIdx = 0 |
---|
221 | search = 1 |
---|
222 | |
---|
223 | if caseSensitive: |
---|
224 | sData = data |
---|
225 | else: |
---|
226 | sData = data.lower() |
---|
227 | n1S = n1S.lower() |
---|
228 | n1E = n1E.lower() |
---|
229 | if n1P != None: n1P = n1P.lower() |
---|
230 | n2S = n2S.lower() |
---|
231 | n2E = n2E.lower() |
---|
232 | if n2P != None: n2P = n2P.lower() |
---|
233 | |
---|
234 | while True: |
---|
235 | if search == 1: |
---|
236 | # node 1 - start |
---|
237 | idx1 = sData.find(n1S, lastIdx) |
---|
238 | if -1 == idx1: return itemsTab |
---|
239 | lastIdx = idx1 + len(n1S) |
---|
240 | idx2 = sData.find(n1E, lastIdx) |
---|
241 | if -1 == idx2: return itemsTab |
---|
242 | lastIdx = idx2 + len(n1E) |
---|
243 | if n1P != None and sData.find(n1P, idx1 + len(n1S), idx2) == -1: |
---|
244 | continue |
---|
245 | search = 2 |
---|
246 | else: |
---|
247 | # node 2 - end |
---|
248 | tIdx1 = sData.find(n2S, lastIdx) |
---|
249 | if -1 == tIdx1: return itemsTab |
---|
250 | lastIdx = tIdx1 + len(n2S) |
---|
251 | tIdx2 = sData.find(n2E, lastIdx) |
---|
252 | if -1 == tIdx2: return itemsTab |
---|
253 | lastIdx = tIdx2 + len(n2E) |
---|
254 | |
---|
255 | if n2P != None and sData.find(n2P, tIdx1 + len(n2S), tIdx2) == -1: |
---|
256 | continue |
---|
257 | |
---|
258 | if withNodes: |
---|
259 | idx2 = tIdx2 + len(n2E) |
---|
260 | else: |
---|
261 | idx1 = idx2 + len(n1E) |
---|
262 | idx2 = tIdx1 |
---|
263 | search = 1 |
---|
264 | itemsTab.append(data[idx1:idx2]) |
---|
265 | if numNodes > 0 and len(itemsTab) == numNodes: |
---|
266 | break |
---|
267 | return itemsTab |
---|
268 | |
---|
269 | def getAllItemsBeetwenMarkers(self, data, marker1, marker2, withMarkers=True, caseSensitive=True): |
---|
270 | itemsTab = [] |
---|
271 | if caseSensitive: |
---|
272 | sData = data |
---|
273 | else: |
---|
274 | sData = data.lower() |
---|
275 | marker1 = marker1.lower() |
---|
276 | marker2 = marker2.lower() |
---|
277 | idx1 = 0 |
---|
278 | while True: |
---|
279 | idx1 = sData.find(marker1, idx1) |
---|
280 | if -1 == idx1: return itemsTab |
---|
281 | idx2 = sData.find(marker2, idx1 + len(marker1)) |
---|
282 | if -1 == idx2: return itemsTab |
---|
283 | tmpIdx2 = idx2 + len(marker2) |
---|
284 | if withMarkers: |
---|
285 | idx2 = tmpIdx2 |
---|
286 | else: |
---|
287 | idx1 = idx1 + len(marker1) |
---|
288 | itemsTab.append(data[idx1:idx2]) |
---|
289 | idx1 = tmpIdx2 |
---|
290 | return itemsTab |
---|
291 | |
---|
292 | def getSearchGroups(self, data, pattern, grupsNum=1, ignoreCase=False): |
---|
293 | tab = [] |
---|
294 | if ignoreCase: |
---|
295 | match = re.search(pattern, data, re.IGNORECASE) |
---|
296 | else: |
---|
297 | match = re.search(pattern, data) |
---|
298 | |
---|
299 | for idx in range(grupsNum): |
---|
300 | try: value = match.group(idx + 1) |
---|
301 | except Exception: value = '' |
---|
302 | tab.append(value) |
---|
303 | return tab |
---|
304 | |
---|
305 | def getPage(self, url, addParams = {}, post_data = None): |
---|
306 | ''' wraps getURLRequestData ''' |
---|
307 | try: |
---|
308 | addParams['url'] = url |
---|
309 | if 'return_data' not in addParams: |
---|
310 | addParams['return_data'] = True |
---|
311 | response = self.getURLRequestData(addParams, post_data) |
---|
312 | status = True |
---|
313 | except urllib2.HTTPError, e: |
---|
314 | # printExc() |
---|
315 | response = e |
---|
316 | status = False |
---|
317 | except Exception: |
---|
318 | # printExc() |
---|
319 | response = None |
---|
320 | status = False |
---|
321 | |
---|
322 | if addParams['return_data'] and status and not isinstance(response, basestring): |
---|
323 | status = False |
---|
324 | |
---|
325 | return (status, response) |
---|
326 | |
---|
327 | def GetTmpDir(self, file = ''): |
---|
328 | path = "/tmp/" |
---|
329 | path = path.replace('//', '/') |
---|
330 | self.mkdirs(path) |
---|
331 | return path + '/' + file |
---|
332 | |
---|
333 | def GetDukPath(self): |
---|
334 | # return "/tmp/localhoster/bin/duk.arm" |
---|
335 | arch = self.command("cat /etc/.arch") |
---|
336 | # print "arch", arch |
---|
337 | return "/tmp/localhoster/bin/duk.%s" % (arch) |
---|
338 | # return "/tmp/localhoster/bin/duk.sh4" |
---|
339 | |
---|
340 | # return config.plugins.iptvplayer.dukpath.value |
---|
341 | |
---|
342 | def iptv_js_execute(self, jscode): |
---|
343 | sts, tmpPath = self.CreateTmpFile('.iptv_js.js', jscode) |
---|
344 | if sts: |
---|
345 | cmd = self.GetDukPath() + ' ' + tmpPath + ' 2> /dev/null' |
---|
346 | # printDBG("iptv_js_execute cmd[%s]" % cmd) |
---|
347 | # print "iptv_js_execute cmd[%s]" % cmd |
---|
348 | # test = self.command(cmd); |
---|
349 | # print "test", test |
---|
350 | |
---|
351 | ret = self.command(cmd); |
---|
352 | # print "test3", os.system(cmd); |
---|
353 | |
---|
354 | # ret = iptv_execute()( cmd ) |
---|
355 | # ret = {'sts':False, 'code':-12, 'data':''} |
---|
356 | # leave last script for debug purpose |
---|
357 | # if getDebugMode() == '': |
---|
358 | # rm(tmpPath) |
---|
359 | else: |
---|
360 | ret = {'sts':False, 'code':-12, 'data':''} |
---|
361 | # printDBG('iptv_js_execute cmd ret[%s]' % ret) |
---|
362 | # print 'iptv_js_execute cmd ret[%s]' % ret |
---|
363 | |
---|
364 | return ret |
---|
365 | |
---|
366 | def mkdirs(self, newdir): |
---|
367 | """ Create a directory and all parent folders. |
---|
368 | Features: |
---|
369 | - parent directories will be created |
---|
370 | - if directory already exists, then do nothing |
---|
371 | - if there is another filsystem object with the same name, raise an exception |
---|
372 | """ |
---|
373 | # printDBG('mkdirs: "%s"' % newdir) |
---|
374 | # print 'mkdirs: "%s"' % newdir |
---|
375 | try: |
---|
376 | if os.path.isdir(newdir): |
---|
377 | pass |
---|
378 | elif os.path.isfile(newdir): |
---|
379 | # raise OSError("cannot create directory, file already exists: '%s'" % newdir) |
---|
380 | raise #print "cannot create directory, file already exists: '%s'" % newdir |
---|
381 | else: |
---|
382 | head, tail = os.path.split(newdir) |
---|
383 | if head and not os.path.isdir(head) and not os.path.ismount(head) and not os.path.islink(head): |
---|
384 | mkdirs(head) |
---|
385 | if tail: |
---|
386 | os.mkdir(newdir) |
---|
387 | return True |
---|
388 | except Exception: |
---|
389 | # printExc('!!!!!!!!!! EXCEPTION mkdirs["%s"]' % newdir) |
---|
390 | print '!!!!!!!!!! EXCEPTION mkdirs["%s"]' % newdir |
---|
391 | return False |
---|
392 | |
---|
393 | def CreateTmpFile(self, filename, data=''): |
---|
394 | sts = False |
---|
395 | filePath = self.GetTmpDir(filename) |
---|
396 | try: |
---|
397 | with open(filePath, 'w') as f: |
---|
398 | f.write(data) |
---|
399 | sts = True |
---|
400 | except Exception: |
---|
401 | printExc() |
---|
402 | return sts, filePath |
---|
403 | |
---|
404 | def getDataBeetwenMarkers(self, data, marker1, marker2, withMarkers=True, caseSensitive=True): |
---|
405 | if caseSensitive: |
---|
406 | idx1 = data.find(marker1) |
---|
407 | else: |
---|
408 | idx1 = data.lower().find(marker1.lower()) |
---|
409 | if -1 == idx1: return False, '' |
---|
410 | if caseSensitive: |
---|
411 | idx2 = data.find(marker2, idx1 + len(marker1)) |
---|
412 | else: |
---|
413 | idx2 = data.lower().find(marker2.lower(), idx1 + len(marker1)) |
---|
414 | if -1 == idx2: return False, '' |
---|
415 | |
---|
416 | if withMarkers: |
---|
417 | idx2 = idx2 + len(marker2) |
---|
418 | else: |
---|
419 | idx1 = idx1 + len(marker1) |
---|
420 | |
---|
421 | return True, data[idx1:idx2] |
---|
422 | |
---|
423 | # edit bb , touch commands.getouput with this def # |
---|
424 | def command(self, comandline, strip=1): |
---|
425 | comandline = comandline + " >/tmp/command.txt" |
---|
426 | os.system(comandline) |
---|
427 | text = "" |
---|
428 | if os.path.exists("/tmp/command.txt") is True: |
---|
429 | file = open("/tmp/command.txt", "r") |
---|
430 | if strip == 1: |
---|
431 | for line in file: |
---|
432 | text = text + line.strip() + '\n' |
---|
433 | else: |
---|
434 | for line in file: |
---|
435 | text = text + line |
---|
436 | if text[-1:] != '\n': text = text + "\n" |
---|
437 | file.close |
---|
438 | # if one or last line then remove linefeed |
---|
439 | if text[-1:] == '\n': text = text[:-1] |
---|
440 | comandline = text |
---|
441 | os.system("rm /tmp/command.txt") |
---|
442 | return comandline |
---|
443 | |
---|
444 | def decode(self,code, parseInt, _0x59ce16, _1x4bfb36): |
---|
445 | |
---|
446 | import math |
---|
447 | |
---|
448 | _0x1bf6e5 = '' |
---|
449 | ke = [] |
---|
450 | |
---|
451 | for i in range(0, len(code[0:9*8]),8): |
---|
452 | ke.append(int(code[i:i+8],16)) |
---|
453 | |
---|
454 | _0x439a49 = 0 |
---|
455 | _0x145894 = 0 |
---|
456 | |
---|
457 | while _0x439a49 < len(code[9*8:]): |
---|
458 | _0x5eb93a = 64 |
---|
459 | _0x896767 = 0 |
---|
460 | _0x1a873b = 0 |
---|
461 | _0x3c9d8e = 0 |
---|
462 | while True: |
---|
463 | if _0x439a49 + 1 >= len(code[9*8:]): |
---|
464 | _0x5eb93a = 143; |
---|
465 | |
---|
466 | _0x3c9d8e = int(code[9*8+_0x439a49:9*8+_0x439a49+2], 16) |
---|
467 | _0x439a49 +=2 |
---|
468 | |
---|
469 | if _0x1a873b < 6*5: |
---|
470 | _0x332549 = _0x3c9d8e & 63 |
---|
471 | _0x896767 += _0x332549 << _0x1a873b |
---|
472 | else: |
---|
473 | _0x332549 = _0x3c9d8e & 63 |
---|
474 | _0x896767 += int(_0x332549 * math.pow(2, _0x1a873b)) |
---|
475 | |
---|
476 | _0x1a873b += 6 |
---|
477 | if not _0x3c9d8e >= _0x5eb93a: break |
---|
478 | |
---|
479 | # _0x30725e = _0x896767 ^ ke[_0x145894 % 9] ^ _0x59ce16 ^ parseInt ^ _1x4bfb36 |
---|
480 | _0x30725e = _0x896767 ^ ke[_0x145894 % 9] ^ parseInt ^ _1x4bfb36 |
---|
481 | _0x2de433 = _0x5eb93a * 2 + 127 |
---|
482 | |
---|
483 | for i in range(4): |
---|
484 | _0x3fa834 = chr(((_0x30725e & _0x2de433) >> (9*8/ 9)* i) - 1) |
---|
485 | if _0x3fa834 != '$': |
---|
486 | _0x1bf6e5 += _0x3fa834 |
---|
487 | _0x2de433 = (_0x2de433 << (9*8/ 9)) |
---|
488 | |
---|
489 | _0x145894 += 1 |
---|
490 | |
---|
491 | |
---|
492 | url = "https://openload.co/stream/%s?mime=true" % _0x1bf6e5 |
---|
493 | return url |
---|
494 | |
---|
495 | def get_media_url(self, host, media_id): |
---|
496 | web_url = self.get_url(host, media_id) |
---|
497 | # web_url = "https://openload.co/embed/SVMiyZR_yM4/Game_of_Thrones_S07E07_Der_Drache_und_der_Wolf_German_AC3_Dubbed_AmazonHD.mkv" |
---|
498 | # web_url = "https://openload.co/embed/8ATYb_yCakU/pso-atomic_ts.sd.mkv" |
---|
499 | headers = { |
---|
500 | 'Referer': web_url |
---|
501 | } |
---|
502 | headers.update(self.headers) |
---|
503 | data = self.net.http_GET(web_url, headers=headers).content |
---|
504 | ret = self.net.save_cookies('/mnt/network/cookies') |
---|
505 | |
---|
506 | # print "data", data |
---|
507 | baseUrl = web_url |
---|
508 | # baseUrl = "https://openload.co/embed/SVMiyZR_yM4/Game_of_Thrones_S07E07_Der_Drache_und_der_Wolf_German_AC3_Dubbed_AmazonHD.mkv" |
---|
509 | HTTP_HEADER= { 'User-Agent':"Mozilla/5.0", 'Referer':baseUrl} |
---|
510 | HTTP_HEADER = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', |
---|
511 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', |
---|
512 | 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', |
---|
513 | 'Accept-Encoding': 'none', |
---|
514 | 'Accept-Language': 'en-US,en;q=0.8', |
---|
515 | 'Referer':baseUrl} #'Connection': 'keep-alive' |
---|
516 | |
---|
517 | # sts, data = self.getPage(baseUrl, {'header':HTTP_HEADER}) |
---|
518 | # data = self.net.http_GET(web_url, headers=headers).content |
---|
519 | |
---|
520 | orgData = data |
---|
521 | # print "data", data |
---|
522 | |
---|
523 | #################### |
---|
524 | videoTab = [] |
---|
525 | code = self.getSearchGroups(data, '<p style="" id="[^"]+">(.*?)</p>' )[0] |
---|
526 | _0x59ce16 = eval(self.getSearchGroups(data, '_0x59ce16=([^;]+)')[0].replace('parseInt', 'int')) |
---|
527 | _1x4bfb36 = eval(self.getSearchGroups(data, '_1x4bfb36=([^;]+)')[0].replace('parseInt', 'int')) |
---|
528 | parseInt = eval(self.getSearchGroups(data, '_0x30725e,(\(parseInt.*?)\),')[0].replace('parseInt', 'int')) |
---|
529 | url = self.decode(code, parseInt, _0x59ce16, _1x4bfb36) |
---|
530 | print url |
---|
531 | return None |
---|
532 | #url2 = self.cm.getPage(url).headers.get('location') |
---|
533 | #print "url2",url2 |
---|
534 | #videoTab.append(('mp4',url)) |
---|
535 | #videoTab.append({'url': url, 'name': 'openload.co (mp4)'}) |
---|
536 | #print "videoTab",videoTab |
---|
537 | |
---|
538 | #return videoTab |
---|
539 | # sts, data = self.cm.getPage(url, defaultParams) |
---|
540 | # print "data",data |
---|
541 | |
---|
542 | #################### |
---|
543 | # print "222222222222222222222222" |
---|
544 | if re.search('Sorry!</h3>', data): |
---|
545 | print 'errormsg=%s %s' % (str(re.compile('<h3>(.*)</h3>').findall(data)[0]), str(re.compile('<h6>(.*)</h6>').findall(data)[0])) |
---|
546 | |
---|
547 | subTracksData = self.getAllItemsBeetwenMarkers(data, '<track ', '>', False, False) |
---|
548 | subTracks = [] |
---|
549 | for track in subTracksData: |
---|
550 | if 'kind="captions"' not in track: continue |
---|
551 | subUrl = self.getSearchGroups(track, 'src="([^"]+?)"')[0] |
---|
552 | # print "suburl", subUrl |
---|
553 | if subUrl.startswith('/'): |
---|
554 | subUrl = 'http://openload.co' + subUrl |
---|
555 | if subUrl.startswith('http'): |
---|
556 | subLang = self.getSearchGroups(track, 'srclang="([^"]+?)"')[0] |
---|
557 | subLabel = self.getSearchGroups(track, 'label="([^"]+?)"')[0] |
---|
558 | subTracks.append({'title':subLabel + '_' + subLang, 'url':subUrl, 'lang':subLang, 'format':'srt'}) |
---|
559 | |
---|
560 | videoUrl = '' |
---|
561 | tmp = self.getAllItemsBeetwenNodes(data, ('<div', '>', 'display:none'), ('</div', '>')) |
---|
562 | for item in tmp: |
---|
563 | encTab = re.compile('''<[^>]+?id="[^"]*?"[^>]*?>([^<]+?)<''').findall(data) |
---|
564 | for e in encTab: |
---|
565 | if len(e) > 40: |
---|
566 | encTab.insert(0, e) |
---|
567 | break |
---|
568 | |
---|
569 | def __decode_k(enc, jscode): |
---|
570 | decoded = '' |
---|
571 | tmpPath = '' |
---|
572 | try: |
---|
573 | jscode = base64.b64decode('''ICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSAiJXMiDQogICAgICAgICAgICAgICAgICAgICAgLCBkZWNvZGVkDQogICAgICAgICAgICAgICAgICAgICAgLCBkb2N1bWVudCA9IHt9DQogICAgICAgICAgICAgICAgICAgICAgLCB3aW5kb3cgPSB0aGlzDQogICAgICAgICAgICAgICAgICAgICAgLCAkID0gZnVuY3Rpb24oKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBmdW5jdGlvbihhKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGEpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29kZWQgPSBhOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWQ7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkeTogZnVuY3Rpb24oYSl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhKCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH07DQogICAgICAgICAgICAgICAgICAgIChmdW5jdGlvbihkLCB3KXsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgZiA9IGZ1bmN0aW9uKCl7fTsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgcyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgIHZhciBvID0gbnVsbDsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgYiA9IGZhbHNlOw0KICAgICAgICAgICAgICAgICAgICAgIHZhciBuID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgZGYgPSBbJ2Nsb3NlJywnY3JlYXRlQXR0cmlidXRlJywnY3JlYXRlRG9jdW1lbnRGcmFnbWVudCcsJ2NyZWF0ZUVsZW1lbnQnLCdjcmVhdGVFbGVtZW50TlMnLCdjcmVhdGVFdmVudCcsJ2NyZWF0ZU5TUmVzb2x2ZXInLCdjcmVhdGVSYW5nZScsJ2NyZWF0ZVRleHROb2RlJywnY3JlYXRlVHJlZVdhbGtlcicsJ2V2YWx1YXRlJywnZXhlY0NvbW1hbmQnLCdnZXRFbGVtZW50QnlJZCcsJ2dldEVsZW1lbnRzQnlOYW1lJywnZ2V0RWxlbWVudHNCeVRhZ05hbWUnLCdpbXBvcnROb2RlJywnb3BlbicsJ3F1ZXJ5Q29tbWFuZEVuYWJsZWQnLCdxdWVyeUNvbW1hbmRJbmRldGVybScsJ3F1ZXJ5Q29tbWFuZFN0YXRlJywncXVlcnlDb21tYW5kVmFsdWUnLCd3cml0ZScsJ3dyaXRlbG4nXTsNCiAgICAgICAgICAgICAgICAgICAgICBkZi5mb3JFYWNoKGZ1bmN0aW9uKGUpe2RbZV09Zjt9KTsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9fID0gWydhbmNob3JzJywnYXBwbGV0cycsJ2JvZHknLCdkZWZhdWx0VmlldycsJ2RvY3R5cGUnLCdkb2N1bWVudEVsZW1lbnQnLCdlbWJlZHMnLCdmaXJzdENoaWxkJywnZm9ybXMnLCdpbWFnZXMnLCdpbXBsZW1lbnRhdGlvbicsJ2xpbmtzJywnbG9jYXRpb24nLCdwbHVnaW5zJywnc3R5bGVTaGVldHMnXTsNCiAgICAgICAgICAgICAgICAgICAgICBkb18uZm9yRWFjaChmdW5jdGlvbihlKXtkW2VdPW87fSk7DQogICAgICAgICAgICAgICAgICAgICAgdmFyIGRzID0gWydVUkwnLCdjaGFyYWN0ZXJTZXQnLCdjb21wYXRNb2RlJywnY29udGVudFR5cGUnLCdjb29raWUnLCdkZXNpZ25Nb2RlJywnZG9tYWluJywnbGFzdE1vZGlmaWVkJywncmVmZXJyZXInLCd0aXRsZSddOw0KICAgICAgICAgICAgICAgICAgICAgIGRzLmZvckVhY2goZnVuY3Rpb24oZSl7ZFtlXT1zO30pOw0KICAgICAgICAgICAgICAgICAgICAgIHZhciB3YiA9IFsnY2xvc2VkJywnaXNTZWN1cmVDb250ZXh0J107DQogICAgICAgICAgICAgICAgICAgICAgd2IuZm9yRWFjaChmdW5jdGlvbihlKXt3W2VdPWI7fSk7DQogICAgICAgICAgICAgICAgICAgICAgdmFyIHdmID0gWydhZGRFdmVudExpc3RlbmVyJywnYWxlcnQnLCdhdG9iJywnYmx1cicsJ2J0b2EnLCdjYW5jZWxBbmltYXRpb25GcmFtZScsJ2NhcHR1cmVFdmVudHMnLCdjbGVhckludGVydmFsJywnY2xlYXJUaW1lb3V0JywnY2xvc2UnLCdjb25maXJtJywnY3JlYXRlSW1hZ2VCaXRtYXAnLCdkaXNwYXRjaEV2ZW50JywnZmV0Y2gnLCdmaW5kJywnZm9jdXMnLCdnZXRDb21wdXRlZFN0eWxlJywnZ2V0U2VsZWN0aW9uJywnbWF0Y2hNZWRpYScsJ21vdmVCeScsJ21vdmVUbycsJ29wZW4nLCdwb3N0TWVzc2FnZScsJ3Byb21wdCcsJ3JlbGVhc2VFdmVudHMnLCdyZW1vdmVFdmVudExpc3RlbmVyJywncmVxdWVzdEFuaW1hdGlvbkZyYW1lJywncmVzaXplQnknLCdyZXNpemVUbycsJ3Njcm9sbCcsJ3Njcm9sbEJ5Jywnc2Nyb2xsVG8nLCdzZXRJbnRlcnZhbCcsJ3NldFRpbWVvdXQnLCdzdG9wJ107DQogICAgICAgICAgICAgICAgICAgICAgd2YuZm9yRWFjaChmdW5jdGlvbihlKXt3W2VdPWY7fSk7DQogICAgICAgICAgICAgICAgICAgICAgdmFyIHduID0gWydkZXZpY2VQaXhlbFJhdGlvJywnaW5uZXJIZWlnaHQnLCdpbm5lcldpZHRoJywnbGVuZ3RoJywnb3V0ZXJIZWlnaHQnLCdvdXRlcldpZHRoJywncGFnZVhPZmZzZXQnLCdwYWdlWU9mZnNldCcsJ3NjcmVlblgnLCdzY3JlZW5ZJywnc2Nyb2xsWCcsJ3Njcm9sbFknXTsNCiAgICAgICAgICAgICAgICAgICAgICB3bi5mb3JFYWNoKGZ1bmN0aW9uKGUpe3dbZV09bjt9KTsNCiAgICAgICAgICAgICAgICAgICAgICB2YXIgd28gPSBbJ2FwcGxpY2F0aW9uQ2FjaGUnLCdjYWNoZXMnLCdjcnlwdG8nLCdleHRlcm5hbCcsJ2ZyYW1lRWxlbWVudCcsJ2ZyYW1lcycsJ2hpc3RvcnknLCdpbmRleGVkREInLCdsb2NhbFN0b3JhZ2UnLCdsb2NhdGlvbicsJ2xvY2F0aW9uYmFyJywnbWVudWJhcicsJ25hdmlnYXRvcicsJ29uYWJvcnQnLCdvbmFuaW1hdGlvbmVuZCcsJ29uYW5pbWF0aW9uaXRlcmF0aW9uJywnb25hbmltYXRpb25zdGFydCcsJ29uYmVmb3JldW5sb2FkJywnb25ibHVyJywnb25jYW5wbGF5Jywnb25jYW5wbGF5dGhyb3VnaCcsJ29uY2hhbmdlJywnb25jbGljaycsJ29uY29udGV4dG1lbnUnLCdvbmRibGNsaWNrJywnb25kZXZpY2Vtb3Rpb24nLCdvbmRldmljZW9yaWVudGF0aW9uJywnb25kcmFnJywnb25kcmFnZW5kJywnb25kcmFnZW50ZXInLCdvbmRyYWdsZWF2ZScsJ29uZHJhZ292ZXInLCdvbmRyYWdzdGFydCcsJ29uZHJvcCcsJ29uZHVyYXRpb25jaGFuZ2UnLCdvbmVtcHRpZWQnLCdvbmVuZGVkJywnb25lcnJvcicsJ29uZm9jdXMnLCdvbmhhc2hjaGFuZ2UnLCdvbmlucHV0Jywnb25pbnZhbGlkJywnb25rZXlkb3duJywnb25rZXlwcmVzcycsJ29ua2V5dXAnLCdvbmxhbmd1YWdlY2hhbmdlJywnb25sb2FkJywnb25sb2FkZWRkYXRhJywnb25sb2FkZWRtZXRhZGF0YScsJ29ubG9hZHN0YXJ0Jywnb25tZXNzYWdlJywnb25tb3VzZWRvd24nLCdvbm1vdXNlZW50ZXInLCdvbm1vdXNlbGVhdmUnLCdvbm1vdXNlbW92ZScsJ29ubW91c2VvdXQnLCdvbm1vdXNlb3ZlcicsJ29ubW91c2V1cCcsJ29ub2ZmbGluZScsJ29ub25saW5lJywnb25wYWdlaGlkZScsJ29ucGFnZXNob3cnLCdvbnBhdXNlJywnb25wbGF5Jywnb25wbGF5aW5nJywnb25wb3BzdGF0ZScsJ29ucHJvZ3Jlc3MnLCdvbnJhdGVjaGFuZ2UnLCdvbnJlc2V0Jywnb25yZXNpemUnLCdvbnNjcm9sbCcsJ29uc2Vla2VkJywnb25zZWVraW5nJywnb25zZWxlY3QnLCdvbnNob3cnLCdvbnN0YWxsZWQnLCdvbnN0b3JhZ2UnLCdvbnN1Ym1pdCcsJ29uc3VzcGVuZCcsJ29udGltZXVwZGF0ZScsJ29udG9nZ2xlJywnb250cmFuc2l0aW9uZW5kJywnb251bmxvYWQnLCdvbnZvbHVtZWNoYW5nZScsJ29ud2FpdGluZycsJ29ud2Via2l0YW5pbWF0aW9uZW5kJywnb253ZWJraXRhbmltYXRpb25pdGVyYXRpb24nLCdvbndlYmtpdGFuaW1hdGlvbnN0YXJ0Jywnb253ZWJraXR0cmFuc2l0aW9uZW5kJywnb253aGVlbCcsJ29wZW5lcicsJ3BhcmVudCcsJ3BlcmZvcm1hbmNlJywncGVyc29uYWxiYXInLCdzY3JlZW4nLCdzY3JvbGxiYXJzJywnc2VsZicsJ3Nlc3Npb25TdG9yYWdlJywnc3BlZWNoU3ludGhlc2lzJywnc3RhdHVzYmFyJywndG9vbGJhcicsJ3RvcCddOw0KICAgICAgICAgICAgICAgICAgICAgIHdvLmZvckVhY2goZnVuY3Rpb24oZSl7d1tlXT1vO30pOw0KICAgICAgICAgICAgICAgICAgICAgIHZhciB3cyA9IFsnbmFtZSddOw0KICAgICAgICAgICAgICAgICAgICAgIHdzLmZvckVhY2goZnVuY3Rpb24oZSl7d1tlXT1zO30pOw0KICAgICAgICAgICAgICAgICAgICB9KShkb2N1bWVudCwgd2luZG93KTsNCiAgICAgICAgICAgICAgICAgICAgJXM7DQogICAgICAgICAgICAgICAgICAgIHByaW50KGRlY29kZWQpOw==''') % (enc, jscode) |
---|
574 | # printDBG("+++++++++++++++++++++++ CODE ++++++++++++++++++++++++") |
---|
575 | # printDBG(jscode) |
---|
576 | # printDBG("+++++++++++++++++++++++++++++++++++++++++++++++++++++++") |
---|
577 | # print "+++++++++++++++++++++++ CODE ++++++++++++++++++++++++" |
---|
578 | # print jscode |
---|
579 | # print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++" |
---|
580 | # return self.iptv_js_execute( jscode ) |
---|
581 | return self.iptv_js_execute( jscode ) |
---|
582 | |
---|
583 | # ret = self.iptv_js_execute( jscode ) |
---|
584 | # if ret['sts'] and 0 == ret['code']: |
---|
585 | # decoded = ret['data'].strip() |
---|
586 | # printDBG('DECODED DATA -> [%s]' % decoded) |
---|
587 | except Exception: |
---|
588 | # printExc() |
---|
589 | print "__decode_k error" |
---|
590 | |
---|
591 | #rm(tmpPath) |
---|
592 | return decoded |
---|
593 | |
---|
594 | # marker = '゚ω゚ノ= /`m´)ノ' |
---|
595 | marker = '゚ω゚ノ= /`m' |
---|
596 | |
---|
597 | # marker = '゚ω゚' |
---|
598 | |
---|
599 | orgData = marker + self.getDataBeetwenMarkers(orgData, marker, marker, False)[1] |
---|
600 | orgData = re.sub('''if\s*\([^\}]+?typeof[^\}]+?\}''', '', orgData) |
---|
601 | orgData = re.sub('''if\s*\([^\}]+?document[^\}]+?\}''', '', orgData) |
---|
602 | # dec = self.__decode_k(encTab[0], orgData) |
---|
603 | dec = __decode_k(encTab[0], orgData) |
---|
604 | |
---|
605 | videoUrl = 'https://openload.co/stream/{0}?mime=true'.format(dec) |
---|
606 | params = dict(HTTP_HEADER) |
---|
607 | params['external_sub_tracks'] = subTracks |
---|
608 | print videoUrl |
---|
609 | # print "params:", params |
---|
610 | |
---|
611 | |
---|
612 | def get_url(self, host, media_id): |
---|
613 | return 'https://openload.co/embed/%s' % (media_id) |
---|
614 | |
---|
615 | def __auth_ip(self, media_id): |
---|
616 | js_data = self.__get_json(INFO_URL) |
---|
617 | pair_url = js_data.get('result', {}).get('auth_url', '') |
---|
618 | if pair_url: |
---|
619 | pair_url = pair_url.replace('\/', '/') |
---|
620 | header = i18n('ol_auth_header') |
---|
621 | line1 = i18n('auth_required') |
---|
622 | line2 = i18n('visit_link') |
---|
623 | line3 = i18n('click_pair') % (pair_url) |
---|
624 | with common.kodi.CountdownDialog(header, line1, line2, line3) as cd: |
---|
625 | return cd.start(self.__check_auth, [media_id]) |
---|
626 | |
---|
627 | def __check_auth(self, media_id): |
---|
628 | try: |
---|
629 | js_data = self.__get_json(GET_URL.format(media_id=media_id)) |
---|
630 | except ResolverError as e: |
---|
631 | # except Exception as e: |
---|
632 | status, mscommandg = e |
---|
633 | if status == 403: |
---|
634 | print "errormsg=%s" % (e) |
---|
635 | return |
---|
636 | else: |
---|
637 | print "errormsg=%s" % (msg) |
---|
638 | # raise ResolverError(msg) |
---|
639 | |
---|
640 | return js_data.get('result', {}).get('url') |
---|
641 | |
---|
642 | def __get_json(self, url): |
---|
643 | result = self.net.http_GET(url).content |
---|
644 | js_result = json.loads(result) |
---|
645 | # common.log_utils.log_debug(js_result) |
---|
646 | # if js_result['status'] != 200: |
---|
647 | # raise ResolverError(js_result['status'], js_result['msg']) |
---|
648 | return js_result |
---|
649 | |
---|
650 | |
---|
651 | sys.stdout = OpenLoadResolver() |
---|