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