X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/88a6749020acfb921ae70f714e995af74e72c47c..aa4989974a32ab2437d51fb6352b3eb54cecd83d:/lib/python/Plugins/Extensions/ZappingAlternatives/plugin.py diff --git a/lib/python/Plugins/Extensions/ZappingAlternatives/plugin.py b/lib/python/Plugins/Extensions/ZappingAlternatives/plugin.py index b018c250..118f0cb6 100644 --- a/lib/python/Plugins/Extensions/ZappingAlternatives/plugin.py +++ b/lib/python/Plugins/Extensions/ZappingAlternatives/plugin.py @@ -13,11 +13,43 @@ import NavigationInstance 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 = """ @@ -25,12 +57,14 @@ class AlternativeZapping(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 @@ -41,19 +75,25 @@ class AlternativeZapping(Screen): 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, @@ -64,8 +104,52 @@ class AlternativeZapping(Screen): "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) @@ -82,59 +166,64 @@ class AlternativeZapping(Screen): 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 + serviceString = str(ServiceReference(args)) + if not self.alternatives.has_key(serviceString): + self.alternatives[serviceString] = [] 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 - + self.selectService(serviceString) + self.updateAlternatives() + def yellowKey(self): if len(self.serviceslist) > 0: self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service")) @@ -145,22 +234,69 @@ class AlternativeZapping(Screen): 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): - 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: + try: + loadAlternatives() + except: + pass NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation) + -def AlternativeZappingSetup(session): +def AlternativeZappingSetup(session, **kwargs): 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)]