Python module (submodule repositary), which provides content (video streams) from various online stream sources to corresponding Enigma2, Kodi, Plex plugins

tvplay.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 requests
  13. import datetime, re, sys,os
  14. import ConfigParser
  15. import ssl
  16. if "_create_unverified_context" in dir(ssl):
  17. ssl._create_default_https_context = ssl._create_unverified_context
  18. from SourceBase import SourceBase
  19. import resolver
  20. try:
  21. import util
  22. except:
  23. sys.path.insert(0,'..')
  24. import util
  25. from YouTubeVideoUrl import YouTubeVideoUrl
  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="lv",cfg_path=None):
  31. self.name = "tvplay"
  32. self.title = "TVPlay"
  33. self.img = "tvplay.png"
  34. self.desc = "tvplay.skaties.lv saturs"
  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://login.tvplayhome.lt:8081/sb/public/"
  46. self.kategorijas = [
  47. ("zinas", "Ziņas un aktualitātes", 33, "tvplay.png", "Ziņas un aktualitātes"),
  48. ("berniem", "Bērniem", 52, "tvplay.png", "Bērniem"),
  49. ("seriali", "Seriāli", 38, "tvplay.png", "Seriāli"),
  50. ("filmas", "Filmas", 72, "tvplay.png", "Filmas"),
  51. ("izklaide", "Izklaide", 21, "tvplay.png", "Izklaide"),
  52. ("sovi", "Šovi un raidijumi", 44, "tvplay.png", "Šovi un raidijumi"),
  53. ("sports", "Sports", 32, "tvplay.png", "Sports"),
  54. ("rus", "rus.tvplay.lv", 35, "tvplay.png", "Krievu raidijumi"),
  55. ]
  56. ######### Entry point ########
  57. def get_content(self, data):
  58. print "[lmt] get_content:", data
  59. source, data, path, plist, clist, params, qs = self.parse_data(data)
  60. content = []
  61. content.append(("..return", "back","back.png","Return back"))
  62. if clist=="home":
  63. content.extend([
  64. ("Meklēt", "tvplay::meklet/{0}","tvplay.png","Meklēt"),
  65. ("Tiešraides", "tvplay::tiesraides","tvplay.png","Tiešraides"),
  66. ("Jaunākās epizodes", "tvplay::jaunakais/epizodes", "tvplay.png", "Visu kategoriju jaunākie video"),
  67. ("Jaunākie klipi", "tvplay::jaunakais/klipi", "tvplay.png", "Visu kategoriju jaunākie video"),
  68. ("Jaunākais pa kategorijām", "tvplay::jaunakais/kategorijas", "tvplay.png", "Jaunākie video pa kategorijām žanru jaunākie video"),
  69. ("Raidijumi pa kategorijām", "tvplay::raidijumi/kategorijas", "tvplay.png", "Jaunākie video pa kategorijām žanru jaunākie video"),
  70. ])
  71. return content
  72. elif clist in ("meklet"):
  73. term = plist[1]
  74. data = "tvplay::asset/search?size=30&page=0&f_title.title=%s&f_country=LV&f_metadata.contentType=EPISODE" % term
  75. return self.get_content(data)
  76. elif clist in ("tiesraides"):
  77. data = "tvplay::asset/search?size=30&page=0&f_metadata.contentType=LIVE"
  78. return self.get_content(data)
  79. elif clist == "jaunakais":
  80. if plist[1] == "epizodes":
  81. data = "tvplay::asset/search?f_title.categories=15004&size=30&page=0&f_metadata.contentType=EPISODE"
  82. return self.get_content(data)
  83. elif plist[1] == "klipi":
  84. data = "tvplay::asset/search?f_title.categories=15004&size=30&page=0&f_metadata.contentType=CLIP"
  85. return self.get_content(data)
  86. elif plist[1] == "kategorijas":
  87. for kat in self.kategorijas:
  88. content.append(("Jaunākais - "+kat[1], "tvplay::jaunakais/%s" % kat[0], kat[3], kat[4]))
  89. return content
  90. elif plist[1] in zip(*self.kategorijas)[0]:
  91. for k in self.kategorijas:
  92. if k[0] == plist[1]:
  93. kat_num = k[2]
  94. break
  95. else:
  96. return content
  97. data = "tvplay::asset/search?f_title.categories=%s&size=30&page=0" % kat_num
  98. return self.get_content(data)
  99. elif clist == "raidijumi":
  100. if plist[1] == "kategorijas":
  101. for kat in self.kategorijas:
  102. content.append(("Raidijumi - "+kat[1], "tvplay::raidijumi/%s" % kat[0], kat[3], kat[4]))
  103. #content.append(kat[1], "tvplay::tvSeries/category/id/%s?type=tvseries&size=500&sort=title.title&descending=true" % kat[2], kat[3], kat[4])
  104. return content
  105. else:
  106. for k in self.kategorijas:
  107. if k[0] == plist[1]:
  108. kat_num = k[2]
  109. break
  110. else:
  111. return content
  112. data = "tvplay::tvSeries/category/id/%s?type=tvseries&size=500&sort=title.title&descending=true" % kat_num
  113. return self.get_content(data)
  114. elif path == "asset/search":
  115. r = self.call(data)
  116. for item in r["content"]:
  117. data2 = "asset/%s" % item["id"]
  118. title, img, desc = self.get_title_desc(item)
  119. content.append((title, self.name+"::"+data2, img, desc))
  120. if "page" in qs and len(r["content"]) == 30:
  121. page = int(qs["page"]) + 1
  122. data2 = re.sub("page=\d+", "page=%s" % page, data)
  123. content.append(("Next page",self.name+"::"+data2,"next.png","Next page"))
  124. return content
  125. elif plist[0] == "tvSeries" and plist[1] == "category":
  126. r = self.call(data)
  127. for item in r["content"]:
  128. tvseries = True if "type" in qs and qs["type"] == "tvseries" else False
  129. if tvseries and not "seasonNumber" in item: # tvseries (programma)
  130. #if len(item["seasonIds"]) > 1:
  131. #tvseries_id = item["id"]
  132. #else:
  133. # tvseries_id = item["seasonIds"][0]
  134. data2 = "tvSeries/%s" % item["id"]
  135. title = item["title"]["title"]
  136. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  137. desc = []
  138. if "summaryLong" in item["title"]:
  139. desc.append(item["title"]["summaryLong"])
  140. desc = "\n".join(desc)
  141. content.append((title, self.name+"::"+data2, img, desc))
  142. if "page" in qs:
  143. page = int(qs["page"]) + 1
  144. data2 = re.sub("page=\d+", "page=%s" % page, data)
  145. content.append(("Next page",self.name+"::"+data2,"next.png","Next page"))
  146. return content
  147. elif plist[0] == "tvSeries":
  148. item = self.call(data)
  149. if "seasonIds" in item and len(item["seasonIds"]) > 1:
  150. title0 = item["title"]["title"] + ". " + "Visi video"
  151. data2 = "asset/search?f_metadata.tvSeriesId=%s&page=0&size=30" % item["id"]
  152. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  153. desc = []
  154. if "summaryShort" in item["title"]:
  155. desc.append(item["title"]["summaryShort"])
  156. if "summaryLong" in item["title"]:
  157. desc.append(item["title"]["summaryLong"])
  158. desc = "\n".join(desc)
  159. content.append((title0, self.name+"::"+data2, img, desc))
  160. for season in item["seasonIds"]:
  161. data2 = "tvSeries/%s" % season
  162. item = self.call(data2)
  163. title = item["title"]["title"]
  164. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  165. desc = []
  166. if "summaryShort" in item["title"]:
  167. desc.append(item["title"]["summaryShort"])
  168. if "summaryLong" in item["title"]:
  169. desc.append(item["title"]["summaryLong"])
  170. desc = "\n".join(desc)
  171. content.append((title, self.name+"::"+data2, img, desc))
  172. return content
  173. else:
  174. data1 = item["vodAssetsUrl"].replace("/sb/public/", "")
  175. data1 += "&size=30&page=0"
  176. return self.get_content(data1)
  177. ### kaut kas neparedzets ###
  178. else:
  179. return content
  180. def get_title_desc(self, item):
  181. title = item["title"]["title"]
  182. if "titleBrief" in item["title"]:
  183. title += ". " + item["title"]["titleBrief"]
  184. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"]
  185. desc = []
  186. if "summaryShort" in item["title"]:
  187. desc.append(item["title"]["summaryShort"])
  188. if "summaryLong" in item["title"] and item["title"]["summaryLong"] <> item["title"]["summaryShort"]:
  189. desc.append(item["title"]["summaryLong"])
  190. if "metadata" in item:
  191. if "contentType" in item["metadata"]:
  192. if item["metadata"]["contentType"] == "CLIP":
  193. desc.append("Klips")
  194. #desc.append(item["metadata"]["contentType"])
  195. if "seasonNumber" in item["metadata"]:
  196. desc.append("Season: %s, episode: %s" % (item["metadata"]["seasonNumber"], item["metadata"]["episodeNumber"] if "episodeNumber" in item["metadata"] else ""))
  197. if "displayRunTime" in item:
  198. desc.append("Lenght: %s" % item["displayRunTime"])
  199. if "airDate" in item["metadata"]:
  200. desc.append("Aired: %s" % item["metadata"]["airDate"])
  201. dd = item["metadata"]["airDate"].split("T")[0].split("-")
  202. title = title + " [%s.%s.%s]" % (dd[2], dd[1], dd[0])
  203. if "licensingWindowEnd" in item["metadata"]:
  204. desc.append("Till: %s" %item["metadata"]["licensingWindowEnd"])
  205. desc = "\n".join(desc)
  206. return title, img, desc
  207. def is_video(self,data):
  208. source,data,path,plist,clist,params,qs = self.parse_data(data)
  209. if clist == "asset" and re.search("\d+", plist[1]):
  210. return True
  211. else:
  212. return False
  213. def call(self, data,params=None,headers=None,lang=""):
  214. if not headers: headers = self.headers
  215. url = self.url+data
  216. r = requests.get(url,headers = headers)
  217. result = json.loads(r.content)
  218. #result = self._http_request(url,params,headers=headers)
  219. return result
  220. def get_streams(self,data):
  221. print "[tvplay] get_streams:", data
  222. if not self.is_video(data):
  223. return []
  224. source,data,path,plist,clist,params,qs = self.parse_data(data)
  225. r = self.call(data)
  226. if not ("movie" in r and "contentUrl" in r["movie"]):
  227. return []
  228. data2 = r["movie"]["contentUrl"]
  229. title, img, desc = self.get_title_desc(r)
  230. stream = util.item()
  231. stream["name"] = title
  232. stream["url"] = data2
  233. stream["img"] = img
  234. stream["desc"] = desc
  235. stream["resolver"] = "tvplay"
  236. return [stream]
  237. if __name__ == "__main__":
  238. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  239. import run
  240. source = Source()
  241. data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
  242. if len(sys.argv) > 2:
  243. run.run_cli(source, data)
  244. else:
  245. run.run(source, data)
  246. sys.exit()