DeviceManager : disable hotplugAction for mkfs.
[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
526         def timerStart(self):
527                 self.initStartTimer.start(100,True)
528
529         def confirmMessage(self):
530                 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
531                 self.session.openWithCallback(self.confirmed, MessageBox, message)
532
533         def confirmed(self, ret):
534                 if ret:
535                         self.InitializeStart()
536                 else:
537                         self.exit()
538
539         def exit(self, ret = True):
540                 self.close()
541
542         def unmountAll(self, device):
543                 mounts = file('/proc/mounts').read().split('\n')
544                 cmd = ""
545 # umount all
546                 for line in mounts:
547                         if not line.startswith("/dev/" + device):
548                                 continue
549                         cmd += "umount %s ;"% line.split()[0]
550                 print "[DeviceManager] %s"%cmd
551                 os.system(cmd)
552 #recheck if umounted
553                 mounts = file('/proc/mounts').read().split('\n')
554                 for line in mounts:
555                         if line.startswith("/dev/" + device):
556                                 return False
557                 return True
558
559         def InitializeStart(self):
560                 self.InputPartitionSize_step1()
561
562         def InputPartitionSize_step1(self):
563                 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
564
565         def InputPartitionSize_step1_CB(self, ret):
566                 if ret is not None and int(ret) in range(1,5): # ret in 1~4
567                         self.inputbox_partitions = int(ret)
568                         self.InputPartitionSize_step2()
569                 else:
570                         self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
571
572         def InputPartitionSize_step2(self):
573                 current_partition = len(self.inputbox_partitionSizeList)+1
574                 if self.inputbox_partitionSizeRemain == 0:
575                         self.choiceBoxFstype()
576                 elif current_partition == self.inputbox_partitions:
577                         self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
578                         self.choiceBoxFstype()
579                 else:
580                         text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
581                         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)
582
583         def InputPartitionSize_step2_CB(self, ret):
584                 if ret is not None:
585                         if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
586                                 self.InputPartitionSize_step2()
587                         else:
588                                 self.inputbox_partitionSizeList.append(str(ret))
589                                 self.inputbox_partitionSizeRemain -= int(ret)
590                                 self.InputPartitionSize_step2()
591                 else:
592                         self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
593
594         def choiceBoxFstype(self):
595                 menu = []
596                 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
597                 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
598                 menu.append((_("ext4 - experimental"), "ext4"))
599                 menu.append((_("vfat - for USB flash memory"), "vfat"))
600                 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
601
602         def choiceBoxFstypeCB(self, choice):
603                 if choice is None:
604                         self.exit()
605                 else:
606                         self.fstype = choice[1]
607                         if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
608                                 self.exit()
609                         else:
610                                 self.initInitializeConfirm()
611
612         def initInitializeConfirm(self):
613 #               print self.inputbox_partitionSizeList
614                 partitionsInfo = ""
615                 for index in range(len(self.inputbox_partitionSizeList)):
616                         print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
617                         partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
618                 partitionsInfo += "filesystem type : %s"%(self.fstype)
619                 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
620
621         def initInitializeConfirmCB(self,ret):
622                 if ret:
623                         self.initInitialize()
624                 else:
625                         self.exit()
626         
627         def initInitialize(self):
628                 if not self.unmountAll(self.device):
629                         self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
630                 else:
631                         msg = _("InitInitializing, please wait ...")
632                         msg += _("\nDevice : %s")%self.device
633                         msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
634                         for index in range(len(self.inputbox_partitionSizeList)):
635                                 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
636                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
637                         set = ""
638                         partitions = len(self.inputbox_partitionSizeList)
639                         if partitions == 1:
640                                 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
641                         else:
642                                 for p in range(4):
643                                         if partitions > p+1:
644                                                 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
645                                         else:
646                                                 set +=";\n"
647                                 set+="y\n"
648                                 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
649                         self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
650
651         def initInitializeFinished(self, result, retval, extra_args = None):
652                 if retval == 0:
653                         cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
654                         self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
655                 else:
656                         errorMsg = "initInitializing device Error at /dev/%s"%self.device
657                         self.msgWaiting.run_close(False, errorMsg)
658
659         def initInitializingRefreshFinished(self, result, retval, extra_args = None):
660                 cmd = "/bin/umount /dev/%s*" % (self.device)
661                 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
662
663         def initInitializingUmountFinished(self, result, retval, extra_args = None):
664                 partitions = open("/proc/partitions")
665                 self.devicenumber = 0
666                 self.newpartitions = 0
667                 for part in partitions:
668                         res = re.sub("\s+", " ", part).strip().split(" ")
669                         if res and len(res) == 4 and res[3][:3] == self.device:
670                                 if len(res[3]) > 3 and res[3][:2] == "sd":
671                                         self.newpartitions += 1
672                 partitions.close()
673                 self.msgWaiting.run_close(True)
674 #               self.createFilesystem(self.newpartitions)
675
676         def createFilesystem(self, newpartitions):
677                 self.devicenumber = self.devicenumber + 1
678                 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
679                 shortdevicename = self.device + str(self.devicenumber)
680 # get partition size
681                 partitions = open("/proc/partitions")
682                 for part in partitions:
683                         res = re.sub("\s+", " ", part).strip().split(" ")
684                         if res and len(res) == 4:
685                                 if res[3] == shortdevicename:
686                                         partitionsize = int(res[2])
687                                         break
688                 partitions.close()
689
690                 if self.fstype == "ext4":
691                         cmd = "/sbin/mkfs.ext4 -F "
692                         if partitionsize > 2 * 1024 * 1024: # 2GB
693                                 cmd += "-T largefile "
694                         cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
695                 elif self.fstype == "ext3":
696                         cmd = "/sbin/mkfs.ext3 -F "
697                         if partitionsize > 2 * 1024 * 1024:
698                                 cmd += "-T largefile "
699                         cmd += "-m0 " + fulldevicename
700                 elif self.fstype == "ext2":
701                         cmd = "/sbin/mkfs.ext2 -F "
702                         if partitionsize > 2 * 1024 * 1024:
703                                 cmd += "-T largefile "
704                         cmd += "-m0 " + fulldevicename
705                 elif self.fstype == "vfat":
706                         if partitionsize > 4 * 1024 * 1024 * 1024:
707                                 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
708                         else:
709                                 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
710                 else:
711                         self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
712                         return
713
714                 msg = _("Create filesystem, please wait ...")
715                 msg += _("\nPartition : %s") % (fulldevicename)
716                 msg += _("\nFilesystem : %s") % (self.fstype)
717                 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
718                 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
719                 self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
720
721         def createFilesystemFinished(self, result, retval, extra_args = None):
722                 device = extra_args[0]
723                 fulldevicename = extra_args[1]
724                 if retval == 0:
725                         self.msgWaitingMkfs.run_close(True)
726                 else:
727                         errorMsg = _("Creating filesystem Error")
728                         if fulldevicename is not None:
729                                 errorMsg += _(" at /dev/%s")%fulldevicename
730                         self.msgWaitingMkfs.run_close(False, errorMsg)
731
732         def createFilesystemStart(self):
733                 self.createFilesystem(self.newpartitions)
734
735         def msgWaitingCB(self, ret, msg=""):
736                 if ret:
737                         self.createFSStartTimer.start(100,True)
738                 else:
739                         self.success = False
740                         self.msg = msg
741                         self.exitMessageTimer.start(100,True)
742
743         def msgWaitingMkfsCB(self, ret, msg=""):
744                 if self.devicenumber < self.newpartitions:
745                         self.createFSStartTimer.start(100,True)
746                 else:
747                         if ret == True:
748                                 self.success = True
749                                 self.msg = _("Device Initialization finished sucessfully!")
750                                 self.updateDeviceInfo()
751                                 self.exitMessageTimer.start(100,True)
752                         else:
753                                 self.success = False
754                                 self.msg = msg
755                                 self.exitMessageTimer.start(100,True)
756
757         def exitMessage(self):
758                 if self.success:
759                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
760                 else:
761                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
762
763         def updateDeviceInfo(self):
764 # update devicemanager configs
765                 devicemanagerconfig.updateConfigList()
766
767 # Initializing end
768
769 # device check start..
770 class DeviceCheck(Screen):
771         skin = """<screen position="0,0" size="0,0"/>"""
772         def __init__(self, session, partition):
773                 Screen.__init__(self, session)
774                 self.session = session
775                 self.deviceCheckConsole = Console()
776                 self.partition = partition
777                 self.onLayoutFinish.append(self.timerStart)
778                 self.checkStartTimer = eTimer()
779                 self.checkStartTimer.callback.append(self.confirmMessage)
780
781         def timerStart(self):
782                 self.checkStartTimer.start(100,True)
783
784         def confirmMessage(self):
785                 fssize = self.partition["size"]
786                 if long(fssize) > 1024*1024*1024*16:
787                         message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
788                         self.session.openWithCallback(self.confirmed, MessageBox, message)
789                 else:
790                         self.deviceCheckStart()
791
792         def confirmed(self, ret):
793                 print "confirmed : ",ret
794                 if ret:
795                         self.deviceCheckStart()
796                 else:
797                         self.exit()
798
799         def deviceCheckStart(self):
800                 print "deviceCheckStart "
801                 print "partition : ", self.partition
802                 device = self.partition["partition"]
803                 mountpoint = self.partition["mountpoint"]
804                 fstype = self.partition["fstype"]
805                 fssize = self.partition["size"]
806                 if device is not None and fstype.startswith("ext"):
807                         msg = _("Check filesystem, please wait ...")
808                         msg += _("\nDevice : /dev/%s")%(device)
809                         msg += _("\nFilesystem : %s")%(fstype)
810                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
811                         if mountpoint != "":
812                                 self.doUmountFsck(device, mountpoint, fstype)
813                         else:
814                                 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
815                 else:
816                         self.exit()
817
818         def doUmountFsck(self, device, mountpoint, fstype):
819                 cmd = "umount /dev/%s" % device
820                 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
821
822         def umountFsckFinished(self, result, retval, extra_args = None):
823                 device = extra_args[0]
824                 mountpoint = extra_args[1]
825                 fstype = extra_args[2]
826                 if retval == 0:
827                         cmd = "fsck." + fstype + " -f -p /dev/" + device
828                         self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
829                 else:
830                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
831                         self.msgWaiting.run_close(False,errorMsg)
832                         
833         def fsckFinished(self, result, retval, extra_args = None):
834                 device = extra_args[0]
835                 mountpoint = extra_args[1]
836                 if retval == 0:
837                         text = _("Filesystem check finished sucessfully")
838                         self.msgWaiting.run_close(True, text)
839                 else:
840                         text = _("Error checking disk. The disk or filesystem may be damaged")
841                         self.msgWaiting.run_close(False, text)
842
843         def msgWaitingCB(self, ret, msg):
844                 if ret:
845                         self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
846                 else:
847                         self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
848
849                 partition = self.partition["partition"]
850                 mountpoint = self.partition["mountpoint"]
851                 fstype = self.partition["fstype"]
852                 if mountpoint != "":
853                         if fstype == "ntfs":
854                                 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
855                         else:
856                                 cmd = "mount /dev/" + partition + " " + mountpoint
857                         self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
858                 else:
859                         self.exit()
860
861         def mountPartitionFinished(self, result, retval, extra_args = None):
862                 self.exit()
863
864         def exit(self):
865                 self.close()
866
867 #device check end
868
869 #device format start
870 class DeviceFormat(Screen):
871         skin = """<screen position="0,0" size="0,0"/>"""
872         def __init__(self, session, partition, newfstype):
873                 Screen.__init__(self, session)
874                 self.session = session
875                 self.deviceFormatConsole = Console()
876                 self.partition = partition
877                 self.newfstype = newfstype
878                 self.unmountedList = []
879                 self.onLayoutFinish.append(self.timerStart)
880                 self.formatStartTimer = eTimer()
881                 self.formatStartTimer.callback.append(self.DeviceFormatStart)
882                 self.setHotplugDisabled = False
883
884         def timerStart(self):
885                 self.formatStartTimer.start(100,True)
886
887         def DeviceFormatStart(self):
888                 devicemanagerhotplug.setHotplugActive(False)
889                 self.setHotplugDisabled = True
890                 print "DeviceFormatStart : ", self.partition,
891                 print "Filesystem : ",self.newfstype
892                 device = self.partition["partition"]
893                 devicepath = "/dev/"+device
894                 mountpoint = self.partition["mountpoint"]
895                 fssize = self.partition["size"]
896                 newfstype = self.newfstype
897
898                 msg = _("Format filesystem, please wait ...")
899                 msg += _("\nDevice : %s")%(devicepath)
900                 msg += _("\nFilesystem : %s")%(newfstype)
901                 msg += _("\nSize : %s")%(byteConversion(fssize))
902                 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
903                 if mountpoint != "":
904                         self.doumountPartition()
905                 else:
906                         self.umountPartitionFinished("NORESULT", 0)
907
908         def doumountPartition(self):
909                 oldfstype = self.partition["fstype"]
910                 newfstype = self.newfstype
911
912                 if newfstype == oldfstype:
913                         device = self.partition["partition"]
914                 else:
915                         device = self.partition["partition"][:3]
916                 cmd = ""
917                 mounts = file('/proc/mounts','r')
918                 for line in mounts.readlines():
919                         if line.startswith("/dev/%s"%device):
920                                 cmd += "umount %s;"%line.split()[0]
921                                 self.unmountedList.append([line.split()[0], line.split()[1]])
922                 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
923
924         def umountPartitionFinished(self, result, retval, extra_args = None):
925                 partition = self.partition["partition"]
926                 oldfstype = self.partition["fstype"]
927                 newfstype = self.newfstype
928                 if retval == 0:
929                         if oldfstype == newfstype:
930                                 self.changePartitionIDFinished("NORESULT", 0)
931                         else:
932                                 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
933                                 if newfstype[:3] == "ext":
934                                         cmd += " 83"
935                                 else:
936                                         cmd += " c"
937                                 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
938                 else:
939                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
940                         self.msgWaiting.run_close(False,errorMsg)
941
942         def changePartitionIDFinished(self, result, retval, extra_args = None):
943                 device = self.partition["partition"][:3]
944                 mountpoint = self.partition["mountpoint"]
945                 oldfstype = self.partition["fstype"]
946                 newfstype = self.newfstype
947                 if retval == 0:
948                         if oldfstype == newfstype:
949                                 self.refreshPartitionFinished("NORESULT", 0)
950                         else:
951                                 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
952                                 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
953                 else:
954                         errorMsg = _("Can not change the partition ID for %s")%device
955                         self.msgWaiting.run_close(False,errorMsg)
956
957         def refreshPartitionFinished(self, result, retval, extra_args = None):
958                 print "refreshPartitionFinished!"
959                 partition = self.partition["partition"]
960                 mountpoint = self.partition["mountpoint"]
961                 size = int(self.partition["size"])/1024/1024
962                 oldfstype = self.partition["fstype"]
963                 newfstype = self.newfstype
964                 if retval == 0:
965                         if newfstype == "ext4":
966                                 cmd = "/sbin/mkfs.ext4 -F "
967                                 if size > 2 * 1024:
968                                         cmd += "-T largefile "
969                                 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
970                         elif newfstype == "ext3":
971                                 cmd = "/sbin/mkfs.ext3 -F "
972                                 if size > 2 * 1024:
973                                         cmd += "-T largefile "
974                                 cmd += "-m0 /dev/" + partition
975                         elif newfstype == "ext2":
976                                 cmd = "/sbin/mkfs.ext2 -F "
977                                 if size > 2 * 1024:
978                                         cmd += "-T largefile "
979                                 cmd += "-m0 /dev/" + partition
980                         elif newfstype == "vfat":
981                                 if size > 4 * 1024 * 1024:
982                                         cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
983                                 else:
984                                         cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
985                         self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
986                 else:
987                         errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
988                         self.msgWaiting.run_close(False,errorMsg)
989                         
990         def mkfsFinished(self, result, retval, extra_args = None):
991                 print "mkfsFinished!"
992                 partition = self.partition["partition"]
993                 if retval == 0:
994                         cmd = ""
995                         if len(self.unmountedList) == 0:
996                                 self.doMountFinished("NORESULT",0)
997                         for x in self.unmountedList:
998                                 cmd += "mount %s %s;"%(x[0], x[1])
999                                 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1000                 else:
1001                         text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1002                         self.msgWaiting.run_close(False, text)
1003
1004         def doMountFinished(self, result, retval, extra_args = None):
1005                 print "doMountFinished!"
1006                 text = _("Format finished sucessfully.")
1007                 self.msgWaiting.run_close(True, text)
1008
1009         def msgWaitingCB(self, ret, msg):
1010                 if ret:
1011                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1012                 else:
1013                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1014
1015         def exit(self, ret):
1016                 if self.setHotplugDisabled == True:
1017                         devicemanagerhotplug.setHotplugActive(True)
1018                         self.setHotplugDisabled = False
1019                 self.close()
1020
1021 #device format end
1022
1023 class DeviceInfo():
1024         def __init__(self):
1025                 self.blockDeviceList = []
1026
1027         def getBlockDevices(self):
1028                 return self.blockDeviceList
1029
1030         def refresh(self):
1031                 self.blockDeviceList = []
1032                 self.getBlockDeviceList()
1033
1034         def getBlockDeviceList(self):
1035                 print "get block device Infomations..."
1036                 for blockdev in listdir("/sys/block"):
1037                         (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1038                         if not blacklisted and not error:
1039 #                               print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1040                                 blockDevice = {}
1041                                 blockDevice["blockdev"] = blockdev # str
1042                                 blockDevice["removable"] = removable # bool [True, False]
1043                                 blockDevice["partitions"] = partitions # list
1044                                 blockDevice["size"] = size # str
1045                                 blockDevice["model"] = model # str
1046                                 blockDevice["vendor"] = vendor # str
1047                                 self.blockDeviceList.append(blockDevice)
1048
1049         def getBlockDeviceInfo(self, blockdev):
1050                 devpath = "/sys/block/" + blockdev
1051                 error = False
1052                 removable = False
1053                 blacklisted = False
1054                 partitions = []
1055                 size =""
1056                 model = ""
1057                 vendor = ""
1058                 try:
1059                         dev = int(readFile(devpath + "/dev").split(':')[0])
1060                         if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1061                                 blacklisted = True
1062                                 return error, blacklisted, removable, partitions, size, model, vendor
1063                         removable = bool(int(readFile(devpath + "/removable")))
1064                         size = str(int(readFile(devpath + "/size").strip())*512)
1065                         model = readFile(devpath + "/device/model")
1066                         vendor = readFile(devpath + "/device/vendor")
1067                         for partition in listdir(devpath):
1068                                 if partition[:len(blockdev)] != blockdev:
1069                                         continue
1070                                 partitions.append(partition)
1071                 except IOError:
1072                         error = True
1073                 return error, blacklisted, removable, partitions, size, model, vendor
1074
1075         def getPartitionInfo(self, partition):
1076                 mountPoint = self.getPartitionMountpoint(partition)
1077                 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1078                 size_total = self.getPartitionSize(partition)
1079                 size_free = ""
1080                 if mountPoint != "":
1081                         size_free = self.getPartitionFree(mountPoint)   
1082                 partitionInfo = {}
1083                 partitionInfo["partition"] = partition
1084                 partitionInfo["mountpoint"] = mountPoint
1085                 partitionInfo["uuid"] = uuid
1086                 partitionInfo["fstype"] = fsType
1087                 partitionInfo["size"] = size_total
1088                 partitionInfo["free"] = size_free
1089                 return partitionInfo
1090
1091         def getPartitionMountpoint(self, partition):
1092                 mounts = file('/proc/mounts').read().split('\n')
1093                 for x in mounts:
1094                         if not x.startswith('/'):
1095                                 continue
1096                         devpath, mountpoint,  = x.split()[:2]
1097                         if mountpoint.startswith('/autofs'):
1098                                 continue
1099                         if path.basename(devpath) == partition:
1100                                 return mountpoint
1101                 return ""
1102
1103         def getPartitionBlkidInfo(self, partition):
1104                 parttionDev = "/dev/"+str(partition)
1105                 uuid = ""
1106                 partitionType = ""
1107                 cmd = "blkid -c /dev/null "+str(parttionDev)
1108                 try:
1109                         line = popen(cmd).readline().strip()
1110                         if not line.startswith(parttionDev):
1111                                 return (uuid, partitionType)
1112 #                       print "Blikd %s : %s"%(parttionDev, line)
1113                         if line.find(" UUID=") != -1:
1114                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1115                         if line.find(" TYPE=") != -1:
1116                                 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1117                 except:
1118                         print "get blkid info error (%s)"%cmd
1119                 return (uuid, partitionType)
1120
1121         def getPartitionSize(self, partition):          
1122                 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1123                 try:
1124                         size = readFile(devpath + "/size")
1125                         return str(int(size)*512)
1126                 except:
1127                         return ""
1128
1129         def getPartitionFree(self, mountPoint):
1130                 try:
1131                         stat = statvfs(mountPoint)
1132                         size_free = stat.f_bfree*stat.f_bsize
1133                         return size_free
1134                 except:
1135                         return ""
1136
1137         def checkMountPoint(self, check_mountpoint):
1138                 res = []
1139                 try:
1140                         mounts = file('/proc/mounts').read().split('\n')
1141                         for x in mounts:
1142                                 if not x.startswith('/'):
1143                                         continue
1144                                 devpath, mountpoint  = x.split()[:2]
1145                                 if mountpoint == check_mountpoint:
1146                                         res.append(devpath)
1147                 except:
1148                         pass
1149                 return res
1150
1151         def checkMountDev(self, device):
1152                 res = []
1153                 try:
1154                         mounts = file('/proc/mounts').read().split('\n')
1155                         for x in mounts:
1156                                 if not x.startswith('/'):
1157                                         continue
1158                                 devpath, mountpoint  = x.split()[:2]
1159                                 if devpath == device:
1160                                         res.append(mountpoint)
1161                 except:
1162                         pass
1163                 return res
1164
1165         def isMounted(self, devpath, mountpoint):
1166                 try:
1167                         mounts = file('/proc/mounts').read().split('\n')
1168                         for x in mounts:
1169                                 if not x.startswith('/'):
1170                                         continue
1171                                 _devpath, _mountpoint  = x.split()[:2]
1172                                 if devpath == _devpath and mountpoint == _mountpoint:
1173                                         return True
1174                 except:
1175                         pass
1176                 return False
1177
1178         def isMountable(self, partition):
1179                 autofsPath = "/autofs/"+partition.device
1180                 mountable = False
1181                 try:
1182                         os.listdir(autofsPath)
1183                         mountable = True
1184                 except:
1185                         pass
1186                 return mountable
1187
1188         def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1189 #               print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1190                 if mountpoint[-1] == '/':
1191                         mountpoint = mountpoint[:-1]
1192                 data = file('/etc/fstab').read().split('\n')
1193                 for line in data:
1194                         if not line.startswith('/'):
1195                                 continue
1196                         dev, mp, ms = line.split()[0:3]
1197                         if uuid is not None and dev.startswith('UUID'):
1198                                 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1199 #                                       print " >> line : ", line
1200                                         return True
1201                         elif dev == devpath and mp == mountpoint and ms == 'auto':
1202 #                               print " >> line : ", line
1203                                 return True
1204                 return False
1205
1206         def umountByMountpoint(self, mountpoint):
1207                 if mountpoint is None:
1208                         return False
1209                 try:
1210                         if path.ismount(mountpoint):
1211                                 cmd = "umount " + mountpoint
1212                                 print "[DeviceManager] ", cmd
1213                                 os.system(cmd)
1214                 except:
1215                         print "Umount by mountpoint failed!"
1216                 if not path.ismount(mountpoint):
1217                         return True
1218                 return False
1219
1220         def umountByDevpath(self, devpath):
1221                 cmd = "umount " + devpath
1222                 print "[DeviceManager] ", cmd
1223                 os.system(cmd)
1224
1225 deviceinfo = DeviceInfo()
1226
1227 class MountpointBrowser(Screen):
1228         skin="""
1229                 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1230                         <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1231                         <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1232                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1233                         <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1234                         <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" />
1235                         <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" />
1236                         <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" />
1237                         <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" />
1238                         <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1239                         <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1240                 </screen>
1241         """
1242         def __init__(self, session):
1243                 Screen.__init__(self, session)
1244                 self["key_red"] = StaticText(_("Cancel"))
1245                 self["key_green"] = StaticText(_("Select"))
1246                 self["key_yellow"] = StaticText(_("Create directory"))
1247                 self["key_blue"] = StaticText("Delete directory")
1248                 directory = "/media/"
1249                 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1250                 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1251                 self["filelist"] = self.filelist
1252
1253                 self["shortcuts"] = ActionMap(["ColorActions"],
1254                         {
1255                         "red": self.exit,
1256                         "green": self.select,
1257                         "yellow": self.createDirectory,
1258                         "blue": self.deleteDirectory,
1259                         }, -2)
1260
1261                 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1262                         {
1263                         "cancel": self.exit,
1264                         "ok": self.ok,
1265                         }, -2)
1266
1267         def ok(self):
1268                 if self.filelist.canDescent():
1269                         self.filelist.descent()
1270
1271         def select(self):
1272                 if self["filelist"].getCurrentDirectory() is not None:
1273                         if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1274                                 self.filelist.descent()
1275                                 currDir = self["filelist"].getCurrentDirectory()
1276                                 self.close(currDir)
1277                 else:
1278                         self.close(self["filelist"].getFilename())
1279
1280         def createDirectory(self):
1281                 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1282
1283         def createDirectoryCB(self, retval = None):
1284                 newdir=None
1285                 try:
1286                         if retval is not None:
1287                                 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1288                                 if not path.exists(newdir):
1289                                         os.system("mkdir %s"%newdir)
1290                                 self.filelist.refresh()
1291                 except:
1292                         if newdir:
1293                                 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1294
1295         def deleteDirectory(self):
1296                 delDir=None
1297                 try:
1298                         if self["filelist"].getCurrentDirectory() is not None:
1299                                 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1300                                         delDir = self["filelist"].getFilename()
1301                                         if path.exists(delDir):
1302                                                 os.system("rmdir '%s'"%delDir)
1303                                         if path.exists(delDir):
1304                                                 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1305                                         self.filelist.refresh()
1306                 except:
1307                         if delDir:
1308                                 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1309
1310         def exit(self):
1311                 self.close(False)
1312
1313 class MessageBoxConfirm(MessageBox):
1314         skin =  """
1315                 <screen position="center,center" size="620,10" title="Message">
1316                         <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1317                         <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1318                         <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1319                         <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1320                         <widget name="list" position="100,100" size="380,375" transparent="1" />
1321                         <applet type="onLayoutFinish">
1322 # this should be factored out into some helper code, but currently demonstrates applets.
1323 from enigma import eSize, ePoint
1324
1325 orgwidth  = self.instance.size().width()
1326 orgheight = self.instance.size().height()
1327 orgpos    = self.instance.position()
1328 textsize  = self[&quot;text&quot;].getSize()
1329
1330 # y size still must be fixed in font stuff...
1331 textsize = (textsize[0] + 50, textsize[1] + 50)
1332 offset = 0
1333 if self.type == self.TYPE_YESNO:
1334         offset = 60
1335 wsizex = textsize[0] + 60
1336 wsizey = textsize[1] + offset
1337 if (280 &gt; wsizex):
1338         wsizex = 280
1339 wsize = (wsizex, wsizey)
1340
1341 # resize
1342 self.instance.resize(eSize(*wsize))
1343
1344 # resize label
1345 self[&quot;text&quot;].instance.resize(eSize(*textsize))
1346
1347 # move list
1348 listsize = (wsizex, 50)
1349 self[&quot;list&quot;].instance.move(ePoint(0, textsize[1]))
1350 self[&quot;list&quot;].instance.resize(eSize(*listsize))
1351
1352 # center window
1353 newwidth = wsize[0]
1354 newheight = wsize[1]
1355 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1356                         </applet>
1357                 </screen>
1358                 """
1359
1360 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1361 class DeviceManagerConfig():
1362         def __init__(self):
1363                 self.configList = []
1364
1365         def getConfigList(self):
1366                 return self.configList
1367
1368         def updateConfigList(self):
1369                 try:
1370                         self.configList = []
1371                         file = open("/proc/mounts")
1372                         mounts = file.readlines()
1373                         file.close()
1374                         for x in mounts:
1375                                 if x.startswith("/dev/sd"):
1376                                         device = x.split()[0].split('/dev/')[1]
1377                                         mountpoint = x.split()[1]
1378                                         if mountpoint.startswith('/autofs'):
1379                                                 continue
1380                                         (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1381                                         if uuid != '' and mountpoint != '':
1382                                                 self.configList.append([uuid, mountpoint])
1383                         self.saveConfig()
1384                 except:
1385                         print "updateConfigList failed!"
1386
1387         def loadConfig(self):
1388                 if not fileExists(dmconfigfile):
1389                         os.system("touch %s" % dmconfigfile)
1390                 self.configList = []
1391                 data = file(dmconfigfile).read().split('\n')
1392                 for line in data:
1393                         if line.find(':') != -1:
1394                                 (uuid, mountpoint) = line.split(':')
1395                                 if uuid != '' and mountpoint != '':
1396                                         self.configList.append([uuid, mountpoint])
1397
1398         def saveConfig(self):
1399                 confFile = open(dmconfigfile,'w')
1400                 data = ""
1401                 for line in self.configList:
1402                         data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1403                 confFile.write(data)
1404                 confFile.close()
1405
1406         def appendConfig(self, uuid, mountpoint):
1407                 for x in self.configList:
1408                         if x[0] == uuid or x[1] == mountpoint:
1409                                 self.configList.remove(x)
1410                 self.configList.append([uuid, mountpoint])
1411
1412         def removeConfig(self, value):
1413                 for x in self.configList:
1414                         if x[0] == value or x[1] == value:
1415                                 self.configList.remove(x)
1416
1417 devicemanagerconfig = DeviceManagerConfig()
1418
1419 class deviceManagerHotplug:
1420         def __init__(self):
1421                 self.hotplugActive = True
1422
1423         def setHotplugActive(self,value=True):
1424                 if value:
1425                         self.hotplugActive = True
1426                 else:
1427                         self.hotplugActive = False
1428
1429         def printDebug(self):
1430                 for p in harddiskmanager.partitions:
1431                         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)
1432
1433         def doMount(self, uuid, devpath, mountpoint, filesystem):
1434 # check current device mounted on another mountpoint.
1435                 mp_list = []
1436                 mp_list = deviceinfo.checkMountDev(devpath)
1437                 for mp in mp_list:
1438                         if mp != mountpoint and path.ismount(mp):
1439                                 deviceinfo.umountByMountpoint(mp)
1440 # check another device mounted on configmountpoint
1441                 devpath_list = []
1442                 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1443                 for devpath_ in devpath_list:
1444                         if devpath_ != devpath:
1445                                 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1446                                 return
1447 # do mount
1448 #               print "[DeviceManager] doMount"
1449                 if not path.exists(mountpoint):
1450                         os.system("mkdir %s"%mountpoint)
1451                 if path.exists(mountpoint):
1452                         if not path.ismount(mountpoint):
1453                                 if filesystem == "ntfs":
1454                                         cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1455                                 elif filesystem is None:
1456                                         cmd = "mount %s %s"%(devpath, mountpoint)
1457                                 else:
1458                                         cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1459                                 print "[DeviceManager] cmd : %s"%cmd
1460                                 os.system(cmd)
1461                                 if not deviceinfo.isMounted(devpath, mountpoint):
1462                                         print "[DeviceManager] %s doMount failed!"%devpath
1463                                         return
1464                                 else:
1465 # Update partition Info, add
1466                                         self.addPartitionAutofsMountpoint(devpath, mountpoint)
1467
1468         def doUmount(self, device, mountpoint):
1469                 devpath = "/dev/"+device
1470                 mountpoints = deviceinfo.checkMountDev(devpath)
1471                 if len(mountpoints) == 0:
1472                         return
1473                 for mp in mountpoints:
1474                         cmd = "umount %s"%devpath
1475                         print "[DeviceManager] cmd : %s"%cmd
1476                         os.system(cmd)
1477
1478         def addHotPlugDevice(self, partition):
1479                 device = partition.device
1480                 devpath = "/dev/"+device
1481 # get BlkidInfo
1482                 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1483                 if uuid == "":
1484 # retry..
1485                         os.system("sleep 1")
1486                         (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1487                 if uuid == "":
1488                         print "[DeviceManagerHotplug] getBlkidInfo failed!"
1489                         return
1490 # get configList
1491                 devicemanagerconfig.loadConfig()
1492                 configList = devicemanagerconfig.getConfigList()
1493                 mountpoint = None
1494                 for line in configList:
1495                         if uuid == line[0].strip():
1496                                 mountpoint = line[1].strip()
1497                                 break
1498                 if mountpoint is None:
1499                         return
1500 # do mount
1501                 if deviceinfo.isMounted(devpath, mountpoint):
1502                         pass
1503 #                       print "[DeviceManagerHotplug] already mounted"
1504                 else:
1505                         self.doMount(uuid, devpath, mountpoint, filesystem)
1506
1507         def removeHotplugDevice(self, partition):
1508                 self.doUmount(partition.device, partition.mountpoint)
1509
1510         def getHotplugAction(self, action, partition):
1511                 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1512                         return
1513                 if partition.device is None or not partition.device.startswith("sd"):
1514                         return
1515                 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1516
1517                 if action == 'add':
1518                         self.addHotPlugDevice(partition)
1519                 elif action == 'remove':
1520                         self.removeHotplugDevice(partition)
1521
1522         def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1523                 device = path.basename(devpath)
1524                 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1525 # check already appended to partition list
1526                 for x in harddiskmanager.partitions:
1527                         if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1528                                 return
1529 #
1530                 from Components.Harddisk import Partition
1531                 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1532                 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1533                 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1534                 harddiskmanager.partitions.append(p)
1535                 harddiskmanager.on_partition_list_change("add", p)
1536
1537         def autoMountOnStartup(self):
1538                 devicemanagerconfig.loadConfig()
1539                 configList = devicemanagerconfig.getConfigList()
1540 # get blkid info
1541                 blkiddata = []
1542                 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1543                 for line in data:
1544                         devpath = uuid = filesystem = ""
1545                         devpath = line.split(':')[0]
1546                         if line.find(" UUID=") != -1:
1547                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1548                         if line.find(" TYPE=") != -1:
1549                                 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1550                         blkiddata.append((devpath, uuid, filesystem))
1551 # check configList
1552                 for c in configList:
1553                         uuid_cfg = c[0].strip()
1554                         mountpoint_cfg = c[1].strip()
1555                         for (devpath, uuid, filesystem) in blkiddata:
1556                                 if uuid_cfg == uuid:
1557 # do mount
1558                                         if deviceinfo.isMounted(devpath, mountpoint_cfg):
1559 #                                               print "[Devicemanager startup] already mounted"
1560                                                 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1561                                         else:
1562 #                                               print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1563                                                 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1564
1565         def umountOnShutdown(self):
1566                 devicemanagerconfig.loadConfig()
1567                 configList = devicemanagerconfig.getConfigList()
1568 # get mount info
1569                 mounts = []
1570                 data = file('/proc/mounts').read().split('\n')
1571                 for x in data:
1572                         if not x.startswith('/dev/sd'):
1573                                 continue
1574                         devpath, mountpoint  = x.split()[:2]
1575                         mounts.append((path.basename(devpath), mountpoint))
1576 # get blkid info
1577                 data = self.getBlkidInfo()
1578 # check configList
1579                 for c in configList:
1580                         uuid_cfg = c[0].strip()
1581                         mountpoint_cfg = c[1].strip()
1582                         device_cfg = None
1583                         if uuid_cfg in data.keys():
1584                                 device_cfg = data[uuid_cfg]
1585                         if device_cfg is None:
1586                                 continue
1587                         for (device, mountpoint) in mounts:
1588                                 if device_cfg == device:
1589                                         if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1590                                                 self.doUmount(device, mountpoint)
1591
1592         def getBlkidInfo(self):
1593                 data = {}
1594                 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1595                 for line in blkid_data.split('\n'):
1596 #                       print "[DeviceManager] getBlkidInfo line : ",line
1597                         device = uuid = ""
1598                         device = path.basename(line.split(':')[0])
1599                         if line.find(" UUID=") != -1:
1600                                 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1601                                 data[blkid_uuid] = device
1602                 return data
1603
1604 devicemanagerhotplug = deviceManagerHotplug()
1605
1606 def DeviceManagerhotplugDeviceStart(action, device):
1607         devicemanagerhotplug.getHotplugAction(action, device)
1608
1609 def callBackforDeviceManager(session, callback_result = False):
1610         if callback_result == True:
1611                 session.open(DeviceManager)
1612
1613 def checkMounts(session):
1614         try:
1615                 noMountable_dev = ""
1616                 for blockdev in listdir("/sys/block"):
1617                         devpath = "/sys/block/" + blockdev
1618                         dev = int(readFile(devpath + "/dev").split(':')[0])
1619                         if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1620                                 continue
1621                         partitions = []
1622                         noMountable_partitions = []
1623                         for partition in listdir(devpath):
1624                                 if not partition.startswith(blockdev):
1625                                         continue
1626                                 partitions.append(partition)
1627                                 if os.access('/autofs/'+partition,0) is False:
1628                                         noMountable_partitions.append(partition)
1629                         if len(partitions) == 0 or len(noMountable_partitions) != 0:
1630                                 if noMountable_dev != "":
1631                                         noMountable_dev +=  ' '
1632                                 noMountable_dev += blockdev
1633
1634                 if noMountable_dev != "":
1635                                 print "Umountable partitions found."
1636                                 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
1637                                 AddNotificationWithCallback(
1638                                                                 boundFunction(callBackforDeviceManager, session), 
1639                                                                 MessageBox, InfoText, timeout = 60, default = False
1640                                 )
1641         except:
1642                 print "checkMounts failed!"
1643
1644 def sessionstart(reason, **kwargs):
1645         if reason == 0:
1646                 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1647                         session = kwargs["session"]
1648                         checkMounts(session)
1649                 if config.plugins.devicemanager.hotplug_enable.value:
1650                         harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1651         elif reason == 1:
1652                 if config.plugins.devicemanager.hotplug_enable.value:
1653                         harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1654
1655 def autostart(reason, **kwargs):
1656         if reason == 0:
1657                 try:
1658 # check at first enigma2 start  
1659                         if not fileExists(dmconfigfile):
1660                                 print "[DeviceManager] autostart : check devices at first start"
1661                                 sda_isremovable = False
1662                                 sda_UUID = ""
1663                                 os.system("touch %s"%dmconfigfile)
1664 # check sda
1665                                 sda_data = popen("cat /proc/partitions | grep sda1").read()
1666                                 if sda_data != '':
1667                                         sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1668                                         sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1669                                         print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1670                                 cfg = ""
1671                                 if sda_data != '':
1672                                         cfg += '"%s":/media/hdd\n'%sda_UUID
1673                                 confFile = open(dmconfigfile,'w')
1674                                 confFile.write(cfg)
1675                                 confFile.close()
1676                                 if not path.exists("/media/hdd"):
1677                                         os.system("mkdir -p /media/hdd")
1678 # auto mount
1679                         devicemanagerhotplug.autoMountOnStartup()
1680                 except:
1681                         print "[DeviceManager] autostart failed!"
1682         elif reason == 1:
1683                 devicemanagerhotplug.umountOnShutdown()
1684
1685 def menu(menuid, **kwargs):
1686         if menuid == "system":
1687                 return [(_("DeviceManager"), main, "device_manager", 50)]
1688         return []
1689
1690 def main(session, **kwargs):
1691         session.open(DeviceManager)
1692
1693 def Plugins(path, **kwargs):
1694         return [
1695                 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1696                 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1697                 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1698                 ]
1699
1700 class MessageBox_2(MessageBox):
1701         def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1702                 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1703                 self.skinName = "MessageBox"
1704                 self.closeTimer = eTimer()
1705                 self.closeTimer.callback.append(self.msg_close)
1706                 self.devicemanager_ret = False
1707                 self.devicemanager_msg = ""
1708
1709         def msg_close(self):
1710                 self.close(self.devicemanager_ret, self.devicemanager_msg)
1711
1712         def run_close(self, ret, msg=""):
1713                 self.devicemanager_ret = ret
1714                 self.devicemanager_msg = msg
1715                 self.closeTimer.start(100,True)
1716
1717         def createSummary(self):
1718                 return MessageBox_2_Summary
1719
1720 class MessageBox_2_Summary(Screen):
1721         skin="""
1722                 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1723                         <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />
1724                 </screen>
1725         """
1726