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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. from collections import OrderedDict
  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. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  26. import HTMLParser
  27. h = HTMLParser.HTMLParser()
  28. class Source(SourceBase):
  29. def __init__(self, country="lv",cfg_path=None):
  30. self.name = "enigma2"
  31. self.title = "Engima2"
  32. self.img = "enigma2.png"
  33. self.desc = "Get streams from engima2 sat receiver"
  34. self.headers = headers2dict("""
  35. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  36. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  37. Accept-Language: en-US,en;q=0.5
  38. """)
  39. #self.url = "http://login.tvplayhome.lt:8081/sb/public/"
  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([("host", "localhost"), ("user",""),("password","")])
  44. self.options_read()
  45. if self.options["user"]:
  46. self.url = "http://%s/api/" % (self.options["host"])
  47. else:
  48. self.url = "http://%s:%s@%s/api/" % (self.options["user"], self.options["password"],self.options["host"])
  49. ######### Entry point ########
  50. def get_content(self, data):
  51. print "[enigma2] get_content:", data
  52. source, data, path, plist, clist, params, qs = self.parse_data(data)
  53. content = []
  54. content.append(("..return", "back","back.png","Return back"))
  55. if clist=="home":
  56. data3 = "getcurrent"
  57. r2 = self.call(data3)
  58. event = r2["now"]
  59. title, img, desc = self.get_title_desc(event)
  60. content.append(("Current stream: "+title, self.name+"::"+"streamcurrent.m3u", img, desc))
  61. r = self.call("bouquets?stype=tv")
  62. for item in r["bouquets"]:
  63. title = item[1]
  64. data2 = "getservices?sRef=%s" % item[0]
  65. #data2 = "epgbouquet?bRef=%s" % item[1]
  66. content.append((title, self.name+"::"+data2, self.img, title))
  67. return content
  68. elif clist == "getservices":
  69. r = self.call(data)
  70. data3 = data.replace("getservices?sRef", "epgbouquet?bRef")
  71. r2 = self.call(data3)
  72. for item in r["services"]:
  73. title = item["servicename"]
  74. data2 = "stream.m3u?ref=%s&name=%s" % (item["servicereference"], title)
  75. img = self.img
  76. desc = title
  77. for item2 in r2["events"]:
  78. if item2["sref"] == item["servicereference"]:
  79. title, img, desc = self.get_title_desc(item2)
  80. break
  81. content.append((title,self.name+"::"+data2, img,desc))
  82. return content
  83. ### kaut kas neparedzets ###
  84. else:
  85. return content
  86. def get_title_desc(self, event):
  87. t1 = event["begin_timestamp"]
  88. t2 = event["begin_timestamp"] + event["duration_sec"]
  89. t1 = datetime.datetime.fromtimestamp(t1).strftime("%H:%M")
  90. t2 = datetime.datetime.fromtimestamp(t2).strftime("%H:%M")
  91. title = "%s - %s [%s-%s]" % (event["sname"], event["title"], t1, t2)
  92. desc = event["shortdesc"]
  93. if event["longdesc"]:
  94. desc += "\n" + event["longdesc"]
  95. img = event["sref"][:-1].replace(":", "_") + ".png"
  96. img = self.url.replace("/api/", "/picon/") + img
  97. return title, img, desc
  98. def is_video(self,data):
  99. source,data,path,plist,clist,params,qs = self.parse_data(data)
  100. if clist in ("stream.m3u", "streamcurrent.m3u"):
  101. return True
  102. else:
  103. return False
  104. def call(self, data,params=None,headers=None,lang=""):
  105. if not headers: headers = self.headers
  106. url = self.url+data
  107. r = requests.get(url,headers = headers)
  108. result = json.loads(r.content)
  109. #result = self._http_request(url,params,headers=headers)
  110. return result
  111. def get_streams(self,data):
  112. print "[enigma2] get_streams:", data
  113. if not self.is_video(data):
  114. return []
  115. source,data,path,plist,clist,params,qs = self.parse_data(data)
  116. if "stream.m3u" in data:
  117. data3 = data.replace("stream.m3u?ref=","epgservicenow?sRef=")
  118. r2 = self.call(data3)
  119. event = r2["events"][0]
  120. else:
  121. data3 = "getcurrent"
  122. r2 = self.call(data3)
  123. event = r2["now"]
  124. title, img, desc = self.get_title_desc(event)
  125. r = self.call(data)
  126. m = re.search("(http(s)*:.+)", r)
  127. if not m:
  128. raise Exception("No streams found!")
  129. data2 = m.group(1)
  130. #data2 = "http://videolink"
  131. stream = util.item()
  132. stream["name"] = title
  133. stream["url"] = data2
  134. stream["img"] = img
  135. stream["desc"] = desc
  136. stream["resolver"] = "enigma2"
  137. return [stream]
  138. if __name__ == "__main__":
  139. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  140. import run
  141. source = Source()
  142. data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
  143. if len(sys.argv) > 2:
  144. run.run_cli(source, data)
  145. else:
  146. run.run(source, data)
  147. sys.exit()