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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 traceback
  15. from collections import OrderedDict
  16. import ssl
  17. if "_create_unverified_context" in dir(ssl):
  18. ssl._create_default_https_context = ssl._create_unverified_context
  19. from SourceBase import SourceBase
  20. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  21. headers0 = headers2dict("""
  22. Host: m-api.ustvnow.com
  23. User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
  24. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  25. DNT: 1
  26. Connection: keep-alive
  27. """)
  28. import HTMLParser
  29. h = HTMLParser.HTMLParser()
  30. class Source(SourceBase):
  31. def __init__(self,country="lv",cfg_path=None):
  32. self.hidden = True
  33. self.name = "ustvnow"
  34. self.title = "USTVNow"
  35. self.img = "ustvnow.png"
  36. self.desc = "USTVNow kanālu tiešraide"
  37. self.headers = headers0
  38. self.country=country
  39. self.token = ""
  40. cur_directory = os.path.dirname(os.path.abspath(__file__))
  41. if not cfg_path: cfg_path = cur_directory
  42. self.config_file = os.path.join(cfg_path,self.name+".cfg")
  43. self.options = OrderedDict([("user","lietotajs"),("password","parole")])
  44. self.options_read()
  45. def login(self,user="",password=""):
  46. self.options_read()
  47. if not user: user=self.options["user"]
  48. if not password: password = self.options["password"]
  49. headers = headers2dict("""
  50. Host: m-api.ustvnow.com
  51. Accept-Language: en-US,en;q=0.5
  52. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  53. Accept: text/html,application/xhtml+xml,application/xml
  54. Connection: keep-alive
  55. """)
  56. url = "http://m-api.ustvnow.com/iphone/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
  57. #url = "http://m-api.ustvnow.com/gtv/1/live/login?username=%s&password=%s&device=gtv&redir=0"%(user,password)
  58. r = self._http_request(url,headers=headers)
  59. if 'success' in r:
  60. self.token = re.search('"token":"([^"]+)',r).group(1)
  61. return True
  62. else:
  63. return False
  64. def get_content(self, data):
  65. print "[ustvnow] get_content:", data
  66. if "::" in data:
  67. data = data.split("::")[1]
  68. path = data.split("?")[0]
  69. clist = path.split("/")[0]
  70. params = data[data.find("?"):] if "?" in data else ""
  71. qs = dict(map(lambda x:x.split("="),re.findall("\w+=\w+",params)))
  72. lang = qs["lang"] if "lang" in qs else self.country
  73. content=[]
  74. content.append(("..return", "back","back.png","Return back"))
  75. if clist=="home":
  76. content.extend([
  77. ("TV live streams", "ustvnow::tvlive","","TV live streams"),
  78. ("Movies", "ustvnow::movies","","Movies (not implemented yet"),
  79. ("Recordings", "ustvnow::recordings","","Recordings (not implemented yet"),
  80. ])
  81. return content
  82. if clist=="movies":
  83. return content
  84. if clist=="recordings":
  85. return content
  86. ### Tiesraides kanalu saraksts ###
  87. elif data=="tvlive":
  88. if not self.token:
  89. if not self.login():
  90. raise Exception("Can not login\nPlease check USTVNow username/password in\n/usr/lib/enigma2/python/Plugins/Extensions/sources/ustvnow.cfg file")
  91. data = "live/channelguide?token=%s"%self.token
  92. self.r = self.call(data)
  93. if not self.r:
  94. return content
  95. for item in self.r["results"]:
  96. if item["order"] == 1:
  97. title = item["stream_code"]
  98. title = h.unescape(title.decode("utf8")).encode("utf8")
  99. img = "http://m-api.ustvnow.com/"+item["prg_img"] #item["img"]
  100. data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
  101. desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
  102. content.append((title,self.name+"::"+data2,img,desc))
  103. return content
  104. ### Tiesraides kanāls ###
  105. elif path == "live/view":
  106. url = "http://m-api.ustvnow.com/stream/1/%s"%data
  107. #url = "http://m.ustvnow.com/stream/1/live/view?scode=whphd&token=o7oxits4dcjd8hbxusf9d9cgcyad&br_n=Chrome&br_v=60&br_d=desktop"
  108. url = "http://m.ustvnow.com/stream/1/live/%s"%data
  109. headers = headers2dict("""
  110. Accept: application/json, text/javascript, */*; q=0.01
  111. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
  112. Referer: http://watch.ustvnow.com/guide
  113. """)
  114. r = self._http_request(url, headers=headers )
  115. if not r:
  116. return ("No stream found %s"%data,"","","No stream found")
  117. r = json.loads(r)
  118. if not "r" in dir(self):
  119. if not self.token:
  120. self.login()
  121. self.r = self.call("live/channelguide?token=%s"%self.token)
  122. if self.r:
  123. ch = qs["scode"]
  124. for item in self.r["results"]:
  125. if item["order"] == 1 and item["scode"] == ch:
  126. title = item["stream_code"]
  127. title = "%s - %s (%s)"%(item["stream_code"],item["title"],item["event_time"])
  128. img = "http://m-api.ustvnow.com/"+item["prg_img"]
  129. data2 = "live/view?scode=%s&token=%s"%(item["scode"],self.token)
  130. desc = "%s\n%s (+%s')\n%s"%(item["title"],item["event_time"],int(item["actualremainingtime"])/60,item["description"])
  131. else:
  132. title = data
  133. data2 = r["stream"]
  134. desc = title
  135. img = "" # img TODO
  136. return (title,data2,img,desc)
  137. def is_video(self,data):
  138. if "::" in data:
  139. data = data.split("::")[1]
  140. if "live/view" in data:
  141. return True
  142. else:
  143. return False
  144. def call(self, data,headers=headers0,lang=""):
  145. if not lang: lang = self.country
  146. url = "http://m-api.ustvnow.com/gtv/1/"+data
  147. content = self._http_request(url)
  148. result = None
  149. if content:
  150. try:
  151. result = json.loads(content)
  152. except Exception, ex:
  153. return None
  154. return result
  155. if __name__ == "__main__":
  156. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  157. import run
  158. source = Source()
  159. data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
  160. run.run(source, data)
  161. sys.exit()