f4bc3fad6e5f9902ed3b85affa7599070349610a
[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 def loadAlternatives():
41         doc = xml.dom.minidom.parse(self.filename)
42         
43         root = doc.childNodes[0]
44         for service in elementsWithTag(root.childNodes, 'service'):
45                 newService = str(service.getAttribute('ref'))
46                 for alternative in elementsWithTag(service.childNodes, 'alternative'):
47                         newAlternative = str(alternative.getAttribute('ref'))
48                         addAlternative(newService, newAlternative)
49
50 def sortKey(x):
51         return str.lower(ServiceReference(x).getServiceName().strip())
52                         
53 class AlternativeZapping(Screen):
54         skin = """
55                 <screen position="100,100" size="560,400" title="Services alternatives setup..." >
56                         <widget name="red" position="0,0" size="140,40" backgroundColor="red" halign="center" valign="center" font="Regular;21" />
57                         <widget name="green" position="140,0" size="140,40" backgroundColor="green" halign="center" valign="center" font="Regular;21" />
58                         <widget name="yellow" position="280,0" size="140,40" backgroundColor="yellow" halign="center" valign="center" font="Regular;21" />
59                         <widget name="blue" position="420,0" size="140,40" backgroundColor="blue" halign="center" valign="center" font="Regular;21" />
60                         <widget name="serviceslist" position="0,40" size="280,360" />
61                         <widget name="alternativeslist" position="280,40" size="280,360" selectionDisabled="1" />
62                 </screen>"""
63         def __init__(self, session):
64                 self.skin = AlternativeZapping.skin
65                 Screen.__init__(self, session)
66
67                 self.filename = resolveFilename(SCOPE_CONFIG, "alternatives.xml")
68                 
69                 self.red = Label("")
70                 self["red"] = self.red
71                 self.green = Label(_("Add service"))
72                 self["green"] = self.green
73                 self.yellow = Label("")
74                 self["yellow"] = self.yellow
75                 self.blue = Label("")
76                 self["blue"] = self.blue
77                 
78                 self.alternatives = {}
79                 
80                 self.serviceslist = []
81                 self.alternativeslist = []
82                 
83                 try:
84                         self.loadAlternatives()
85                 except:
86                         pass
87                 self["serviceslist"] = MenuList(self.serviceslist)
88                 self["alternativeslist"] = MenuList(self.alternativeslist)
89
90                 self.onShown.append(self.updateServices)
91                 self.onShown.append(self.updateAlternatives)
92
93                 self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ColorActions"],
94                 {
95                         "ok": self.go,
96                         "cancel": self.go,
97                         "up": self.up,
98                         "down": self.down,
99                         "left": self.left,
100                         "right": self.right,
101                         "red": self.redKey,
102                         "green": self.greenKey,
103                         "yellow": self.yellowKey,
104                         "blue": self.blueKey,
105                 }, -1)
106                 
107         def saveAlternatives(self):
108                 doc = xml.dom.minidom.Document()
109                 root_element = doc.createElement('alternatives')
110                 doc.appendChild(root_element)
111                 root_element.appendChild(doc.createTextNode("\n"))
112                 
113                 for alternative in self.alternatives.keys():
114                         t = doc.createTextNode("\t")
115                         root_element.appendChild(t)
116                         t = doc.createElement('service')
117                         t.setAttribute("ref", alternative)
118                         root_element.appendChild(t)
119                         t.appendChild(doc.createTextNode("\n"))
120                         for x in self.alternatives[alternative]:
121                                 t.appendChild(doc.createTextNode("\t\t"))
122                                 l = doc.createElement('alternative')
123                                 l.setAttribute("ref", str(x))
124                                 t.appendChild(l)
125                                 t.appendChild(doc.createTextNode("\n"))
126                         t.appendChild(doc.createTextNode("\t"))
127                         root_element.appendChild(t)
128                         t = doc.createTextNode("\n")
129                         root_element.appendChild(t)
130                 file = open(self.filename, "w")
131                 doc.writexml(file)
132                 file.write("\n")
133                 file.close()
134         
135         def loadAlternatives(self):
136                 self.alternatives = {}
137                 alternatives = {}
138                 doc = xml.dom.minidom.parse(self.filename)
139                 
140                 root = doc.childNodes[0]
141                 for service in elementsWithTag(root.childNodes, 'service'):
142                         newService = str(service.getAttribute('ref'))
143                         if not self.alternatives.has_key(newService):
144                                 self.alternatives[newService] = []
145                         for alternative in elementsWithTag(service.childNodes, 'alternative'):
146                                 newAlternative = str(alternative.getAttribute('ref'))
147                                 self.alternatives[newService].append(newAlternative)
148                                 addAlternative(newService, newAlternative)
149                 
150         def go(self):
151                 self.saveAlternatives()
152                 self.close()
153         
154         def up(self):
155                 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveUp)
156                 self.updateAlternatives()
157                 
158         def down(self):
159                 self["serviceslist"].instance.moveSelection(self["serviceslist"].instance.moveDown)
160                 self.updateAlternatives()
161         
162         def left(self):
163                 pass
164         
165         def right(self):
166                 pass
167         
168         def redKey(self):
169                 for x in self.alternatives[self["serviceslist"].getCurrent()[1]]:
170                         removeAlternative(self["serviceslist"].getCurrent()[1], x)
171                 if len(self.serviceslist) > 0:
172                         del self.alternatives[self["serviceslist"].getCurrent()[1]]
173                 self.updateServices()
174                 self.updateAlternatives()
175         
176         def finishedAlternativeSelection(self, args):
177                 self.alternatives[self["serviceslist"].getCurrent()[1]].append(str(ServiceReference(args)))
178                 addAlternative(self["serviceslist"].getCurrent()[1], str(ServiceReference(args)))
179                 self.updateAlternatives()
180         
181         def updateServices(self):
182                 self.serviceslist = []
183                 keys = self.alternatives.keys()
184                 keys.sort(key = sortKey)
185                 for x in keys:
186                         self.serviceslist.append((ServiceReference(x).getServiceName(), x))
187                         
188                 self["serviceslist"].setList(self.serviceslist)
189                 if len(self.serviceslist) > 0:
190                         self.yellow.setText(_("Add alternative"))
191                         self.red.setText(_("Remove service"))
192                 else:
193                         self.yellow.setText("")
194                         self.red.setText("")
195         
196         def selectService(self, ref):
197                 count = 0
198                 for x in self["serviceslist"].list:
199                         if x[1] == ref:
200                                 self["serviceslist"].instance.moveSelectionTo(count)
201                                 return
202                         count += 1
203                         
204                         
205         def updateAlternatives(self):
206                 self.alternativeslist = []
207         
208                 if len(self.serviceslist) > 0:
209                         alternativelist = self.alternatives[self["serviceslist"].getCurrent()[1]]
210
211                         for x in alternativelist:
212                                 self.alternativeslist.append((ServiceReference(x).getServiceName(), x))
213                         
214                 self["alternativeslist"].setList(self.alternativeslist)
215                         
216         def greenKey(self):
217                 self.session.openWithCallback(self.finishedChannelSelection, SimpleChannelSelection, _("Select reference service"))
218
219         def finishedChannelSelection(self, args):
220                 serviceString = str(ServiceReference(args))
221                 if not self.alternatives.has_key(serviceString):
222                         self.alternatives[serviceString] = []
223                 self.updateServices()
224                 self.updateAlternatives()
225                 self.selectService(serviceString)
226
227         def yellowKey(self):
228                 if len(self.serviceslist) > 0:
229                         self.session.openWithCallback(self.finishedAlternativeSelection, SimpleChannelSelection, _("Select alternative service"))
230         
231         def blueKey(self):
232                 pass
233
234
235 oldPlayService = NavigationInstance.instance.playService
236
237 def playService(self, ref):
238         if not oldPlayService(ref):
239                 if alternatives.has_key(str(ServiceReference(ref))):
240                         for x in alternatives[str(ServiceReference(ref))]:
241                                 if oldPlayService(ServiceReference(x).ref):
242                                         return 1
243                 return 0
244         return 1
245
246 def autostart(reason):
247         if reason == 0:
248                 try:
249                         loadAlternatives()
250                 except:
251                         pass
252                 NavigationInstance.instance.playService = type(NavigationInstance.instance.playService)(playService, NavigationInstance, Navigation)
253
254 def AlternativeZappingSetup(session):
255         session.open(AlternativeZapping)
256
257 def Plugins():
258         return [PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, fnc = autostart),
259                         PluginDescriptor(name="Alternative services setup" , description="Defines alternatives for services.", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=AlternativeZappingSetup)]