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

tvplay.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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&f_country=LV" % 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&f_country=LV"
  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&f_country=LV"
  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&f_country=LV"
  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&f_country=LV" % 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=&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=&descending=true&tenantId=2" % kat_num
  113. return self.get_content(data)
  114. elif path == "asset/search":
  115. r = self.call(data)
  116. if not "content" in r:
  117. raise Exception("Error reading items list")
  118. for item in r["content"]:
  119. data2 = "asset/%s" % item["id"]
  120. title, img, desc = self.get_title_desc(item)
  121. content.append((title, self.name+"::"+data2, img, desc))
  122. if "page" in qs and len(r["content"]) == 30:
  123. page = int(qs["page"]) + 1
  124. data2 = re.sub("page=\d+", "page=%s" % page, data)
  125. content.append(("Next page",self.name+"::"+data2,"next.png","Next page"))
  126. return content
  127. elif plist[0] == "tvSeries" and plist[1] == "category":
  128. r = self.call(data)
  129. if not "content" in r:
  130. raise Exception("Error reading items list")
  131. for item in r["content"]:
  132. tvseries = True if "type" in qs and qs["type"] == "tvseries" else False
  133. if tvseries and not "seasonNumber" in item: # tvseries (programma)
  134. #if len(item["seasonIds"]) > 1:
  135. #tvseries_id = item["id"]
  136. #else:
  137. # tvseries_id = item["seasonIds"][0]
  138. try:
  139. data2 = "tvSeries/%s" % item["id"]
  140. title = item["title"]["title"] if "title" in item["title"] else item["titles"]["LV"]["title"]
  141. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  142. desc = []
  143. if "summaryShort" in item["title"]:
  144. desc.append(item["title"]["summaryShort"])
  145. elif "summaryShort" in item["titles"]["LV"]:
  146. desc.append(item["titles"]["LV"]["summaryShort"])
  147. if "summaryLong" in item["title"]:
  148. desc.append(item["title"]["summaryLong"])
  149. elif "summaryLong" in item["titles"]["LV"]:
  150. desc.append(item["titles"]["LV"]["summaryLong"])
  151. desc = "\n".join(desc)
  152. content.append((title, self.name+"::"+data2, img, desc))
  153. except:
  154. return content
  155. if "page" in qs:
  156. page = int(qs["page"]) + 1
  157. data2 = re.sub("page=\d+", "page=%s" % page, data)
  158. content.append(("Next page",self.name+"::"+data2,"next.png","Next page"))
  159. return content
  160. elif plist[0] == "tvSeries":
  161. item = self.call(data)
  162. if "seasonIds" in item and len(item["seasonIds"]) > 1:
  163. title0 = item["title"]["title"] + ". " + "Visi video"
  164. data2 = "asset/search?f_metadata.tvSeriesId=%s&page=0&size=30" % item["id"]
  165. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  166. desc = []
  167. if "summaryShort" in item["title"]:
  168. desc.append(item["title"]["summaryShort"])
  169. if "summaryLong" in item["title"]:
  170. desc.append(item["title"]["summaryLong"])
  171. desc = "\n".join(desc)
  172. content.append((title0, self.name+"::"+data2, img, desc))
  173. for season in item["seasonIds"]:
  174. data2 = "tvSeries/%s" % season
  175. item = self.call(data2)
  176. title = item["title"]["title"]
  177. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"] if "posterUrl" in item else self.img
  178. desc = []
  179. if "summaryShort" in item["title"]:
  180. desc.append(item["title"]["summaryShort"])
  181. if "summaryLong" in item["title"]:
  182. desc.append(item["title"]["summaryLong"])
  183. desc = "\n".join(desc)
  184. content.append((title, self.name+"::"+data2, img, desc))
  185. return content
  186. else:
  187. data1 = item["vodAssetsUrl"].replace("/sb/public/", "")
  188. data1 += "&size=30&page=0"
  189. return self.get_content(data1)
  190. ### kaut kas neparedzets ###
  191. else:
  192. return content
  193. def get_title_desc(self, item):
  194. title = item["title"]["title"]
  195. if "titleBrief" in item["title"]:
  196. title += ". " + item["title"]["titleBrief"]
  197. img = "http://login.tvplayhome.lt:8081" + item["posterUrl"]
  198. desc = []
  199. if "summaryShort" in item["title"]:
  200. desc.append(item["title"]["summaryShort"])
  201. if "summaryLong" in item["title"] and item["title"]["summaryLong"] <> item["title"]["summaryShort"]:
  202. desc.append(item["title"]["summaryLong"])
  203. if "metadata" in item:
  204. if "contentType" in item["metadata"]:
  205. if item["metadata"]["contentType"] == "CLIP":
  206. desc.append("Klips")
  207. #desc.append(item["metadata"]["contentType"])
  208. if "seasonNumber" in item["metadata"]:
  209. desc.append("Season: %s, episode: %s" % (item["metadata"]["seasonNumber"], item["metadata"]["episodeNumber"] if "episodeNumber" in item["metadata"] else ""))
  210. if "displayRunTime" in item:
  211. desc.append("Lenght: %s" % item["displayRunTime"])
  212. if "airDate" in item["metadata"]:
  213. desc.append("Aired: %s" % item["metadata"]["airDate"])
  214. dd = item["metadata"]["airDate"].split("T")[0].split("-")
  215. title = title + " [%s.%s.%s]" % (dd[2], dd[1], dd[0])
  216. if "licensingWindowEnd" in item["metadata"]:
  217. desc.append("Till: %s" %item["metadata"]["licensingWindowEnd"])
  218. desc = "\n".join(desc)
  219. return title, img, desc
  220. def is_video(self,data):
  221. source,data,path,plist,clist,params,qs = self.parse_data(data)
  222. if clist == "asset" and re.search("\d+", plist[1]):
  223. return True
  224. else:
  225. return False
  226. def call(self, data,params=None,headers=None,lang=""):
  227. if not headers: headers = self.headers
  228. url = self.url+data
  229. r = requests.get(url,headers = headers)
  230. result = json.loads(r.content)
  231. #result = self._http_request(url,params,headers=headers)
  232. return result
  233. def get_streams(self,data):
  234. print "[tvplay] get_streams:", data
  235. if not self.is_video(data):
  236. return []
  237. source,data,path,plist,clist,params,qs = self.parse_data(data)
  238. r = self.call(data)
  239. if not ("movie" in r and "contentUrl" in r["movie"]):
  240. return []
  241. data2 = r["movie"]["contentUrl"]
  242. title, img, desc = self.get_title_desc(r)
  243. stream = util.item()
  244. stream["name"] = title
  245. stream["url"] = data2
  246. stream["img"] = img
  247. stream["desc"] = desc
  248. stream["resolver"] = "tvplay"
  249. return [stream]
  250. if __name__ == "__main__":
  251. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  252. import run
  253. source = Source()
  254. data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
  255. if len(sys.argv) > 2:
  256. run.run_cli(source, data)
  257. else:
  258. run.run(source, data)
  259. sys.exit()