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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #!/usr/bin/env python
  2. # coding=utf8
  3. #
  4. # This file is part of PlayStream - enigma2 plugin to play video streams from various sources
  5. # Copyright (c) 2016 ivars777 (ivars777@gmail.com)
  6. # Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
  7. #
  8. try:
  9. import json
  10. except:
  11. import simplejson as json
  12. import urllib2, urllib
  13. import datetime, re, sys,os
  14. import ConfigParser
  15. from collections import OrderedDict
  16. from SourceBase import SourceBase
  17. import ssl
  18. if "_create_unverified_context" in dir(ssl):
  19. ssl._create_default_https_context = ssl._create_unverified_context
  20. import resolver
  21. try:
  22. import util
  23. except:
  24. sys.path.insert(0,'..')
  25. import util
  26. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  27. import HTMLParser
  28. h = HTMLParser.HTMLParser()
  29. class Source(SourceBase):
  30. def __init__(self, country="",cfg_path=None):
  31. self.name = "movieplace"
  32. self.title = "MoviePlace.lv"
  33. self.img = "http://movieplace.lv/images/logo.png"
  34. self.desc = "Movieplace.lv - filmas latviesu valodā"
  35. self.headers = headers2dict("""
  36. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  37. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  38. Accept-Language: en-US,en;q=0.5
  39. """)
  40. self.headers2 = headers2dict("""
  41. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  42. X-Requested-With: XMLHttpRequest
  43. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  44. """)
  45. self.url = "http://movieplace.lv/"
  46. ######### Entry point ########
  47. def get_content(self, data):
  48. print "[movieplace] get_content:", data
  49. source, data, path, plist, clist, params, qs = self.parse_data(data)
  50. content = []
  51. content.append(("..return", "back","","Return back"))
  52. if clist=="home":
  53. content.extend([
  54. ("Meklēt", "movieplace::search/?q={0}","","Meklēt"),
  55. ("Jaunākās filmas", "movieplace::load/?page1","","Visu žanru jaunākās filmas"),
  56. ("Jaunākie seriāli", "movieplace::dir/?page1","","Visu žanru jaunākās filmas"),
  57. #("Top50 filmas", "movieplace::index/top_50_filmas/0-4","","Top 50 filmas"),
  58. ])
  59. r = self.call("load/")
  60. #i = r.find('<div class="cat-title">Meklēt pēc žanriem</div>')
  61. #if i<=0:
  62. # return content
  63. i = 0
  64. for item in re.findall('<a href="/([^"]+)" class="catName">([^>]+)</a>', r[i:]):
  65. title = item[1]
  66. data2 = item[0]+"-1"
  67. img = self.img
  68. desc = title
  69. content.append((title,self.name+"::"+data2,img,desc))
  70. return content
  71. elif clist=="search":
  72. # TODO
  73. r=self.call(data)
  74. result = re.findall('<a href="([^"]+)"> (.+?) </a></div>.+?> (.+?)</div>', r, re.DOTALL)
  75. for item in result:
  76. title = item[1].replace("<b>","").replace("</b>","")
  77. data2 = item[0].replace("http://movieplace.lv/","")
  78. img = self.img
  79. desc = item[2].replace("<b>","").replace("</b>","")
  80. content.append((title,self.name+"::"+data2,img,desc))
  81. if '<span>&raquo;</span>' in r:
  82. m = re.search("p=(\d+)",data)
  83. if m:
  84. page = int(m.group(1))+1
  85. data2 = re.sub(r"p=\d+", r"p=%s"%page, data)
  86. content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
  87. return content
  88. # Filmu saraksti ##
  89. elif clist in ["load","dir"] and len(plist)<=3:
  90. if clist == "jaunakas":
  91. r = self.call("")
  92. else:
  93. r = self.call(data)
  94. #r = r.decode("cp1251").encode("utf8")
  95. if clist == "load":
  96. result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="([^"]+)">.+?<div class="years">([^<]+)</div>\s+<div class="country">([^<]+)</div>', r, re.DOTALL)
  97. else:
  98. result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="[^"]+">.+?<span>([^<]+)</span>\s*<div class="country">([^<]+)</div>', r, re.IGNORECASE | re.DOTALL)
  99. for item in result:
  100. title = item[1]+" [%s]"%item[4] if clist=="load" else item[1]+" / %s [%s]"%(item[3],item[4])
  101. img = "http://movieplace.lv/"+item[2]
  102. data2 = item[0]
  103. desc = "%s\n%s"%(title,item[5]) if clist=="load" else title
  104. content.append((title,self.name+"::"+data2,img,desc))
  105. m = re.search('<[ab] class="swchItemA*1"( href="/([^"]+)" onclick="[^"]+")*><span>([^<]+)</span></[ab]> </span>', r, re.DOTALL)
  106. if m:
  107. if m.group(1):
  108. page = int(re.search("\d+$",data).group())
  109. page = page+1
  110. data2 = re.sub("\d$","%s"%page,data)
  111. content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
  112. return content
  113. ### Seriāls ###
  114. elif clist=="dir" and len(plist)==4:
  115. r = self.call(path)
  116. title0 = re.search('<h2 class="title" itemprop="name">(.+?)</h2>', r, re.DOTALL).group(1)
  117. m = re.search(r'<span>VALODA:</span> <b><em itemprop="alternativeHeadline"><a href="[^"]*" class="entAllCats">([^<]+)</a></em></b></div>\s+?<div><span>SEZONA:</span> <b>([^<]+)</b></div>', r, re.IGNORECASE | re.DOTALL)
  118. if m:
  119. title0 = "%s / Season %s [%s]"%(title0,m.group(2),m.group(1))
  120. desc0 = title0
  121. img0 = "http://movieplace.lv" + re.search('<img src="(.+?)".+?itemprop="image">', r, re.DOTALL).group(1)
  122. #TODO
  123. result = re.findall(r'<summary>([^<]+)</summary><iframe src="https://openload\.co/embed/[^/]+/"', r, re.DOTALL)
  124. i = 1
  125. for item in result:
  126. title = title0+" - " + item
  127. data2 = data+"?e=%s"%i
  128. img = img0
  129. desc = desc0
  130. content.append((title,self.name+"::"+data2,img,desc))
  131. i += 1
  132. return content
  133. ### kaut kas neparedzets ###
  134. else:
  135. return content
  136. def is_video(self,data):
  137. source,data,path,plist,clist,params,qs = self.parse_data(data)
  138. if clist=="dir" and len(plist) == 4 and "e"in qs: # sērija
  139. return True
  140. elif clist=="load" and len(plist) == 4:
  141. return True
  142. else:
  143. return False
  144. def call(self, data,params=None,headers=None,lang=""):
  145. if not headers: headers = self.headers
  146. url = self.url+data
  147. result = self._http_request(url,params,headers=headers)
  148. return result
  149. def get_streams(self,data):
  150. print "[movieplace] get_streams:", data
  151. if not self.is_video(data):
  152. return []
  153. source,data,path,plist,clist,params,qs = self.parse_data(data)
  154. r = self.call(path)
  155. if clist=="load":
  156. m = re.search('<h2 class="title" itemprop="name">([^<]+)</h2>', r, re.DOTALL)
  157. title = re.search('<itemprop="name">(.+?)</itemprop="name">', r, re.DOTALL).group(1)
  158. m = re.search(r'<div role="tabpanel" class="tab-pane fade in active" id="heading-tab4">\s*(.+?)\s*</div>', r, re.DOTALL)
  159. desc = m.group(1) if m else title
  160. m = re.search('<meta property="og:image" content="([^"]+)" />', r, re.DOTALL)
  161. img = m.group(1) if m else ""
  162. rr = []
  163. for m in re.finditer("(RU|ENG|LAT|LAT SUB)<BR( /)*>.*?>?<BR( /)*>.*?<iframe", r, re.IGNORECASE | re.DOTALL):
  164. if len(rr)>0:
  165. rr[-1]["end"] = m.start()
  166. rr.append({"lang":m.group(1),"start":m.start(),"end":len(r)})
  167. streams = []
  168. for m in re.finditer(r'src="(https*://(goo\.gl|songs2dl|kodik|cdn\.kapnob|hqq|openload|sv1.servkino|vidwatch|online\.kinozz).+?)"', r, re.IGNORECASE | re.DOTALL):
  169. url = m.group(1)
  170. lang = "?"
  171. for rrr in rr:
  172. if m.start()>rrr["start"] and m.start()<rrr["end"]:
  173. lang = rrr["lang"]
  174. break
  175. for s in resolver.resolve(url):
  176. s["name"] = title
  177. s["desc"] = desc
  178. s["img"] = img
  179. s["type"] = self.stream_type(s["url"])
  180. s["lang"] = lang
  181. streams.append(s)
  182. return streams
  183. elif clist=="dir" and "e" in qs: # serialā sērija
  184. #TODO
  185. result = re.findall(r'<summary>([^<]+)</summary><iframe src="([^"]+)"', r, re.DOTALL)
  186. i = int(qs["s"])-1
  187. url0 = result[i][1]
  188. title = title + " - " + result[i][0]
  189. else:
  190. #iframe src="https://openload.co/embed/wlw6Vl9zwL0/"
  191. result = re.findall(r'<iframe src="([^"]+)"', r, re.DOTALL)
  192. if not result:
  193. return []
  194. url0 = result[0]
  195. return streams
  196. if __name__ == "__main__":
  197. country= "lv"
  198. c = Source(country)
  199. if len(sys.argv)>1:
  200. data= sys.argv[1]
  201. else:
  202. data = "home"
  203. content = c.get_content(data)
  204. for item in content:
  205. print item
  206. #cat = api.get_categories(country)
  207. #chan = api.get_channels("lv")
  208. #prog = api.get_programs(channel=6400)
  209. #prog = api.get_programs(category=55)
  210. #seas = api.get_seasons(program=6453)
  211. #str = api.get_streams(660243)
  212. #res = api.get_videos(802)
  213. #formats = api.getAllFormats()
  214. #det = api.detailed("1516")
  215. #vid = api.getVideos("13170")
  216. pass