12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304 |
- #!/usr/bin/env python
- # coding=utf8
- # This file is part of PlayStream - enigma2 plughhhhin 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)
- #
-
- __version__ = "0.7t"
- __id__ = "playstream"
- __title__ = "PlayStream"
- __author__ = "ivars777@gmail.com"
- __desc__ = "Play online video streams from various sources"
-
- import os,time,sys,os,os.path
- import datetime,re, traceback
- 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.Console import Console
- from Screens.Standby import TryQuitMainloop
- #from Screens.InputBox import InputBox
- from Components.AVSwitch import AVSwitch
- from Components.ActionMap import ActionMap, HelpableActionMap
- from Components.Label import Label
- from Components.ScrollLabel import ScrollLabel
- 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.config import config, ConfigSubsection, ConfigYesNo, getConfigListEntry, ConfigSelection, ConfigNumber, ConfigDirectory,ConfigText, ConfigSubDict
- from Components.ConfigList import ConfigListScreen
- #from Screens.LocationBox import LocationBox
- from Tools import Notifications
- from Tools.BoundFunction import boundFunction
- from Tools.Directories import resolveFilename, SCOPE_PLUGINS
- from Tools.LoadPixmap import LoadPixmap
- from skin import loadSkin
- from twisted.web.client import downloadPage,defer,reactor
- try:
- # available since twisted 14.0
- from twisted.internet._sslverify import ClientTLSOptions
- except ImportError:
- ClientTLSOptions = None
- from twisted.internet.ssl import ClientContextFactory
-
- from plugin_locale import _
- from content import ContentSources
- from content import util
- from VideoDownload import DownloadJob, HLSDownloadJob,VideoDownloadList
- from content.Downloader import get_header, get_ext
- #import enigma2_api
-
- e2 = None
- cur_directory = os.path.dirname(os.path.realpath(__file__))
- loadSkin(os.path.join(cur_directory, "skin.xml"))
-
- #####################################################################################################################
- 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)
- config.plugins.playstream.check_update = ConfigYesNo(default = True)
- config.plugins.playstream.streams_file = ConfigText(default="streams.cfg")
- config.plugins.playstream.streams_file_remote = ConfigText(default="ftp://user:password@host/hdd/streams.cfg")
- config.plugins.playstream.use_streams_file_remote = ConfigYesNo(default = False)
-
- class CustomContextFactory(ClientContextFactory):
- def __init__(self, hostname = None):
- self.hostname = hostname
- def getContext(self):
- ctx = self._contextFactory(self.method)
- if self.hostname and ClientTLSOptions:
- ClientTLSOptions(self.hostname, ctx)
- return ctx
-
- #####################################################################################################################
- class MainScreen(Screen):
- def __init__(self, session):
- Screen.__init__(self, session)
- self.skinName = ["PSMain"]
- 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",
- "WizardActions","ButtonSetupActions"], {
- #"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,
- "info": self.show_info,
- "pageup": self.page_up,
- "channelup":self.page_up,
- "pagedown": self.page_down,
- "channeldown":self.page_down,
- })
- self["list"] = List([])
- self["list"].onSelectionChanged.append(self.selection_changed)
- self["pic"] = Pixmap()
- self["cur"] = ScrollLabel()
- self["title"] = Label()
- self.downloading = 0
- self.active_downloads = 0
- if not os.path.exists(config.plugins.playstream.tmp_dir.value):
- os.mkdir(config.plugins.playstream.tmp_dir.value)
- self.onLayoutFinish.append(self.layout_finished)
-
- def layout_finished(self):
- self.defimage = LoadPixmap(os.path.join(cur_directory,"PlayStream.png"))
- #self.defimage = None
- #sc = AVSwitch().getFramebufferScale()
- #self.defimage0 = ePicLoad()
- #self.defimage0.PictureData.get().append(boundFunction(self.FinishDecodeDef, os.path.join(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.active_downloads = 0
- self.images = {}
- self.images_url = {}
- self.picloads = {}
- self.history = []
-
- reload(ContentSources)
- sources_directory = os.path.join(cur_directory, "content", "sources")
- print "**** use_streams_file_remote=", config.plugins.playstream.use_streams_file_remote.value
- print "**** streams_file_remote=", config.plugins.playstream.streams_file_remote.value
- print "**** streams_file=", config.plugins.playstream.streams_file.value
- print "**** sources_directory=", sources_directory
- if config.plugins.playstream.use_streams_file_remote.value:
- try:
- self.sources = ContentSources.ContentSources(sources_directory, config.plugins.playstream.streams_file_remote.value)
- print "Remote stream file opened"
- except Exception as e:
- try:
- self.sources = ContentSources.ContentSources(sources_directory, config.plugins.playstream.streams_file.value)
- print "Streams_file fallback"
- self.msg2("Remote streams file is not available, fallback to local")
- except Exception as e:
- self.msg2(e.message)
- else:
- try:
- self.sources = ContentSources.ContentSources(sources_directory, config.plugins.playstream.streams_file.value)
- print "Local stream file opened"
- except Exception as e:
- self.msg2(e.message)
- self.cancel()
-
- if "config" not in self.sources.plugins:
- self.msg2("No streams config file")
- self.cancel()
-
- 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.cur_menu[1].split("::")[0]+")")
- self.show_picture(self.content[0][2])
- reactor.callLater(1,self.check_update)
-
- def check_update(self):
- #print "Check PlayStream for update"
- if config.plugins.playstream.check_update:
- self.cver = util.check_version("enigma2-plugin-extensions-playstream")
- if self.cver and self.cver>__version__:
- txt = "New version of plugin available for update - %s\nCurrent version - %s\nDo you want to upgrade?"%(self.cver,__version__)
- mbox = self.session.openWithCallback(self.update, MessageBox, txt, MessageBox.TYPE_YESNO)
- mbox.setTitle("Upgrade plugin?")
-
- def update(self,answer):
- if answer:
- plugin_update(self.session)
-
- def page_down(self):
- self["cur"].pageDown()
-
- def page_up(self):
- self["cur"].pageUp()
-
- def selection_changed(self):
- current = self["list"].getCurrent()
- print "[PlayStream] SelectionChanged: current=",current[1]
- if not current: return
- self["cur"].setText(current[3]) if current[3] else self["cur"].setText("")
- if current[2]:
- self.show_picture(current[2])
- else:
- self.show_default_picture()
-
- def setTitle2(self,title):
- #print self.keys()
- self["title"].setText(title)
-
- def show_default_picture(self):
- if self.defimage:
- self["pic"].instance.setPixmap(self.defimage)
-
- def show_picture(self, image_url):
- if image_url == "default":
- self.show_default_picture()
- return
- elif self.images.has_key(image_url):
- if self.images[image_url] in (-1,-2):
- return
- elif self.images[image_url] == -3:
- self.show_default_picture()
- 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(cur_directory, "picons", 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()
- try:
- self.picloads[image_path].PictureData.get().append(boundFunction(self.decode_finished, image_path))
- except:
- self.picloads[image_path].PictureData.connect(boundFunction(self.decode_finished, 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 decode_finished(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, CustomContextFactory(image_url.split("/")[2])).addCallback(boundFunction(self.download_image_finished, image_path, image_url)).addErrback(boundFunction(self.download_image_failed, image_path, image_url))
-
- def download_image_finished(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 download_image_failed(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
-
- if self.sources.is_video(current[1]):
- if ContentSources.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)
- traceback.print_exc()
- 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:
- traceback.print_exc()
- 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()
- self.update_streams_file()
- 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.cur_menu[1].split("::")[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.history.append(self.cur_menu)
- self.update_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.history.append(self.cur_menu)
- self.update_content(current)
-
- def update_content(self,current=None):
- if current:
- self.cur_menu = current
- self.update_streams_file()
- try:
- new_content = self.sources.get_content(self.cur_menu[1])
- except Exception,e:
- self.cur_menu = self.history.pop()
- traceback.print_exc()
- self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
- return
- self.setTitle2(self.cur_menu[0] + " (" + self.cur_menu[1].split("::")[0]+")")
- self.show_content(new_content)
-
- def show_content(self,content,index=0):
- self["list"].setList(content)
- self["list"].setIndex(index)
- self.selection_changed()
-
- def show_info(self):
- self.current = self["list"].getCurrent()
- data = self.current[1]
- source = data.split("::")[0]
- if self.sources.is_video(data) and "get_info" in dir(self.sources.plugins[source]):
- #self.sources.plugins
- try:
- nfo = self.sources.get_info(self.current[1])
- except Exception, e:
- print str(e)
- traceback.print_exc()
- self.session.open(MessageBox, "Error - %s" % str(e), MessageBox.TYPE_INFO)
- return
- else:
- nfo = {"movie": {"title": self.current[0], "thumb": self.current[2], "plot": self.current[3]}}
- self.session.open(StreamInfo, nfo)
-
- def back(self):
- if self.history:
- self["list"].setIndex(0)
- self.ok()
- else:
- self.cancel()
-
- def update_streams_file(self):
- if config.plugins.playstream.use_streams_file_remote.value:
- self.config.set_streams_file(config.plugins.playstream.streams_file_remote.value)
- else:
- self.config.set_streams_file(config.plugins.playstream.streams_file.value)
-
- 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"),
- ]
- 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"),
- ])
- lst.extend([
- ("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"),
- ])
- 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.show_nfo()
- #self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)
- self.show_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] == "delete":
- lst = self.cur_menu[1].replace("config::","")
- #print lst
- self.config.del_item(lst,self.index)
- self.config.write_streams()
- self.update_content()
- 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] == "move":
- lst = self.cur_menu[1].replace("config::","")
- items = self.config.get_list_items(lst)
- self.session.openWithCallback(self.cb_move, ChoiceBox, title="Move before selected item",list = items)
- #self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)
- #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
-
- 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)
-
- 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]))
- self.update_streams_file()
- 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 ContentSources.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)
- traceback.print_exc()
- 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
- url = stream["url"]
- headers = stream["headers"] if "headers" in stream else {}
- stream_type = ContentSources.stream_type(url) #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()
- 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:
- traceback.print_exc()
- 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)
- #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_txt = util.nfo2xml(self.stream["nfo"])
- f.write(nfo_txt)
- try:
- h = get_header(url,headers)
- except:
- h = None
- if not h:
- self.session.open(MessageBox, "Can non get headers - %s" % url)
- return False
-
- mtype = h.get("content-type")
- if not mtype:
- mtype = "videp/mp4" # TODO default mtype if not content-type in header?
-
- fext,stream_type = get_ext(mtype)
- fname = fname0 + fext
- outputfile = os.path.join(downloadDir, fname)
- 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", "hls"):
- print "\n**Download %s - %s"%(title,url)
- #reload(DownloadJob)
- try:
- job_manager.AddJob(DownloadJob(url, outputfile, title[:20], self.video_download_stop, headers, stream_type))
- except Exception as e:
- print str(e)
- traceback.print_exc()
- self.session.open(MessageBox, "Error - %s" % str(e), MessageBox.TYPE_INFO)
- return False
-
- self.active_downloads += 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.active_downloads += 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 - %s!"%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()
- self.update_content()
- #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 cb_move(self,answer):
- print "cb_move",answer,self.current
- if not answer:
- return
- answer[1]
- lst = self.cur_menu[1].replace("config::","")
- pos = self.index
- items = self.config.get_list_items(lst)
- for pos2, it in enumerate(items):
- if it[1] == answer[1]:
- break
- else:
- pos2 = None
- self.config.move_item(lst, pos, pos2)
- self.config.write_streams()
- self.update_content()
- #txt = "Item moved from position %s to %s'"%(pos,pos2)
- #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.active_downloads -= 1
- self.msg2(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)
-
- 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
-
- def plugin_update(session):
- feed_file = "/etc/opkg/ivars777-feed.conf"
- if not os.path.exists(feed_file):
- with open(feed_file, "w") as f:
- f.write("src/gz ivars777 http://feed.blue.lv")
- cmdlist = [
- "opkg update",
- "opkg install enigma2-plugin-extensions-playstream",
- "echo Restart Enigma after upgrade!"
- ]
- # os.chmod(cmd, 493)
- session.open(Console, "Update PlayStream plugin", cmdlist)
-
- #####################################################################################################################
- 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 = """
- <screen position="%d,%d" size="%d,140" zPosition="2" backgroundColor="transparent" flags="wfNoBorder">
- <widget name="subtitle" position="0,0" size="%d,140" valign="center" halign="center" font="Regular;36" transparent="1" foregroundColor="white" shadowColor="#40101010" shadowOffset="2,2" />
- </screen>""" % (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" in dir(self.stimer):
- 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 konfigurācijas
- self.svisible = True # TODO - no konfigurācijas
- 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_timer0(self):
- if self.stimer:
- self.subtitle_window.show()
- print "start_subtitles_timer"
- self.stimer.start(self.stimer_step)
-
- def start_subtitles_timer(self):
- 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 <sc["begin"]:
- return " "
- else:
- txt = sc["text"] if sc["text"] else " "
- return txt
-
- def get_sub_ind(self,ind):
- subs_object = self.get_subs_current() # current subs object
- if subs_object:
- return subs_object.subs[ind] if ind<len(subs_object.subs) else None
- else:
- return None
-
- def get_subs_current(self):
- "Return current sub_object"
- if not "subs" in self.subs[self.cur_subs]:
- print "===== Captions to download", self.subs[self.cur_subs]["url"]
- subs_object = util.Captions(self.subs[self.cur_subs]["url"])
- print len(subs_object.subs), "items"
- self.subs[self.cur_subs]["subs"] = subs_object
- if not subs_object:
- return None
- else:
- return subs_object
- else:
- return self.subs[self.cur_subs]["subs"]
-
- def update_subtitles(self):
- if not self.shown and self.svisible:
- seek = self.getSeek()
- pos = seek.getPlayPosition()
- pts = pos[1]/90
- txt0 = "%d:%02d (%i)" % (pts/60/1000, (pts/1000)%60, pts)
- #print "Update_subtitles", txt0
- if not self.subtitle_window.shown:
- self.subtitle_window.show()
- if not self.subs:
- return
- txt = self.get_sub_pts(pts)
- #print "Show subtitle",txt
- #txt = txt0+": "+ txt
- self.subtitle_window["subtitle"].setText(txt)
- elif self.shown and self.svisible:
- if self.subtitle_window.shown:
- self.subtitle_window.hide()
- elif not self.svisible:
- if self.subtitle_window.shown:
- self.subtitle_window.hide()
-
- # struct SubtitleTrack
- # int type;
- # int pid;
- # int page_number;
- # int magazine_number;
- # std::string language_code;
- #selectedSubtitle = ???
- #self.enableSubtitle(selectedSubtitle)
-
- def play_service(self,service):
- self.movieSelected(service)
-
- #def doShow(self):
- #self.svisible = False
- #InfoBarShowHide.doShow(self)
-
- #def doHide(self):
- #self.svisible = True
- #InfoBarShowHide.doHide(self)
-
- def service_info(self):
- print "########[MoviePlayer] service_info"
- text = "%s\n%s %s\n%s"%(self.cur_stream["name"],self.cur_stream["lang"],self.cur_stream["quality"],self.cur_stream["desc"])
- text = text.encode("utf8")
- #print text
- #mtype = MessageBox.TYPE_INFO
- #Notifications.AddPopup(text = text, type=mtype, timeout = 10)
- print "StreamInfo", self.cur_stream
- nfo = self.cur_stream["nfo"] if "nfo" in self.cur_stream else {"movie":{"title":self.current[0],"thumb":self.current[1],"plot":self.current[3]}}
- self.session.open(StreamInfo, nfo)
-
- def select_stream(self):
- print "########[MoviePlayer] select_stream"
- lst = []
- title = "Select stream"
- for i,s in enumerate(self.streams):
- lst.append(("[%s,%s] %s"%(s["lang"],s["quality"],s["name"]),i))
- self.session.openWithCallback(self.cb_select_stream, ChoiceBox, title = title, list = lst,selection = self.selected)
-
- def cb_select_stream(self,answer):
- #print "item_menu_selected",answer
- if not answer:
- return
- self.selected = answer[1]
- service = make_service(self.streams[self.selected])
- self.resume_pos = self.getSeek().getPlayPosition()[1]
- self.play_service(service)
-
- def serviceStarted(self):
- print "serviceStarted"
- if not self.resume_pos:
- self.resume_pos = 0
- print "doSeek",self.resume_pos
- #self.doSeek(self.resume_pos)
-
-
- def select_captions(self):
- print "########[MoviePlayer] select_caption"
- lst = []
- title = "Select subtitles"
- for i,s in enumerate(self.subs):
- lst.append((("%s - %s"%(s["lang"],s["name"])).encode("utf8"),i))
- if self.svisible:
- selection = self.cur_subs
- else:
- selection = len(lst)
- lst.append(("No captions",-1))
- self.session.openWithCallback(self.cb_select_captions, ChoiceBox, title = title, list = lst,selection = selection)
-
- def cb_select_captions(self,answer):
- #print "item_menu_selected",answer
- if not answer:
- return
- if answer[1] == -1:
- self.svisible = False
- else:
- self.cur_subs = answer[1]
- self.svisible = True
-
- def leavePlayer(self):
- self.close()
- #self.session.openWithCallback(self.leavePlayerConfirmed, MessageBox, _("Stop playing?"))
-
- def leavePlayerConfirmed(self, answer):
- if answer:
- self.close()
-
- def doEofInternal(self, playing):
- self.close()
-
- #def getPluginList(self):
- #from Components.PluginComponent import plugins
- #list = []
- #for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU):
- #if p.name != _("TV Play"):
- #list.append(((boundFunction(self.getPluginName, p.name),
- #boundFunction(self.runPlugin, p), lambda: True), None))
- #return list
-
- #def showMovies(self):
- #pass
-
-
- #####################################################################################################################
- class ConfigScreen(ConfigListScreen,Screen):
-
- def __init__(self, session, main):
- #print main
- self.main = main
- self.session = session
- #self.setup_title = "Options"
- Screen.__init__(self, session)
- self.skinName = ["PSConfig"]
- self.list = [
- getConfigListEntry(_("Download folder"), config.plugins.playstream.download_dir),
- getConfigListEntry(_("Overwrite download video"), config.plugins.playstream.overwrite_download),
- getConfigListEntry(_("TMP folder"), config.plugins.playstream.tmp_dir),
- getConfigListEntry(_("Clear tmp folder on exit"), config.plugins.playstream.clear_tmp),
- getConfigListEntry(_("Start playstreamproxy"), config.plugins.playstream.streamproxy_start),
- getConfigListEntry(_("Check new plugin version in feed"), config.plugins.playstream.check_update),
- getConfigListEntry(_("Content config file"), config.plugins.playstream.streams_file),
- getConfigListEntry(_("Remote content config file"), config.plugins.playstream.streams_file_remote),
- getConfigListEntry(_("User remote content config file"), config.plugins.playstream.use_streams_file_remote),
- ]
- ConfigListScreen.__init__(self, self.list, session = self.session)
- self["title"] = Label()
- self["key_red"] = Button(_("Cancel"))
- self["key_green"] = Button(_("Save"))
- self["key_yellow"] = Button("Update")
- self["key_blue"] = Button("Downloads")
- self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
- {
- "red": self.cancel,
- "green": self.save,
- "yellow": self.update_plugin,
- "blue": self.downloads,
- "save": self.save,
- "cancel": self.cancel,
- "ok": self.ok,
- }, -2)
- self["title"].setText("Version %s, ivars777@gmail.com"%__version__)
-
- 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)
- self.main.update_content()
-
- def cancel(self):
- #print "cancel"
- self.close(False,self.session)
-
- def downloads(self):
- self.session.open(VideoDownloadList)
-
- def update_plugin(self):
- #print "Check PlayStream for update"
- self.cver = util.check_version("enigma2-plugin-extensions-playstream")
- if self.cver and self.cver>__version__:
- txt = "New version of plugin available for update - %s\nCurrent version - %s\nDo you want to upgrade?"%(self.cver,__version__)
- else:
- txt = "No new version of plugin available for update - %s\nCurrent version - %s\nDo you want to upgrade?"%(self.cver,__version__)
- mbox = self.session.openWithCallback(self.update, MessageBox, txt, MessageBox.TYPE_YESNO)
- mbox.setTitle("Upgrade plugin?")
-
- def update(self,answer):
- if answer:
- plugin_update(self.session)
-
- def restart_dialog(self):
- self.session.openWithCallback(self.restart, MessageBox, _("Restart Enigma2?"),MessageBox.TYPE_YESNO)
-
- def restart(self, answer):
- if answer:
- self.session.open(TryQuitMainloop, retvalue=3)
- else:
- return
-
- #####################################################################################################################
- class OptionsScreen(ConfigListScreen,Screen):
-
- def __init__(self, session,*args):
- self.session = session
- Screen.__init__(self, session)
- self.skinName = ["PSOptions"]
- self.main = args[0]
- self.setTitle("Source 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["title"] = Label()
- 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)
- self["title"].setText(self.main.sources.plugins[self.source].title)
-
- 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)
-
- #####################################################################################################################
- class StreamInfo(Screen):
-
- def __init__(self, session, nfo):
- if not nfo:
- return
- Screen.__init__(self, session)
- self.skinName = ["PSStreamInfo"]
- self.session = session
- self["key_red"] = Button(_("Exit"))
- self["actions"] = ActionMap(["OkCancelActions", "ColorActions","ButtonSetupActions"], {
- "ok": self.cancel,
- "red": self.cancel,
- "cancel": self.cancel,
- "pageup": self.page_up,
- "channelup":self.page_up,
- "pagedown": self.page_down,
- "channeldown":self.page_down,
- })
- self["pic"] = Pixmap()
- self["info"] = ScrollLabel()
- self["title"] = Label()
- self.nfo = nfo
- self.onLayoutFinish.append(self.layout_finished)
-
- def cancel(self):
- #print "cancel"
- self.close(False,self.session)
-
- def layout_finished(self):
- nfo = self.nfo
- print "StreamInfo nfo", nfo
- if not "title" in nfo:
- nfo_type, nfo = next(nfo.iteritems())
- title = util.nfo2title(nfo)
- desc = util.nfo2desc(nfo)
- self["title"].setText(title)
- self["info"].setText(desc)
- image_url = nfo["thumb"]
- if image_url and image_url.startswith("http"):
- fname = image_url.replace(":", "-").replace("/", "_")
- image_path = os.path.join(config.plugins.playstream.tmp_dir.value, fname)
- if not os.path.exists(image_path):
- downloadPage(image_url, image_path, CustomContextFactory(image_url.split("/")[2])).addCallback(boundFunction(self.download_finished, image_path,image_url)).addErrback(boundFunction(self.download_failed, image_path,image_url))
- else:
- self.download_finished(image_path, image_url)
- elif image_url:
- image_path = os.path.join(cur_directory, image_url)
- self.download_finished(image_path,"")
-
- def download_finished(self, image_path,image_url):
- sc = AVSwitch().getFramebufferScale()
- self.picloads = ePicLoad()
- try:
- self.picloads.PictureData.get().append(boundFunction(self.finish_decode, image_path))
- except:
- self.picloads.PictureData.connect(boundFunction(self.finish_decode, image_path))
- # 0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
- self.picloads.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.startDecode(image_path.encode("utf8"))
-
- def download_failed(self, image_path,image_url):
- print "[PlayStream] Image downloaded failed ",image_url
-
- def finish_decode(self, image_path,picInfo = None):
- ptr = self.picloads.getData()
- self["pic"].instance.setPixmap(ptr)
-
- def page_down(self):
- self["info"].pageDown()
-
- def page_up(self):
- self["info"].pageUp()
|