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