lambdascrapers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

solarmoviez.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. # -*- coding: UTF-8 -*-
  2. #######################################################################
  3. # ----------------------------------------------------------------------------
  4. # "THE BEER-WARE LICENSE" (Revision 42):
  5. # @tantrumdev wrote this file. As long as you retain this notice you
  6. # can do whatever you want with this stuff. If we meet some day, and you think
  7. # this stuff is worth it, you can buy me a beer in return. - Muad'Dib
  8. # ----------------------------------------------------------------------------
  9. #######################################################################
  10. # Addon Name: Yoda
  11. # Addon id: plugin.video.Yoda
  12. # Addon Provider: MuadDib
  13. import re,traceback,urllib,urlparse,hashlib,random,string,json,base64,sys,xbmc
  14. from resources.lib.modules import cleantitle
  15. from resources.lib.modules import client
  16. from resources.lib.modules import cache
  17. from resources.lib.modules import directstream
  18. from resources.lib.modules import jsunfuck
  19. from resources.lib.modules import log_utils
  20. CODE = '''def retA():
  21. class Infix:
  22. def __init__(self, function):
  23. self.function = function
  24. def __ror__(self, other):
  25. return Infix(lambda x, self=self, other=other: self.function(other, x))
  26. def __or__(self, other):
  27. return self.function(other)
  28. def __rlshift__(self, other):
  29. return Infix(lambda x, self=self, other=other: self.function(other, x))
  30. def __rshift__(self, other):
  31. return self.function(other)
  32. def __call__(self, value1, value2):
  33. return self.function(value1, value2)
  34. def my_add(x, y):
  35. try: return x + y
  36. except Exception: return str(x) + str(y)
  37. x = Infix(my_add)
  38. return %s
  39. param = retA()'''
  40. class source:
  41. def __init__(self):
  42. self.priority = 1
  43. self.language = ['en']
  44. self.domains = ['solarmoviez.to', 'solarmoviez.ru']
  45. self.base_link = 'https://solarmoviez.ru'
  46. self.search_link = '/movie/search/%s.html'
  47. self.info_link = '/ajax/movie_info/%s.html?is_login=false'
  48. self.server_link = '/ajax/v4_movie_episodes/%s'
  49. self.embed_link = '/ajax/movie_embed/%s'
  50. self.token_link = '/ajax/movie_token?eid=%s&mid=%s'
  51. self.source_link = '/ajax/movie_sources/%s?x=%s&y=%s'
  52. def matchAlias(self, title, aliases):
  53. try:
  54. for alias in aliases:
  55. if cleantitle.get(title) == cleantitle.get(alias['title']):
  56. return True
  57. except:
  58. return False
  59. def movie(self, imdb, title, localtitle, aliases, year):
  60. try:
  61. aliases.append({'country': 'us', 'title': title})
  62. url = {'imdb': imdb, 'title': title, 'year': year, 'aliases': aliases}
  63. url = urllib.urlencode(url)
  64. return url
  65. except:
  66. failure = traceback.format_exc()
  67. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  68. return
  69. def tvshow(self, imdb, tvdb, tvshowtitle, localtvshowtitle, aliases, year):
  70. try:
  71. aliases.append({'country': 'us', 'title': tvshowtitle})
  72. url = {'imdb': imdb, 'tvdb': tvdb, 'tvshowtitle': tvshowtitle, 'year': year, 'aliases': aliases}
  73. url = urllib.urlencode(url)
  74. return url
  75. except:
  76. failure = traceback.format_exc()
  77. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  78. return
  79. def episode(self, url, imdb, tvdb, title, premiered, season, episode):
  80. try:
  81. if url == None: return
  82. url = urlparse.parse_qs(url)
  83. url = dict([(i, url[i][0]) if url[i] else (i, '') for i in url])
  84. url['title'], url['premiered'], url['season'], url['episode'] = title, premiered, season, episode
  85. url = urllib.urlencode(url)
  86. return url
  87. except:
  88. failure = traceback.format_exc()
  89. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  90. return
  91. def searchShow(self, title, season, aliases, headers):
  92. try:
  93. title = cleantitle.normalize(title)
  94. search = '%s Season %s' % (title, season)
  95. url = urlparse.urljoin(self.base_link, self.search_link % urllib.quote_plus(cleantitle.getsearch(search)))
  96. r = client.request(url)
  97. url = re.findall('<a href=\"(.+?\/movie\/%s-season-%s-.+?\.html)\"' % (cleantitle.geturl(title), season), r)[0]
  98. return url
  99. except:
  100. failure = traceback.format_exc()
  101. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  102. return
  103. def searchMovie(self, title, year, aliases, headers):
  104. try:
  105. title = cleantitle.normalize(title)
  106. url = urlparse.urljoin(self.base_link, self.search_link % urllib.quote_plus(cleantitle.getsearch(title)))
  107. r = client.request(url, headers=headers, timeout='15')
  108. r = client.parseDOM(r, 'div', attrs={'class': 'ml-item'})
  109. r = zip(client.parseDOM(r, 'a', ret='href'), client.parseDOM(r, 'a', ret='title'))
  110. results = [(i[0], i[1], re.findall('\((\d{4})', i[1])) for i in r]
  111. try:
  112. r = [(i[0], i[1], i[2][0]) for i in results if len(i[2]) > 0]
  113. url = [i[0] for i in r if self.matchAlias(i[1], aliases) and (year == i[2])][0]
  114. except:
  115. url = None
  116. pass
  117. if (url == None):
  118. url = [i[0] for i in results if self.matchAlias(i[1], aliases)][0]
  119. return url
  120. except:
  121. failure = traceback.format_exc()
  122. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  123. return
  124. def sources(self, url, hostDict, hostprDict):
  125. try:
  126. sources = []
  127. if url is None: return sources
  128. data = urlparse.parse_qs(url)
  129. data = dict([(i, data[i][0]) if data[i] else (i, '') for i in data])
  130. aliases = eval(data['aliases'])
  131. headers = {}
  132. if 'tvshowtitle' in data:
  133. episode = int(data['episode'])
  134. url = self.searchShow(data['tvshowtitle'], data['season'], aliases, headers)
  135. else:
  136. episode = 0
  137. url = self.searchMovie(data['title'], data['year'], aliases, headers)
  138. mid = re.findall('-(\d+)', url)[-1]
  139. try:
  140. headers = {'Referer': url}
  141. u = urlparse.urljoin(self.base_link, self.server_link % mid)
  142. r = client.request(u, headers=headers, XHR=True)
  143. r = json.loads(r)['html']
  144. r = client.parseDOM(r, 'div', attrs = {'class': 'pas-list'})
  145. ids = client.parseDOM(r, 'li', ret='data-id')
  146. servers = client.parseDOM(r, 'li', ret='data-server')
  147. labels = client.parseDOM(r, 'a', ret='title')
  148. r = zip(ids, servers, labels)
  149. for eid in r:
  150. try:
  151. try:
  152. ep = re.findall('episode.*?(\d+).*?', eid[2].lower())[0]
  153. except:
  154. ep = 0
  155. if (episode == 0) or (int(ep) == episode):
  156. url = urlparse.urljoin(self.base_link, self.token_link % (eid[0], mid))
  157. script = client.request(url)
  158. if '$_$' in script:
  159. params = self.uncensored1(script)
  160. elif script.startswith('[]') and script.endswith('()'):
  161. params = self.uncensored2(script)
  162. elif '_x=' in script:
  163. x = re.search('''_x=['"]([^"']+)''', script).group(1)
  164. y = re.search('''_y=['"]([^"']+)''', script).group(1)
  165. params = {'x': x, 'y': y}
  166. else:
  167. raise Exception()
  168. u = urlparse.urljoin(self.base_link, self.source_link % (eid[0], params['x'], params['y']))
  169. r = client.request(u, XHR=True)
  170. json_sources = json.loads(r)['playlist'][0]['sources']
  171. try:
  172. if 'google' in json_sources['file']:
  173. quality = 'HD'
  174. if 'bluray' in json_sources['file'].lower():
  175. quality = '1080p'
  176. sources.append({'source': 'gvideo', 'quality': quality, 'language': 'en',
  177. 'url': json_sources['file'], 'direct': True, 'debridonly': False})
  178. except Exception:
  179. if 'blogspot' in json_sources[0]['file']:
  180. url = [i['file'] for i in json_sources if 'file' in i]
  181. url = [directstream.googletag(i) for i in url]
  182. url = [i[0] for i in url if i]
  183. for s in url:
  184. sources.append({'source': 'gvideo', 'quality': s['quality'], 'language': 'en',
  185. 'url': s['url'], 'direct': True, 'debridonly': False})
  186. elif 'lemonstream' in json_sources[0]['file']:
  187. sources.append({
  188. 'source': 'CDN',
  189. 'quality': 'HD',
  190. 'language': 'en',
  191. 'url': json_sources[0]['file'] + '|Referer=' + self.base_link,
  192. 'direct': True,
  193. 'debridonly': False})
  194. except:
  195. pass
  196. except:
  197. pass
  198. return sources
  199. except:
  200. failure = traceback.format_exc()
  201. log_utils.log('SolarMoviez - Exception: \n' + str(failure))
  202. return sources
  203. def resolve(self, url):
  204. return url
  205. def uncensored(a, b):
  206. x = '' ; i = 0
  207. for i, y in enumerate(a):
  208. z = b[i % len(b) - 1]
  209. y = int(ord(str(y)[0])) + int(ord(str(z)[0]))
  210. x += chr(y)
  211. x = base64.b64encode(x)
  212. return x
  213. def uncensored1(self, script):
  214. try:
  215. script = '(' + script.split("(_$$)) ('_');")[0].split("/* `$$` */")[-1].strip()
  216. script = script.replace('(__$)[$$$]', '\'"\'')
  217. script = script.replace('(__$)[_$]', '"\\\\"')
  218. script = script.replace('(o^_^o)', '3')
  219. script = script.replace('(c^_^o)', '0')
  220. script = script.replace('(_$$)', '1')
  221. script = script.replace('($$_)', '4')
  222. vGlobals = {"__builtins__": None, '__name__': __name__, 'str': str, 'Exception': Exception}
  223. vLocals = {'param': None}
  224. exec (CODE % script.replace('+', '|x|'), vGlobals, vLocals)
  225. data = vLocals['param'].decode('string_escape')
  226. x = re.search('''_x=['"]([^"']+)''', data).group(1)
  227. y = re.search('''_y=['"]([^"']+)''', data).group(1)
  228. return {'x': x, 'y': y}
  229. except:
  230. pass
  231. def uncensored2(self, script):
  232. try:
  233. js = jsunfuck.JSUnfuck(script).decode()
  234. x = re.search('''_x=['"]([^"']+)''', js).group(1)
  235. y = re.search('''_y=['"]([^"']+)''', js).group(1)
  236. return {'x': x, 'y': y}
  237. except:
  238. pass