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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. import sys, os, re
  9. import glob, traceback
  10. sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
  11. from sources.SourceBase import stream_type
  12. import util
  13. show_hidden = False # Ja True, tad vienalga radā hidden sources (noder izstradē)
  14. class ContentSources(object):
  15. """Wrapper for content sources plugin"""
  16. #----------------------------------------------------------------------
  17. def __init__(self, plugin_path, cfg_file="streams.cfg", cfg_file2=None):
  18. self.plugins = {}
  19. self.error_content = [("..atpakaļ", "back", "back.png", "Kļūda, atgriezties atpakaļ")]
  20. if not plugin_path:
  21. plugin_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "sources")
  22. sys.path.insert(0, plugin_path)
  23. #for f in os.listdir(plugin_path):
  24. #for f in next(os.walk(plugin_path))[2]:
  25. print "ContentSources: Importing sources from "+plugin_path
  26. files = glob.glob(os.path.join(plugin_path, "*.py"))
  27. for f in files:
  28. fname, ext = os.path.splitext(f)
  29. fname = os.path.split(fname)[1]
  30. if fname == "__init__": continue
  31. if ext == '.py':
  32. #print "Importing %s"%fname
  33. mod = __import__(fname)
  34. reload(mod)
  35. if "Source" in dir(mod):
  36. if mod.__name__ == "config":
  37. self.plugins[fname] = mod.Source(cfg_file=cfg_file)
  38. else:
  39. self.plugins[fname] = mod.Source()
  40. print fname+ " imported"
  41. else:
  42. pass
  43. #print fname+ "skipped"
  44. sys.path.pop(0)
  45. if not "config" in self.plugins:
  46. raise Exception("Problem importing content sources")
  47. cfg = self.plugins["config"]
  48. for pl in self.plugins.keys():
  49. found = False
  50. for lst in cfg.get_lists():
  51. for item in cfg.lists[lst]:
  52. if item[1].split("::")[0]==pl:
  53. found = True
  54. break
  55. if found: break
  56. if not found:
  57. title = self.plugins[pl].title if "title" in dir(self.plugins[pl]) else pl
  58. img = self.plugins[pl].img if "img" in dir(self.plugins[pl]) else ""
  59. desc = self.plugins[pl].desc if "desc" in dir(self.plugins[pl]) else title
  60. cfg.add_item("home",(title,"%s::home"%pl,img,desc))
  61. cfg.write_streams()
  62. def get_content(self,data, qs=None):
  63. source = data.split("::")[0]
  64. if source in self.plugins:
  65. content0 = self.plugins[source].get_content(data)
  66. if content0:
  67. content = []
  68. if isinstance(content0,list):
  69. for i,item in enumerate(content0):
  70. source2 = item[1].split("::")[0]
  71. if not (source2 == "back" or item[1].startswith("http") or item[1].startswith("rtmp")):
  72. if source2 not in self.plugins or (not show_hidden and "hidden" in dir(self.plugins[source2]) and self.plugins[source2].hidden):
  73. continue
  74. item2=[]
  75. for el in item:
  76. if isinstance(el,unicode):
  77. el = el.encode("utf8")
  78. el = util.unescape(el)
  79. item2.append(el)
  80. content.append(tuple(item2))
  81. else:
  82. item2=[]
  83. for el in content0:
  84. if isinstance(el,unicode):
  85. el = el.encode("utf8")
  86. item2.append(el)
  87. content=tuple(item2)
  88. return content
  89. else:
  90. return self.error_content
  91. else:
  92. return self.error_content
  93. def get_streams(self,data, qs=None):
  94. if stream_type(data):
  95. if "::" in data:
  96. data = data.split("::")[1]
  97. content = self.get_content(data)
  98. stream = util.item()
  99. stream["name"] = data
  100. stream["url"] = data
  101. stream["type"] = stream_type(data)
  102. #stream["img"] = ""
  103. #stream["desc"] = ""
  104. return[stream]
  105. if not self.is_video(data):
  106. return []
  107. source = data.split("::")[0]
  108. if source in self.plugins:
  109. streams = self.plugins[source].get_streams(data)
  110. for s in streams:
  111. for k in s:
  112. if isinstance(s[k],unicode):
  113. s[k] = s[k].encode("utf8")
  114. if not "resolver" in s:
  115. s["resolver"] = source
  116. if not "surl" in s or not s["surl"]:
  117. s["surl"] = data
  118. if not "nfo" in s:
  119. s["nfo"]={"movie":{"title":s["name"],"thumb":s["img"],"plot":s["desc"]}}
  120. return streams
  121. else:
  122. return []
  123. def get_info(self,data, qs=None):
  124. nfo = {}
  125. if self.is_video(data):
  126. source = data.split("::")[0]
  127. if source in self.plugins:
  128. if "get_info" in dir(self.plugins[source]):
  129. nfo = self.plugins[source].get_info(data)
  130. else:
  131. streams = self.get_streams(data)
  132. if streams and "nfo" in streams[0] and streams[0]["nfo"]:
  133. nfo = streams[0]["nfo"]
  134. else:
  135. nfo = {"movie": {"title": current[0], "thumb": self.current[2], "plot": self.current[3]}}
  136. else:
  137. pass # TODO create nfo for listing
  138. return nfo
  139. def stream_type(self,data, qs=None):
  140. return stream_type(data)
  141. def is_video(self,data, qs=None):
  142. if self.stream_type(data):
  143. return True
  144. source = data.split("::")[0]
  145. if source in self.plugins:
  146. return self.plugins[source].is_video(data)
  147. else:
  148. return False
  149. def options_read(self,source, qs=None):
  150. if source in self.plugins:
  151. options = self.plugins[source].options_read()
  152. if options:
  153. return options
  154. else:
  155. return None
  156. else:
  157. return None
  158. def options_write(self,source,options, qs=None):
  159. if source in self.plugins:
  160. return self.plugins[source].options_write(options)
  161. else:
  162. return None
  163. if __name__ == "__main__":
  164. from run import run
  165. show_hidden = False
  166. data= sys.argv[1] if len(sys.argv) > 1 else "config::home"
  167. cfg_file = sys.argv[2] if len(sys.argv) > 2 else "streams.cfg"
  168. sources = ContentSources("sources", cfg_file=cfg_file)
  169. run(sources, data)