plugin api change: Plugins() and main functions must receive (and possibly ignore...
[enigma2.git] / lib / python / Plugins / Extensions / ZappingAlternatives / plugin.py
index d3e8012..118f0cb 100644 (file)
@@ -36,6 +36,19 @@ def removeAlternative(service1, service2):
                del alternatives[service1]
        if len(alternatives[service2]) == 0:
                del alternatives[service2]
                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 = """
                        
 class AlternativeZapping(Screen):
        skin = """
@@ -44,8 +57,8 @@ class AlternativeZapping(Screen):
                        <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="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>"""
        def __init__(self, session):
                self.skin = AlternativeZapping.skin
@@ -167,17 +180,27 @@ class AlternativeZapping(Screen):
        
        def updateServices(self):
                self.serviceslist = []
        
        def updateServices(self):
                self.serviceslist = []
-               
-               for x in self.alternatives.keys():
+               keys = self.alternatives.keys()
+               keys.sort(key = sortKey)
+               for x in keys:
                        self.serviceslist.append((ServiceReference(x).getServiceName(), x))
                        
                        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("")
                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 = []
                        
        def updateAlternatives(self):
                self.alternativeslist = []
@@ -187,20 +210,20 @@ class AlternativeZapping(Screen):
 
                        for x in alternativelist:
                                self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
 
                        for x in alternativelist:
                                self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
-                               print ServiceReference(x).frontendStatusInfo().getFrontendData(True)
                        
                        
-               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):
                        
        def greenKey(self):
                self.session.openWithCallback(self.finishedChannelSelection, SimpleChannelSelection, _("Select reference service"))
 
        def finishedChannelSelection(self, args):
-               if not self.alternatives.has_key(str(ServiceReference(args))):
-                       self.alternatives[str(ServiceReference(args))] = []
-               print "alternatives:", self.alternatives
+               serviceString = str(ServiceReference(args))
+               if not self.alternatives.has_key(serviceString):
+                       self.alternatives[serviceString] = []
                self.updateServices()
                self.updateServices()
+               self.selectService(serviceString)
                self.updateAlternatives()
                self.updateAlternatives()
-
+               
        def yellowKey(self):
                if len(self.serviceslist) > 0:
                        self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
        def yellowKey(self):
                if len(self.serviceslist) > 0:
                        self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
@@ -211,22 +234,69 @@ class AlternativeZapping(Screen):
 
 oldPlayService = NavigationInstance.instance.playService
 
 
 oldPlayService = NavigationInstance.instance.playService
 
+from Components.PerServiceDisplay import PerServiceDisplay
+
+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 = ServiceChanged(NavigationInstance.instance)
+
 def playService(self, ref):
 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
+       #print "--------------------Alternatives: trying to play service", str(ServiceReference(ref))
+       servicechanged.lastPlayAction = str(ServiceReference(ref))
+       servicechanged.nextPlayTry = 0
+       result = oldPlayService(ref)
+
+       
+       return result
 
 def autostart(reason):
        if reason == 0:
 
 def autostart(reason):
        if reason == 0:
+               try:
+                       loadAlternatives()
+               except:
+                       pass
                NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation)
                NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation)
+               
 
 
-def AlternativeZappingSetup(session):
+def AlternativeZappingSetup(session, **kwargs):
        session.open(AlternativeZapping)
 
        session.open(AlternativeZapping)
 
-def Plugins():
+def Plugins(**kwargs):
        return [PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart),
                        PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]
        return [PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart),
                        PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]