#!/usr/bin/env python
# coding=utf8
#
# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
# Used fragments of code from enigma2-plugin-tv3play by Taapat (https://github.com/Taapat/enigma2-plugin-tv3play)
#
import os,time,sys,os,os.path
import datetime,re
import urllib2
from Plugins.Plugin import PluginDescriptor
from enigma import ePicLoad, eServiceReference, eTimer, getDesktop
from Screens.Screen import Screen
from Screens.InfoBarGenerics import InfoBarShowHide
from Screens.InfoBar import MoviePlayer
from Screens.MessageBox import MessageBox
from Screens.LocationBox import LocationBox
from Screens.ChoiceBox import ChoiceBox
from Screens.VirtualKeyBoard import VirtualKeyBoard
#from Screens.InputBox import InputBox
from Components.AVSwitch import AVSwitch
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.Label import Label
from Components.Input import Input
from Components.MenuList import MenuList
from Components.Pixmap import Pixmap
from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from Components.Button import Button
from Components.Task import job_manager
from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations, ConfigDirectory, ConfigSet, ConfigYesNo, ConfigSelection, getConfigListEntry, ConfigSelectionNumber, ConfigNumber
from Components.ConfigList import ConfigListScreen
from Tools import Notifications
from Tools.BoundFunction import boundFunction
from Tools.Directories import resolveFilename, SCOPE_PLUGINS
from Tools.LoadPixmap import LoadPixmap
from twisted.web.client import downloadPage,defer,reactor
import ContentSources
import util
from VideoDownload import downloadJob, HLSDownloadJob,VideoDownloadList
#import enigma2_api
e2 = None
##########################################################################
config.plugins.playstream = ConfigSubsection()
config.plugins.playstream.locations = ConfigLocations(default=["/media/hdd/movie/"])
config.plugins.playstream.download_dir = ConfigDirectory(default="/media/hdd/movie/")
config.plugins.playstream.tmp_dir = ConfigDirectory(default="/tmp/playstream/")
config.plugins.playstream.streamproxy_start = ConfigYesNo(default = True)
config.plugins.playstream.overwrite_download = ConfigYesNo(default = False)
#config.plugins.playstream.size = ConfigSelection({"400x240":"400x240","220x132":"220x132","100x60":"100x60"}, default="220x132")
config.plugins.playstream.clear_tmp = ConfigYesNo(default = True)
class ConfigScreen(ConfigListScreen,Screen):
skin = """
"""
def __init__(self, session, args = 0):
self.session = session
#self.setup_title = "Options"
Screen.__init__(self, session)
cfg = config.plugins.playstream
self.list = [
getConfigListEntry(_("Download folder"), cfg.download_dir),
getConfigListEntry(_("Overwrite download video"), cfg.overwrite_download),
getConfigListEntry(_("TMP folder"), cfg.tmp_dir),
getConfigListEntry(_("Clear tmp folder on exit"), cfg.clear_tmp),
getConfigListEntry(_("Start playstreamproxy"), cfg.streamproxy_start),
]
ConfigListScreen.__init__(self, self.list, session = self.session)
self["key_red"] = Button(_("Cancel"))
self["key_green"] = Button(_("Save"))
self["key_yellow"] = Button("")
self["key_blue"] = Button("")
self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
{
"red": self.cancel,
"green": self.save,
"save": self.save,
"cancel": self.cancel,
"ok": self.ok,
}, -2)
def getCurrentEntry(self):
return self["config"].getCurrent()[0]
def getCurrentValue(self):
return str(self["config"].getCurrent()[1].getText())
def ok(self):
if self["config"].getCurrent()[1] == config.plugins.playstream.download_dir:
folder = config.plugins.playstream.download_dir.value
#self.session.openWithCallback(self.cb_download_dir, LocationBox,"Select Folder")
self.session.openWithCallback(self.cb_download_dir, LocationBox,"Select download folder","",config.plugins.playstream.download_dir.value,config.plugins.playstream.locations,False,"Select folder",None,True,True)
elif self["config"].getCurrent()[1] == config.plugins.playstream.tmp_dir:
self.session.openWithCallback(self.select_tmp_dir, LocationBox,"Select tmp folder","",config.plugins.playstream.download_dir.value,config.plugins.playstream.locations,False,"Select folder",None,True,True)
else:
self.save()
def cb_download_dir(self, folder, select=None):
if not folder:
return
print "Folder selected - %s"%folder
config.plugins.playstream.download_dir.setValue(folder)
config.plugins.playstream.download_dir.save()
config.plugins.playstream.locations.save()
config.save()
def select_tmp_dir(self, folder, select=None):
if not folder:
return
print "Folder selected - %s"%folder
config.plugins.playstream.tmp_dir.setValue(folder)
config.plugins.playstream.tmp_dir.save()
config.plugins.playstream.locations.save()
config.save()
def save(self):
print "saving"
self.saveAll()
self.close(True,self.session)
def cancel(self):
#print "cancel"
self.close(False,self.session)
def make_service(stream):
url = stream["url"]
headers = []
if stream.has_key("headers"):
for h in stream["headers"]:
headers.append("%s=%s"%(h,stream["headers"][h]))
if headers:
headers ="&".join(headers)
url = url+"#"+headers
print "stream_url with headers=",headers
url = url.encode("utf8")
if "|" in url:
url = url.replace("|","#")
service_type = 4097
if re.search("\.ts$",url.split("?")[0],re.IGNORECASE):
service_type = 1
if "resolver" in stream and stream["resolver"] in ("hqq","viaplay","filmas"):
url = util.streamproxy_encode(stream["url"], stream["headers"])
#if os.path.exists("/usr/bin/exteplayer3"): # problem playing hqq streams with gstreamer, use exteplayer3
#service_type = 5002
print "service_type=",service_type
print "stream_url=",url
service = eServiceReference(service_type, 0, url)
service.setName( stream["name"])
return service
#####################################################################################################################
class PSSubs(Screen):
def __init__(self, session):
desktopWidth = getDesktop(0).size().width()
desktopHeight = getDesktop(0).size().height()
offset = 20
screenWidth = desktopWidth - (2 * offset)
widgetWidth = screenWidth / 2 - 5
self.skin = """
""" % (offset, desktopHeight-offset-140, screenWidth, screenWidth)
self['subtitle'] = Label()
Screen.__init__(self, session)
#####################################################################################################################
class PSPlayer(MoviePlayer):
def __init__(self, session, streams):
print "PSPlayer init: ",streams
self.session = session
self.streams = streams
self.cur_stream = self.streams[0] # TODO
self.selected = 0
self.resume_pos = 0
service = make_service(self.cur_stream)
MoviePlayer.__init__(self, session, service)
self.skinName = "MoviePlayer"
self["actions"] = ActionMap(["MediaPlayerActions","MediaPlayerSeekActions","MoviePlayerActions","InfobarSeekActions","MovieSelectionActions","ColorActions"], {
"stop":self.leavePlayer,
"leavePlayer":self.leavePlayer,
"audio":self.select_stream,
"AudioSelection":self.select_stream,
"green":self.select_stream,
"subtitles":self.select_captions,
"text":self.select_captions,
"yellow_key":self.select_captions,
"yellow":self.select_captions,
"pauseServiceYellow":self.select_captions,
"pause":self.select_captions,
"showEventInfo":self.service_info,
"info":self.service_info
})
self.stimer = eTimer()
if "callback" in dir(self.stimer):
self.stimer.callback.append(self.update_subtitles)
elif "timeout":
self.stimer_conn = self.stimer.timeout.connect(self.update_subtitles)
else:
self.stimer = None
self.stimer_step = 500
if self.cur_stream["subs"]:
self.subs = self.cur_stream["subs"]
self.cur_subs = 0 # TODO - no konfiguracijas
self.svisible = True # TODO - no konfiguracija
self.sind = 0
self.get_subs_current()
else:
self.subs = []
self.cur_subs = 0
self.svisible = False
self.subtitle_window = self.session.instantiateDialog (PSSubs)
self.onLayoutFinish.append(self.start_subtitles_timer)
def start_subtitles_timer(self):
if self.stimer:
self.subtitle_window.show()
print "start_subtitles_timer"
self.stimer.start(self.stimer_step)
def get_sub_pts(self,pts):
sc = self.get_sub_ind(self.sind) # current subbtitle
while True:
if not sc:
return "Error - no subs find" # TODO
if pts > sc["end"]:
self.sind += 1
sc = self.get_sub_ind(self.sind)
continue
else:
if pts
{
"template": [MultiContentEntryText(pos=(10, 1), size=(560, 30), \
font=0, flags=RT_HALIGN_LEFT, text=0)],
"fonts": [gFont("Regular", 20)],
"itemHeight": 30
}
"""
def __init__(self, session):
Screen.__init__(self, session)
#self.setTitle2("Home")
self.session = session
self.e2 = None
self["key_red"] = Button(_("Exit"))
self["key_green"] = Button(_("Select"))
self["key_yellow"] = Button(_("Options"))
self["key_blue"] = Button(_("Config"))
self["key_menu"] = Button("Menu")
self["key_exit"] = Button("Back")
self["actions"] = ActionMap(["OkCancelActions", "ColorActions","MenuActions", "NumberActions"],
{
#"cancel": self.Cancel,
"ok": self.Ok,
"green": self.Ok,
"red": self.Cancel,
"yellow": self.options_screen,
"blue": self.config_screen,
"menu": self.item_menu,
"cancel": self.Back,
})
self["list"] = List([])
self["list"].onSelectionChanged.append(self.SelectionChanged)
self["pic"] = Pixmap()
self["cur"] = Label()
self["title"] = Label()
self.downloading = 0
self.activeDownloads = 0
if not os.path.exists(config.plugins.playstream.tmp_dir.value):
os.mkdir(config.plugins.playstream.tmp_dir.value)
self.onLayoutFinish.append(self.LayoutFinish)
def LayoutFinish(self):
self.cur_directory = os.path.dirname(os.path.realpath(__file__))
self.defimage = LoadPixmap(os.path.join(self.cur_directory,"PlayStream.png"))
#self.defimage = None
#sc = AVSwitch().getFramebufferScale()
#self.defimage0 = ePicLoad()
#self.defimage0.PictureData.get().append(boundFunction(self.FinishDecodeDef, os.path.join(self.cur_directory,"PlayStream.png")))
#self.defimage0.setPara((self["pic"].instance.size().width(),self["pic"].instance.size().height(),sc[0], sc[1], False, 0, "#00000000"))
#self.defimage0.startDecode("default")
self.activeDownloads = 0
self.images = {}
self.images_url = {}
self.picloads = {}
self.history = []
reload(ContentSources)
self.sources = ContentSources.ContentSources(os.path.join(self.cur_directory,"sources"))
self.config = self.sources.plugins["config"]
self.cur_menu = ("Home","config::home","","Sākums") #
self.content = self.sources.get_content(self.cur_menu[1])
#print self.content
self["list"].setList(self.content)
self["cur"].setText(self.content[0][3])
self.setTitle2(self.cur_menu[0])
self.ShowPic(self.content[0][2])
def SelectionChanged(self):
current = self["list"].getCurrent()
print "[PlayStream] SelectionChanged: current=",current
if not current: return
self["cur"].setText(current[3]) if current[3] else self["cur"].setText("")
if current[2]:
self.ShowPic(current[2])
else:
self.ShowDefPic()
def setTitle2(self,title):
#print self.keys()
self["title"].setText(title)
def ShowDefPic(self):
if self.defimage:
self["pic"].instance.setPixmap(self.defimage)
def ShowPic(self,image_url):
if image_url == "default":
self.ShowDefPic()
return
elif self.images.has_key(image_url):
if self.images[image_url] in (-1,-2):
return
elif self.images[image_url] == -3:
self.ShowDefPic()
return
else:
self["pic"].instance.setPixmap(self.images[image_url])
else:
if image_url.startswith("http"):
fname = image_url.replace(":","-").replace("/","_")
image_path = os.path.join(config.plugins.playstream.tmp_dir.value, fname)
self.download_image(image_path, image_url)
else: # local file
image_path = os.path.join(self.cur_directory,image_url)
self.start_decode(image_path,image_url)
def start_decode(self,image_path,image_url):
self.images[image_url] = -2
self.images_url[image_path] = image_url
sc = AVSwitch().getFramebufferScale()
if not self.picloads.has_key(image_path):
self.picloads[image_path] = ePicLoad()
self.picloads[image_path].PictureData.get().append(boundFunction(self.FinishDecode, image_path))
self.picloads[image_path].setPara((self["pic"].instance.size().width(),
self["pic"].instance.size().height(),
sc[0], sc[1], True, 0, "#00000000"))
#print image_path,image_url
self.picloads[image_path].startDecode(image_path)
def FinishDecode(self, image_path,picInfo = None):
image_url = self.images_url[image_path]
del self.images_url[image_path] #III
self.images[image_url] = self.picloads[image_path].getData()
self["pic"].instance.setPixmap(self.images[image_url])
del self.picloads[image_path]
if len(self.images)>30:
del self.images[self.images.keys()[0]]
# self.images.pop()
#def FinishDecodeDef(self, image_path,picInfo = None):
# self.defimage = self.defimage0.getData()
# del self.defimage0
# self["pic"].instance.setPixmap(self.defimage)
def download_image(self,image_path,image_url):
#print "Image download started",self.downloading,image_path,image_url
self.downloading += 1
self.images[image_url] = -1
downloadPage(image_url, image_path).addCallback(boundFunction(self.downloadFinished, image_path,image_url)).addErrback(boundFunction(self.downloadFailed, image_path,image_url))
def downloadFinished(self, image_path, image_url, result):
self.downloading -= 1
#print "[ Play] Image downloaded finished ",self.downloading,image_path, image_url,result
self.start_decode(image_path,image_url)
def downloadFailed(self, image_path, image_url,result):
self.downloading -= 1
print "[TV Play] Image downloaded failed ",self.downloading,image_path, image_url,result
self.images[image_url] = -3
def Ok(self):
current = self["list"].getCurrent()
self.current = current
index = self["list"].getIndex()
self.index = index
print "[PlayStream] - menu selected ", current
data = current[1].split("::")[1] if "::" in current[1] else current[1]
if not data:
return
elif self.sources.is_video(current[1]):
if self.sources.stream_type(current[1]):
stream = util.item()
stream["url"] = current[1]
stream["name"] = current[0]
streams = [stream]
else:
try:
streams = self.sources.get_streams(current[1])
except Exception,e:
print str(e)
self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
return
if streams:
#print streams
for s in streams:
if not s["name"]: s["name"] = current[0]
if not s["img"]: s["img"] = current[2]
if not s["desc"]: s["desc"] = current[3]
try:
self.session.open(PSPlayer, streams)
except Exception as e:
self.msg("Error launching player - " + str(e))
return
else:
self.msg("No stream found - %s"%(self.current[1]))
return
elif current[1] == "back":
cur_menu_old = self.cur_menu
self.cur_menu = self.history.pop()
new_content = self.sources.get_content(self.cur_menu[1])
try:
index = zip(*new_content)[1].index(cur_menu_old[1])
except:
index = 0
self.setTitle2(self.cur_menu[0])
self.show_content(new_content,index)
else:
print "selected=",current
if "{0}" in current[1]:
self.session.openWithCallback(self.cb_input,VirtualKeyBoard, title="Enter value", text="")
#a = raw_input("Enter value:")
#a = "big bang"
#current = (current[0],current[1].format(a),current[2],current[3])
#self.get_content(current)
else:
self.get_content(current)
def cb_input(self,value):
if not value:
return
current = self.current
current = (current[0],current[1].format(value),current[2],current[3])
self.get_content(current)
def get_content(self,current):
self.history.append(self.cur_menu)
self.cur_menu = current
try:
new_content = self.sources.get_content(self.cur_menu[1])
except Exception,e:
self.cur_menu = self.history.pop()
self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
return
self.setTitle2(self.cur_menu[0])
self.show_content(new_content)
def Back(self):
self["list"].setIndex(0)
self.Ok()
def show_content(self,content,index=0):
self["list"].setList(content)
self["list"].setIndex(index)
self.SelectionChanged()
def Cancel(self):
print "Exiting PlayStream"
if config.plugins.playstream.clear_tmp.value and os.path.exists(config.plugins.playstream.tmp_dir.value):
for name in os.listdir(config.plugins.playstream.tmp_dir.value):
#print "remove "+os.path.join(config.plugins.playstream.tmp_dir.value, name)
os.remove(os.path.join(config.plugins.playstream.tmp_dir.value, name))
#os.rmdir(config.plugins.playstream.tmp_dir.value)
self.close()
def item_menu(self):
print "\n[PlayStream] options\n"
self.current = self["list"].getCurrent()
self.index = self["list"].getIndex()
#self.session. open(MessageBox, "Item options - %s"%current[0] , MessageBox.TYPE_INFO)
#args=[current,self.cur_menu]
#self.session.open(ItemMenuScreen,current,index,self)
lst = [
("Aditional information","info","Display additional information about item"),
("Add to bouquet","bouquet","Add current item to Enigma2 bouquet"),
("Add to favorites","favorites","Add current item to PlayStrem favorites"),
("Show active downloads","download_list","Show active downloads list"),
("Set download folder","download_folder","Set download folder")
]
if self.sources.is_video(self.current[1]):
lst.extend([
("Download video to default folder","download","Download video to default folder"),
("Download video, ask folder","download2","Download video, ask download folder"),
("Download video to subfolder, ask parent folder","download3","Download video to subfolder, ask download folder"),
])
else:
lst.extend([
("Download list to default folder","download","Download videos in list (if any)"),
("Download list, ask folder","download2","Download videos in list (if any), ask download folder"),
])
if "config::" in self.cur_menu[1]:
lst.extend([
("Rename item","rename","Rename list item"),
("Move item","move","Move list item"),
("Delete item","delete","Delete list item"),
("Add submenu","add_list","Add submenu before selected item"),
])
title = self.current[0]
self.session.openWithCallback(self.cb_item_menu, ChoiceBox, title = title, list = lst) #TODO
def cb_item_menu(self,answer):
#print "item_menu_selected",answer
if not answer:
return
self.answer = answer[1]
if answer[1] == "info":
self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)
pass # TODO parada papildus info
elif answer[1] == "bouquet":
#if not e2:
#e2 = enigma2_api.DBServices()
#print "load_buuquets - ",e2._load_bouquets()
self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)
elif answer[1] == "favorites":
lists = self.config.get_lists()
lists2 = [(self.config.get_title(l),l) for l in lists]
print lists2
self.session.openWithCallback(self.cb_favorites, ChoiceBox, title="Selected menu item will be added",list = lists2)
elif answer[1] in ("download2","download3"): # ask download folder before
self.session.openWithCallback(self.download_prepare, LocationBox,"Select download folder","",config.plugins.playstream.download_dir.value,config.plugins.playstream.locations,False,"Select folder",None,True,True)
elif answer[1] == 'download':
self.download_prepare(config.plugins.playstream.download_dir.value)
elif answer[1] == 'download_list':
self.download_list()
elif answer[1] == 'download_folder':
#downloadDir = "/media/hdd/movie" #config.plugins.playstream.downloadDir.value TODO
self.session.openWithCallback(self.cb_download_dir, LocationBox,"Select download folder","",config.plugins.playstream.download_dir.value,config.plugins.playstream.locations,False,"Select folder",None,True,True)
elif answer[1] == "delete":
lst = self.cur_menu[1].replace("config::","")
#print lst
self.config.del_item(lst,self.index)
self.config.write_streams()
txt = "'%s' deleted from favourite stream list '%s'"%(self.current[0],lst)
self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=5)
elif answer[1] == "rename":
#name2 = "Renamed"
self.session.openWithCallback(self.cb_rename,VirtualKeyBoard, title="Enter new item name", text=self.current[0])
elif answer[1] == "add_list":
self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO,timeout=5)
pass #TODO
return
def download_prepare(self, download_dir=""):
current = self.current
if not download_dir:
return
#download_dir = config.plugins.playstream.download_dir.value
title = re.sub("\[.+?\]","", util.make_fname(current[0])).strip()
download_dir2 = os.path.join(download_dir, title)
if not self.sources.is_video(current[1]):
#self.msg("Can not download listst (yet) - %s"%(current[1]))
n = 0
for current2 in self.sources.get_content(current[1]):
if self.sources.is_video(current2[1]):
n += 1
self.download_video(current2,download_dir2)
if n>0:
self.msg("%s videos download started to %s"%(n,download_dir2))
else:
self.msg("No videos to download")
else:
if self.answer == "download":
download_dir2 = download_dir
if self.download_video(current,download_dir2):
self.msg("Video download started to %s"%download_dir2)
def cb_download_dir(self, downloadDir, select=None):
if not downloadDir:
return
print "Folder selected - %s"%downloadDir
config.plugins.playstream.download_dir.setValue(downloadDir)
config.plugins.playstream.download_dir.save()
config.plugins.playstream.locations.save()
config.save()
def download_list(self):
self.session.open(VideoDownloadList)
def download_video(self,current, download_dir=""):
if self.sources.stream_type(current[1]):
stream = util.item()
stream["url"] = current[1]
stream["name"] = current[0]
streams = [stream]
else:
try:
streams = self.sources.get_streams(current[1])
except Exception,e:
print "Error - %s"%str(e)
self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
return
if not streams:
self.msg("No stream found to download - %s"%(self.current[1]))
return
for s in streams:
if not s["name"]: s["name"] = current[0]
if not s["img"]: s["img"] = current[2]
if not s["desc"]: s["desc"] = current[3]
if len(streams)>1:
stream = streams[0] # TODO iespeja izvelēties strīmu, ja to ir vairāki
else:
stream = streams[0]
stream = util.stream_change(stream)
return self.download_stream(stream, download_dir)
def download_stream(self,stream,download_dir=""):
print "download stream",stream
#self.msg("Start downloading..")
self.stream = stream
stream_type = self.stream["type"] #self.sources.stream_type(stream["url"])
if not stream_type: #
print "Not supported stream type found to download - %s"%(self.current[1])
self.msg("Not supported stream type found to download - %s"%(self.current[1]))
return
title = self.stream["name"].strip()
url = self.stream["url"]
stream_type = self.stream["type"] #self.sources.stream_type(stream["url"])
downloadDir = config.plugins.playstream.download_dir.value if not download_dir else download_dir
if not os.path.exists(downloadDir):
try:
os.mkdir(downloadDir)
except Exception as e:
print 'Error creating download directory "%s"!\nPlease specify in the settings existing directory\n%s'%(downloadDir,str(e))
self.msg('Error creating download directory "%s"!\nPlease specify in the settings existing directory\n%s'%(downloadDir,str(e)))
return
fname0 = util.make_fname(title)
fname = fname0 +".mp4"
outputfile = os.path.join(downloadDir, fname)
#print "Trying to download - ", current
if self.stream["img"]:
try:
thumb = urllib2.urlopen(stream["img"]).read()
except:
thumb = ""
if thumb:
imgext = ".jpg"
m = re.search("(\.\w{3})$",stream["img"])
if m:
imgext = m.group(1)
imgfile = os.path.join(downloadDir,fname0+imgext)
with open(imgfile,"wb") as f:
f.write(thumb)
if self.stream["subs"]:
suburl = self.stream["subs"][0]["url"]
print "\n**Download subtitles %s - %s"%(title,suburl)
subs = urllib2.urlopen(suburl).read()
if subs:
#fname0 = re.sub("[/\n\r\t,:]"," ",title)
subext = ".srt"
subfile = os.path.join(downloadDir,fname0+subext)
if ".xml" in suburl:
subs = util.ttaf2srt(subs)
with open(subfile,"w") as f:
f.write(subs)
else:
print "\n Error downloading subtitle %s"%suburl
if "nfo" in self.stream and self.stream["nfo"]:
nfofile = subfile = os.path.join(downloadDir,fname0+".nfo")
with open(nfofile,"w") as f:
nfo_type,nfo = next(self.stream["nfo"].iteritems())
f.write("<%s>\n"%nfo_type.encode("utf8"))
for k,v in nfo.iteritems():
if isinstance(v,unicode): v = v.encode("utf8")
f.write(" <%s>%s%s>\n"%(k.encode("utf8"), v, k.encode("utf8")))
f.write("%s>\n"%nfo_type.encode("utf8"))
overwrite = config.plugins.playstream.overwrite_download.value
if not overwrite and os.path.exists(outputfile):
self.msg( _('Sorry, this file already exists:\n%s') % outputfile)
return False
#os.remove(outputfile)
if stream_type in ("http","https"):
print "\n**Download %s - %s"%(title,url)
#reload(downloadJob)
job_manager.AddJob(downloadJob(url, outputfile, title[:20], self.video_download_stop))
self.activeDownloads += 1
#self.msg(_('Video download started!'))
return True
elif stream_type == "hls":
#self.msg("HLS stream download not yet implemented!")
print "\n**Download %s - %s"%(title,url)
#reload(HLSDownloadJob)
print "HLSDownload", url,outputfile
job_manager.AddJob(HLSDownloadJob(url, outputfile, title[:20], self.video_download_stop))
self.activeDownloads += 1
#self.msg(_('Video download started!'))
return True
elif stream_type == "rstp":
self.msg("RSTP stream download not yet implemented!")
return False
else:
self.msg("Unkown stream type!")
return False
def cb_rename(self,value):
if not value:
return
lst = self.cur_menu[1].replace("config::","")
pos = self.index
print value
item2 = list(self.current)
item2[0]=value
item2 = tuple(item2)
self.config.replace_item(lst,item2,pos)
self.config.write_streams()
txt = "'%s' renamed to '%s'"%(self.current[0],value)
self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=5)
def cb_favorites(self,answer):
print "cb_favorites",answer,self.current
if not answer:
return
value = answer[1]
self.config.add_item(value,self.current)
self.config.write_streams()
txt = "'%s' added to favourite stream list '%s'"%(self.current[0],value)
self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=3)
#self.session.openWithCallback(self.callMyMsg, MessageBox, _("Do you want to exit the plugin?"), MessageBox.TYPE_INFO)
def config_screen(self):
self.session.open(ConfigScreen,self)
def options_screen(self):
source = self.cur_menu[1].split("::")[0]
options = self.sources.options_read(source)
print source
if not options:
self.session. open(MessageBox, "No options available for source %s (%s)"%(self.cur_menu[0],source) , MessageBox.TYPE_INFO)
else:
self.session.open(OptionsScreen,self)
def video_download_stop(self,title):
#self.activeDownloads -= 1
#self.msg("Download '%s'finished!"%title)
print "video_download_stop ", title
def msg2(self,msg,timeout=10,mtype = None):
mtype=mtype if mtype else MessageBox.TYPE_INFO
Notifications.AddPopup(text = msg, type=mtype, timeout=timeout)
def msg(self,msg,timeout=10):
self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout)
##########################################################################
from Components.config import config, ConfigSubsection, ConfigYesNo,\
getConfigListEntry, ConfigSelection, ConfigNumber, ConfigDirectory,ConfigText, ConfigSubDict
from Components.ConfigList import ConfigListScreen
#from Screens.LocationBox import LocationBox
#config.plugins.playstream = ConfigSubDict()
class OptionsScreen(ConfigListScreen,Screen):
skin = """
"""
def __init__(self, session,*args):
self.session = session
Screen.__init__(self, session)
self.main = args[0]
self.setTitle(self.main.cur_menu[0]+" options")
self.source = self.main.cur_menu[1].split("::")[0]
self.cfg = ConfigSubDict() #config.plugins.playstream
self.list = []
self.options = self.main.sources.options_read(self.source)
if not self.options:
#self.session. open(MessageBox, "No options available for source %s (%s)"%(self.main.cur_menu[0],self.source) , MessageBox.TYPE_INFO)
self.close(False,self.session)
for k in self.options:
self.cfg[k]=ConfigText(default=self.options[k],fixed_size=False)
self.list.append(getConfigListEntry(k, self.cfg[k]))
ConfigListScreen.__init__(self, self.list, session = self.session)
self["key_red"] = Button(_("Cancel"))
self["key_green"] = Button("Save")
self["key_yellow"] = Button("")
self["key_blue"] = Button("")
self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
{
"red": self.cancel,
"green": self.save,
"save": self.save,
"cancel": self.cancel,
"ok": self.ok,
}, -2)
def getCurrentEntry(self):
return self["config"].getCurrent()[0]
def getCurrentValue(self):
return str(self["config"].getCurrent()[1].getText())
def ok(self):
self.save()
#if self["config"].getCurrent()[1] == config.plugins.getpicons.folder:
#folder = config.plugins.getpicons.folder.value
#self.session.openWithCallback(self.change_dir, LocationBox,"Select Folder")
#else:
#def change_dir(self, folder, select=None):
#if folder:
##print "change_dir to %s"%folder
#config.plugins.getpicons.folder.value = folder
def save(self):
print "saving"
#self.saveAll()
for k in self.options.keys():
self.options[k]=self.cfg[k].value
print "%s=%s"%(k,self.cfg[k].value)
self.main.sources.options_write(self.source,self.options)
self.close(True,self.session)
def cancel(self):
print "cancel"
self.close(False,self.session)