SoftwareManager/BackupRestore.py: save configuration to settingsfile before doing...
[vuplus_dvbapp] / lib / python / Components / FileList.py
1 from re import compile as re_compile
2 from os import path as os_path, listdir
3 from MenuList import MenuList
4 from Components.Harddisk import harddiskmanager
5
6 from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
7
8 from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
9         eServiceReference, eServiceCenter, gFont
10 from Tools.LoadPixmap import LoadPixmap
11
12 EXTENSIONS = {
13                 "m4a": "music",
14                 "mp2": "music",
15                 "mp3": "music",
16                 "wav": "music",
17                 "ogg": "music",
18                 "flac": "music",
19                 "jpg": "picture",
20                 "jpeg": "picture",
21                 "png": "picture",
22                 "bmp": "picture",
23                 "ts": "movie",
24                 "avi": "movie",
25                 "divx": "movie",
26                 "m4v": "movie",
27                 "mpg": "movie",
28                 "mpeg": "movie",
29                 "mkv": "movie",
30                 "mp4": "movie",
31                 "mov": "movie"
32         }
33
34 def FileEntryComponent(name, absolute = None, isDir = False):
35         res = [ (absolute, isDir) ]
36         res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 470, 20, 0, RT_HALIGN_LEFT, name))
37         if isDir:
38                 png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/directory.png"))
39         else:
40                 extension = name.split('.')
41                 extension = extension[-1].lower()
42                 if EXTENSIONS.has_key(extension):
43                         png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/" + EXTENSIONS[extension] + ".png"))
44                 else:
45                         png = None
46         if png is not None:
47                 res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png))
48         
49         return res
50
51 class FileList(MenuList):
52         def __init__(self, directory, showDirectories = True, showFiles = True, showMountpoints = True, matchingPattern = None, useServiceRef = False, inhibitDirs = False, inhibitMounts = False, isTop = False, enableWrapAround = False, additionalExtensions = None):
53                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
54                 self.additional_extensions = additionalExtensions
55                 self.mountpoints = []
56                 self.current_directory = None
57                 self.current_mountpoint = None
58                 self.useServiceRef = useServiceRef
59                 self.showDirectories = showDirectories
60                 self.showMountpoints = showMountpoints
61                 self.showFiles = showFiles
62                 self.isTop = isTop
63                 # example: matching .nfi and .ts files: "^.*\.(nfi|ts)"
64                 self.matchingPattern = matchingPattern
65                 self.inhibitDirs = inhibitDirs or []
66                 self.inhibitMounts = inhibitMounts or []
67
68                 self.refreshMountpoints()
69                 self.changeDir(directory)
70                 self.l.setFont(0, gFont("Regular", 18))
71                 self.l.setItemHeight(23)
72                 self.serviceHandler = eServiceCenter.getInstance()
73
74         def refreshMountpoints(self):
75                 self.mountpoints = [os_path.join(p.mountpoint, "") for p in harddiskmanager.getMountedPartitions()]
76                 self.mountpoints.sort(reverse = True)
77
78         def getMountpoint(self, file):
79                 file = os_path.join(os_path.realpath(file), "")
80                 for m in self.mountpoints:
81                         if file.startswith(m):
82                                 return m
83                 return False
84
85         def getMountpointLink(self, file):
86                 if os_path.realpath(file) == file:
87                         return self.getMountpoint(file)
88                 else:
89                         if file[-1] == "/":
90                                 file = file[:-1]
91                         mp = self.getMountpoint(file)
92                         last = file
93                         file = os_path.dirname(file)
94                         while last != "/" and mp == self.getMountpoint(file):
95                                 last = file
96                                 file = os_path.dirname(file)
97                         return os_path.join(last, "")
98
99         def getSelection(self):
100                 if self.l.getCurrentSelection() is None:
101                         return None
102                 return self.l.getCurrentSelection()[0]
103
104         def getCurrentEvent(self):
105                 l = self.l.getCurrentSelection()
106                 if not l or l[0][1] == True:
107                         return None
108                 else:
109                         return self.serviceHandler.info(l[0][0]).getEvent(l[0][0])
110
111         def getFileList(self):
112                 return self.list
113
114         def inParentDirs(self, dir, parents):
115                 dir = os_path.realpath(dir)
116                 for p in parents:
117                         if dir.startswith(p):
118                                 return True
119                 return False
120
121         def changeDir(self, directory, select = None):
122                 self.list = []
123
124                 # if we are just entering from the list of mount points:
125                 if self.current_directory is None:
126                         if directory and self.showMountpoints:
127                                 self.current_mountpoint = self.getMountpointLink(directory)
128                         else:
129                                 self.current_mountpoint = None
130                 self.current_directory = directory
131                 directories = []
132                 files = []
133
134                 if directory is None and self.showMountpoints: # present available mountpoints
135                         for p in harddiskmanager.getMountedPartitions():
136                                 path = os_path.join(p.mountpoint, "")
137                                 if path not in self.inhibitMounts and not self.inParentDirs(path, self.inhibitDirs):
138                                         self.list.append(FileEntryComponent(name = p.description, absolute = path, isDir = True))
139                         files = [ ]
140                         directories = [ ]
141                 elif directory is None:
142                         files = [ ]
143                         directories = [ ]
144                 elif self.useServiceRef:
145                         root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory)
146                         if self.additional_extensions:
147                                 root.setName(self.additional_extensions)
148                         serviceHandler = eServiceCenter.getInstance()
149                         list = serviceHandler.list(root)
150
151                         while 1:
152                                 s = list.getNext()
153                                 if not s.valid():
154                                         del list
155                                         break
156                                 if s.flags & s.mustDescent:
157                                         directories.append(s.getPath())
158                                 else:
159                                         files.append(s)
160                         directories.sort()
161                         files.sort()
162                 else:
163                         if os_path.exists(directory):
164                                 files = listdir(directory)
165                                 files.sort()
166                                 tmpfiles = files[:]
167                                 for x in tmpfiles:
168                                         if os_path.isdir(directory + x):
169                                                 directories.append(directory + x + "/")
170                                                 files.remove(x)
171
172                 if directory is not None and self.showDirectories and not self.isTop:
173                         if directory == self.current_mountpoint and self.showMountpoints:
174                                 self.list.append(FileEntryComponent(name = "<" +_("List of Storage Devices") + ">", absolute = None, isDir = True))
175                         elif (directory != "/") and not (self.inhibitMounts and self.getMountpoint(directory) in self.inhibitMounts):
176                                 self.list.append(FileEntryComponent(name = "<" +_("Parent Directory") + ">", absolute = '/'.join(directory.split('/')[:-2]) + '/', isDir = True))
177
178                 if self.showDirectories:
179                         for x in directories:
180                                 if not (self.inhibitMounts and self.getMountpoint(x) in self.inhibitMounts) and not self.inParentDirs(x, self.inhibitDirs):
181                                         name = x.split('/')[-2]
182                                         self.list.append(FileEntryComponent(name = name, absolute = x, isDir = True))
183
184                 if self.showFiles:
185                         for x in files:
186                                 if self.useServiceRef:
187                                         path = x.getPath()
188                                         name = path.split('/')[-1]
189                                 else:
190                                         path = directory + x
191                                         name = x
192
193                                 if (self.matchingPattern is None) or re_compile(self.matchingPattern).search(path):
194                                         self.list.append(FileEntryComponent(name = name, absolute = x , isDir = False))
195
196                 self.l.setList(self.list)
197
198                 if select is not None:
199                         i = 0
200                         self.moveToIndex(0)
201                         for x in self.list:
202                                 p = x[0][0]
203                                 
204                                 if isinstance(p, eServiceReference):
205                                         p = p.getPath()
206                                 
207                                 if p == select:
208                                         self.moveToIndex(i)
209                                 i += 1
210
211         def getCurrentDirectory(self):
212                 return self.current_directory
213
214         def canDescent(self):
215                 if self.getSelection() is None:
216                         return False
217                 return self.getSelection()[1]
218
219         def descent(self):
220                 if self.getSelection() is None:
221                         return
222                 self.changeDir(self.getSelection()[0], select = self.current_directory)
223
224         def getFilename(self):
225                 if self.getSelection() is None:
226                         return None
227                 x = self.getSelection()[0]
228                 if isinstance(x, eServiceReference):
229                         x = x.getPath()
230                 return x
231
232         def getServiceRef(self):
233                 if self.getSelection() is None:
234                         return None
235                 x = self.getSelection()[0]
236                 if isinstance(x, eServiceReference):
237                         return x
238                 return None
239
240         def execBegin(self):
241                 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
242
243         def execEnd(self):
244                 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
245
246         def refresh(self):
247                 self.changeDir(self.current_directory, self.getFilename())
248
249         def partitionListChanged(self, action, device):
250                 self.refreshMountpoints()
251                 if self.current_directory is None:
252                         self.refresh()
253
254
255 def MultiFileSelectEntryComponent(name, absolute = None, isDir = False, selected = False):
256         res = [ (absolute, isDir, selected, name) ]
257         res.append((eListboxPythonMultiContent.TYPE_TEXT, 55, 1, 470, 20, 0, RT_HALIGN_LEFT, name))
258         if isDir:
259                 png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/directory.png"))
260         else:
261                 extension = name.split('.')
262                 extension = extension[-1].lower()
263                 if EXTENSIONS.has_key(extension):
264                         png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "extensions/" + EXTENSIONS[extension] + ".png"))
265                 else:
266                         png = None
267         if png is not None:
268                 res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 30, 2, 20, 20, png))
269
270         if not name.startswith('<'):
271                 if selected is False:
272                         icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_off.png"))
273                         res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
274                 else:
275                         icon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_on.png"))
276                         res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 2, 0, 25, 25, icon))
277         
278         return res
279
280
281 class MultiFileSelectList(FileList):
282         def __init__(self, preselectedFiles, directory, showMountpoints = False, matchingPattern = None, showDirectories = True, showFiles = True,  useServiceRef = False, inhibitDirs = False, inhibitMounts = False, isTop = False, enableWrapAround = False, additionalExtensions = None):
283                 self.selectedFiles = preselectedFiles
284                 if self.selectedFiles is None:
285                         self.selectedFiles = []
286                 FileList.__init__(self, directory, showMountpoints = showMountpoints, matchingPattern = matchingPattern, showDirectories = showDirectories, showFiles = showFiles,  useServiceRef = useServiceRef, inhibitDirs = inhibitDirs, inhibitMounts = inhibitMounts, isTop = isTop, enableWrapAround = enableWrapAround, additionalExtensions = additionalExtensions)
287                 self.changeDir(directory)                       
288                 self.l.setItemHeight(25)
289                 self.l.setFont(0, gFont("Regular", 20))
290                 self.onSelectionChanged = [ ]
291
292         def selectionChanged(self):
293                 for f in self.onSelectionChanged:
294                         f()
295
296         def changeSelectionState(self):
297                 idx = self.l.getCurrentSelectionIndex()
298                 count = 0
299                 newList = []
300                 for x in self.list:
301                         if idx == count:
302                                 if x[0][3].startswith('<'):
303                                         newList.append(x)
304                                 else:
305                                         if x[0][1] is True:
306                                                 realPathname = x[0][0]
307                                         else:
308                                                 realPathname = self.current_directory + x[0][0]
309                                         if x[0][2] == True:
310                                                 SelectState = False
311                                                 for entry in self.selectedFiles:
312                                                         if entry == realPathname:
313                                                                 self.selectedFiles.remove(entry)
314         
315                                         else:
316                                                 SelectState = True
317                                                 alreadyinList = False   
318                                                 for entry in self.selectedFiles:
319                                                         if entry == realPathname:
320                                                                 alreadyinList = True
321                                                 if not alreadyinList:
322                                                         self.selectedFiles.append(realPathname)
323                                         newList.append(MultiFileSelectEntryComponent(name = x[0][3], absolute = x[0][0], isDir = x[0][1], selected = SelectState ))
324                         else:
325                                 newList.append(x)
326                         
327                         count += 1
328                 
329                 self.list = newList
330                 self.l.setList(self.list)
331         
332         def getSelectedList(self):
333                 return self.selectedFiles
334
335         def changeDir(self, directory, select = None):
336                 self.list = []
337
338                 # if we are just entering from the list of mount points:
339                 if self.current_directory is None:
340                         if directory and self.showMountpoints:
341                                 self.current_mountpoint = self.getMountpointLink(directory)
342                         else:
343                                 self.current_mountpoint = None
344                 self.current_directory = directory
345                 directories = []
346                 files = []
347
348                 if directory is None and self.showMountpoints: # present available mountpoints
349                         for p in harddiskmanager.getMountedPartitions():
350                                 path = os_path.join(p.mountpoint, "")
351                                 if path not in self.inhibitMounts and not self.inParentDirs(path, self.inhibitDirs):
352                                         self.list.append(MultiFileSelectEntryComponent(name = p.description, absolute = path, isDir = True))
353                         files = [ ]
354                         directories = [ ]
355                 elif directory is None:
356                         files = [ ]
357                         directories = [ ]
358                 elif self.useServiceRef:
359                         root = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + directory)
360                         if self.additional_extensions:
361                                 root.setName(self.additional_extensions)
362                         serviceHandler = eServiceCenter.getInstance()
363                         list = serviceHandler.list(root)
364
365                         while 1:
366                                 s = list.getNext()
367                                 if not s.valid():
368                                         del list
369                                         break
370                                 if s.flags & s.mustDescent:
371                                         directories.append(s.getPath())
372                                 else:
373                                         files.append(s)
374                         directories.sort()
375                         files.sort()
376                 else:
377                         if os_path.exists(directory):
378                                 files = listdir(directory)
379                                 files.sort()
380                                 tmpfiles = files[:]
381                                 for x in tmpfiles:
382                                         if os_path.isdir(directory + x):
383                                                 directories.append(directory + x + "/")
384                                                 files.remove(x)
385
386                 if directory is not None and self.showDirectories and not self.isTop:
387                         if directory == self.current_mountpoint and self.showMountpoints:
388                                 self.list.append(MultiFileSelectEntryComponent(name = "<" +_("List of Storage Devices") + ">", absolute = None, isDir = True))
389                         elif (directory != "/") and not (self.inhibitMounts and self.getMountpoint(directory) in self.inhibitMounts):
390                                 self.list.append(MultiFileSelectEntryComponent(name = "<" +_("Parent Directory") + ">", absolute = '/'.join(directory.split('/')[:-2]) + '/', isDir = True))
391
392                 if self.showDirectories:
393                         for x in directories:
394                                 if not (self.inhibitMounts and self.getMountpoint(x) in self.inhibitMounts) and not self.inParentDirs(x, self.inhibitDirs):
395                                         name = x.split('/')[-2]
396                                         alreadySelected = False
397                                         for entry in self.selectedFiles:
398                                                 if entry  == x:
399                                                         alreadySelected = True                                  
400                                         if alreadySelected:             
401                                                 self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x, isDir = True, selected = True))
402                                         else:
403                                                 self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x, isDir = True, selected = False))
404                                                 
405                 if self.showFiles:
406                         for x in files:
407                                 if self.useServiceRef:
408                                         path = x.getPath()
409                                         name = path.split('/')[-1]
410                                 else:
411                                         path = directory + x
412                                         name = x
413
414                                 if (self.matchingPattern is None) or re_compile(self.matchingPattern).search(path):
415                                         alreadySelected = False
416                                         for entry in self.selectedFiles:
417                                                 if os_path.basename(entry)  == x:
418                                                         alreadySelected = True  
419                                         if alreadySelected:
420                                                 self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x , isDir = False, selected = True))
421                                         else:
422                                                 self.list.append(MultiFileSelectEntryComponent(name = name, absolute = x , isDir = False, selected = False))
423
424                 self.l.setList(self.list)
425
426                 if select is not None:
427                         i = 0
428                         self.moveToIndex(0)
429                         for x in self.list:
430                                 p = x[0][0]
431                                 
432                                 if isinstance(p, eServiceReference):
433                                         p = p.getPath()
434                                 
435                                 if p == select:
436                                         self.moveToIndex(i)
437                                 i += 1
438