Enigma2 plugin to to play various online streams (mostly Latvian).

openload2.py0 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. # -*- coding: UTF-8 -*-
  2. # /*
  3. # * Copyright (C) 2015 Lubomir Kucera
  4. # *
  5. # *
  6. # * This Program is free software; you can redistribute it and/or modify
  7. # * it under the terms of the GNU General Public License as published by
  8. # * the Free Software Foundation; either version 2, or (at your option)
  9. # * any later version.
  10. # *
  11. # * This Program is distributed in the hope that it will be useful,
  12. # * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # * GNU General Public License for more details.
  15. # *
  16. # * You should have received a copy of the GNU General Public License
  17. # * along with this program; see the file COPYING. If not, write to
  18. # * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19. # * http://www.gnu.org/copyleft/gpl.html
  20. # *
  21. # */
  22. import re,os,sys
  23. try:
  24. import util
  25. except:
  26. pp = os.path.dirname(os.path.abspath(__file__))
  27. sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
  28. import util
  29. import urllib2
  30. from aadecode import AADecoder
  31. __author__ = 'Jose Riha/Lubomir Kucera'
  32. __name__ = 'openload2'
  33. def supports(url):
  34. #return re.search(r'openload\.\w+/embed/.+', url) is not None
  35. return False
  36. # uses code fragments from https://github.com/LordVenom/venom-xbmc-addons
  37. def resolve(url):
  38. stream = util.item()
  39. stream["url"]=get_media_url(url)
  40. ### Retrieve subtitles ####
  41. HTTP_HEADER = {
  42. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
  43. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  44. 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
  45. 'Accept-Encoding': 'none',
  46. 'Accept-Language': 'en-US,en;q=0.8',
  47. 'Referer': url} # 'Connection': 'keep-alive'
  48. html = requests.get(url, headers=HTTP_HEADER).content
  49. m = re.search('<track kind="captions" src="([^"]+)" srclang="([^"]+)" label="([^"]+)"', html)
  50. if m:
  51. stream["subs"] = m.group(1)
  52. stream["lang"] = m.group(2)
  53. return [stream]
  54. txt = """
  55. openload.io urlresolver plugin
  56. Copyright (C) 2015 tknorris
  57. This program is free software: you can redistribute it and/or modify
  58. it under the terms of the GNU General Public License as published by
  59. the Free Software Foundation, either version 3 of the License, or
  60. (at your option) any later version.
  61. This program is distributed in the hope that it will be useful,
  62. but WITHOUT ANY WARRANTY; without even the implied warranty of
  63. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64. GNU General Public License for more details.
  65. You should have received a copy of the GNU General Public License
  66. along with this program. If not, see <http://www.gnu.org/licenses/>.
  67. """
  68. import urllib
  69. import re
  70. import urllib2
  71. from HTMLParser import HTMLParser
  72. import requests
  73. #from lib.net import Net
  74. #from urlresolver import common
  75. #from urlresolver.resolver import ResolverError
  76. #net = Net() #III
  77. SIZE_LIMIT = 32 * 1024 * 1024
  78. def caesar_shift(s, shift=13):
  79. s2 = ''
  80. for c in s:
  81. if c.isalpha():
  82. limit = 90 if c <= 'Z' else 122
  83. new_code = ord(c) + shift
  84. if new_code > limit:
  85. new_code -= 26
  86. s2 += chr(new_code)
  87. else:
  88. s2 += c
  89. return s2
  90. def unpack(html):
  91. strings = re.findall('{\s*var\s+a\s*=\s*"([^"]+)', html)
  92. shifts = re.findall('\)\);}\((\d+)\)', html)
  93. for s, shift in zip(strings, shifts):
  94. s = caesar_shift(s, int(shift))
  95. s = urllib.unquote(s)
  96. for i, replace in enumerate(['j', '_', '__', '___']):
  97. s = s.replace(str(i), replace)
  98. html += '<script>%s</script>' % (s)
  99. return html
  100. def get_media_url(url):
  101. HTTP_HEADER = {
  102. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
  103. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  104. 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
  105. 'Accept-Encoding': 'none',
  106. 'Accept-Language': 'en-US,en;q=0.8',
  107. 'Referer': url} # 'Connection': 'keep-alive'
  108. #html = net.http_GET(url, headers=HTTP_HEADER).content
  109. html = requests.get(url, headers=HTTP_HEADER).content
  110. try: html = html.encode('utf-8')
  111. except: pass
  112. html = unpack(html)
  113. #match = re.search('''>([^<]+)</span>\s*<span\s+id="streamurl"''', html, re.DOTALL | re.IGNORECASE)
  114. match = re.search(r'<span[^>]*>([^<]+)</span>\s*<span[^>]*>[^<]+</span>\s*<span[^>]+id="streamurl"', html, re.DOTALL | re.IGNORECASE)
  115. if not match:
  116. raise Exception('Stream Url Not Found. Deleted?')
  117. hiddenurl = HTMLParser().unescape(match.group(1))
  118. decodes = []
  119. for match in re.finditer('<script[^>]*>(.*?)</script>', html, re.DOTALL):
  120. encoded = match.group(1)
  121. match = re.search("(゚ω゚ノ.*?\('_'\);)", encoded, re.DOTALL)
  122. if match:
  123. decodes.append(AADecoder(match.group(1)).decode())
  124. match = re.search('(.=~\[\].*\(\);)', encoded, re.DOTALL)
  125. if match:
  126. decodes.append(JJDecoder(match.group(1)).decode())
  127. if not decodes:
  128. raise Exception('No Encoded Section Found. Deleted?')
  129. magic_number = 0
  130. for decode in decodes:
  131. match = re.search('charCodeAt\(\d+\)\s*\+\s*(\d+)\)', decode, re.DOTALL | re.I)
  132. if match:
  133. magic_number = match.group(1)
  134. break
  135. s = []
  136. for idx, i in enumerate(hiddenurl):
  137. j = ord(i)
  138. if (j >= 33 & j <= 126):
  139. j = 33 + ((j + 14) % 94)
  140. if idx == len(hiddenurl) - 1:
  141. j += int(magic_number)
  142. s.append(chr(j))
  143. res = ''.join(s)
  144. videoUrl = 'https://openload.co/stream/{0}?mime=true'.format(res)
  145. dtext = videoUrl.replace('https', 'http')
  146. headers = HTTP_HEADER = {
  147. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0',
  148. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  149. 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
  150. 'Accept-Encoding': 'none',
  151. 'Accept-Language': 'en-US,en;q=0.8',
  152. 'Referer': url} # 'Connection': 'keep-alive'
  153. req = urllib2.Request(dtext, None, headers)
  154. res = urllib2.urlopen(req)
  155. videourl = res.geturl()
  156. #if int(res.headers['Content-Length']) < SIZE_LIMIT:
  157. #raise Exception('Openload.co resolve failed. Pigeons?')
  158. res.close()
  159. return videourl
  160. # -*- coding: utf-8 -*-
  161. # ------------------------------------------------------------
  162. # pelisalacarta - XBMC Plugin
  163. # Conector for openload.io
  164. # http://blog.tvalacarta.info/plugin-xbmc/pelisalacarta/
  165. # by DrZ3r0
  166. # ------------------------------------------------------------
  167. # Modified by Shani
  168. import re
  169. #from urlresolver import common
  170. #import common
  171. class AADecoder(object):
  172. def __init__(self, aa_encoded_data):
  173. self.encoded_str = aa_encoded_data.replace('/*´∇`*/', '')
  174. self.b = ["(c^_^o)", "(゚Θ゚)", "((o^_^o) - (゚Θ゚))", "(o^_^o)",
  175. "(゚ー゚)", "((゚ー゚) + (゚Θ゚))", "((o^_^o) +(o^_^o))", "((゚ー゚) + (o^_^o))",
  176. "((゚ー゚) + (゚ー゚))", "((゚ー゚) + (゚ー゚) + (゚Θ゚))", "(゚Д゚) .゚ω゚ノ", "(゚Д゚) .゚Θ゚ノ",
  177. "(゚Д゚) ['c']", "(゚Д゚) .゚ー゚ノ", "(゚Д゚) .゚Д゚ノ", "(゚Д゚) [゚Θ゚]"]
  178. def is_aaencoded(self):
  179. idx = self.encoded_str.find("゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); ")
  180. if idx == -1:
  181. return False
  182. is_encoded = self.encoded_str.find("(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');", idx) != -1
  183. return is_encoded
  184. def base_repr(self, number, base=2, padding=0):
  185. digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  186. if base > len(digits):
  187. base = len(digits)
  188. num = abs(number)
  189. res = []
  190. while num:
  191. res.append(digits[num % base])
  192. num //= base
  193. if padding:
  194. res.append('0' * padding)
  195. if number < 0:
  196. res.append('-')
  197. return ''.join(reversed(res or '0'))
  198. def decode_char(self, enc_char, radix):
  199. end_char = "+ "
  200. str_char = ""
  201. while enc_char != '':
  202. found = False
  203. # for i in range(len(self.b)):
  204. # print self.b[i], enc_char.find(self.b[i])
  205. # if enc_char.find(self.b[i]) == 0:
  206. # str_char += self.base_repr(i, radix)
  207. # enc_char = enc_char[len(self.b[i]):]
  208. # found = True
  209. # break
  210. # print 'found', found, enc_char
  211. if not found:
  212. for i in range(len(self.b)):
  213. enc_char = enc_char.replace(self.b[i], str(i))
  214. # enc_char = enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
  215. # print 'enc_char', enc_char
  216. startpos = 0
  217. findClose = True
  218. balance = 1
  219. result = []
  220. if enc_char.startswith('('):
  221. l = 0
  222. for t in enc_char[1:]:
  223. l += 1
  224. # print 'looping', findClose, startpos, t, balance
  225. if findClose and t == ')':
  226. balance -= 1
  227. if balance == 0:
  228. result += [enc_char[startpos:l + 1]]
  229. findClose = False
  230. continue
  231. elif not findClose and t == '(':
  232. startpos = l
  233. findClose = True
  234. balance = 1
  235. continue
  236. elif t == '(':
  237. balance += 1
  238. if result is None or len(result) == 0:
  239. return ""
  240. else:
  241. for r in result:
  242. value = self.decode_digit(r, radix)
  243. # print 'va', value
  244. str_char += value
  245. if value == "":
  246. return ""
  247. return str_char
  248. enc_char = enc_char[len(end_char):]
  249. return str_char
  250. def parseJSString(self, s):
  251. try:
  252. # print s
  253. # offset = 1 if s[0] == '+' else 0
  254. tmp = (s.replace('!+[]', '1').replace('!![]', '1').replace('[]', '0')) # .replace('(','str(')[offset:])
  255. val = int(eval(tmp))
  256. return val
  257. except:
  258. pass
  259. def decode_digit(self, enc_int, radix):
  260. # enc_int = enc_int.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
  261. # print 'enc_int before', enc_int
  262. # for i in range(len(self.b)):
  263. # print self.b[i], enc_char.find(self.b[i])
  264. # if enc_char.find(self.b[i]) > 0:
  265. # str_char += self.base_repr(i, radix)
  266. # enc_char = enc_char[len(self.b[i]):]
  267. # found = True
  268. # break
  269. # enc_int=enc_int.replace(self.b[i], str(i))
  270. # print 'enc_int before', enc_int
  271. try:
  272. return str(eval(enc_int))
  273. except: pass
  274. rr = '(\(.+?\)\))\+'
  275. rerr = enc_int.split('))+') # re.findall(rr, enc_int)
  276. v = ""
  277. # print rerr
  278. for c in rerr:
  279. if len(c) > 0:
  280. # print 'v', c
  281. if c.strip().endswith('+'):
  282. c = c.strip()[:-1]
  283. # print 'v', c
  284. startbrackets = len(c) - len(c.replace('(', ''))
  285. endbrackets = len(c) - len(c.replace(')', ''))
  286. if startbrackets > endbrackets:
  287. c += ')' * (startbrackets - endbrackets)
  288. if '[' in c:
  289. v += str(self.parseJSString(c))
  290. else:
  291. # print c
  292. v += str(eval(c))
  293. return v
  294. # unreachable code
  295. # mode 0=+, 1=-
  296. # mode = 0
  297. # value = 0
  298. # while enc_int != '':
  299. # found = False
  300. # for i in range(len(self.b)):
  301. # if enc_int.find(self.b[i]) == 0:
  302. # if mode == 0:
  303. # value += i
  304. # else:
  305. # value -= i
  306. # enc_int = enc_int[len(self.b[i]):]
  307. # found = True
  308. # break
  309. # if not found:
  310. # return ""
  311. # enc_int = re.sub('^\s+|\s+$', '', enc_int)
  312. # if enc_int.find("+") == 0:
  313. # mode = 0
  314. # else:
  315. # mode = 1
  316. # enc_int = enc_int[1:]
  317. # enc_int = re.sub('^\s+|\s+$', '', enc_int)
  318. # return self.base_repr(value, radix)
  319. def decode(self):
  320. self.encoded_str = re.sub('^\s+|\s+$', '', self.encoded_str)
  321. # get data
  322. pattern = (r"\(゚Д゚\)\[゚o゚\]\+ (.+?)\(゚Д゚\)\[゚o゚\]\)")
  323. result = re.search(pattern, self.encoded_str, re.DOTALL)
  324. if result is None:
  325. #common.log_utils.log_debug("AADecoder: data not found")
  326. print "AADecoder: data not foun"
  327. return False
  328. data = result.group(1)
  329. # hex decode string
  330. begin_char = "(゚Д゚)[゚ε゚]+"
  331. alt_char = "(o゚ー゚o)+ "
  332. out = ''
  333. # print data
  334. while data != '':
  335. # Check new char
  336. if data.find(begin_char) != 0:
  337. #common.log_utils.log_debug("AADecoder: data not found")
  338. print "AADecoder: data not found"
  339. return False
  340. data = data[len(begin_char):]
  341. # Find encoded char
  342. enc_char = ""
  343. if data.find(begin_char) == -1:
  344. enc_char = data
  345. data = ""
  346. else:
  347. enc_char = data[:data.find(begin_char)]
  348. data = data[len(enc_char):]
  349. radix = 8
  350. # Detect radix 16 for utf8 char
  351. if enc_char.find(alt_char) == 0:
  352. enc_char = enc_char[len(alt_char):]
  353. radix = 16
  354. # print repr(enc_char), radix
  355. # print enc_char.replace('(゚Θ゚)', '1').replace('(゚ー゚)', '4').replace('(c^_^o)', '0').replace('(o^_^o)', '3')
  356. # print 'The CHAR', enc_char, radix
  357. str_char = self.decode_char(enc_char, radix)
  358. if str_char == "":
  359. #common.log_utils.log_debug("no match : "),
  360. print "no match : "
  361. #common.log_utils.log_debug(data + "\nout = " + out + "\n")
  362. print data + "\nout = " + out + "\n"
  363. return False
  364. # print 'sofar', str_char, radix,out
  365. out += chr(int(str_char, radix))
  366. # print 'sfar', chr(int(str_char, radix)), out
  367. if out == "":
  368. #common.log_utils.log_debug("no match : " + data)
  369. print "no match : " + data
  370. return False
  371. return out
  372. #
  373. # Python version of the jjdecode function written by Syed Zainudeen
  374. # http://csc.cs.utm.my/syed/images/files/jjdecode/jjdecode.html
  375. #
  376. # +NCR/CRC! [ReVeRsEr] - crackinglandia@gmail.com
  377. # Thanks to Jose Miguel Esparza (@EternalTodo) for the final push to make it work!
  378. #
  379. class JJDecoder(object):
  380. def __init__(self, jj_encoded_data):
  381. self.encoded_str = jj_encoded_data
  382. def clean(self):
  383. return re.sub('^\s+|\s+$', '', self.encoded_str)
  384. def checkPalindrome(self, Str):
  385. startpos = -1
  386. endpos = -1
  387. gv, gvl = -1, -1
  388. index = Str.find('"\'\\"+\'+",')
  389. if index == 0:
  390. startpos = Str.find('$$+"\\""+') + 8
  391. endpos = Str.find('"\\"")())()')
  392. gv = Str[Str.find('"\'\\"+\'+",') + 9:Str.find('=~[]')]
  393. gvl = len(gv)
  394. else:
  395. gv = Str[0:Str.find('=')]
  396. gvl = len(gv)
  397. startpos = Str.find('"\\""+') + 5
  398. endpos = Str.find('"\\"")())()')
  399. return (startpos, endpos, gv, gvl)
  400. def decode(self):
  401. self.encoded_str = self.clean()
  402. startpos, endpos, gv, gvl = self.checkPalindrome(self.encoded_str)
  403. if startpos == endpos:
  404. raise Exception('No data!')
  405. data = self.encoded_str[startpos:endpos]
  406. b = ['___+', '__$+', '_$_+', '_$$+', '$__+', '$_$+', '$$_+', '$$$+', '$___+', '$__$+', '$_$_+', '$_$$+', '$$__+', '$$_$+', '$$$_+', '$$$$+']
  407. str_l = '(![]+"")[' + gv + '._$_]+'
  408. str_o = gv + '._$+'
  409. str_t = gv + '.__+'
  410. str_u = gv + '._+'
  411. str_hex = gv + '.'
  412. str_s = '"'
  413. gvsig = gv + '.'
  414. str_quote = '\\\\\\"'
  415. str_slash = '\\\\\\\\'
  416. str_lower = '\\\\"+'
  417. str_upper = '\\\\"+' + gv + '._+'
  418. str_end = '"+'
  419. out = ''
  420. while data != '':
  421. # l o t u
  422. if data.find(str_l) == 0:
  423. data = data[len(str_l):]
  424. out += 'l'
  425. continue
  426. elif data.find(str_o) == 0:
  427. data = data[len(str_o):]
  428. out += 'o'
  429. continue
  430. elif data.find(str_t) == 0:
  431. data = data[len(str_t):]
  432. out += 't'
  433. continue
  434. elif data.find(str_u) == 0:
  435. data = data[len(str_u):]
  436. out += 'u'
  437. continue
  438. # 0123456789abcdef
  439. if data.find(str_hex) == 0:
  440. data = data[len(str_hex):]
  441. for i in range(len(b)):
  442. if data.find(b[i]) == 0:
  443. data = data[len(b[i]):]
  444. out += '%x' % i
  445. break
  446. continue
  447. # start of s block
  448. if data.find(str_s) == 0:
  449. data = data[len(str_s):]
  450. # check if "R
  451. if data.find(str_upper) == 0: # r4 n >= 128
  452. data = data[len(str_upper):] # skip sig
  453. ch_str = ''
  454. for i in range(2): # shouldn't be more than 2 hex chars
  455. # gv + "."+b[ c ]
  456. if data.find(gvsig) == 0:
  457. data = data[len(gvsig):]
  458. for k in range(len(b)): # for every entry in b
  459. if data.find(b[k]) == 0:
  460. data = data[len(b[k]):]
  461. ch_str = '%x' % k
  462. break
  463. else:
  464. break
  465. out += chr(int(ch_str, 16))
  466. continue
  467. elif data.find(str_lower) == 0: # r3 check if "R // n < 128
  468. data = data[len(str_lower):] # skip sig
  469. ch_str = ''
  470. ch_lotux = ''
  471. temp = ''
  472. b_checkR1 = 0
  473. for j in range(3): # shouldn't be more than 3 octal chars
  474. if j > 1: # lotu check
  475. if data.find(str_l) == 0:
  476. data = data[len(str_l):]
  477. ch_lotux = 'l'
  478. break
  479. elif data.find(str_o) == 0:
  480. data = data[len(str_o):]
  481. ch_lotux = 'o'
  482. break
  483. elif data.find(str_t) == 0:
  484. data = data[len(str_t):]
  485. ch_lotux = 't'
  486. break
  487. elif data.find(str_u) == 0:
  488. data = data[len(str_u):]
  489. ch_lotux = 'u'
  490. break
  491. # gv + "."+b[ c ]
  492. if data.find(gvsig) == 0:
  493. temp = data[len(gvsig):]
  494. for k in range(8): # for every entry in b octal
  495. if temp.find(b[k]) == 0:
  496. if int(ch_str + str(k), 8) > 128:
  497. b_checkR1 = 1
  498. break
  499. ch_str += str(k)
  500. data = data[len(gvsig):] # skip gvsig
  501. data = data[len(b[k]):]
  502. break
  503. if b_checkR1 == 1:
  504. if data.find(str_hex) == 0: # 0123456789abcdef
  505. data = data[len(str_hex):]
  506. # check every element of hex decode string for a match
  507. for i in range(len(b)):
  508. if data.find(b[i]) == 0:
  509. data = data[len(b[i]):]
  510. ch_lotux = '%x' % i
  511. break
  512. break
  513. else:
  514. break
  515. out += chr(int(ch_str, 8)) + ch_lotux
  516. continue
  517. else: # "S ----> "SR or "S+
  518. # if there is, loop s until R 0r +
  519. # if there is no matching s block, throw error
  520. match = 0
  521. n = None
  522. # searching for matching pure s block
  523. while True:
  524. n = ord(data[0])
  525. if data.find(str_quote) == 0:
  526. data = data[len(str_quote):]
  527. out += '"'
  528. match += 1
  529. continue
  530. elif data.find(str_slash) == 0:
  531. data = data[len(str_slash):]
  532. out += '\\'
  533. match += 1
  534. continue
  535. elif data.find(str_end) == 0: # reached end off S block ? +
  536. if match == 0:
  537. raise '+ no match S block: ' + data
  538. data = data[len(str_end):]
  539. break # step out of the while loop
  540. elif data.find(str_upper) == 0: # r4 reached end off S block ? - check if "R n >= 128
  541. if match == 0:
  542. raise 'no match S block n>128: ' + data
  543. data = data[len(str_upper):] # skip sig
  544. ch_str = ''
  545. ch_lotux = ''
  546. for j in range(10): # shouldn't be more than 10 hex chars
  547. if j > 1: # lotu check
  548. if data.find(str_l) == 0:
  549. data = data[len(str_l):]
  550. ch_lotux = 'l'
  551. break
  552. elif data.find(str_o) == 0:
  553. data = data[len(str_o):]
  554. ch_lotux = 'o'
  555. break
  556. elif data.find(str_t) == 0:
  557. data = data[len(str_t):]
  558. ch_lotux = 't'
  559. break
  560. elif data.find(str_u) == 0:
  561. data = data[len(str_u):]
  562. ch_lotux = 'u'
  563. break
  564. # gv + "."+b[ c ]
  565. if data.find(gvsig) == 0:
  566. data = data[len(gvsig):] # skip gvsig
  567. for k in range(len(b)): # for every entry in b
  568. if data.find(b[k]) == 0:
  569. data = data[len(b[k]):]
  570. ch_str += '%x' % k
  571. break
  572. else:
  573. break # done
  574. out += chr(int(ch_str, 16))
  575. break # step out of the while loop
  576. elif data.find(str_lower) == 0: # r3 check if "R // n < 128
  577. if match == 0:
  578. raise 'no match S block n<128: ' + data
  579. data = data[len(str_lower):] # skip sig
  580. ch_str = ''
  581. ch_lotux = ''
  582. temp = ''
  583. b_checkR1 = 0
  584. for j in range(3): # shouldn't be more than 3 octal chars
  585. if j > 1: # lotu check
  586. if data.find(str_l) == 0:
  587. data = data[len(str_l):]
  588. ch_lotux = 'l'
  589. break
  590. elif data.find(str_o) == 0:
  591. data = data[len(str_o):]
  592. ch_lotux = 'o'
  593. break
  594. elif data.find(str_t) == 0:
  595. data = data[len(str_t):]
  596. ch_lotux = 't'
  597. break
  598. elif data.find(str_u) == 0:
  599. data = data[len(str_u):]
  600. ch_lotux = 'u'
  601. break
  602. # gv + "."+b[ c ]
  603. if data.find(gvsig) == 0:
  604. temp = data[len(gvsig):]
  605. for k in range(8): # for every entry in b octal
  606. if temp.find(b[k]) == 0:
  607. if int(ch_str + str(k), 8) > 128:
  608. b_checkR1 = 1
  609. break
  610. ch_str += str(k)
  611. data = data[len(gvsig):] # skip gvsig
  612. data = data[len(b[k]):]
  613. break
  614. if b_checkR1 == 1:
  615. if data.find(str_hex) == 0: # 0123456789abcdef
  616. data = data[len(str_hex):]
  617. # check every element of hex decode string for a match
  618. for i in range(len(b)):
  619. if data.find(b[i]) == 0:
  620. data = data[len(b[i]):]
  621. ch_lotux = '%x' % i
  622. break
  623. else:
  624. break
  625. out += chr(int(ch_str, 8)) + ch_lotux
  626. break # step out of the while loop
  627. elif (0x21 <= n and n <= 0x2f) or (0x3A <= n and n <= 0x40) or (0x5b <= n and n <= 0x60) or (0x7b <= n and n <= 0x7f):
  628. out += data[0]
  629. data = data[1:]
  630. match += 1
  631. continue
  632. print 'No match : ' + data
  633. break
  634. return out
  635. if __name__ == "__main__":
  636. from subprocess import call
  637. #url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
  638. #url = "http://hqq.tv/player/embed_player.php?vid=243221241234244238208213206212211231&autoplay=no"
  639. url = "http://hqq.tv/player/embed_player.php?vid=208231211231207221227243206206221244&autoplay=no"
  640. #url = "https://openload.co/embed/TMthIdpy4PI/"
  641. #url = "https://www.youtube.com/watch?v=Tx1K51_F99o"
  642. #url = "https://www.youtube.com/watch?v=8BkcX7O1890"
  643. #url = "https://www.youtube.com/watch?v=Se07R8SYsg0"
  644. #url = "https://kinostok.tv/embed/731f3437e3c53104dd56d04039a0b15a"
  645. #url = "http://vk.com/video_ext.php?oid=246066565&id=169244575&hash=d430ab0e76c9f7a1&hd=3"
  646. #url ="https://openload.co/embed/rPMXJYPTkw4/"
  647. #url = "https://openload.co/embed/bE7WfZ-vz_A/"
  648. #url = "https://openload.co/embed/bE7WfZ/"
  649. #url = "https://openload.co/embed/OuskaKyC2GU/"
  650. url = "http://hqq.tv/player/embed_player.php?vid=235238210241210222228241233208212245&autoplay=no"
  651. url = "https://openload.co/embed/rmNcP-0QopE/"
  652. url = "https://openload.co/embed/oQLXcU1ITAY/"
  653. streams = resolve(url)
  654. if not streams:
  655. print "No streams found"
  656. sys.exit()
  657. for s in streams:
  658. print s
  659. print streams[0]["url"]
  660. call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",streams[0]["url"]])
  661. pass