don't die on loadAlternatives when no file is present
[enigma2.git] / lib / python / Plugins / Extensions / ZappingAlternatives / plugin.py
1 from enigma import *
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Components.ActionMap import ActionMap
5 from Components.Label import Label
6 from Components.Input import Input
7 from Components.GUIComponent import *
8 from Components.Pixmap import Pixmap
9 from Components.MenuList import MenuList
10 from Components.FileList import FileEntryComponent, FileList
11 from Navigation import Navigation
12 import NavigationInstance
13 from Screens.ChannelSelection import SimpleChannelSelection
14 from ServiceReference import ServiceReference
15 from Plugins.Plugin import PluginDescriptor
16 from Tools.Directories import resolveFilename, SCOPE_CONFIG
17 import xml.dom.minidom
18 from Tools.XMLTools import elementsWithTag
19
20 import os
21
22 alternatives = {}
23
24 def addAlternative(service1, service2):
25         if not alternatives.has_key(service1):
26                 alternatives[service1] = []
27         alternatives[service1].append(service2)
28         if not alternatives.has_key(service2):
29                 alternatives[service2] = []
30         alternatives[service2].append(service1)
31
32 def removeAlternative(service1, service2):
33         alternatives[service1].remove(service2)
34         alternatives[service2].remove(service1)
35         if len(alternatives[service1]) == 0:
36                 del alternatives[service1]
37         if len(alternatives[service2]) == 0:
38                 del alternatives[service2]
39                         
40 class AlternativeZapping(Screen):
41         skin = """
42                 <screen position="100,100" size="560,400" title="Services alternatives setup..." >
43                         <widget name="red" position="0,0" size="140,40" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
44                         <widget name="green" position="140,0" size="140,40" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
45                         <widget name="yellow" position="280,0" size="140,40" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
46                         <widget name="blue" position="420,0" size="140,40" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
47                         <widget name="serviceslist" position="0,40" size="280,360" />
48                         <widget name="alternativeslist" position="280,40" size="280,360" selectionDisabled="1" />
49                 </screen>"""
50         def __init__(self, session):
51                 self.skin = AlternativeZapping.skin
52                 Screen.__init__(self, session)
53
54                 self.filename = resolveFilename(SCOPE_CONFIG, "alternatives.xml")
55                 
56                 self.red = Label("")
57                 self["red"] = self.red
58                 self.green = Label(_("Add service"))
59                 self["green"] = self.green
60                 self.yellow = Label("")
61                 self["yellow"] = self.yellow
62                 self.blue = Label("")
63                 self["blue"] = self.blue
64                 
65                 self.alternatives = {}
66                 
67                 self.serviceslist = []
68                 self.alternativeslist = []
69                 
70                 try:
71                         self.loadAlternatives()
72                 except:
73                         pass
74                 self["serviceslist"] = MenuList(self.serviceslist)
75                 self["alternativeslist"] = MenuList(self.alternativeslist)
76
77                 self.onShown.append(self.updateServices)
78                 self.onShown.append(self.updateAlternatives)
79
80                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
81                 {
82                         "ok": self.go,
83                         "cancel": self.go,
84                         "up": self.up,
85                         "down": self.down,
86                         "left": self.left,
87                         "right": self.right,
88                         "red": self.redKey,
89                         "green": self.greenKey,
90                         "yellow": self.yellowKey,
91                         "blue": self.blueKey,
92                 }, -1)
93                 
94         def saveAlternatives(self):
95                 doc = xml.dom.minidom.Document()
96                 root_element = doc.createElement('alternatives')
97                 doc.appendChild(root_element)
98                 root_element.appendChild(doc.createTextNode("\n"))
99                 
100                 for alternative in self.alternatives.keys():
101                         t = doc.createTextNode("\t")
102                         root_element.appendChild(t)
103                         t = doc.createElement('service')
104                         t.setAttribute("ref", alternative)
105                         root_element.appendChild(t)
106                         t.appendChild(doc.createTextNode("\n"))
107                         for x in self.alternatives[alternative]:
108                                 t.appendChild(doc.createTextNode("\t\t"))
109                                 l = doc.createElement('alternative')
110                                 l.setAttribute("ref", str(x))
111                                 t.appendChild(l)
112                                 t.appendChild(doc.createTextNode("\n"))
113                         t.appendChild(doc.createTextNode("\t"))
114                         root_element.appendChild(t)
115                         t = doc.createTextNode("\n")
116                         root_element.appendChild(t)
117                 file = open(self.filename, "w")
118                 doc.writexml(file)
119                 file.write("\n")
120                 file.close()
121         
122         def loadAlternatives(self):
123                 self.alternatives = {}
124                 alternatives = {}
125                 doc = xml.dom.minidom.parse(self.filename)
126                 
127                 root = doc.childNodes[0]
128                 for service in elementsWithTag(root.childNodes, 'service'):
129                         newService = str(service.getAttribute('ref'))
130                         if not self.alternatives.has_key(newService):
131                                 self.alternatives[newService] = []
132                         for alternative in elementsWithTag(service.childNodes, 'alternative'):
133                                 newAlternative = str(alternative.getAttribute('ref'))
134                                 self.alternatives[newService].append(newAlternative)
135                                 addAlternative(newService, newAlternative)
136                 
137         def go(self):
138                 self.saveAlternatives()
139                 self.close()
140         
141         def up(self):
142                 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveUp)
143                 self.updateAlternatives()
144                 
145         def down(self):
146                 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveDown)
147                 self.updateAlternatives()
148         
149         def left(self):
150                 pass
151         
152         def right(self):
153                 pass
154         
155         def redKey(self):
156                 for x in self.alternatives[self["serviceslist"].getCurrent()[1]]:
157                         removeAlternative(self["serviceslist"].getCurrent()[1], x)
158                 if len(self.serviceslist) > 0:
159                         del self.alternatives[self["serviceslist"].getCurrent()[1]]
160                 self.updateServices()
161                 self.updateAlternatives()
162         
163         def finishedAlternativeSelection(self, args):
164                 self.alternatives[self["serviceslist"].getCurrent()[1]].append(str(ServiceReference(args)))
165                 addAlternative(self["serviceslist"].getCurrent()[1], str(ServiceReference(args)))
166                 self.updateAlternatives()
167         
168         def updateServices(self):
169                 self.serviceslist = []
170                 
171                 for x in self.alternatives.keys():
172                         self.serviceslist.append((ServiceReference(x).getServiceName(), x))
173                         
174                 self["serviceslist"].l.setList(self.serviceslist)
175                 if len(self.serviceslist) > 0:
176                         self.yellow.setText(_("Add alternative"))
177                         self.red.setText(_("Remove service"))
178                 else:
179                         self.yellow.setText("")
180                         self.red.setText("")
181                         
182         def updateAlternatives(self):
183                 self.alternativeslist = []
184         
185                 if len(self.serviceslist) > 0:
186                         alternativelist = self.alternatives[self["serviceslist"].getCurrent()[1]]
187
188                         for x in alternativelist:
189                                 self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
190                                 print ServiceReference(x).frontendStatusInfo().getFrontendData(True)
191                         
192                 self["alternativeslist"].l.setList(self.alternativeslist)
193                         
194         def greenKey(self):
195                 self.session.openWithCallback(self.finishedChannelSelection, SimpleChannelSelection, _("Select reference service"))
196
197         def finishedChannelSelection(self, args):
198                 if not self.alternatives.has_key(str(ServiceReference(args))):
199                         self.alternatives[str(ServiceReference(args))] = []
200                 print "alternatives:", self.alternatives
201                 self.updateServices()
202                 self.updateAlternatives()
203
204         def yellowKey(self):
205                 if len(self.serviceslist) > 0:
206                         self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
207         
208         def blueKey(self):
209                 pass
210
211
212 oldPlayService = NavigationInstance.instance.playService
213
214 def playService(self, ref):
215         if not oldPlayService(ref):
216                 if alternatives.has_key(str(ServiceReference(ref))):
217                         for x in alternatives[str(ServiceReference(ref))]:
218                                 if oldPlayService(ServiceReference(x).ref):
219                                         return 1
220                 return 0
221         return 1
222
223 def autostart(reason):
224         if reason == 0:
225                 NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation)
226
227 def AlternativeZappingSetup(session):
228         session.open(AlternativeZapping)
229
230 def Plugins():
231         return [PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart),
232                         PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]