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

mtgplay.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. #!/usr/bin/env python
  13. # coding=utf8
  14. import urllib2, urllib
  15. import datetime, re, sys
  16. import ssl
  17. ssl._create_default_https_context = ssl._create_unverified_context
  18. from SourceBase import SourceBase
  19. API_URL = 'http://playapi.mtgx.tv/v3/'
  20. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  21. headers0 = headers2dict("""
  22. User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
  23. """)
  24. REGIONS = [
  25. ("Latvia",None,"lv",""),
  26. ("Estonia",None,"ee",""),
  27. ("Lituania",None,"lt",""),
  28. ("Sweden",None,"se",""),
  29. ("Denmark",None,"dk",""),
  30. ("Norway",None,"no",""),
  31. ("Bulgaria",None,"bg","")
  32. ]
  33. class Source(SourceBase):
  34. def __init__(self,country="lv",cfg_path=None):
  35. self.name = "mtgplay"
  36. self.title = "Skaties.lv (TV3)"
  37. self.img = "http://skaties.lv/touch-icon-192x192.png"
  38. self.desc = "MTG skaties.lv satura skatīšanās (LNT,TV3, TV6 u.c.)"
  39. self.country=country
  40. self.pic_size = "327x250" #"1000x765"
  41. def get_content(self, data):
  42. print "[mtgplay] get_content:", data
  43. if "::" in data:
  44. data = data.split("::")[1]
  45. if "/" in data:
  46. citem,cid = data.split("/")
  47. clist = ""
  48. else:
  49. clist = data.split("?")[0]
  50. qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",data)))
  51. citem,cid = ("","")
  52. self.country = qs["country"] if "country" in qs else "lv"
  53. content=[]
  54. content.append(("..return", "back","","Return back"))
  55. if clist=="home":
  56. content.extend([
  57. #("Search", "mtgplay::meklet?country=%s&term={0}"%self.country,"","Search videos"), ### TODO
  58. ("TV Live", "mtgplay::videos?country=%s&order=title&type=live"%self.country,"","TV live streams(not always available)"),
  59. ("Last videos", "mtgplay::videos?country=%s&order=-airdate"%self.country,"","Last aired videos"),
  60. ("Categories", "mtgplay::categories?country=%s&order=name"%self.country,"","Categories"),
  61. ("Channels", "mtgplay::channels?country=%s&order=id"%self.country,"","TV channels"),
  62. ("Programs by name", "mtgplay::formats?country=%s&order=-title"%self.country,"","Programs by name"),
  63. ("Programs by popularity", "mtgplay::formats?country=%s&order=-popularity"%self.country,"","Programs by popularity")
  64. ])
  65. return content
  66. r = self.call(data)
  67. if not r:
  68. content.append(("Error", "","","Error reading '%s'"%data))
  69. return content
  70. if clist:
  71. if r["_links"].has_key("prev"):
  72. data2 = r["_links"]["prev"]["href"].replace(API_URL,"")
  73. content.append(("Previous page", self.name+"::"+data2.encode("utf8"),"", "Goto previous page"))
  74. if "_embedded" in r:
  75. for item in r["_embedded"][clist]:
  76. if "title" in item:
  77. title = item["title"]
  78. elif "name" in item:
  79. title = item["name"]
  80. #data2 = self.name+"::"+"%s/%s"%(clist,item["id"])
  81. img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
  82. desc = item["summary"] if "summary" in item and item["summary"] else ""
  83. ### Video ###
  84. if clist=="videos":
  85. data2 = "videos/%s"%item["id"]
  86. summary = item["summary"] if item["summary"] else ""
  87. air_at = item["broadcasts"][0]["air_at"] if "broadcasts" in item and len(item["broadcasts"])>0 and "air_at" in item["broadcasts"][0] else ""
  88. if not air_at:
  89. air_at = item["publish_at"] if "publish_at" in item else ""
  90. air_at = air_at[0:16].replace("T"," ") if air_at else ""
  91. try: playable_to = item["broadcasts"][0]["playable_to"]
  92. except: playable_to =""
  93. playable_to = "(till "+playable_to[0:10].replace("T"," ")+")" if playable_to else ""
  94. duration = item["duration"] if "duration" in item else ""
  95. duration = str(datetime.timedelta(seconds=int(duration))) if duration else ""
  96. try:
  97. views = item["views"]["total"] if "views" in item and "total" in item["views"] else ""
  98. views = views+" views"
  99. except: views = ""
  100. desc = "Aired: %s %s\nDuration: %s %s\n\n%s"%(air_at, playable_to,duration,views,summary)
  101. ### Categories ###
  102. elif clist == "categories":
  103. #data2 = item["_links"]["formats"]["href"].replace(API_URL,"")
  104. data2 = "formats?category=%s"%item["id"]
  105. if "country" in qs: data2 += "&country="+qs["country"]
  106. if "category" in qs: data2 += "&category="+qs["category"]
  107. if "channel" in qs: data2 += "&channel="+qs["channel"]
  108. data2 += "&order=title"
  109. ### Channels ###
  110. elif clist == "channels":
  111. #data2 = item["_links"]["categories"]["href"].replace(API_URL,"")
  112. data2 = "categories?channel=%s"%item["id"]
  113. if "country" in qs: data2 += "&country="+qs["country"]
  114. if "category" in qs: data2 += "&category="+qs["category"]
  115. if "channel" in qs: data2 += "&channel="+qs["channel"]
  116. data2 += "&order=name"
  117. ### Formats (programs) ###
  118. elif clist == "formats":
  119. #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
  120. data2 = "seasons?format=%s"%item["id"]
  121. #if "country" in qs: data2 += "&country="+qs["country"]
  122. #if "category" in qs: data2 += "&category="+qs["category"]
  123. #if "channel" in qs: data2 += "&channel="+qs["channel"]
  124. data2 += "&order=title"
  125. air_at = item["latest_video"]["publish_at"] if "publish_at" in item["latest_video"] else ""
  126. air_at = air_at[0:16].replace("T"," ") if air_at else ""
  127. if air_at:
  128. desc = "Last video: %s\n"%air_at + desc
  129. ### Seasons ###
  130. elif clist == "seasons":
  131. #data2 = item["_links"]["videos"]["href"].replace(API_URL,"")
  132. data2 = "videos?season=%s"%item["id"]
  133. #if "country" in qs: data2 += "&country="+qs["country"]
  134. #if "category" in qs: data2 += "&category="+qs["category"]
  135. #if "channel" in qs: data2 += "&channel="+qs["channel"]
  136. data2 += "&order=title"
  137. summary = item["summary"] if "summary" in item and item["summary"] else ""
  138. try:
  139. latest_video = item["latest_video"]["publish_at"]
  140. latest_video = latest_video[0:16].replace("T"," ")
  141. except: latest_video = ""
  142. desc = ("%s\nLatest video: %s"%(summary,latest_video))
  143. content.append((title.encode("utf8"),self.name+"::"+data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8")))
  144. if r["_links"].has_key("next"):
  145. data2 = r["_links"]["next"]["href"].replace(API_URL,"").encode("utf8")
  146. content.append(("Next page", self.name+"::"+data2.encode("utf8"),"","Goto next page"))
  147. elif citem:
  148. item = r
  149. if "title" in item:
  150. title = item["title"]
  151. elif "name" in item:
  152. title = r["name"]
  153. #data2 = self.name+"::"+"%s/%s"%(clist,item["id"])
  154. img = item["_links"]["image"]["href"].replace("{size}",self.pic_size) if "image" in item["_links"] else ""
  155. desc = item["summary"] if "summary" in item and item["summary"] else ""
  156. dd = "videos/stream/%s"%cid
  157. r2 = self.call(dd)
  158. if "streams" in r2 and "hls" in r2["streams"]:
  159. data2 = r2["streams"]["hls"]
  160. content = (title.encode("utf8"),data2.encode("utf8"),img.encode("utf8"),desc.encode("utf8"))
  161. elif "msg" in r2:
  162. content = (r2["msg"].encode("utf8"),"","","")
  163. else:
  164. content = ("Error getting stream","","","")
  165. else:
  166. pass
  167. return content
  168. def is_video(self,data):
  169. if "::" in data:
  170. data = data.split("::")[1]
  171. cmd = data.split("/")
  172. if cmd[0]=="videos":
  173. return True
  174. else:
  175. return False
  176. def get_stream(self,id):
  177. dd = "videos/stream/%s"%id
  178. r2 = self.call(dd)
  179. if "streams" in r2 and "hls" in r2["streams"]:
  180. data2 = r2["streams"]["hls"]
  181. else:
  182. data2 = ""
  183. return data2.encode("utf8")
  184. def call_all(self, endpoint, params = None):
  185. url = API_URL % (endpoint)
  186. if params:
  187. url += '?' + params
  188. print "[TVPlay Api] url: ",url
  189. result = []
  190. while True:
  191. content = self._http_request(url)
  192. if content:
  193. try:
  194. content = json.loads(content)
  195. except Exception, ex:
  196. return {" Error " : "in call_api: %s" % ex}
  197. else: break
  198. if content.has_key("_embedded") and content["_embedded"].has_key(endpoint):
  199. result.extend(content["_embedded"][endpoint])
  200. pass
  201. else: break
  202. if content.has_key("_links") and content["_links"].has_key("next"):
  203. url = content["_links"]["next"]["href"]
  204. else: break
  205. return result
  206. def call(self, data,headers=headers0):
  207. url = API_URL + data
  208. #print "[TVPlay Api] url: ",url
  209. result = []
  210. content = self._http_request(url)
  211. if content:
  212. try:
  213. result = json.loads(content)
  214. except Exception, ex:
  215. return None
  216. return result
  217. def _http_request0(self, url,headers=headers0):
  218. try:
  219. r = urllib2.Request(url, headers=headers)
  220. u = urllib2.urlopen(r)
  221. content = u.read()
  222. u.close()
  223. return content
  224. except Exception as ex:
  225. if "read" in ex:
  226. content = ex.read()
  227. else:
  228. content = None
  229. return content
  230. if __name__ == "__main__":
  231. country= "lv"
  232. c = Source(country)
  233. if len(sys.argv)>1:
  234. data= sys.argv[1]
  235. else:
  236. data = "home"
  237. content = c.get_content(data)
  238. for item in content:
  239. print item
  240. #cat = api.get_categories(country)
  241. #chan = api.get_channels("lv")
  242. #prog = api.get_programs(channel=6400)
  243. #prog = api.get_programs(category=55)
  244. #seas = api.get_seasons(program=6453)
  245. #str = api.get_streams(660243)
  246. #res = api.get_videos(802)
  247. #formats = api.getAllFormats()
  248. #det = api.detailed("1516")
  249. #vid = api.getVideos("13170")
  250. pass