add webbouqueteditor (dmm plugin contest winner plugin)
[enigma2-plugins.git] / webbouqueteditor / src / WebComponents / Sources / BouquetEditor.py
1 from enigma import eServiceReference, eServiceCenter, eDVBDB
2 from Components.Sources.Source import Source
3 from Screens.ChannelSelection import service_types_tv, MODE_TV, MODE_RADIO
4 from Components.config import config
5 from os import remove, path, popen
6 from Screens.InfoBar import InfoBar
7 from ServiceReference import ServiceReference
8 from Components.ParentalControl import parentalControl, IMG_WHITESERVICE, IMG_WHITEBOUQUET, IMG_BLACKSERVICE, IMG_BLACKBOUQUET, LIST_BLACKLIST
9 from re import compile as re_compile
10 from Components.NimManager import nimmanager 
11
12 class BouquetEditor(Source):
13
14         ADD_BOUQUET = 0
15         REMOVE_BOUQUET = 1
16         MOVE_BOUQUET = 2
17         ADD_SERVICE_TO_BOUQUET = 3
18         REMOVE_SERVICE = 4
19         MOVE_SERVICE = 5
20         ADD_PROVIDER_TO_BOUQUETLIST = 6
21         ADD_SERVICE_TO_ALTERNATIVE = 7
22         REMOVE_ALTERNATIVE_SERVICES = 8
23         TOGGLE_LOCK = 9
24         BACKUP = 10
25         RESTORE = 11
26         RENAME_SERVICE = 12
27         ADD_MARKER_TO_BOUQUET = 13
28         
29         BACKUP_PATH = "/tmp"
30         BACKUP_FILENAME = "webbouqueteditor_backup.tar"
31         
32
33         def __init__(self, session, func=ADD_BOUQUET):
34                 Source.__init__(self)
35                 self.func = func
36                 self.session = session
37                 self.command = None
38                 self.bouquet_rootstr = ""
39                 self.result = ( False, "one two three four unknown command" )
40                 
41
42         def handleCommand(self, cmd):
43                 print "[WebComponents.BouquetEditor] handleCommand with cmd = ", cmd
44                 if self.func is self.ADD_BOUQUET:
45                         self.result = self.addToBouquet(cmd)
46                 elif self.func is self.MOVE_BOUQUET:
47                         self.result = self.moveBouquet(cmd)     
48                 elif self.func is self.MOVE_SERVICE:
49                         self.result = self.moveService(cmd)     
50                 elif self.func is self.REMOVE_BOUQUET:
51                         self.result = self.removeBouquet(cmd)
52                 elif self.func is self.REMOVE_SERVICE:
53                         self.result = self.removeService(cmd)
54                 elif self.func is self.ADD_SERVICE_TO_BOUQUET:
55                         self.result = self.addServiceToBouquet(cmd)
56                 elif self.func is self.ADD_PROVIDER_TO_BOUQUETLIST:
57                         self.result = self.addProviderToBouquetlist(cmd)
58                 elif self.func is self.ADD_SERVICE_TO_ALTERNATIVE:
59                         self.result = self.addServiceToAlternative(cmd)
60                 elif self.func is self.REMOVE_ALTERNATIVE_SERVICES:
61                         self.result = self.removeAlternativeServices(cmd)
62                 elif self.func is self.TOGGLE_LOCK:
63                         self.result = self.toggleLock(cmd)
64                 elif self.func is self.BACKUP:
65                         self.result = self.backupFiles(cmd)
66                 elif self.func is self.RESTORE:
67                         self.result = self.restoreFiles(cmd)
68                 elif self.func is self.RENAME_SERVICE:
69                         self.result = self.renameService(cmd)
70                 elif self.func is self.ADD_MARKER_TO_BOUQUET:
71                         self.result = self.addMarkerToBouquet(cmd)
72                 else:
73                         self.result = ( False, "one two three four unknown command" )
74
75         def addToBouquet(self, param):
76                 print "[WebComponents.BouquetEditor] addToBouquet with param = ", param
77                 bName = param["name"]
78                 if bName is None:
79                         return (False, "No bouquet name given!")
80                 mode = MODE_TV # init
81                 if "mode" in param:
82                         if param["mode"] is not None:
83                                 mode = int(param["mode"])
84                 return self.addBouquet(bName, mode, None)
85
86         def addBouquet(self, bName, mode, services):
87                 if config.usage.multibouquet.value:
88                         mutableBouquetList = self.getMutableBouquetList(mode)
89                         if mutableBouquetList:
90                                 if mode == MODE_TV:
91                                         bName += " (TV)"
92                                         sref = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(bName, "userbouquet.", mode))
93                                 else:
94                                         bName += " (Radio)"
95                                         sref = '1:7:2:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(bName, "userbouquet.", mode))
96                                 new_bouquet_ref = eServiceReference(sref)
97                                 if not mutableBouquetList.addService(new_bouquet_ref):
98                                         mutableBouquetList.flushChanges()
99                                         eDVBDB.getInstance().reloadBouquets()
100                                         mutableBouquet = self.getMutableList(new_bouquet_ref)
101                                         if mutableBouquet:
102                                                 mutableBouquet.setListName(bName)
103                                                 if services is not None:
104                                                         for service in services:
105                                                                 if mutableBouquet.addService(service):
106                                                                         print "add", service.toString(), "to new bouquet failed"
107                                                 mutableBouquet.flushChanges()
108                                                 self.setRoot(self.bouquet_rootstr)
109                                                 return (True, "Bouquet %s created." % bName)
110                                         else:
111                                                 return (False, "Get mutable list for new created bouquet failed!")
112
113                                 else:
114                                         return (False, "Bouquet %s already exists." % bName)
115                         else:
116                                 return (False, "Bouquetlist is not editable!")
117                 else:
118                         return (False, "Multi-Bouquet is not enabled!")
119
120
121         def addProviderToBouquetlist(self, param):
122                 print "[WebComponents.BouquetEditor] addProviderToBouquet with param = ", param
123                 refstr = sref = param["sProviderRef"]
124                 if refstr is None:
125                         return (False, "No provider given!")
126                 mode = MODE_TV # init
127                 if "mode" in param:
128                         if param["mode"] is not None:
129                                 mode = int(param["mode"])
130                 ref = eServiceReference(refstr)
131                 provider = ServiceReference(ref)
132                 providerName = provider.getServiceName()
133                 serviceHandler = eServiceCenter.getInstance()
134                 services = serviceHandler.list(provider.ref)
135                 return self.addBouquet(providerName, mode, services and services.getContent('R', True))
136
137         def removeBouquet(self, param):
138                 print "[WebComponents.BouquetEditor] removeBouquet with param = ", param
139                 refstr = sref = param["sBouquetRef"]
140                 if refstr is None:
141                         return (False, "No bouquet name given!")
142                 mode = MODE_TV # init
143                 if "mode" in param:
144                         if param["mode"] is not None:
145                                 mode = int(param["mode"])
146                 
147                 if param.has_key("BouquetRefRoot"):
148                         bouquet_root = param["BouquetRefRoot"] # only when removing alternative
149                 else:
150                         bouquet_root = None
151                 pos = refstr.find('FROM BOUQUET "')
152                 filename = None
153                 if pos != -1:
154                         refstr = refstr[pos+14:]
155                         pos = refstr.find('"')
156                         if pos != -1:
157                                 filename = '/etc/enigma2/' + refstr[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
158                 ref = eServiceReference(sref)
159                 bouquetName = self.getName(ref)
160                 if not bouquetName:
161                         bouquetName = filename
162                 if bouquet_root:
163                         mutableList = self.getMutableList(eServiceReference(bouquet_root))
164                 else:
165                         mutableList = self.getMutableBouquetList(mode)
166                         
167                 if ref.valid() and mutableList is not None:
168                         if not mutableList.removeService(ref):
169                                 mutableList.flushChanges()
170                                 self.setRoot(self.bouquet_rootstr)
171                         else:
172                                 return (False, "Bouquet %s removed failed." % filename)
173                 else:
174                         return (False, "Bouquet %s removed failed, sevicerefence or mutable list is not valid." % filename)
175                 try:
176                         if filename is not None:
177                                 remove(filename)
178                                 return (True, "Bouquet %s deleted." % bouquetName)
179                 except OSError:
180                         return (False, "Error: Bouquet %s could not deleted, OSError." % filename)
181
182         def moveBouquet(self, param):
183                 print "[WebComponents.BouquetEditor] moveBouquet with param = ", param
184                 sBouquetRef = param["sBouquetRef"]
185                 if sBouquetRef is None:
186                         return (False, "No bouquet name given!")
187                 mode = MODE_TV # init
188                 if "mode" in param:
189                         if param["mode"] is not None:
190                                 mode = int(param["mode"])
191                 position = None
192                 if "position" in param:
193                         if param["position"] is not None:
194                                 position = int(param["position"])
195                 if position is None:
196                         return (False, "No position given!")
197                 mutableBouquetList = self.getMutableBouquetList(mode)
198                 if mutableBouquetList is not None:
199                         ref = eServiceReference(sBouquetRef)
200                         mutableBouquetList.moveService(ref, position)
201                         mutableBouquetList.flushChanges()
202                         self.setRoot(self.bouquet_rootstr)
203                         return (True, "Bouquet %s moved." % self.getName(ref))
204                 else:
205                         return (False, "Bouquet %s can not be moved." % self.getName(ref))
206                         
207         def removeService(self, param):
208                 print "[WebComponents.BouquetEditor] removeService with param = ", param
209                 sBouquetRef = param["sBouquetRef"]
210                 if sBouquetRef is None:
211                         return (False, "No bouquet given!")
212                 sRef = None
213                 if "sRef" in param:
214                         if param["sRef"] is not None:
215                                 sRef =param["sRef"]
216                 if sRef is None:
217                         return (False, "No service given!")
218                 ref = eServiceReference(sRef)
219                 if ref.flags & eServiceReference.isGroup: # check if  service is an alternative, if so delete it with removeBouquet
220                         new_param = {}
221                         new_param["sBouquetRef"] = sRef
222                         new_param["mode"] = None # of no interest when passing BouquetRefRoot
223                         new_param["BouquetRefRoot"] = sBouquetRef
224                         returnValue = self.removeBouquet(new_param)
225                         if returnValue[0]:
226                                 return (True, "Service %s removed." % self.getName(ref))
227                 else:
228                         bouquetRef = eServiceReference(sBouquetRef)
229                         mutableBouquetList = self.getMutableList(bouquetRef)
230                         if mutableBouquetList is not None:
231                                 if not mutableBouquetList.removeService(ref):
232                                         mutableBouquetList.flushChanges()
233                                         self.setRoot(sBouquetRef)
234                                         return (True, "Service %s removed from bouquet %s." % (self.getName(ref), self.getName(bouquetRef)))
235                 return (False, "Service %s can not be removed." % self.getName(ref))
236
237         def moveService(self, param):
238                 print "[WebComponents.BouquetEditor] moveService with param = ", param
239                 sBouquetRef = param["sBouquetRef"]
240                 if sBouquetRef is None:
241                         return (False, "No bouquet given!")
242                 sRef = None
243                 if "sRef" in param:
244                         if param["sRef"] is not None:
245                                 sRef =param["sRef"]
246                 if sRef is None:
247                         return (False, "No service given!")
248                 position = None
249                 if "position" in param:
250                         if param["position"] is not None:
251                                 position = int(param["position"])
252                 if position is None:
253                         return (False, "No position given!")
254                 mutableBouquetList = self.getMutableList(eServiceReference(sBouquetRef))
255                 if mutableBouquetList is not None:
256                         ref = eServiceReference(sRef)
257                         mutableBouquetList.moveService(ref, position)
258                         mutableBouquetList.flushChanges()
259                         self.setRoot(sBouquetRef)
260                         return (True, "Service %s moved." % self.getName(ref))
261                 return (False, "Service can not be moved.")
262
263         def addServiceToBouquet(self, param):
264                 print "[WebComponents.BouquetEditor] addService with param = ", param
265                 sBouquetRef = param["sBouquetRef"]
266                 if sBouquetRef is None:
267                         return (False, "No bouquet given!")
268                 sRef = None
269                 if "sRef" in param:
270                         if param["sRef"] is not None:
271                                 sRef =param["sRef"]
272                 if sRef is None:
273                         return (False, "No service given!")
274                 sName = None
275                 if "Name" in param:
276                         if param["Name"] is not None:
277                                 sName =param["Name"]
278                 sRefBefore = eServiceReference()
279                 if "sRefBefore" in param:
280                         if param["sRefBefore"] is not None:
281                                 sRefBefore = eServiceReference(param["sRefBefore"])
282                 bouquetRef = eServiceReference(sBouquetRef)
283                 mutableBouquetList = self.getMutableList(bouquetRef)
284                 if mutableBouquetList is not None:
285                         ref = eServiceReference(sRef)
286                         if sName:
287                                 ref.setName(sName)
288                         if not mutableBouquetList.addService(ref, sRefBefore):
289                                 mutableBouquetList.flushChanges()
290                                 self.setRoot(sBouquetRef)
291                                 return (True, "Service %s added." % self.getName(ref))
292                         else:
293                                 bouquetName = self.getName(bouquetRef)
294                                 return (False, "Service %s already exists in bouquet %s." % (self.getName(ref), bouquetName))
295                 return (False, "This service can not be added.")
296                 
297         def addMarkerToBouquet(self, param):
298                 print "[WebComponents.BouquetEditor] addMarkerToBouquet with param = ", param
299                 sBouquetRef = param["sBouquetRef"]
300                 if sBouquetRef is None:
301                         return (False, "No bouquet given!")
302                 name = None
303                 if "Name" in param:
304                         if param["Name"] is not None:
305                                 name =param["Name"]
306                 if name is None:
307                         return (False, "No marker-name given!")
308                 sRefBefore = eServiceReference()
309                 if "sRefBefore" in param:
310                         if param["sRefBefore"] is not None:
311                                 sRefBefore = eServiceReference(param["sRefBefore"])
312                 bouquet_ref = eServiceReference(sBouquetRef) 
313                 mutableBouquetList = self.getMutableList(bouquet_ref)
314                 cnt = 0
315                 while mutableBouquetList:
316                         service_str = '1:64:%d:0:0:0:0:0:0:0::%s'%(cnt, name)
317                         ref = eServiceReference(service_str)
318                         if not mutableBouquetList.addService(ref, sRefBefore):
319                                 mutableBouquetList.flushChanges()
320                                 self.setRoot(sBouquetRef)
321                                 return (True, "Marker added.")
322                         cnt+=1
323                 return (False, "Internal error!")
324                 
325         def renameService(self, param):
326                 sRef = None
327                 if "sRef" in param:
328                         if param["sRef"] is not None:
329                                 sRef =param["sRef"]
330                 if sRef is None:
331                         return (False, "No service given!")
332                 sName = None
333                 if "newName" in param:
334                         if param["newName"] is not None:
335                                 sName =param["newName"]
336                 if sName is None:
337                         return (False, "No new servicename given!")             
338                 sBouquetRef = None
339                 if "sBouquetRef" in param:
340                         if param["sBouquetRef"] is not None:
341                                 sBouquetRef =param["sBouquetRef"]
342                 cur_ref = eServiceReference(sRef) 
343                 if cur_ref.flags & eServiceReference.mustDescent:
344                         # bouquets or alternatives can be renamed with setListName directly
345                         mutableBouquetList = self.getMutableList(cur_ref)
346                         if mutableBouquetList:
347                                         mutableBouquetList.setListName(sName)
348                                         mutableBouquetList.flushChanges()
349                                         if sBouquetRef: # BouquetRef is given when renaming alternatives
350                                                 self.setRoot(sBouquetRef)
351                                         else:
352                                                 mode = MODE_TV # mode is given when renaming bouquet
353                                                 if "mode" in param:
354                                                         if param["mode"] is not None:
355                                                                 mode = int(param["mode"])
356                                                 if mode == MODE_TV:
357                                                         bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
358                                                 else:
359                                                         bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
360                                                 self.setRoot(bouquet_rootstr)
361                                         return (True, "Bouquet renamed successfully.")
362                 else: # service
363                         # services can not be renamed directly, so delete the current and add it again with new servicename
364                         sRefBefore = None
365                         if "sRefBefore" in param:
366                                 if param["sRefBefore"] is not None:
367                                         sRefBefore =param["sRefBefore"]
368                         new_param = {}
369                         new_param["sBouquetRef"] = sBouquetRef
370                         new_param["sRef"] = sRef
371                         new_param["Name"] = sName
372                         new_param["sRefBefore"] = sRefBefore
373                         returnValue = self.removeService(new_param)
374                         if returnValue[0]:
375                                 returnValue = self.addServiceToBouquet(new_param)
376                                 if returnValue[0]:
377                                         return (True, "Service renamed successfully.")
378                 return (False, "Service can not be renamed.")
379                 
380         def addServiceToAlternative(self, param):
381                 sBouquetRef = param["sBouquetRef"]
382                 if sBouquetRef is None:
383                         return (False, "No bouquet given!")
384                 sRef = None
385                 if "sRef" in param:
386                         if param["sRef"] is not None:
387                                 sRef =param["sRef"] #  service to add to the alternative
388                 if sRef is None:
389                         return (False, "No service given!")
390                 sCurrentRef = param["sCurrentRef"] #  alternative service
391                 if sCurrentRef is None:
392                         return (False, "No current service given!")
393                 cur_ref = eServiceReference(sCurrentRef) 
394                 # check if  service is already an alternative
395                 if not (cur_ref.flags & eServiceReference.isGroup):
396                         # sCurrentRef is not an alternative service yet, so do this and add itself to new alternative liste
397                         mode = MODE_TV # init
398                         if "mode" in param:
399                                 if param["mode"] is not None:
400                                         mode = int(param["mode"])
401                         mutableBouquetList = self.getMutableList(eServiceReference(sBouquetRef))
402                         if mutableBouquetList:
403                                 cur_service = ServiceReference(cur_ref)
404                                 name = cur_service.getServiceName()
405                                 if mode == MODE_TV:
406                                         sref = '1:134:1:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.tv\" ORDER BY bouquet'%(self.buildBouquetID(name, "alternatives.", mode))
407                                 else:
408                                         sref = '1:134:2:0:0:0:0:0:0:0:FROM BOUQUET \"alternatives.%s.radio\" ORDER BY bouquet'%(self.buildBouquetID(name, "alternatives.", mode))
409                                 new_ref = eServiceReference(sref)
410                                 if not mutableBouquetList.addService(new_ref, cur_ref):
411                                         mutableBouquetList.removeService(cur_ref)
412                                         mutableBouquetList.flushChanges()
413                                         eDVBDB.getInstance().reloadBouquets()
414                                         mutableAlternatives = self.getMutableList(new_ref)
415                                         if mutableAlternatives:
416                                                 mutableAlternatives.setListName(name)
417                                                 if mutableAlternatives.addService(cur_ref):
418                                                                         print "add", cur_ref.toString(), "to new alternatives failed"
419                                                 mutableAlternatives.flushChanges()
420                                                 self.setRoot(sBouquetRef)
421                                                 sCurrentRef = sref # currentRef is now an alternative (bouquet)
422                                         else:
423                                                 return (False, "Get mutable list for new created alternative failed!")
424                                 else:
425                                         return (False, "Alternative %s created failed." % name)
426                         else:
427                                 return (False, "Bouquetlist is not editable!")
428                 # add service to alternative-bouquet
429                 new_param = {}
430                 new_param["sBouquetRef"] = sCurrentRef
431                 new_param["sRef"] = sRef
432                 returnValue = self.addServiceToBouquet(new_param)
433                 if returnValue[0]:
434                         cur_ref = eServiceReference(sCurrentRef) 
435                         cur_service = ServiceReference(cur_ref)
436                         name = cur_service.getServiceName()
437                         service_ref = ServiceReference(sRef)
438                         service_name = service_ref.getServiceName()
439                         return (True, "Added %s to alternative service %s." % (service_name,name))
440                 else:
441                         return returnValue
442                         
443         def removeAlternativeServices(self, param):
444                 print "[WebComponents.BouquetEditor] removeAlternativeServices with param = ", param
445                 sBouquetRef = param["sBouquetRef"]
446                 if sBouquetRef is None:
447                         return (False, "No bouquet given!")
448                 sRef = None
449                 if "sRef" in param:
450                         if param["sRef"] is not None:
451                                 sRef =param["sRef"]
452                 if sRef is None:
453                         return (False, "No service given!")
454                 cur_ref = eServiceReference(sRef) 
455                 # check if  service is an alternative
456                 if cur_ref.flags & eServiceReference.isGroup:
457                         cur_service = ServiceReference(cur_ref)
458                         list = cur_service.list()
459                         first_in_alternative = list and list.getNext()
460                         if first_in_alternative:
461                                 mutableBouquetList = self.getMutableList(eServiceReference(sBouquetRef))
462                                 if mutableBouquetList is not None:
463                                         if mutableBouquetList.addService(first_in_alternative, cur_service.ref):
464                                                 print "couldn't add first alternative service to current root"
465                                 else:
466                                         print "couldn't edit current root"
467                         else:
468                                 print "remove empty alternative list"
469                 else:
470                         return (False, "Service is not an alternative.")
471                 new_param = {}
472                 new_param["sBouquetRef"] = sRef
473                 new_param["mode"] = None # of no interest when passing BouquetRefRoot
474                 new_param["BouquetRefRoot"] = sBouquetRef
475                 returnValue = self.removeBouquet(new_param)
476                 if returnValue[0]:
477                         self.setRoot(sBouquetRef)
478                         return (True,"All alternative services deleted.")
479                 else:
480                         return returnValue
481                         
482         def toggleLock(self, param):
483                 if not config.ParentalControl.configured.value:
484                         return (False, "Parent Control is not activated.")
485                 sRef = None
486                 if "sRef" in param:
487                         if param["sRef"] is not None:
488                                 sRef =param["sRef"]
489                 if sRef is None:
490                         return (False, "No service given!")
491                 if config.ParentalControl.setuppinactive.value:
492                         password = None
493                         if "password" in param:
494                                 if param["password"] is not None:
495                                         password =param["password"]
496                         if password is None:
497                                 return (False, "No Parent Control Setup Pin given!")
498                         else:
499                                 if password.isdigit():
500                                         if int(password) != config.ParentalControl.setuppin.value:
501                                                 return (False, "Parent Control Setup Pin is wrong!")
502                                 else:
503                                         return (False, "Parent Control Setup Pin is wrong!")
504                 cur_ref = eServiceReference(sRef)
505                 protection = parentalControl.getProtectionType(cur_ref.toCompareString())
506                 if protection[0]:
507                         parentalControl.unProtectService(cur_ref.toCompareString())
508                 else:
509                         parentalControl.protectService(cur_ref.toCompareString())
510                 protection = parentalControl.getProtectionType(cur_ref.toCompareString())
511                 if cur_ref.flags & eServiceReference.mustDescent:
512                         serviceType = "Bouquet"
513                 else:
514                         serviceType = "Service"
515                 protectionText = "%s %s is unlocked." % (serviceType, self.getName(cur_ref))
516                 if protection[0]:
517                         if protection[1] == IMG_BLACKSERVICE:
518                                 protectionText = "Service %s is locked." % self.getName(cur_ref)
519                         elif protection[1] == IMG_BLACKBOUQUET:
520                                 #(locked -B-)
521                                 protectionText = "Bouquet %s is locked." % self.getName(cur_ref)
522                         elif protection[1] == "":
523                                 # (locked)
524                                 protectionText = "%s %s is locked." % (serviceType, self.getName(cur_ref))
525                 else:
526                         if protection[1] == IMG_WHITESERVICE:
527                                 #(unlocked -S-)
528                                 protectionText = "Service %s is unlocked."  % self.getName(cur_ref)
529                         elif protection[1] == IMG_WHITEBOUQUET:
530                                 #(unlocked -B-)
531                                 protectionText = "Bouquet %s is unlocked."  % self.getName(cur_ref)
532                 return (True, protectionText)
533
534         def backupFiles(self, param):
535                 filename = param
536                 if not filename:
537                         filename = self.BACKUP_FILENAME
538                 invalidCharacters= re_compile(r'[^A-Za-z0-9_. ]+|^\.|\.$|^ | $|^$')
539                 tarFilename= "%s.tar" % invalidCharacters.sub('_', filename)
540                 backupFilename = path.join(self.BACKUP_PATH, tarFilename)
541                 if path.exists(backupFilename):
542                         remove(backupFilename)
543                 checkfile = path.join(self.BACKUP_PATH,'.webouquetedit')
544                 f = open(checkfile, 'w')
545                 if f:
546                         files = []
547                         f.write('created with WebBouquetEditor')
548                         f.close()
549                         files.append(checkfile)
550                         files.append("/etc/enigma2/bouquets.tv")
551                         files.append("/etc/enigma2/bouquets.radio")
552                         files.append("/etc/enigma2/userbouquet.favourites.tv")
553                         files.append("/etc/enigma2/userbouquet.favourites.radio")
554                         files.append("/etc/enigma2/lamedb")
555                         files.append("/etc/tuxbox/satellites.xml")
556                         if config.ParentalControl.configured.value:
557                                 if config.ParentalControl.type.value == LIST_BLACKLIST:
558                                         files.append("/etc/enigma2/blacklist")
559                                 else:
560                                         files.append("/etc/enigma2/whitelist")
561                         files += self.getPhysicalFilenamesFromServicereference(eServiceReference('1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
562                         files += self.getPhysicalFilenamesFromServicereference(eServiceReference('1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'))
563                         tarFiles = ""
564                         for arg in files:
565                                 if not path.exists(arg):
566                                         return (False, "Error while preparing backup file, %s does not exists." % arg)
567                                 tarFiles += "%s " % arg
568                         lines = popen("tar cvf %s %s" % (backupFilename,tarFiles)).readlines()
569                         remove(checkfile)
570                         return (True, tarFilename)
571                 else:
572                         return (False, "Error while preparing backup file.")
573                 
574         def getPhysicalFilenamesFromServicereference(self, ref):
575                 files = []
576                 serviceHandler = eServiceCenter.getInstance()
577                 services = serviceHandler.list(ref)
578                 servicelist = services and services.getContent("S", True)
579                 for service in servicelist:
580                         sref = service
581                         pos = sref.find('FROM BOUQUET "')
582                         filename = None
583                         if pos != -1:
584                                 sref = sref[pos+14:]
585                                 pos = sref.find('"')
586                                 if pos != -1:
587                                         filename = '/etc/enigma2/' + sref[:pos] # FIXMEEE !!! HARDCODED /etc/enigma2
588                                         files.append(filename)
589                                         files += self.getPhysicalFilenamesFromServicereference(eServiceReference(service))
590                 return files
591                 
592         def restoreFiles(self, param):
593                 tarFilename = param
594                 backupFilename = tarFilename #path.join(self.BACKUP_PATH, tarFilename)
595                 if path.exists(backupFilename):
596                         check_tar = False
597                         lines = popen('tar -tf %s' % backupFilename).readlines()
598                         for line in lines:
599                                 pos = line.find('tmp/.webouquetedit')
600                                 if pos != -1:
601                                         check_tar = True
602                                         break
603                         if check_tar:
604                                 eDVBDB.getInstance().removeServices()
605                                 files = []      
606                                 files += self.getPhysicalFilenamesFromServicereference(eServiceReference('1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
607                                 files += self.getPhysicalFilenamesFromServicereference(eServiceReference('1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'))
608                                 for bouquetfiles in files:
609                                         if path.exists(bouquetfiles):
610                                                 remove(bouquetfiles)
611                                 lines = popen('tar xvf %s -C / --exclude tmp/.webouquetedit' % backupFilename).readlines()
612                                 nimmanager.readTransponders()
613                                 eDVBDB.getInstance().reloadServicelist()
614                                 eDVBDB.getInstance().reloadBouquets()
615                                 infoBarInstance = InfoBar.instance
616                                 if infoBarInstance is not None:
617                                         servicelist = infoBarInstance.servicelist
618                                         root = servicelist.getRoot()
619                                         currentref = servicelist.getCurrentSelection()
620                                         servicelist.setRoot(root)
621                                         servicelist.setCurrentSelection(currentref)
622                                 remove(backupFilename)
623                                 return (True, "Bouquet-settings were restored successfully")
624                         else:
625                                 return (False, "Error, %s was not created with WebBouquetEditor..." % backupFilename)
626                 else:
627                         return (False, "Error, %s does not exists, restore is not possible..." % backupFilename)
628
629         def getMutableBouquetList(self, mode):
630                 if mode == MODE_TV:
631                         self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet'
632                 else:
633                         self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet'
634                 return self.getMutableList(eServiceReference(self.bouquet_rootstr))
635
636         def getMutableList(self, ref):
637                 serviceHandler = eServiceCenter.getInstance()
638                 return serviceHandler.list(ref).startEdit()
639
640         def setRoot(self, bouquet_rootstr):
641                 infoBarInstance = InfoBar.instance
642                 if infoBarInstance is not None:
643                         servicelist = infoBarInstance.servicelist
644                         root = servicelist.getRoot()
645                         if bouquet_rootstr ==  root.toString():
646                                 currentref = servicelist.getCurrentSelection()
647                                 servicelist.setRoot(root)
648                                 servicelist.setCurrentSelection(currentref)
649
650         def buildBouquetID(self, str, prefix, mode):
651                 tmp = str.lower()
652                 name = ''
653                 for c in tmp:
654                         if (c >= 'a' and c <= 'z') or (c >= '0' and c <= '9'):
655                                 name += c
656                         else:
657                                 name += '_'
658                 # check if file is unique
659                 suffix = ""
660                 if mode == MODE_TV:
661                         suffix = ".tv"
662                 else:
663                         suffix = ".radio"
664                 filename = '/etc/enigma2/' + prefix + name + suffix
665                 if path.exists(filename):
666                         i = 1
667                         while True:
668                                 filename = "/etc/enigma2/%s%s_%d%s" %( prefix , name , i, suffix)
669                                 if path.exists(filename):
670                                         i += 1
671                                 else:
672                                         name = "%s_%d" % (name,i)
673                                         break
674                 return name
675
676         def getName(self,ref):
677                 serviceHandler = eServiceCenter.getInstance()
678                 info = serviceHandler.info(ref)
679                 if info:
680                         name = info.getName(ref)
681                 else:
682                         name = ""
683                 return name