123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- # -*- coding: utf-8 -*-
-
- try:
- import wingdbstub
- #import ptvsd
- #ptvsd.enable_attach("debug", address = ('127.0.0.1', 5678))
- #ptvsd.wait_for_attach()
- print "[playstream] Remote debug started"
- except:
- print "[playstream] Remote debug skipped"
- pass
- import os, os.path,sys, glob, shutil, re
- import urllib, traceback
- try:
- import cPickle as pickle
- except:
- import pickle
- import pickle, threading
- from kodiswift import Plugin, ListItem, storage
- from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon, CLI_MODE
- from resources.lib.content import ContentSources, util
- #from downloadqueue import DownloadQueue
-
- cur_directory = os.path.dirname(__file__)
- icon_folder = os.path.join(cur_directory, "resources", "picons")
- icong_url = xbmcaddon.Addon().getAddonInfo("path") + "/resources/picons/"
- sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),"resources","lib", "content", "sources"))
-
- plugin = Plugin()
- prefix = "plugin://%s/" % plugin.id
- #plugin.load_addon_settings()
- use_storage = plugin.get_setting("general_use_storage",bool) # TODO vajag nočekot vai nav labāk lietot pickle
- storage_ttl = plugin.get_setting("general_ttl",int)
- use_proxy = plugin.get_setting("general_proxy_use",bool)
- proxy_url = plugin.get_setting("general_proxy_url",str)
- proxy_remote_key = plugin.get_setting("general_proxy_remote_key",str)
- playlist = plugin.get_setting("general_playlist",str)
- download_dir = plugin.get_setting("general_download_dir",str)
- view_mode = plugin.get_setting("general_view_mode",str)
- streams_file = plugin.get_setting("general_streams_file",str)
- streams_file_remote = plugin.get_setting("general_streams_file_remote",str)
- use_streams_file_remote = plugin.get_setting("general_use_streams_file_remote",bool)
- download_overwrite = plugin.get_setting("general_download_overwrite",bool)
-
- #storage_path = os.path.join(plugin.storage_path,"sources.p")
- if use_storage:
- try:
- storage = plugin.get_storage("playstream","pickle",ttl=30)
- except Exception as e:
- os.remove(os.path.join(plugin.storage_path, "playstream"))
- try:
- storage = plugin.get_storage("playstream", "pickle", ttl=30)
- except Exception as e:
- print "[playstream] error opening storage", plugin.storage_path
- print "Got Exception: ", str(e)
- import traceback
- traceback.print_exc()
- plugin.notify("Error opening permament storage", "Info", 10000, xbmcgui.NOTIFICATION_INFO)
- storage = None
- os.remove(os.path.join(plugin.storage_path, "playstream"))
- cur_directory = os.path.dirname(__file__)
- sources_directory = os.path.join(cur_directory,"resources","lib", "content", "sources")
- cfg_list = glob.glob(os.path.join(sources_directory,"*.cfg"))
- for cf in cfg_list:
- cf2 = os.path.join(plugin.storage_path,os.path.split(cf)[1])
- if not os.path.exists(cf2):
- shutil.copyfile(cf,cf2)
-
- if use_storage and storage is not None and "sources" in storage:
- print "[playstream] Restore sources from storage"
- sources = storage["sources"]
- # if use_storage and os.path.exists(storage_path): #"sources" in storage:
- #sources = pickle.load(open(storage_path,"rb"))
- else:
- print "[playstream] Create sources objects"
- if use_streams_file_remote:
- cfg_file = streams_file_remote
- cfg_file2 = streams_file
- else:
- cfg_file = streams_file
- cfg_file2 = None
- try:
- sources = ContentSources.ContentSources(sources_directory, cfg_file, cfg_file2)
- except Exception as e:
- xbmc.executebuiltin("Notification(Error,%s" % e.message)
- xbmc.executebuiltin("XBMC.ActivateWindow(Home)")
- #plugin.notify("Using streams file '%s'" % sources.plugins["config"].streams_file)
-
- for source in sources.plugins:
- if not ("options" in dir(sources.plugins[source]) and sources.plugins[source].options): continue
- options = sources.plugins[source].options
- if not options: continue
- for option in options:
- key="%s_%s"%(source,option)
- if key in ("viaplay_device"): continue # exception list,
- value = plugin.get_setting(key)
- options[option] = value
- sources.plugins[source].options_write(options)
-
-
- @plugin.route(".+" )
- def main():
- global prefix
- plugin.set_content("movies")
- data = plugin.request.url.replace(prefix,"")
- data = urllib.unquote(data)
- sources.plugins["config"].read_streams()
- if not data:
- data = u"config::home"
- print "[playstream] processing data=%s"%data
-
-
- if sources.is_video(data):
- try:
- streams = sources.get_streams(data)
- except Exception,e:
- #xbmcgui.Dialog().ok("Error",unicode(e))
- plugin.notify(unicode(e),"Error",10000, xbmcgui.NOTIFICATION_ERROR)
- traceback.print_exc()
- return plugin.set_resolved_url(None)
- if streams:
- return play_video(streams)
- else:
- plugin.notify("No streams found!","Error",10000,xbmcgui.NOTIFICATION_ERROR)
- return plugin.set_resolved_url(None)
- else:
- if "{0}" in data:
- q = plugin.keyboard(default=None, heading="Search for", hidden=False)
- if isinstance(q,str):
- q = q.decode("utf8")
- if isinstance(data,str):
- data = data.decode("utf8")
- data = data.format(q)
- try:
- items = get_list(data)
- except Exception,e:
- plugin.notify(unicode(e),"Error",10000,xbmcgui.NOTIFICATION_ERROR)
- traceback.print_exc()
- return []
- if use_storage and storage is not None:
- print "[playstream] Save sources to storage"
- storage["sources"] = sources
- storage.sync()
- return plugin.finish(items, view_mode=get_view_mode(view_mode), update_listing=False, cache_to_disc=False)
-
- def get_list(data):
- if isinstance(data,unicode):
- data = data.encode("utf8")
- content = sources.get_content(data)
- print "[playstream] %s items returned"%len(content)
- items = []
- i = 1
- for item in content:
- if item[1] == "back": continue
- title = item[0].decode("utf8") if isinstance(item[0],str) else item[0]
- data2 = item[1].decode("utf8") if isinstance(item[1],str) else item[1]
- data2 = urllib.quote(data2, ":/")
- is_playable = True if sources.is_video(item[1]) else False
- img = item[2].decode("utf8") if isinstance(item[2],str) else item[2]
- desc = item[3].decode("utf8") if isinstance(item[3],str) else item[3]
- #print title.encode("utf8"),data2,img
- context_menu = [
- #("Add to PlayStream playlist",
- # u'RunScript(special://home/addons/%s/context_menu.py,"playlist","%s","%s","%s","%s")' % (
- # plugin.id, title, data2, playlist, proxy_url)),
- ("Add to PlayStream favorites",
- u'RunScript(special://home/addons/%s/context_menu.py,"add","%s","%s","%s","%s")'%(
- plugin.id, title, data2 ,img, desc)),
- ]
- if data.startswith("config::"):
- lst = data.split("::")[1]
- context_menu.extend([
- ("Delete from PlayStream favorites",
- u'RunScript(special://home/addons/%s/context_menu.py,"delete","%s","%s")' % (
- plugin.id, lst, i)),
- ("Move in PlayStream favorites",
- u'RunScript(special://home/addons/%s/context_menu.py,"move","%s","%s")' % (
- plugin.id, lst, i)),
- ])
- context_menu.extend([
- # "ActivateWindow(<window-id>,'plugin://<plugin-id>/<parameter-optional>',return)"
- ("* Download jobs list *",
- u'RunScript(special://home/addons/%s/queue_management.py,"%s","list")' % (plugin.id, plugin.handle)),
- #("* Download jobs list *", u'ActivateWindow(10025,"plugin://plugin.video.playstream/downloads::list")'), #plugin.id
- #("Active download jobs", u'RunPlugin(plugin://plugin.video.playstream/downloads::list)'), #plugin.id
- ])
- if is_playable:
- context_menu.extend([
- ("Download video to default folder",
- u'RunScript(special://home/addons/%s/context_download.py,"download","%s","%s","%s")' % (
- plugin.id, title, data2, download_dir)),
- ("Download video, ask folder",
- u'RunScript(special://home/addons/%s/context_download.py,"download2","%s","%s","%s")' % (
- plugin.id, title, data2, download_dir)),
- ("Download video to subfolder, ask parent folder",
- u'RunScript(special://home/addons/%s/context_download.py,"download3","%s","%s","%s")' % (
- plugin.id, title, data2, download_dir)),
- ])
- else:
- context_menu.extend([
- ("Download list to default folder",
- u'RunScript(special://home/addons/%s/context_download.py,"download","%s","%s","%s")' % (
- plugin.id, title, data2, download_dir)),
- ("Download list, ask folder",
- u'RunScript(special://home/addons/%s/context_download.py,"download2","%s","%s","%s")' % (
- plugin.id, title, data2, download_dir)),
- ])
-
- item = {
- "label": title,
- "path": prefix+data2,
- "thumbnail":thumb_data(img, is_playable),
- #"poster":thumb_data(img, is_playable) ,
- "icon":thumb_data(img, is_playable) ,
- "info":{"plot":desc},
- "is_playable":is_playable,
- "context_menu": context_menu,
- }
- if view_mode == "Poster":
- item["poster"] = thumb_data(img, is_playable)
- items.append(item)
- i += 1
- return items
-
- def play_video(streams):
- if len(streams)>1:
- slist = []
- for s in streams:
- name2 = "%s,%s" % (s["quality"],s["lang"]) if s["lang"] else s["quality"]
- slist.append("[%s] %s"%(name2, s["name"]))
- res = xbmcgui.Dialog().select("Select stream",slist) if not CLI_MODE else 0
- #res = xbmcgui.Dialog().contextmenu(slist) if not CLI_MODE else 0
- stream = streams[res]
- else:
- stream = streams[0]
- subfiles = []
- #stream = util.stream_chamge(stream)
- if use_proxy:
- # if "resolver" in stream and stream["resolver"] in ("hqq","filmas") or \
- # "surl" in stream and re.search(r"http*://(hqq|goo\.gl)",stream["surl"]) or \
- # "lattelecom.tv/mobile-vod/" in stream["url"]: # TODO
- 3 #re.search(r"http*://.+?lattelecom\.tv/.+?auth_token=[^=]+=", stream["url"]):
- # stream["url"] = util.streamproxy_encode(stream["url"],stream["headers"],proxy_url)
- # stream["headers"] = {}
- qs = {"key": proxy_remote_key} if proxy_remote_key else None
- stream["url"] = util.streamproxy_encode3("playstream", stream["url"], proxy_url, stream["headers"] )
- stream["headers"] = None
- if stream["headers"]:
- hh = []
- for k in stream["headers"]:
- h = "%s=%s"%(k,urllib.quote(stream["headers"][k]))
- hh.append(h)
- hh = "&".join(hh)
- stream["url"] = stream["url"] +"|"+hh
- print "[playstream] play_video ", stream["url"]
- if "subs" in stream and stream["subs"]:
- for sub in stream["subs"]:
- suburl = sub["url"]
- subs = util.Captions(suburl)
- srt = subs.get_srt()
- #subfile = plugin.temp_fn("subtitles.srt")
- subfile = os.path.join(os.path.dirname(__file__),sub["lang"]+".srt")
- f = open(subfile, "w")
- f.write(srt)
- f.close()
- subfiles.append(subfile)
- item = ListItem(label=stream["name"], thumbnail=thumb_data(stream["img"], True), path=stream["url"])
- item.set_info("video",{"plot":stream["desc"]})
- item.set_is_playable(True)
- return plugin.set_resolved_url(item,subfiles)
- #return plugin.play_video(item)
-
- def thumb_data(img, video=False):
- default = "video.png" if video else "folder.png"
- if img in ("default", ""):
- img = default
- if not img.startswith("http"):
- img = icong_url + img
- return img
-
- def get_view_mode(vm):
- modes = {
- "skin.estuary": {
- "None": None,
- "List": 50,
- "Poster": 51,
- "IconWall":52 ,
- "Shift": 53,
- "InfoWall": 54,
- "WideList": 55,
- "Wall": 500,
- "Banner": 501,
- "FanArt": 502
- },
- "skin.estuary.is": {
- "None": None,
- "List": 50,
- "Poster": 51,
- "IconWall":52 ,
- "Shift": 53,
- "InfoWall": 54,
- "WideList": 55,
- "Wall": 500,
- "Banner": 501,
- "FanArt": 502
- },
- "skin.estuary.isl": {
- "None": None,
- "List": 50,
- "Poster": 51,
- "IconWall":52 ,
- "Shift": 53,
- "InfoWall": 54,
- "WideList": 55,
- "Wall": 500,
- "Banner": 501,
- "FanArt": 502
- },
-
- }
- skin = xbmc.getSkinDir()
- if skin in modes and vm in modes[skin]:
- view_mode = modes[skin][vm]
- else:
- view_mode = 50
- return view_mode
-
-
-
- if __name__ == '__main__':
- if CLI_MODE:
- from kodiswift.cli.cli import main as start
- start()
- else:
- plugin.run()
- if use_storage and storage is not None:
- print "[playstream] Save sources to storage"
- storage["sources"] = sources
- storage.sync()
- print "Save sources to storage"
- #pickle.dump(sources,open(storage_path,"wb"),pickle.HIGHEST_PROTOCOL)
|