from Screens.ChannelSelection import SimpleChannelSelection
from ServiceReference import ServiceReference
from Plugins.Plugin import PluginDescriptor
+from Tools.Directories import resolveFilename, SCOPE_CONFIG
+import xml.dom.minidom
+from Tools.XMLTools import elementsWithTag
import os
alternatives = {}
+def addAlternative(service1, service2):
+ if not alternatives.has_key(service1):
+ alternatives[service1] = []
+ alternatives[service1].append(service2)
+ if not alternatives.has_key(service2):
+ alternatives[service2] = []
+ alternatives[service2].append(service1)
+
+def removeAlternative(service1, service2):
+ alternatives[service1].remove(service2)
+ alternatives[service2].remove(service1)
+ if len(alternatives[service1]) == 0:
+ del alternatives[service1]
+ if len(alternatives[service2]) == 0:
+ del alternatives[service2]
+
+def loadAlternatives():
+ doc = xml.dom.minidom.parse(resolveFilename(SCOPE_CONFIG, "alternatives.xml"))
+
+ root = doc.childNodes[0]
+ for service in elementsWithTag(root.childNodes, 'service'):
+ newService = str(service.getAttribute('ref'))
+ for alternative in elementsWithTag(service.childNodes, 'alternative'):
+ newAlternative = str(alternative.getAttribute('ref'))
+ addAlternative(newService, newAlternative)
+
+def sortKey(x):
+ return str.lower(ServiceReference(x).getServiceName().strip())
+
class AlternativeZapping(Screen):
skin = """
<screen position="100,100" size="560,400" title="Services alternatives setup..." >
<widget name="green" position="140,0" size="140,40" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
<widget name="yellow" position="280,0" size="140,40" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
<widget name="blue" position="420,0" size="140,40" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
- <widget name="serviceslist" position="0,40" size="280,360" />
- <widget name="alternativeslist" position="280,40" size="280,360" selectionDisabled="1" />
+ <widget name="serviceslist" position="0,40" size="280,360" scrollbarMode="showOnDemand" />
+ <widget name="alternativeslist" position="280,40" size="280,360" selectionDisabled="1" scrollbarMode="showOnDemand" />
</screen>"""
def __init__(self, session):
self.skin = AlternativeZapping.skin
Screen.__init__(self, session)
+
+ self.filename = resolveFilename(SCOPE_CONFIG, "alternatives.xml")
self.red = Label("")
self["red"] = self.red
self.blue = Label("")
self["blue"] = self.blue
+ self.alternatives = {}
+
self.serviceslist = []
- self["serviceslist"] = MenuList(self.serviceslist)
-
self.alternativeslist = []
- self["alternativeslist"] = MenuList(self.alternativeslist)
+ try:
+ self.loadAlternatives()
+ except:
+ pass
+ self["serviceslist"] = MenuList(self.serviceslist)
+ self["alternativeslist"] = MenuList(self.alternativeslist)
+
self.onShown.append(self.updateServices)
self.onShown.append(self.updateAlternatives)
self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
{
"ok": self.go,
- "cancel": self.close,
+ "cancel": self.go,
"up": self.up,
"down": self.down,
"left": self.left,
"blue": self.blueKey,
}, -1)
+ def saveAlternatives(self):
+ doc = xml.dom.minidom.Document()
+ root_element = doc.createElement('alternatives')
+ doc.appendChild(root_element)
+ root_element.appendChild(doc.createTextNode("\n"))
+
+ for alternative in self.alternatives.keys():
+ t = doc.createTextNode("\t")
+ root_element.appendChild(t)
+ t = doc.createElement('service')
+ t.setAttribute("ref", alternative)
+ root_element.appendChild(t)
+ t.appendChild(doc.createTextNode("\n"))
+ for x in self.alternatives[alternative]:
+ t.appendChild(doc.createTextNode("\t\t"))
+ l = doc.createElement('alternative')
+ l.setAttribute("ref", str(x))
+ t.appendChild(l)
+ t.appendChild(doc.createTextNode("\n"))
+ t.appendChild(doc.createTextNode("\t"))
+ root_element.appendChild(t)
+ t = doc.createTextNode("\n")
+ root_element.appendChild(t)
+ file = open(self.filename, "w")
+ doc.writexml(file)
+ file.write("\n")
+ file.close()
+
+ def loadAlternatives(self):
+ self.alternatives = {}
+ alternatives = {}
+ doc = xml.dom.minidom.parse(self.filename)
+
+ root = doc.childNodes[0]
+ for service in elementsWithTag(root.childNodes, 'service'):
+ newService = str(service.getAttribute('ref'))
+ if not self.alternatives.has_key(newService):
+ self.alternatives[newService] = []
+ for alternative in elementsWithTag(service.childNodes, 'alternative'):
+ newAlternative = str(alternative.getAttribute('ref'))
+ self.alternatives[newService].append(newAlternative)
+ addAlternative(newService, newAlternative)
+
def go(self):
- pass
+ self.saveAlternatives()
+ self.close()
def up(self):
self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveUp)
pass
def redKey(self):
+ for x in self.alternatives[self["serviceslist"].getCurrent()[1]]:
+ removeAlternative(self["serviceslist"].getCurrent()[1], x)
if len(self.serviceslist) > 0:
- del alternatives[self["serviceslist"].getCurrent()[1]]
+ del self.alternatives[self["serviceslist"].getCurrent()[1]]
self.updateServices()
self.updateAlternatives()
def finishedAlternativeSelection(self, args):
- alternatives[self["serviceslist"].getCurrent()[1]].append(str(ServiceReference(args)))
+ self.alternatives[self["serviceslist"].getCurrent()[1]].append(str(ServiceReference(args)))
+ addAlternative(self["serviceslist"].getCurrent()[1], str(ServiceReference(args)))
self.updateAlternatives()
def updateServices(self):
self.serviceslist = []
-
- for x in alternatives.keys():
+ keys = self.alternatives.keys()
+ keys.sort(key = sortKey)
+ for x in keys:
self.serviceslist.append((ServiceReference(x).getServiceName(), x))
- self["serviceslist"].l.setList(self.serviceslist)
+ self["serviceslist"].setList(self.serviceslist)
if len(self.serviceslist) > 0:
self.yellow.setText(_("Add alternative"))
self.red.setText(_("Remove service"))
else:
self.yellow.setText("")
self.red.setText("")
+
+ def selectService(self, ref):
+ count = 0
+ for x in self["serviceslist"].list:
+ if x[1] == ref:
+ self["serviceslist"].instance.moveSelectionTo(count)
+ return
+ count += 1
+
def updateAlternatives(self):
self.alternativeslist = []
if len(self.serviceslist) > 0:
- alternativelist = alternatives[self["serviceslist"].getCurrent()[1]]
+ alternativelist = self.alternatives[self["serviceslist"].getCurrent()[1]]
for x in alternativelist:
self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
- self["alternativeslist"].l.setList(self.alternativeslist)
+ self["alternativeslist"].setList(self.alternativeslist)
def greenKey(self):
self.session.openWithCallback(self.finishedChannelSelection, SimpleChannelSelection, _("Select reference service"))
- def finishedChannelSelection(self, args):
- if alternatives.has_key(str(ServiceReference(args))):
- pass
- else:
- alternatives[str(ServiceReference(args))] = []
- print alternatives
- self.updateServices()
- #oldref = self.timer.service_ref
- #try:
- #self.timer.service_ref = ServiceReference(args)
- #config.timerentry.service.vals = (str(self.timer.service_ref.getServiceName()),)
- #self["config"].invalidate(config.timerentry.service)
- #except:
- # print "you pressed cancel"
- #self.timer.service_ref = oldref
-
+ def finishedChannelSelection(self, *args):
+ if len(args):
+ serviceString = str(ServiceReference(args[0]))
+ if not self.alternatives.has_key(serviceString):
+ self.alternatives[serviceString] = []
+ self.updateServices()
+ self.selectService(serviceString)
+ self.updateAlternatives()
+
def yellowKey(self):
if len(self.serviceslist) > 0:
self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
pass
-oldPlayService = NavigationInstance.instance.playService
+oldPlayService = None
-def playService(self, ref):
- if not oldPlayService(ref):
- if alternatives.has_key(str(ServiceReference(ref))):
- for x in alternatives[str(ServiceReference(ref))]:
- if oldPlayService(ServiceReference(x).ref):
- return 1
- return 0
- return 1
+from Components.PerServiceDisplay import PerServiceDisplay
-def autostart(reason):
+class ServiceChanged(PerServiceDisplay):
+ def __init__(self, navcore):
+ PerServiceDisplay.__init__(self, navcore,
+ {
+ iPlayableService.evTuneFailed: self.tuneFailed,
+ iPlayableService.evStart: self.start
+ })
+
+ self.lastPlayAction = None
+ self.nextPlayTry = 0
+
+ def start(self):
+# print "+++++++++++++++++++++++++++++++++++++++++++++++++Start", self.lastPlayAction
+ if self.lastPlayAction is not None:
+ self.lastPlayAction = None
+
+ def tuneFailed(self):
+# print "+++++++++++++++++++++++++++++++++++++++++++++++++Tuning failed!", self.lastPlayAction
+ ref = self.lastPlayAction
+# print "Ref:", ref
+# print "Alternatives: failed to play service"
+ if ref is not None:
+ if alternatives.has_key(ref):
+# print "Alternatives: trying alternatives"
+ if len(alternatives[ref]) > self.nextPlayTry:
+# print "Alternatives: trying alternative", alternatives[ref][self.nextPlayTry]
+ if oldPlayService(ServiceReference(alternatives[ref][self.nextPlayTry]).ref) == 0:
+ self.nextPlayTry += 1
+# print "Alternatives: Alternative found!"
+ else:
+ self.nextPlayTry += 1
+# print "Alternatives: Alternative doesn't play either"
+ self.tuneFailed()
+ else:
+ self.lastPlayAction = None
+
+ #print "Alternatives: No playable alternative found!"
+
+servicechanged = None
+
+def playService(self, ref, **kwargs):
+ #print "--------------------Alternatives: trying to play service", str(ServiceReference(ref))
+ if ref is not None:
+ servicechanged.lastPlayAction = str(ServiceReference(ref))
+ servicechanged.nextPlayTry = 0
+ result = oldPlayService(ref, **kwargs)
+ return result
+
+def sessionstart(reason, session, **kwargs):
if reason == 0:
- NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation)
+ try:
+ loadAlternatives()
+ except: # FIXME, THIS IS ILLEGAL CODE AND WILL BE PROSECUTED!
+ pass
+
+ # attach to this sessions navigation instance.
+ global oldPlayService, servicechanged
+ oldPlayService = session.nav.playService
+ session.nav.playService = type(session.nav.playService)(playService, NavigationInstance, Navigation)
+ servicechanged = ServiceChanged(session.nav)
-def AlternativeZappingSetup(session):
+def AlternativeZappingSetup(session, **kwargs):
session.open(AlternativeZapping)
-def Plugins():
- return [PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart),
+def Plugins(**kwargs):
+ return [PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = sessionstart),
PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]