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

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