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