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