Merge branch 'vuplus_experimental' of code.vuplus.com:/opt/repository/dvbapp into...
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / DeviceManager / plugin.py
1 from Components.Label import Label
2 from Components.ActionMap import ActionMap
3 from Components.config import config, ConfigSelection, getConfigListEntry, ConfigSubsection, ConfigEnableDisable, ConfigYesNo, ConfigInteger
4 from Components.ConfigList import ConfigListScreen
5 from Components.Console import Console
6 from Components.GUIComponent import GUIComponent
7 from Components.Harddisk import harddiskmanager
8 from Components.MenuList import MenuList
9 from Components.Pixmap import Pixmap, MultiPixmap
10 from Components.Sources.List import List
11 from Components.Sources.StaticText import StaticText
12 from Plugins.Plugin import PluginDescriptor
13 from Screens.MessageBox import MessageBox
14 from Screens.Screen import Screen
15 from Screens.VirtualKeyBoard import VirtualKeyBoard
16 from Tools.BoundFunction import boundFunction
17 from Tools.LoadPixmap import LoadPixmap
18 from Tools.Notifications import AddNotificationWithCallback
19 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
20 from skin import loadSkin
21 from os import system, makedirs, path, listdir, statvfs, popen
22 import os
23 import re
24 import time
25
26 from Components.Sources.StaticText import StaticText
27 from Components.FileList import FileList
28 from Screens.InputBox import InputBox
29 from Components.Input import Input
30 from Screens.ChoiceBox import ChoiceBox
31 from enigma import eTimer
32 from __init__ import _
33
34 config.plugins.devicemanager = ConfigSubsection()
35 config.plugins.devicemanager.hotplug_enable = ConfigEnableDisable(default=True)
36 config.plugins.devicemanager.mountcheck_enable = ConfigEnableDisable(default=True)
37
38 def readFile(filename):
39         file = open(filename)
40         data = file.read().strip()
41         file.close()
42         return data
43
44 def byteConversion(byte):
45         if type(byte) == str and len(byte) == 0:
46                 return ""
47         if type(byte) != long:
48                 byte = long(byte)
49         if byte > 1024*1024*1024:
50                 int_part = byte/1024/1024/1024
51                 dec_part = byte%(1024*1024*1024)/(1024*1024)
52                 return "%d.%d GB"%(int_part, dec_part)
53         else:
54                 int_part = byte/1024/1024
55                 dec_part = byte%(1024*1024)/1024
56                 return "%d.%d MB"%(int_part, dec_part)
57
58 def checkStrValue(value , empty = ""):
59         if type(value) != str or len(value) == 0:
60                 return empty
61         return value
62
63 class DeviceManagerConfiguration(Screen, ConfigListScreen):
64         def __init__(self,session):
65                 self.session = session
66                 Screen.__init__(self,session)
67                 self.skinName = "Setup"
68                 self.createConfigList()
69                 ConfigListScreen.__init__(self, self.list, session = self.session)
70                 self["key_red"] = StaticText(_("Cancel"))
71                 self["key_green"] = StaticText(_("OK"))
72                 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ],
73                 {
74                         "ok": self.keySave,
75                         "cancel": self.keyCancel,
76                         "red": self.keyCancel,
77                         "green": self.keySave,
78                 }, -2)
79                 self.onShown.append(self.setWindowTitle)
80                 self.old_hotplug_enable = config.plugins.devicemanager.hotplug_enable.value
81                 
82         def setWindowTitle(self):
83                 self.setTitle(_("DeviceManager configuration"))
84
85         def createConfigList(self):
86                 self.list = []
87                 self.list.append(getConfigListEntry(_("Enable mount check for HDD : "), config.plugins.devicemanager.mountcheck_enable))
88                 self.list.append(getConfigListEntry(_("Harddisk standby after : "), config.usage.hdd_standby))
89                 self.list.append(getConfigListEntry(_("Mount known devices automatically : "), config.plugins.devicemanager.hotplug_enable))
90
91         def keySave(self):
92                 if config.plugins.devicemanager.hotplug_enable.value:
93                         if not DeviceManagerhotplugDeviceStart in harddiskmanager.on_partition_list_change:
94                                 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
95                 else:
96                         if DeviceManagerhotplugDeviceStart in harddiskmanager.on_partition_list_change:
97                                 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
98
99                 for x in self["config"].list:
100                         x[1].save()
101                 self.close()
102
103 class DeviceManager(Screen):
104         skin = """
105                 <screen position="center,center" size="670,400" title="DeviceManager">
106                         <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
107                         <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
108                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
109                         <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
110                         <widget name="key_red" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
111                         <widget name="key_green" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
112                         <widget name="key_yellow" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
113                         <widget name="key_blue" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
114                         <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="670,2" alphatest="on" />
115                         <widget source="menu" render="Listbox" position="0,48" size="670,350" scrollbarMode="showOnDemand">
116                                 <convert type="TemplatedMultiContent">
117                                 {"templates":
118                                         {"default": (54,[
119                                                         MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor  - model
120                                                         MultiContentEntryText(pos = (100, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
121                                                         MultiContentEntryText(pos = (230, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
122                                                         MultiContentEntryText(pos = (360, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
123                                                         MultiContentEntryText(pos = (490, 32), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
124                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # png 5 is the div pixmap
125                                                 ]),
126                                         "partitions": (98, [
127                                                         MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
128                                                         MultiContentEntryText(pos = (100, 32), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
129                                                         MultiContentEntryText(pos = (100, 54), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
130                                                         MultiContentEntryText(pos = (100, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
131                                                         MultiContentEntryText(pos = (230, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
132                                                         MultiContentEntryText(pos = (380, 76), size = (200, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
133                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (670, 2), png = 6), # png 6 is the div pixmap
134                                                 ]),
135                                         "mountpoint": (54,[
136                                                         MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture
137                                                         MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name
138                                                         MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path
139                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # index 5 is the div pixmap
140                                                 ])
141                                         },
142                                         "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)],
143                                         "itemHeight": 54
144                                 }
145                                 </convert>
146                         </widget>
147                 </screen>
148                 """
149
150         def __init__(self, session):
151                 Screen.__init__(self, session)
152                 self.session = session
153                 self.currList = "default"
154                 self.currDevice = None
155                 self.currPartition = None
156                 self.defaultMountPoint = "/media/hdd"
157                 self.deviceList = []
158                 self["menu"] = List(self.deviceList)
159                 self["key_red"] = Label(_("Close"))
160                 self["key_green"] = Label(" ")
161                 self["key_yellow"] = Label(" ")
162                 self["key_blue"] = Label(" ")
163
164                 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions", "MenuActions" ],
165                 {
166                         "ok": self.keyOk,
167                         "cancel": self.keyCancel,
168                         "red": self.keyCancel,
169                         "green": self.keyOk,
170                         "yellow": self.keyYellow,
171                         "blue": self.keyBlue,
172                         "menu": self.keyMenu,
173                 }, -2)
174                 self.DeviceManagerConsole = Console()
175                 self.loadIcon()
176                 if not self.selectionChanged in self["menu"].onSelectionChanged:
177                         self["menu"].onSelectionChanged.append(self.selectionChanged)
178                 self.onLayoutFinish.append(self.showDeviceList)
179                 self.onLayoutFinish.append(self.addPartitionListChange)
180                 self.onClose.append(self.removePartitionListChange)
181                 self.onChangedEntry = []
182                 self.blockDevices = {}
183
184         def addPartitionListChange(self):
185                 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
186
187         def removePartitionListChange(self):
188                 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
189
190         def partitionListChanged(self, action, device):
191                 print "[Device manager] hotplug partitionListChanged"
192                 if self.currList != "default" and device.device[:3] != self.currDevice["blockdev"]:
193                         return
194                 self.showDeviceList()
195
196         def loadIcon(self):
197                 self.icon_button_green = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/button_green.png"))
198                 self.divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
199
200         def selectionChanged(self):
201                 if self.currList == "partitions":
202                         currentPartition = self.getCurrentPartition()
203                         if currentPartition is not None:
204                                 if currentPartition["mountpoint"] != "":
205                                         self["key_green"].setText(_("Umount"))
206                                 else:
207                                         self["key_green"].setText(_("Mount"))
208
209                                 if currentPartition["fstype"] == "":
210                                         self["key_blue"].setText("")
211                                 elif currentPartition["fstype"][:3] == "ext":
212                                         self["key_blue"].setText(_("Check"))
213                                 else:
214                                         self["key_blue"].setText("")
215
216         def showDeviceList(self):
217                 self.deviceList = []
218                 self["key_red"].setText(_("Close"))
219                 self["key_green"].setText(_("Ok"))
220                 self["key_yellow"].setText(" ")
221                 self["key_blue"].setText(_("Initialize"))
222                 deviceinfo.refresh()
223                 for device in deviceinfo.getBlockDevices():
224                         deviceEntry = (
225                                 "%s - %s"%(device["vendor"], device["model"]), # vendor : str, model : str, index 0 
226                                 _("device : %s")%(device["blockdev"]), # str
227                                 _("Size : %s")%(byteConversion(device["size"])), # str, bytes
228                                 _("Partitions : %s")%(len(device["partitions"])), # list
229                                 _("Removable : %s")%(device["removable"] and 'Yes' or 'No'), # bool [True, False]
230                                 self.divpng, # png 5
231                                 device, # index 6
232                                 )
233 #                       print "[DeviceManager] deviceEntry : ", deviceEntry
234                         self.deviceList.append(deviceEntry)
235                 self.currList = "default"
236                 self["menu"].style = "default"
237                 self["menu"].setList(self.deviceList)
238
239         def showPartitionList(self):
240                 if self.currDevice is None:
241                         return
242                 partitionList = []
243                 for partition in self.currDevice["partitions"]:
244                         partitionInfo = deviceinfo.getPartitionInfo(partition)
245                         partitionEntry = (
246                                 _("Partition : /dev/%s")%partition, # index 0
247                                 _("Mounted on : %s")%checkStrValue(partitionInfo["mountpoint"], _("not mounted")),
248                                 _("UUID : %s")%checkStrValue(partitionInfo["uuid"], _("unknown")),
249                                 _("Type : %s")%checkStrValue(partitionInfo["fstype"], _("unknown")),
250                                 _("Size : %s")%checkStrValue(byteConversion(partitionInfo["size"]), _("unknown")),
251                                 _("Free : %s")%checkStrValue(byteConversion(partitionInfo["free"]), _("unknown")),
252                                 self.divpng, # index 6
253                                 partitionInfo, # index 7
254                         )
255 #                       print "[DeviceManager] partitionEntry : ",partitionEntry
256                         partitionList.append(partitionEntry)
257                 if len(partitionList) != 0:
258                         self["key_red"].setText(_("Devices"))
259                         self["key_green"].setText(_("Mount"))
260                         self["key_yellow"].setText(_("Format"))
261                         self["key_blue"].setText(_("Check"))
262                         self.currList = "partitions"
263                         self["menu"].style = "partitions"
264                         self["menu"].setList(partitionList)
265                         self.selectionChanged()
266                 else:
267                         self.session.open(MessageBox, _("No partition list found on device.\nPlease click BLUE key and do Initialize to use this device."), MessageBox.TYPE_ERROR, timeout = 10)
268
269         def showMountPointSetup(self):
270                 if self.currDevice is None or self.currPartition is None:
271                         return
272                 partition =  self.currPartition["partition"]
273                 if not os.access("/autofs/%s"%partition,0):
274                         self.session.open(MessageBox, _("This partition is not mountable.\nYou need to check or format this partition."), MessageBox.TYPE_ERROR, timeout = 10)
275                         return
276                 self["key_red"].setText(_("Partitions"))
277                 self["key_green"].setText(_("Ok"))
278                 self["key_yellow"].setText("")
279                 self["key_blue"].setText("")
280                 self.mountPointList = []
281                 currentMountPoint = self.currPartition["mountpoint"]
282                 if currentMountPoint == "":
283                         currentMountPoint = "'not mounted'"
284                 defaultMountPoint = self.getDefaultMountPoint()
285                 autoMountPoint = self.getAutoMountPoint()
286                 defaultMountPointEntry = (self.icon_button_green, _("Set up Default Mount Point"), _("Mount Point : %s ->%s")%(currentMountPoint, defaultMountPoint), "default", defaultMountPoint, self.divpng)
287                 autoMountPointEntry = (self.icon_button_green, _("Automatically set up a Mount Point"), _("Mount Point : %s -> %s")%(currentMountPoint, autoMountPoint), "auto", autoMountPoint, self.divpng)
288                 manuallyMountPointEntry = (self.icon_button_green, _("User manually Set up a Mount Point"), _("Mount Point : click ok button on here."), "manual", "", self.divpng)
289                 if not path.ismount(defaultMountPoint):
290                         self.mountPointList.append(defaultMountPointEntry)
291                 self.mountPointList.append(autoMountPointEntry)
292                 self.mountPointList.append(manuallyMountPointEntry)
293                 self.currList = "mountpoint"
294                 self["menu"].style = "mountpoint"
295                 self["menu"].setList(self.mountPointList)
296
297         def getCurrentDevice(self):
298                 if self.currList == "default":
299                         return self["menu"].getCurrent()[6]
300                 return None
301
302         def getCurrentPartition(self):
303                 if self.currList == "partitions":
304                         return self["menu"].getCurrent()[7]
305                 return None
306
307         def keyOk(self):
308 #               print "keyOk"
309                 if self.currList == "default":
310                         self.currDevice = self.getCurrentDevice()
311                         if len(self.currDevice["partitions"]) == 0:
312                                 self.session.open(MessageBox, _("No partition list found on device.\nPlease click BLUE key and do Initialize to use this device."), MessageBox.TYPE_ERROR, timeout = 10)
313                         else:
314                                 self.showPartitionList()
315                 elif self.currList == "partitions":
316                         currMountPoint = self.getCurrentPartition()["mountpoint"]
317                         currUuid = self.getCurrentPartition()["uuid"]
318                         if currMountPoint == "":
319                                 self.currPartition = self.getCurrentPartition()
320                                 self.showMountPointSetup()
321                         else:
322                                 self.doUmount(currMountPoint, self.showPartitionList)
323                 elif self.currList == "mountpoint":
324 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
325                         currEntry = self["menu"].getCurrent()[3]
326                         if currEntry == "default":
327 #                               print "Setup mountpoint default!"
328                                 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
329                         elif currEntry == "auto":
330 #                               print "Setup mountpoint automatically!"
331                                 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
332                         else:
333 #                               print "Setup mountpoint manually!"
334                                 self.session.openWithCallback(self.MountpointBrowserCB, MountpointBrowser)
335                 else:
336                         pass
337
338         def keyCancel(self):
339 #               print "keyCancel"
340                 if self.DeviceManagerConsole is not None:
341                         if len(self.DeviceManagerConsole.appContainers):
342                                 for name in self.DeviceManagerConsole.appContainers.keys():
343                                         self.DeviceManagerConsole.kill(name)
344                 if self.currList == "partitions":
345                         self.currDevice = None
346                         self.showDeviceList()
347                 elif self.currList == "mountpoint":
348                         self.currPartition = None
349                         self.showPartitionList()
350                 else: # currList = "default"
351                         self.close()
352
353         def keyYellow(self):
354                 if self.currList == "partitions":
355                         partition = self.getCurrentPartition()
356                         self.choiceBoxFstype()
357
358         def keyBlue(self):
359                 if self.currList == "default":
360                         device = self.getCurrentDevice()
361                         self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
362                 elif self.currList == "partitions":
363                         partition = self.getCurrentPartition()
364                         self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
365
366         def keyMenu(self):
367                 self.session.open(DeviceManagerConfiguration)
368
369         def deviceInitCB(self, ret = True):
370                 self.showDeviceList()
371
372         def deviceCheckCB(self, ret = True):
373                 self.showPartitionList()
374
375         def deviceFormatCB(self, ret = True):
376                 self.showPartitionList()
377
378         def choiceBoxFstype(self):
379                 menu = []
380                 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
381                 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
382                 menu.append((_("ext4 - experimental"), "ext4"))
383                 menu.append((_("vfat - for USB flash memory"), "vfat"))
384                 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
385
386         def choiceBoxFstypeCB(self, choice):
387                 if choice is None:
388                         return
389                 else:
390                         partition = self.getCurrentPartition()
391                         self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
392
393 # about mount funcs..
394         def doUmount(self, mountpoint, callback):
395                 cmd = "umount %s"%mountpoint
396                 print "[DeviceManager] cmd : %s"%cmd
397                 os.system(cmd)
398                 if not path.ismount(mountpoint):
399                         devicemanagerconfig.updateConfigList()
400                 else:
401                         self.session.open(MessageBox, _("Can't umount %s. \nMaybe device or resource busy.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
402                 callback()
403
404         def getDefaultMountPoint(self):
405                 return self.defaultMountPoint
406
407         def getAutoMountPoint(self):
408                 mountPoint = "/media/"+self.currDevice["model"]
409                 mountPoint = mountPoint.replace(' ','-')
410                 if path.ismount(mountPoint):
411                         partnum = 2
412                         while 1:
413                                 mountPoint_fix = mountPoint+str(partnum)
414                                 if not path.ismount(mountPoint_fix):
415                                         break
416                                 partnum +=1
417                         mountPoint = mountPoint_fix
418                 return mountPoint
419
420         def doMount(self, partition, mountpoint):
421                 try:
422 # check mountpoint is in partition list.
423                         if mountpoint != self.getDefaultMountPoint():
424                                 for p in harddiskmanager.partitions:
425                                         if p.mountpoint == mountpoint:
426                                                 self.session.open(MessageBox, _("Can not use this mount point.(%s) \nPlease select another mount point.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
427                                                 return
428 #
429                         device = partition["partition"]
430                         filesystem = partition["fstype"]
431                         uuid = partition["uuid"]
432                         if mountpoint.endswith("/"):
433                                 mountpoint = retval[:-1]
434                         if mountpoint.find(' ') != -1:
435                                 mountpoint = mountpoint.replace(' ','-')
436                         devpath = "/dev/"+device
437                         if deviceinfo.isMounted(devpath, mountpoint):
438                                 print "[DeviceManager] '%s -> %s' is already mounted."%(devpath, mountpoint)
439                                 return
440
441 # check current device mounted on another mountpoint.
442                         mp_list = deviceinfo.checkMountDev(devpath)
443                         for mp in mp_list:
444                                 if mp != mountpoint and path.ismount(mp):
445                                         deviceinfo.umountByMountpoint(mp)
446 # check another device mounted on configmountpoint
447                         devpath_list = deviceinfo.checkMountPoint(mountpoint)
448                         for devpath_ in devpath_list:
449                                 if devpath_ != devpath:
450                                         self.session.open(MessageBox, _("Mount Failed!\nCurrent path is already mounted by \"%s\"")%devpath_list[0], MessageBox.TYPE_ERROR, timeout = 10)
451                                         return
452 # do mount
453                         print "[DeviceManagerHotplugDevice] doMount"
454                         if not path.exists(mountpoint):
455                                 os.system("mkdir %s"%mountpoint)
456                         if path.exists(mountpoint):
457                                 if not path.ismount(mountpoint):
458                                         if filesystem == "ntfs":
459                                                 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
460                                         elif filesystem is None:
461                                                 cmd = "mount %s %s"%(devpath, mountpoint)
462                                         else:
463                                                 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
464                                         print "[DeviceManager] cmd : %s"%cmd
465                                         self.DeviceManagerConsole.ePopen(cmd, self.doMountFinished, (devpath, mountpoint) )
466                 except:
467                         self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(device, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
468
469         def doMountFinished(self, result, retval, extra_args = None):
470                 (devpath, mountpoint) = extra_args
471                 if retval == 0:
472                         if not deviceinfo.isMounted(devpath, mountpoint):
473 #                               print "[DeviceManager] %s doMount failed!"%devpath
474                                 self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(devpath, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
475                                 return
476                         else:
477 # make movie directory
478                                 if mountpoint == "/media/hdd":
479                                         movieDir = mountpoint + "/movie"
480                                         if not pathExists(movieDir):
481                                                 print "[DeviceManager] make dir %s"%movieDir
482                                                 os.makedirs(movieDir)
483                                 self.showPartitionList()
484 # update current mount state ,devicemanager.cfg
485                                 devicemanagerconfig.updateConfigList()
486
487         def MountpointBrowserCB(self, retval = None):
488                 if retval and retval is not None:
489                         mountPoint = retval.strip().replace(' ','')
490                         if retval.endswith("/"):
491                                 mountPoint = retval[:-1]
492                         print "Mount point from MountpointBrowser : %s"%mountPoint
493                         if not path.exists(mountPoint):
494                                 self.session.open(MessageBox, _("Mount Point is not writeable.\nPath : %s")%mountPoint, MessageBox.TYPE_ERROR, timeout = 10)
495
496                         else:
497                                 self.doMount(self.currPartition, mountPoint)
498 # mount funcs end..
499
500 # Initializing Start...
501 class DeviceInit(Screen):
502         skin = """<screen position="0,0" size="0,0"/>"""
503         def __init__(self, session, device, devicesize):
504                 Screen.__init__(self, session)
505                 self.session = session
506                 self.deviceInitConsole = Console()
507                 self.device = device
508                 self.devicesize = int(devicesize)
509                 self.inputbox_partitions = 1
510                 self.inputbox_partitionSizeList = []
511                 self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024)
512                 self.msgWaiting = None
513                 self.msgWaitingMkfs = None
514                 self.devicenumber = 0
515                 self.newpartitions = 0
516                 self.onLayoutFinish.append(self.timerStart)
517                 self.initStartTimer = eTimer()
518                 self.initStartTimer.callback.append(self.confirmMessage)
519                 self.createFSStartTimer = eTimer()
520                 self.createFSStartTimer.callback.append(self.createFilesystemStart)
521                 self.exitMessageTimer = eTimer()
522                 self.exitMessageTimer.callback.append(self.exitMessage)
523                 self.msg = ""
524                 self.fstype = None
525                 self.mkfs_cmd = ""
526                 self.doMkfsTimer = eTimer()
527                 self.doMkfsTimer.callback.append(self.doMkfs)
528                 self.doInitializeTimer = eTimer()
529                 self.doInitializeTimer.callback.append(self.doInitialize)
530
531         def timerStart(self):
532                 self.initStartTimer.start(100,True)
533
534         def confirmMessage(self):
535                 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
536                 self.session.openWithCallback(self.confirmed, MessageBox, message)
537
538         def confirmed(self, ret):
539                 if ret:
540                         self.InitializeStart()
541                 else:
542                         self.exit()
543
544         def exit(self, ret = True):
545                 self.close()
546
547         def unmountAll(self, device):
548                 mounts = file('/proc/mounts').read().split('\n')
549                 cmd = ""
550 # umount all
551                 for line in mounts:
552                         if not line.startswith("/dev/" + device):
553                                 continue
554                         cmd += "umount %s ;"% line.split()[0]
555                 print "[DeviceManager] %s"%cmd
556                 os.system(cmd)
557 #recheck if umounted
558                 mounts = file('/proc/mounts').read().split('\n')
559                 for line in mounts:
560                         if line.startswith("/dev/" + device):
561                                 return False
562                 return True
563
564         def InitializeStart(self):
565                 self.InputPartitionSize_step1()
566
567         def InputPartitionSize_step1(self):
568                 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
569
570         def InputPartitionSize_step1_CB(self, ret):
571                 if ret is not None and int(ret) in range(1,5): # ret in 1~4
572                         self.inputbox_partitions = int(ret)
573                         self.InputPartitionSize_step2()
574                 else:
575                         self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
576
577         def InputPartitionSize_step2(self):
578                 current_partition = len(self.inputbox_partitionSizeList)+1
579                 if self.inputbox_partitionSizeRemain == 0:
580                         self.choiceBoxFstype()
581                 elif current_partition == self.inputbox_partitions:
582                         self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
583                         self.choiceBoxFstype()
584                 else:
585                         text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
586                         self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Max = %d MB)")%(current_partition,self.inputbox_partitionSizeRemain ), text=text, maxSize=False, type=Input.NUMBER)
587
588         def InputPartitionSize_step2_CB(self, ret):
589                 if ret is not None:
590                         if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
591                                 self.InputPartitionSize_step2()
592                         else:
593                                 self.inputbox_partitionSizeList.append(str(ret))
594                                 self.inputbox_partitionSizeRemain -= int(ret)
595                                 self.InputPartitionSize_step2()
596                 else:
597                         self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
598
599         def choiceBoxFstype(self):
600                 menu = []
601                 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
602                 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
603                 menu.append((_("ext4 - experimental"), "ext4"))
604                 menu.append((_("vfat - for USB flash memory"), "vfat"))
605                 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
606
607         def choiceBoxFstypeCB(self, choice):
608                 if choice is None:
609                         self.exit()
610                 else:
611                         self.fstype = choice[1]
612                         if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
613                                 self.exit()
614                         else:
615                                 self.initInitializeConfirm()
616
617         def initInitializeConfirm(self):
618 #               print self.inputbox_partitionSizeList
619                 partitionsInfo = ""
620                 for index in range(len(self.inputbox_partitionSizeList)):
621                         print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
622                         partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
623                 partitionsInfo += "filesystem type : %s"%(self.fstype)
624                 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
625
626         def initInitializeConfirmCB(self,ret):
627                 if ret:
628                         self.initInitialize()
629                 else:
630                         self.exit()
631         
632         def initInitialize(self):
633                 if not self.unmountAll(self.device):
634                         self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
635                 else:
636                         msg = _("InitInitializing, please wait ...")
637                         msg += _("\nDevice : %s")%self.device
638                         msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
639                         for index in range(len(self.inputbox_partitionSizeList)):
640                                 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
641                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
642                         self.doInitializeTimer.start(500,True)
643
644         def doInitialize(self):
645                 set = ""
646                 partitions = len(self.inputbox_partitionSizeList)
647                 if partitions == 1:
648                         cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
649                 else:
650                         for p in range(4):
651                                 if partitions > p+1:
652                                         set += ",%s\n"%(self.inputbox_partitionSizeList[p])
653                                 else:
654                                         set +=";\n"
655                         set+="y\n"
656                         cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
657                 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
658
659         def initInitializeFinished(self, result, retval, extra_args = None):
660                 if retval == 0:
661                         cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
662                         self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
663                 else:
664                         errorMsg = "initInitializing device Error at /dev/%s"%self.device
665                         self.msgWaiting.run_close(False, errorMsg)
666
667         def initInitializingRefreshFinished(self, result, retval, extra_args = None):
668                 cmd = "/bin/umount /dev/%s*" % (self.device)
669                 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
670
671         def initInitializingUmountFinished(self, result, retval, extra_args = None):
672                 partitions = open("/proc/partitions")
673                 self.devicenumber = 0
674                 self.newpartitions = 0
675                 for part in partitions:
676                         res = re.sub("\s+", " ", part).strip().split(" ")
677                         if res and len(res) == 4 and res[3][:3] == self.device:
678                                 if len(res[3]) > 3 and res[3][:2] == "sd":
679                                         self.newpartitions += 1
680                 partitions.close()
681                 self.msgWaiting.run_close(True)
682 #               self.createFilesystem(self.newpartitions)
683
684         def createFilesystem(self, newpartitions):
685                 self.devicenumber = self.devicenumber + 1
686                 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
687                 shortdevicename = self.device + str(self.devicenumber)
688 # get partition size
689                 partitions = open("/proc/partitions")
690                 for part in partitions:
691                         res = re.sub("\s+", " ", part).strip().split(" ")
692                         if res and len(res) == 4:
693                                 if res[3] == shortdevicename:
694                                         partitionsize = int(res[2])
695                                         break
696                 partitions.close()
697
698                 if self.fstype == "ext4":
699                         cmd = "/sbin/mkfs.ext4 -F "
700                         if partitionsize > 2 * 1024 * 1024: # 2GB
701                                 cmd += "-T largefile "
702                         cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
703                 elif self.fstype == "ext3":
704                         cmd = "/sbin/mkfs.ext3 -F "
705                         if partitionsize > 2 * 1024 * 1024:
706                                 cmd += "-T largefile "
707                         cmd += "-m0 " + fulldevicename
708                 elif self.fstype == "ext2":
709                         cmd = "/sbin/mkfs.ext2 -F "
710                         if partitionsize > 2 * 1024 * 1024:
711                                 cmd += "-T largefile "
712                         cmd += "-m0 " + fulldevicename
713                 elif self.fstype == "vfat":
714                         if partitionsize > 4 * 1024 * 1024 * 1024:
715                                 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
716                         else:
717                                 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
718                 else:
719                         self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
720                         return
721
722                 msg = _("Create filesystem, please wait ...")
723                 msg += _("\nPartition : %s") % (fulldevicename)
724                 msg += _("\nFilesystem : %s") % (self.fstype)
725                 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
726                 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
727                 self.mkfs_cmd = cmd
728                 self.doMkfsTimer.start(500,True)
729
730         def doMkfs(self):
731                 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
732                 self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
733
734         def createFilesystemFinished(self, result, retval, extra_args = None):
735                 device = extra_args[0]
736                 fulldevicename = extra_args[1]
737                 if retval == 0:
738                         self.msgWaitingMkfs.run_close(True)
739                 else:
740                         errorMsg = _("Creating filesystem Error")
741                         if fulldevicename is not None:
742                                 errorMsg += _(" at /dev/%s")%fulldevicename
743                         self.msgWaitingMkfs.run_close(False, errorMsg)
744
745         def createFilesystemStart(self):
746                 self.createFilesystem(self.newpartitions)
747
748         def msgWaitingCB(self, ret, msg=""):
749                 if ret:
750                         self.createFSStartTimer.start(100,True)
751                 else:
752                         self.success = False
753                         self.msg = msg
754                         self.exitMessageTimer.start(100,True)
755
756         def msgWaitingMkfsCB(self, ret, msg=""):
757                 if self.devicenumber < self.newpartitions:
758                         self.createFSStartTimer.start(100,True)
759                 else:
760                         if ret == True:
761                                 self.success = True
762                                 self.msg = _("Device Initialization finished sucessfully!")
763                                 self.updateDeviceInfo()
764                                 self.exitMessageTimer.start(100,True)
765                         else:
766                                 self.success = False
767                                 self.msg = msg
768                                 self.exitMessageTimer.start(100,True)
769
770         def exitMessage(self):
771                 if self.success:
772                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
773                 else:
774                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
775
776         def updateDeviceInfo(self):
777 # update devicemanager configs
778                 devicemanagerconfig.updateConfigList()
779
780 # Initializing end
781
782 # device check start..
783 class DeviceCheck(Screen):
784         skin = """<screen position="0,0" size="0,0"/>"""
785         def __init__(self, session, partition):
786                 Screen.__init__(self, session)
787                 self.session = session
788                 self.deviceCheckConsole = Console()
789                 self.partition = partition
790                 self.onLayoutFinish.append(self.timerStart)
791                 self.checkStartTimer = eTimer()
792                 self.checkStartTimer.callback.append(self.confirmMessage)
793                 self.umountTimer = eTimer()
794                 self.umountTimer.callback.append(self.doUnmount)
795
796         def timerStart(self):
797                 self.checkStartTimer.start(100,True)
798
799         def confirmMessage(self):
800                 fssize = self.partition["size"]
801                 if long(fssize) > 1024*1024*1024*16:
802                         message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
803                         self.session.openWithCallback(self.confirmed, MessageBox, message)
804                 else:
805                         self.deviceCheckStart()
806
807         def confirmed(self, ret):
808                 print "confirmed : ",ret
809                 if ret:
810                         self.deviceCheckStart()
811                 else:
812                         self.exit()
813
814         def deviceCheckStart(self):
815                 print "deviceCheckStart "
816                 print "partition : ", self.partition
817                 device = self.partition["partition"]
818                 fstype = self.partition["fstype"]
819                 fssize = self.partition["size"]
820                 if device is not None and fstype.startswith("ext"):
821                         msg = _("Check filesystem, please wait ...")
822                         msg += _("\nDevice : /dev/%s")%(device)
823                         msg += _("\nFilesystem : %s")%(fstype)
824                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
825                         self.umountTimer.start(500,True)
826                 else:
827                         self.exit()
828
829         def doUnmount(self):
830                 device = self.partition["partition"]
831                 mountpoint = self.partition["mountpoint"]
832                 fstype = self.partition["fstype"]
833                 if mountpoint != "":
834                         self.doUmountFsck(device, mountpoint, fstype)
835                 else:
836                         self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
837
838         def doUmountFsck(self, device, mountpoint, fstype):
839                 cmd = "umount /dev/%s" % device
840                 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
841
842         def umountFsckFinished(self, result, retval, extra_args = None):
843                 device = extra_args[0]
844                 mountpoint = extra_args[1]
845                 fstype = extra_args[2]
846                 if retval == 0:
847                         cmd = "fsck." + fstype + " -f -p /dev/" + device
848                         self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
849                 else:
850                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
851                         self.msgWaiting.run_close(False,errorMsg)
852                         
853         def fsckFinished(self, result, retval, extra_args = None):
854                 device = extra_args[0]
855                 mountpoint = extra_args[1]
856                 if retval == 0:
857                         text = _("Filesystem check finished sucessfully")
858                         self.msgWaiting.run_close(True, text)
859                 else:
860                         text = _("Error checking disk. The disk or filesystem may be damaged")
861                         self.msgWaiting.run_close(False, text)
862
863         def msgWaitingCB(self, ret, msg):
864                 if ret:
865                         self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
866                 else:
867                         self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
868
869                 partition = self.partition["partition"]
870                 mountpoint = self.partition["mountpoint"]
871                 fstype = self.partition["fstype"]
872                 if mountpoint != "":
873                         if fstype == "ntfs":
874                                 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
875                         else:
876                                 cmd = "mount /dev/" + partition + " " + mountpoint
877                         self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
878                 else:
879                         self.exit()
880
881         def mountPartitionFinished(self, result, retval, extra_args = None):
882                 self.exit()
883
884         def exit(self):
885                 self.close()
886
887 #device check end
888
889 #device format start
890 class DeviceFormat(Screen):
891         skin = """<screen position="0,0" size="0,0"/>"""
892         def __init__(self, session, partition, newfstype):
893                 Screen.__init__(self, session)
894                 self.session = session
895                 self.deviceFormatConsole = Console()
896                 self.partition = partition
897                 self.newfstype = newfstype
898                 self.unmountedList = []
899                 self.onLayoutFinish.append(self.timerStart)
900                 self.formatStartTimer = eTimer()
901                 self.formatStartTimer.callback.append(self.DeviceFormatStart)
902                 self.setHotplugDisabled = False
903                 self.umountTimer = eTimer()
904                 self.umountTimer.callback.append(self.doUnmount)
905
906         def timerStart(self):
907                 self.formatStartTimer.start(100,True)
908
909         def DeviceFormatStart(self):
910                 devicemanagerhotplug.setHotplugActive(False)
911                 self.setHotplugDisabled = True
912                 print "DeviceFormatStart : ", self.partition,
913                 print "Filesystem : ",self.newfstype
914                 device = self.partition["partition"]
915                 devicepath = "/dev/"+device
916                 fssize = self.partition["size"]
917                 newfstype = self.newfstype
918                 msg = _("Format filesystem, please wait ...")
919                 msg += _("\nDevice : %s")%(devicepath)
920                 msg += _("\nFilesystem : %s")%(newfstype)
921                 msg += _("\nSize : %s")%(byteConversion(fssize))
922                 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
923                 self.umountTimer.start(500,True)
924
925         def doUnmount(self):
926                 mountpoint = self.partition["mountpoint"]
927                 if mountpoint != "":
928                         self.doumountPartition()
929                 else:
930                         self.umountPartitionFinished("NORESULT", 0)
931
932         def doumountPartition(self):
933                 oldfstype = self.partition["fstype"]
934                 newfstype = self.newfstype
935
936                 if newfstype == oldfstype:
937                         device = self.partition["partition"]
938                 else:
939                         device = self.partition["partition"][:3]
940                 cmd = ""
941                 mounts = file('/proc/mounts','r')
942                 for line in mounts.readlines():
943                         if line.startswith("/dev/%s"%device):
944                                 cmd += "umount %s;"%line.split()[0]
945                                 self.unmountedList.append([line.split()[0], line.split()[1]])
946                 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
947
948         def umountPartitionFinished(self, result, retval, extra_args = None):
949                 partition = self.partition["partition"]
950                 oldfstype = self.partition["fstype"]
951                 newfstype = self.newfstype
952                 if retval == 0:
953                         if oldfstype == newfstype:
954                                 self.changePartitionIDFinished("NORESULT", 0)
955                         else:
956                                 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
957                                 if newfstype[:3] == "ext":
958                                         cmd += " 83"
959                                 else:
960                                         cmd += " c"
961                                 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
962                 else:
963                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
964                         self.msgWaiting.run_close(False,errorMsg)
965
966         def changePartitionIDFinished(self, result, retval, extra_args = None):
967                 device = self.partition["partition"][:3]
968                 mountpoint = self.partition["mountpoint"]
969                 oldfstype = self.partition["fstype"]
970                 newfstype = self.newfstype
971                 if retval == 0:
972                         if oldfstype == newfstype:
973                                 self.refreshPartitionFinished("NORESULT", 0)
974                         else:
975                                 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
976                                 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
977                 else:
978                         errorMsg = _("Can not change the partition ID for %s")%device
979                         self.msgWaiting.run_close(False,errorMsg)
980
981         def refreshPartitionFinished(self, result, retval, extra_args = None):
982                 print "refreshPartitionFinished!"
983                 partition = self.partition["partition"]
984                 mountpoint = self.partition["mountpoint"]
985                 size = int(self.partition["size"])/1024/1024
986                 oldfstype = self.partition["fstype"]
987                 newfstype = self.newfstype
988                 if retval == 0:
989                         if newfstype == "ext4":
990                                 cmd = "/sbin/mkfs.ext4 -F "
991                                 if size > 2 * 1024:
992                                         cmd += "-T largefile "
993                                 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
994                         elif newfstype == "ext3":
995                                 cmd = "/sbin/mkfs.ext3 -F "
996                                 if size > 2 * 1024:
997                                         cmd += "-T largefile "
998                                 cmd += "-m0 /dev/" + partition
999                         elif newfstype == "ext2":
1000                                 cmd = "/sbin/mkfs.ext2 -F "
1001                                 if size > 2 * 1024:
1002                                         cmd += "-T largefile "
1003                                 cmd += "-m0 /dev/" + partition
1004                         elif newfstype == "vfat":
1005                                 if size > 4 * 1024 * 1024:
1006                                         cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
1007                                 else:
1008                                         cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
1009                         self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
1010                 else:
1011                         errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
1012                         self.msgWaiting.run_close(False,errorMsg)
1013                         
1014         def mkfsFinished(self, result, retval, extra_args = None):
1015                 print "mkfsFinished!"
1016                 partition = self.partition["partition"]
1017                 if retval == 0:
1018                         cmd = ""
1019                         if len(self.unmountedList) == 0:
1020                                 self.doMountFinished("NORESULT",0)
1021                         for x in self.unmountedList:
1022                                 cmd += "mount %s %s;"%(x[0], x[1])
1023                                 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1024                 else:
1025                         text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1026                         self.msgWaiting.run_close(False, text)
1027
1028         def doMountFinished(self, result, retval, extra_args = None):
1029                 print "doMountFinished!"
1030                 text = _("Format finished sucessfully.")
1031                 self.msgWaiting.run_close(True, text)
1032
1033         def msgWaitingCB(self, ret, msg):
1034                 if ret:
1035                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1036                 else:
1037                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1038
1039         def exit(self, ret):
1040                 if self.setHotplugDisabled == True:
1041                         devicemanagerhotplug.setHotplugActive(True)
1042                         self.setHotplugDisabled = False
1043                 self.close()
1044
1045 #device format end
1046
1047 class DeviceInfo():
1048         def __init__(self):
1049                 self.blockDeviceList = []
1050
1051         def getBlockDevices(self):
1052                 return self.blockDeviceList
1053
1054         def refresh(self):
1055                 self.blockDeviceList = []
1056                 self.getBlockDeviceList()
1057
1058         def getBlockDeviceList(self):
1059                 print "get block device Infomations..."
1060                 for blockdev in listdir("/sys/block"):
1061                         (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1062                         if not blacklisted and not error:
1063 #                               print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1064                                 blockDevice = {}
1065                                 blockDevice["blockdev"] = blockdev # str
1066                                 blockDevice["removable"] = removable # bool [True, False]
1067                                 blockDevice["partitions"] = partitions # list
1068                                 blockDevice["size"] = size # str
1069                                 blockDevice["model"] = model # str
1070                                 blockDevice["vendor"] = vendor # str
1071                                 self.blockDeviceList.append(blockDevice)
1072
1073         def getBlockDeviceInfo(self, blockdev):
1074                 devpath = "/sys/block/" + blockdev
1075                 error = False
1076                 removable = False
1077                 blacklisted = False
1078                 partitions = []
1079                 size =""
1080                 model = ""
1081                 vendor = ""
1082                 try:
1083                         dev = int(readFile(devpath + "/dev").split(':')[0])
1084                         if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1085                                 blacklisted = True
1086                                 return error, blacklisted, removable, partitions, size, model, vendor
1087                         removable = bool(int(readFile(devpath + "/removable")))
1088                         size = str(int(readFile(devpath + "/size").strip())*512)
1089                         model = readFile(devpath + "/device/model")
1090                         vendor = readFile(devpath + "/device/vendor")
1091                         for partition in listdir(devpath):
1092                                 if partition[:len(blockdev)] != blockdev:
1093                                         continue
1094                                 partitions.append(partition)
1095                 except IOError:
1096                         error = True
1097                 return error, blacklisted, removable, partitions, size, model, vendor
1098
1099         def getPartitionInfo(self, partition):
1100                 mountPoint = self.getPartitionMountpoint(partition)
1101                 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1102                 size_total = self.getPartitionSize(partition)
1103                 size_free = ""
1104                 if mountPoint != "":
1105                         size_free = self.getPartitionFree(mountPoint)   
1106                 partitionInfo = {}
1107                 partitionInfo["partition"] = partition
1108                 partitionInfo["mountpoint"] = mountPoint
1109                 partitionInfo["uuid"] = uuid
1110                 partitionInfo["fstype"] = fsType
1111                 partitionInfo["size"] = size_total
1112                 partitionInfo["free"] = size_free
1113                 return partitionInfo
1114
1115         def getPartitionMountpoint(self, partition):
1116                 mounts = file('/proc/mounts').read().split('\n')
1117                 for x in mounts:
1118                         if not x.startswith('/'):
1119                                 continue
1120                         devpath, mountpoint,  = x.split()[:2]
1121                         if mountpoint.startswith('/autofs'):
1122                                 continue
1123                         if path.basename(devpath) == partition:
1124                                 return mountpoint
1125                 return ""
1126
1127         def getPartitionBlkidInfo(self, partition):
1128                 parttionDev = "/dev/"+str(partition)
1129                 uuid = ""
1130                 partitionType = ""
1131                 cmd = "blkid -c /dev/null "+str(parttionDev)
1132                 try:
1133                         line = popen(cmd).readline().strip()
1134                         if not line.startswith(parttionDev):
1135                                 return (uuid, partitionType)
1136 #                       print "Blikd %s : %s"%(parttionDev, line)
1137                         if line.find(" UUID=") != -1:
1138                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1139                         if line.find(" TYPE=") != -1:
1140                                 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1141                 except:
1142                         print "get blkid info error (%s)"%cmd
1143                 return (uuid, partitionType)
1144
1145         def getPartitionSize(self, partition):          
1146                 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1147                 try:
1148                         size = readFile(devpath + "/size")
1149                         return str(int(size)*512)
1150                 except:
1151                         return ""
1152
1153         def getPartitionFree(self, mountPoint):
1154                 try:
1155                         stat = statvfs(mountPoint)
1156                         size_free = stat.f_bfree*stat.f_bsize
1157                         return size_free
1158                 except:
1159                         return ""
1160
1161         def checkMountPoint(self, check_mountpoint):
1162                 res = []
1163                 try:
1164                         mounts = file('/proc/mounts').read().split('\n')
1165                         for x in mounts:
1166                                 if not x.startswith('/'):
1167                                         continue
1168                                 devpath, mountpoint  = x.split()[:2]
1169                                 if mountpoint == check_mountpoint:
1170                                         res.append(devpath)
1171                 except:
1172                         pass
1173                 return res
1174
1175         def checkMountDev(self, device):
1176                 res = []
1177                 try:
1178                         mounts = file('/proc/mounts').read().split('\n')
1179                         for x in mounts:
1180                                 if not x.startswith('/'):
1181                                         continue
1182                                 devpath, mountpoint  = x.split()[:2]
1183                                 if devpath == device:
1184                                         res.append(mountpoint)
1185                 except:
1186                         pass
1187                 return res
1188
1189         def isMounted(self, devpath, mountpoint):
1190                 try:
1191                         mounts = file('/proc/mounts').read().split('\n')
1192                         for x in mounts:
1193                                 if not x.startswith('/'):
1194                                         continue
1195                                 _devpath, _mountpoint  = x.split()[:2]
1196                                 if devpath == _devpath and mountpoint == _mountpoint:
1197                                         return True
1198                 except:
1199                         pass
1200                 return False
1201
1202         def isMountable(self, partition):
1203                 autofsPath = "/autofs/"+partition.device
1204                 mountable = False
1205                 try:
1206                         os.listdir(autofsPath)
1207                         mountable = True
1208                 except:
1209                         pass
1210                 return mountable
1211
1212         def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1213 #               print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1214                 if mountpoint[-1] == '/':
1215                         mountpoint = mountpoint[:-1]
1216                 data = file('/etc/fstab').read().split('\n')
1217                 for line in data:
1218                         if not line.startswith('/'):
1219                                 continue
1220                         dev, mp, ms = line.split()[0:3]
1221                         if uuid is not None and dev.startswith('UUID'):
1222                                 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1223 #                                       print " >> line : ", line
1224                                         return True
1225                         elif dev == devpath and mp == mountpoint and ms == 'auto':
1226 #                               print " >> line : ", line
1227                                 return True
1228                 return False
1229
1230         def umountByMountpoint(self, mountpoint):
1231                 if mountpoint is None:
1232                         return False
1233                 try:
1234                         if path.ismount(mountpoint):
1235                                 cmd = "umount " + mountpoint
1236                                 print "[DeviceManager] ", cmd
1237                                 os.system(cmd)
1238                 except:
1239                         print "Umount by mountpoint failed!"
1240                 if not path.ismount(mountpoint):
1241                         return True
1242                 return False
1243
1244         def umountByDevpath(self, devpath):
1245                 cmd = "umount " + devpath
1246                 print "[DeviceManager] ", cmd
1247                 os.system(cmd)
1248
1249 deviceinfo = DeviceInfo()
1250
1251 class MountpointBrowser(Screen):
1252         skin="""
1253                 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1254                         <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1255                         <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1256                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1257                         <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1258                         <widget source="key_red" render = "Label" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
1259                         <widget source="key_green" render = "Label" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
1260                         <widget source="key_yellow" render = "Label" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
1261                         <widget source="key_blue" render = "Label" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
1262                         <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1263                         <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1264                 </screen>
1265         """
1266         def __init__(self, session):
1267                 Screen.__init__(self, session)
1268                 self["key_red"] = StaticText(_("Cancel"))
1269                 self["key_green"] = StaticText(_("Select"))
1270                 self["key_yellow"] = StaticText(_("Create directory"))
1271                 self["key_blue"] = StaticText("Delete directory")
1272                 directory = "/media/"
1273                 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1274                 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1275                 self["filelist"] = self.filelist
1276
1277                 self["shortcuts"] = ActionMap(["ColorActions"],
1278                         {
1279                         "red": self.exit,
1280                         "green": self.select,
1281                         "yellow": self.createDirectory,
1282                         "blue": self.deleteDirectory,
1283                         }, -2)
1284
1285                 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1286                         {
1287                         "cancel": self.exit,
1288                         "ok": self.ok,
1289                         }, -2)
1290
1291         def ok(self):
1292                 if self.filelist.canDescent():
1293                         self.filelist.descent()
1294
1295         def select(self):
1296                 if self["filelist"].getCurrentDirectory() is not None:
1297                         if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1298                                 self.filelist.descent()
1299                                 currDir = self["filelist"].getCurrentDirectory()
1300                                 self.close(currDir)
1301                 else:
1302                         self.close(self["filelist"].getFilename())
1303
1304         def createDirectory(self):
1305                 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1306
1307         def createDirectoryCB(self, retval = None):
1308                 newdir=None
1309                 try:
1310                         if retval is not None:
1311                                 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1312                                 if not path.exists(newdir):
1313                                         os.system("mkdir %s"%newdir)
1314                                 self.filelist.refresh()
1315                 except:
1316                         if newdir:
1317                                 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1318
1319         def deleteDirectory(self):
1320                 delDir=None
1321                 try:
1322                         if self["filelist"].getCurrentDirectory() is not None:
1323                                 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1324                                         delDir = self["filelist"].getFilename()
1325                                         if path.exists(delDir):
1326                                                 os.system("rmdir '%s'"%delDir)
1327                                         if path.exists(delDir):
1328                                                 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1329                                         self.filelist.refresh()
1330                 except:
1331                         if delDir:
1332                                 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1333
1334         def exit(self):
1335                 self.close(False)
1336
1337 class MessageBoxConfirm(MessageBox):
1338         skin =  """
1339                 <screen position="center,center" size="620,10" title="Message">
1340                         <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1341                         <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1342                         <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1343                         <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1344                         <widget name="list" position="100,100" size="380,375" transparent="1" />
1345                         <applet type="onLayoutFinish">
1346 # this should be factored out into some helper code, but currently demonstrates applets.
1347 from enigma import eSize, ePoint
1348
1349 orgwidth  = self.instance.size().width()
1350 orgheight = self.instance.size().height()
1351 orgpos    = self.instance.position()
1352 textsize  = self[&quot;text&quot;].getSize()
1353
1354 # y size still must be fixed in font stuff...
1355 textsize = (textsize[0] + 50, textsize[1] + 50)
1356 offset = 0
1357 if self.type == self.TYPE_YESNO:
1358         offset = 60
1359 wsizex = textsize[0] + 60
1360 wsizey = textsize[1] + offset
1361 if (280 &gt; wsizex):
1362         wsizex = 280
1363 wsize = (wsizex, wsizey)
1364
1365 # resize
1366 self.instance.resize(eSize(*wsize))
1367
1368 # resize label
1369 self[&quot;text&quot;].instance.resize(eSize(*textsize))
1370
1371 # move list
1372 listsize = (wsizex, 50)
1373 self[&quot;list&quot;].instance.move(ePoint(0, textsize[1]))
1374 self[&quot;list&quot;].instance.resize(eSize(*listsize))
1375
1376 # center window
1377 newwidth = wsize[0]
1378 newheight = wsize[1]
1379 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1380                         </applet>
1381                 </screen>
1382                 """
1383
1384 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1385 class DeviceManagerConfig():
1386         def __init__(self):
1387                 self.configList = []
1388
1389         def getConfigList(self):
1390                 return self.configList
1391
1392         def updateConfigList(self):
1393                 try:
1394                         self.configList = []
1395                         file = open("/proc/mounts")
1396                         mounts = file.readlines()
1397                         file.close()
1398                         for x in mounts:
1399                                 if x.startswith("/dev/sd"):
1400                                         device = x.split()[0].split('/dev/')[1]
1401                                         mountpoint = x.split()[1]
1402                                         if mountpoint.startswith('/autofs'):
1403                                                 continue
1404                                         (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1405                                         if uuid != '' and mountpoint != '':
1406                                                 self.configList.append([uuid, mountpoint])
1407                         self.saveConfig()
1408                 except:
1409                         print "updateConfigList failed!"
1410
1411         def loadConfig(self):
1412                 if not fileExists(dmconfigfile):
1413                         os.system("touch %s" % dmconfigfile)
1414                 self.configList = []
1415                 data = file(dmconfigfile).read().split('\n')
1416                 for line in data:
1417                         if line.find(':') != -1:
1418                                 (uuid, mountpoint) = line.split(':')
1419                                 if uuid != '' and mountpoint != '':
1420                                         self.configList.append([uuid, mountpoint])
1421
1422         def saveConfig(self):
1423                 confFile = open(dmconfigfile,'w')
1424                 data = ""
1425                 for line in self.configList:
1426                         data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1427                 confFile.write(data)
1428                 confFile.close()
1429
1430         def appendConfig(self, uuid, mountpoint):
1431                 for x in self.configList:
1432                         if x[0] == uuid or x[1] == mountpoint:
1433                                 self.configList.remove(x)
1434                 self.configList.append([uuid, mountpoint])
1435
1436         def removeConfig(self, value):
1437                 for x in self.configList:
1438                         if x[0] == value or x[1] == value:
1439                                 self.configList.remove(x)
1440
1441 devicemanagerconfig = DeviceManagerConfig()
1442
1443 class deviceManagerHotplug:
1444         def __init__(self):
1445                 self.hotplugActive = True
1446
1447         def setHotplugActive(self,value=True):
1448                 if value:
1449                         self.hotplugActive = True
1450                 else:
1451                         self.hotplugActive = False
1452
1453         def printDebug(self):
1454                 for p in harddiskmanager.partitions:
1455                         print " # partition : %s %s %s %s %s(mp, des, f_mounted, is_hot, dev)"%(p.mountpoint, p.description, p.force_mounted, p.is_hotplug,p.device)
1456
1457         def doMount(self, uuid, devpath, mountpoint, filesystem):
1458 # check current device mounted on another mountpoint.
1459                 mp_list = []
1460                 mp_list = deviceinfo.checkMountDev(devpath)
1461                 for mp in mp_list:
1462                         if mp != mountpoint and path.ismount(mp):
1463                                 deviceinfo.umountByMountpoint(mp)
1464 # check another device mounted on configmountpoint
1465                 devpath_list = []
1466                 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1467                 for devpath_ in devpath_list:
1468                         if devpath_ != devpath:
1469                                 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1470                                 return
1471 # do mount
1472 #               print "[DeviceManager] doMount"
1473                 if not path.exists(mountpoint):
1474                         os.system("mkdir %s"%mountpoint)
1475                 if path.exists(mountpoint):
1476                         if not path.ismount(mountpoint):
1477                                 if filesystem == "ntfs":
1478                                         cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1479                                 elif filesystem is None:
1480                                         cmd = "mount %s %s"%(devpath, mountpoint)
1481                                 else:
1482                                         cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1483                                 print "[DeviceManager] cmd : %s"%cmd
1484                                 os.system(cmd)
1485                                 if not deviceinfo.isMounted(devpath, mountpoint):
1486                                         print "[DeviceManager] %s doMount failed!"%devpath
1487                                         return
1488                                 else:
1489 # Update partition Info, add
1490                                         self.addPartitionAutofsMountpoint(devpath, mountpoint)
1491
1492         def doUmount(self, device, mountpoint):
1493                 devpath = "/dev/"+device
1494                 mountpoints = deviceinfo.checkMountDev(devpath)
1495                 if len(mountpoints) == 0:
1496                         return
1497                 for mp in mountpoints:
1498                         cmd = "umount %s"%devpath
1499                         print "[DeviceManager] cmd : %s"%cmd
1500                         os.system(cmd)
1501
1502         def addHotPlugDevice(self, partition):
1503                 device = partition.device
1504                 devpath = "/dev/"+device
1505 # get BlkidInfo
1506                 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1507                 if uuid == "":
1508 # retry..
1509                         os.system("sleep 1")
1510                         (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1511                 if uuid == "":
1512                         print "[DeviceManagerHotplug] getBlkidInfo failed!"
1513                         return
1514 # get configList
1515                 devicemanagerconfig.loadConfig()
1516                 configList = devicemanagerconfig.getConfigList()
1517                 mountpoint = None
1518                 for line in configList:
1519                         if uuid == line[0].strip():
1520                                 mountpoint = line[1].strip()
1521                                 break
1522                 if mountpoint is None:
1523                         return
1524 # do mount
1525                 if deviceinfo.isMounted(devpath, mountpoint):
1526                         pass
1527 #                       print "[DeviceManagerHotplug] already mounted"
1528                 else:
1529                         self.doMount(uuid, devpath, mountpoint, filesystem)
1530
1531         def removeHotplugDevice(self, partition):
1532                 self.doUmount(partition.device, partition.mountpoint)
1533
1534         def getHotplugAction(self, action, partition):
1535                 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1536                         return
1537                 if partition.device is None or not partition.device.startswith("sd"):
1538                         return
1539                 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1540
1541                 if action == 'add':
1542                         self.addHotPlugDevice(partition)
1543                 elif action == 'remove':
1544                         self.removeHotplugDevice(partition)
1545
1546         def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1547                 device = path.basename(devpath)
1548                 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1549 # check already appended to partition list
1550                 for x in harddiskmanager.partitions:
1551                         if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1552                                 return
1553 #
1554                 from Components.Harddisk import Partition
1555                 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1556                 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1557                 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1558                 harddiskmanager.partitions.append(p)
1559                 harddiskmanager.on_partition_list_change("add", p)
1560
1561         def autoMountOnStartup(self):
1562                 devicemanagerconfig.loadConfig()
1563                 configList = devicemanagerconfig.getConfigList()
1564 # get blkid info
1565                 blkiddata = []
1566                 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1567                 for line in data:
1568                         devpath = uuid = filesystem = ""
1569                         devpath = line.split(':')[0]
1570                         if line.find(" UUID=") != -1:
1571                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1572                         if line.find(" TYPE=") != -1:
1573                                 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1574                         blkiddata.append((devpath, uuid, filesystem))
1575 # check configList
1576                 for c in configList:
1577                         uuid_cfg = c[0].strip()
1578                         mountpoint_cfg = c[1].strip()
1579                         for (devpath, uuid, filesystem) in blkiddata:
1580                                 if uuid_cfg == uuid:
1581 # do mount
1582                                         if deviceinfo.isMounted(devpath, mountpoint_cfg):
1583 #                                               print "[Devicemanager startup] already mounted"
1584                                                 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1585                                         else:
1586 #                                               print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1587                                                 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1588
1589         def umountOnShutdown(self):
1590                 devicemanagerconfig.loadConfig()
1591                 configList = devicemanagerconfig.getConfigList()
1592 # get mount info
1593                 mounts = []
1594                 data = file('/proc/mounts').read().split('\n')
1595                 for x in data:
1596                         if not x.startswith('/dev/sd'):
1597                                 continue
1598                         devpath, mountpoint  = x.split()[:2]
1599                         mounts.append((path.basename(devpath), mountpoint))
1600 # get blkid info
1601                 data = self.getBlkidInfo()
1602 # check configList
1603                 for c in configList:
1604                         uuid_cfg = c[0].strip()
1605                         mountpoint_cfg = c[1].strip()
1606                         device_cfg = None
1607                         if uuid_cfg in data.keys():
1608                                 device_cfg = data[uuid_cfg]
1609                         if device_cfg is None:
1610                                 continue
1611                         for (device, mountpoint) in mounts:
1612                                 if device_cfg == device:
1613                                         if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1614                                                 self.doUmount(device, mountpoint)
1615
1616         def getBlkidInfo(self):
1617                 data = {}
1618                 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1619                 for line in blkid_data.split('\n'):
1620 #                       print "[DeviceManager] getBlkidInfo line : ",line
1621                         device = uuid = ""
1622                         device = path.basename(line.split(':')[0])
1623                         if line.find(" UUID=") != -1:
1624                                 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1625                                 data[blkid_uuid] = device
1626                 return data
1627
1628 devicemanagerhotplug = deviceManagerHotplug()
1629
1630 def DeviceManagerhotplugDeviceStart(action, device):
1631         devicemanagerhotplug.getHotplugAction(action, device)
1632
1633 def callBackforDeviceManager(session, callback_result = False):
1634         if callback_result == True:
1635                 session.open(DeviceManager)
1636
1637 def checkMounts(session):
1638         try:
1639                 noMountable_dev = ""
1640                 for blockdev in listdir("/sys/block"):
1641                         devpath = "/sys/block/" + blockdev
1642                         dev = int(readFile(devpath + "/dev").split(':')[0])
1643                         if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1644                                 continue
1645                         partitions = []
1646                         noMountable_partitions = []
1647                         for partition in listdir(devpath):
1648                                 if not partition.startswith(blockdev):
1649                                         continue
1650                                 partitions.append(partition)
1651                                 if os.access('/autofs/'+partition,0) is False:
1652                                         noMountable_partitions.append(partition)
1653                         if len(partitions) == 0 or len(noMountable_partitions) != 0:
1654                                 if noMountable_dev != "":
1655                                         noMountable_dev +=  ' '
1656                                 noMountable_dev += blockdev
1657
1658                 if noMountable_dev != "":
1659                                 print "Umountable partitions found."
1660                                 InfoText = _("No mountable devices found.! (%s)\nDo you want to open DeviceManager and do initialize or format this device?\n\n(Open 'Menu->Setup->System -> Harddisk -> DeviceManager'\n and press MENU button to deactivate this check.)")%noMountable_dev
1661                                 AddNotificationWithCallback(
1662                                                                 boundFunction(callBackforDeviceManager, session), 
1663                                                                 MessageBox, InfoText, timeout = 60, default = False
1664                                 )
1665         except:
1666                 print "checkMounts failed!"
1667
1668 def sessionstart(reason, **kwargs):
1669         if reason == 0:
1670                 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1671                         session = kwargs["session"]
1672                         checkMounts(session)
1673                 if config.plugins.devicemanager.hotplug_enable.value:
1674                         harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1675         elif reason == 1:
1676                 if config.plugins.devicemanager.hotplug_enable.value:
1677                         harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1678
1679 def autostart(reason, **kwargs):
1680         if reason == 0:
1681                 try:
1682 # check at first enigma2 start  
1683                         if not fileExists(dmconfigfile):
1684                                 print "[DeviceManager] autostart : check devices at first start"
1685                                 sda_isremovable = False
1686                                 sda_UUID = ""
1687                                 os.system("touch %s"%dmconfigfile)
1688 # check sda
1689                                 sda_data = popen("cat /proc/partitions | grep sda1").read()
1690                                 if sda_data != '':
1691                                         sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1692                                         sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1693                                         print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1694                                 cfg = ""
1695                                 if sda_data != '':
1696                                         cfg += '"%s":/media/hdd\n'%sda_UUID
1697                                 confFile = open(dmconfigfile,'w')
1698                                 confFile.write(cfg)
1699                                 confFile.close()
1700                                 if not path.exists("/media/hdd"):
1701                                         os.system("mkdir -p /media/hdd")
1702 # auto mount
1703                         devicemanagerhotplug.autoMountOnStartup()
1704                 except:
1705                         print "[DeviceManager] autostart failed!"
1706         elif reason == 1:
1707                 devicemanagerhotplug.umountOnShutdown()
1708
1709 def menu(menuid, **kwargs):
1710         if menuid == "system":
1711                 return [(_("DeviceManager"), main, "device_manager", 50)]
1712         return []
1713
1714 def main(session, **kwargs):
1715         session.open(DeviceManager)
1716
1717 def Plugins(path, **kwargs):
1718         return [
1719                 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1720                 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1721                 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1722                 ]
1723
1724 class MessageBox_2(MessageBox):
1725         def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1726                 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1727                 self.skinName = "MessageBox"
1728                 self.closeTimer = eTimer()
1729                 self.closeTimer.callback.append(self.msg_close)
1730                 self.devicemanager_ret = False
1731                 self.devicemanager_msg = ""
1732
1733         def msg_close(self):
1734                 self.close(self.devicemanager_ret, self.devicemanager_msg)
1735
1736         def run_close(self, ret, msg=""):
1737                 self.devicemanager_ret = ret
1738                 self.devicemanager_msg = msg
1739                 self.closeTimer.start(100,True)
1740
1741         def createSummary(self):
1742                 return MessageBox_2_Summary
1743
1744 class MessageBox_2_Summary(Screen):
1745         skin="""
1746                 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1747                         <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />
1748                 </screen>
1749         """
1750