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
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 _
34 config.plugins.devicemanager = ConfigSubsection()
35 config.plugins.devicemanager.hotplug_enable = ConfigEnableDisable(default=True)
36 config.plugins.devicemanager.mountcheck_enable = ConfigEnableDisable(default=True)
38 def readFile(filename):
40 data = file.read().strip()
44 def byteConversion(byte):
45 if type(byte) == str and len(byte) == 0:
47 if type(byte) != long:
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)
54 int_part = byte/1024/1024
55 dec_part = byte%(1024*1024)/1024
56 return "%d.%d MB"%(int_part, dec_part)
58 def checkStrValue(value , empty = ""):
59 if type(value) != str or len(value) == 0:
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" ],
75 "cancel": self.keyCancel,
76 "red": self.keyCancel,
77 "green": self.keySave,
79 self.onShown.append(self.setWindowTitle)
80 self.old_hotplug_enable = config.plugins.devicemanager.hotplug_enable.value
82 def setWindowTitle(self):
83 self.setTitle(_("DeviceManager configuration"))
85 def createConfigList(self):
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))
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)
96 if DeviceManagerhotplugDeviceStart in harddiskmanager.on_partition_list_change:
97 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
99 for x in self["config"].list:
103 class DeviceManager(Screen):
105 <screen position="center,center" size="590,350" 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="160,0" size="140,40" alphatest="on" />
108 <ePixmap pixmap="skin_default/buttons/yellow.png" position="300,0" size="140,40" alphatest="on" />
109 <ePixmap pixmap="skin_default/buttons/blue.png" position="440,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="160,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="300,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="440,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="590,2" alphatest="on" />
115 <widget source="menu" render="Listbox" position="0,48" size="590,350" scrollbarMode="showOnDemand">
116 <convert type="TemplatedMultiContent">
119 MultiContentEntryText(pos = (50, 0), size = (510, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor - model
120 MultiContentEntryText(pos = (50, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
121 MultiContentEntryText(pos = (170, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
122 MultiContentEntryText(pos = (290, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
123 MultiContentEntryText(pos = (410, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
124 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # png 5 is the div pixmap
127 MultiContentEntryText(pos = (50, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
128 MultiContentEntryText(pos = (50, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
129 MultiContentEntryText(pos = (50, 54), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
130 MultiContentEntryText(pos = (50, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
131 MultiContentEntryText(pos = (180, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
132 MultiContentEntryText(pos = (310, 76), size = (190, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
133 MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (590, 2), png = 6), # png 6 is the div pixmap
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 = (590, 2), png = 5), # index 5 is the div pixmap
142 "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)],
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"
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(" ")
164 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions", "MenuActions" ],
167 "cancel": self.keyCancel,
168 "red": self.keyCancel,
170 "yellow": self.keyYellow,
171 "blue": self.keyBlue,
172 "menu": self.keyMenu,
174 self.DeviceManagerConsole = Console()
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 = {}
184 def addPartitionListChange(self):
185 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
187 def removePartitionListChange(self):
188 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
190 def partitionListChanged(self, action, device):
191 print "[Device manager] hotplug partitionListChanged"
192 if self.currList != "default" and device.device[:3] != self.currDevice["blockdev"]:
194 self.showDeviceList()
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"))
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"))
207 self["key_green"].setText(_("Mount"))
209 if currentPartition["fstype"] == "":
210 self["key_blue"].setText("")
211 elif currentPartition["fstype"][:3] == "ext":
212 self["key_blue"].setText(_("Check"))
214 self["key_blue"].setText("")
216 def showDeviceList(self):
218 self["key_red"].setText(_("Close"))
219 self["key_green"].setText(_("Ok"))
220 self["key_yellow"].setText(" ")
221 self["key_blue"].setText(_("Initialize"))
223 for device in deviceinfo.getBlockDevices():
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]
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)
239 def showPartitionList(self):
240 if self.currDevice is None:
243 for partition in self.currDevice["partitions"]:
244 partitionInfo = deviceinfo.getPartitionInfo(partition)
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
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()
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)
269 def showMountPointSetup(self):
270 if self.currDevice is None or self.currPartition is None:
272 partition = self.currPartition["partition"]
273 if deviceinfo.isMountable(partition) is False:
274 self.session.open(MessageBox, _("This partition is not mountable.\nYou need to check or format this partition."), MessageBox.TYPE_ERROR, timeout = 10)
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)
297 def getCurrentDevice(self):
299 return self["menu"].getCurrent()[6]
303 def getCurrentPartition(self):
305 return self["menu"].getCurrent()[7]
311 if self.currList == "default":
312 self.currDevice = self.getCurrentDevice()
313 if self.currDevice is not None:
314 if len(self.currDevice["partitions"]) == 0:
315 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)
317 self.showPartitionList()
319 self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
320 elif self.currList == "partitions":
321 currentPartition = self.getCurrentPartition()
322 if currentPartition is not None:
323 currMountPoint = currentPartition["mountpoint"]
324 currUuid = currentPartition["uuid"]
325 if currMountPoint == "":
326 self.currPartition = currentPartition
327 self.showMountPointSetup()
329 self.doUmount(currMountPoint, self.showPartitionList)
331 self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
332 elif self.currList == "mountpoint":
333 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
334 currEntry = self["menu"].getCurrent()[3]
335 if currEntry == "default":
336 # print "Setup mountpoint default!"
337 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
338 elif currEntry == "auto":
339 # print "Setup mountpoint automatically!"
340 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
342 # print "Setup mountpoint manually!"
343 self.session.openWithCallback(self.MountpointBrowserCB, MountpointBrowser)
349 if self.DeviceManagerConsole is not None:
350 if len(self.DeviceManagerConsole.appContainers):
351 for name in self.DeviceManagerConsole.appContainers.keys():
352 self.DeviceManagerConsole.kill(name)
353 if self.currList == "partitions":
354 self.currDevice = None
355 self.showDeviceList()
356 elif self.currList == "mountpoint":
357 self.currPartition = None
358 self.showPartitionList()
359 else: # currList = "default"
363 if self.currList == "partitions":
364 self.choiceBoxFstype()
367 if self.currList == "default":
368 device = self.getCurrentDevice()
369 if device is not None:
370 self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
372 self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
373 elif self.currList == "partitions":
374 partition = self.getCurrentPartition()
375 if partition is not None:
376 self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
378 self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
381 self.session.open(DeviceManagerConfiguration)
383 def deviceInitCB(self, ret = True):
384 self.showDeviceList()
386 def deviceCheckCB(self, ret = True):
387 self.showPartitionList()
389 def deviceFormatCB(self, ret = True):
390 self.showPartitionList()
392 def choiceBoxFstype(self):
394 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
395 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
396 menu.append((_("ext4 - experimental"), "ext4"))
397 menu.append((_("vfat - for USB flash memory"), "vfat"))
398 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
400 def choiceBoxFstypeCB(self, choice):
404 partition = self.getCurrentPartition()
405 if partition is not None:
406 self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
408 self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
410 # about mount funcs..
411 def doUmount(self, mountpoint, callback):
412 cmd = "umount %s"%mountpoint
413 print "[DeviceManager] cmd : %s"%cmd
415 if not path.ismount(mountpoint):
416 devicemanagerconfig.updateConfigList()
418 self.session.open(MessageBox, _("Can't umount %s. \nMaybe device or resource busy.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
421 def getDefaultMountPoint(self):
422 return self.defaultMountPoint
424 def getAutoMountPoint(self):
425 mountPoint = "/media/"+self.currDevice["model"]
426 mountPoint = mountPoint.replace(' ','-')
427 if path.ismount(mountPoint):
430 mountPoint_fix = mountPoint+str(partnum)
431 if not path.ismount(mountPoint_fix):
434 mountPoint = mountPoint_fix
437 def doMount(self, partition, mountpoint):
439 # check mountpoint is in partition list.
440 if mountpoint != self.getDefaultMountPoint():
441 for p in harddiskmanager.partitions:
442 if p.mountpoint == mountpoint:
443 self.session.open(MessageBox, _("Can not use this mount point.(%s) \nPlease select another mount point.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
446 device = partition["partition"]
447 filesystem = partition["fstype"]
448 uuid = partition["uuid"]
449 if mountpoint.endswith("/"):
450 mountpoint = retval[:-1]
451 if mountpoint.find(' ') != -1:
452 mountpoint = mountpoint.replace(' ','-')
453 devpath = "/dev/"+device
454 if deviceinfo.isMounted(devpath, mountpoint):
455 print "[DeviceManager] '%s -> %s' is already mounted."%(devpath, mountpoint)
458 # check current device mounted on another mountpoint.
459 mp_list = deviceinfo.checkMountDev(devpath)
461 if mp != mountpoint and path.ismount(mp):
462 deviceinfo.umountByMountpoint(mp)
463 # check another device mounted on configmountpoint
464 devpath_list = deviceinfo.checkMountPoint(mountpoint)
465 for devpath_ in devpath_list:
466 if devpath_ != devpath:
467 self.session.open(MessageBox, _("Mount Failed!\nCurrent path is already mounted by \"%s\"")%devpath_list[0], MessageBox.TYPE_ERROR, timeout = 10)
470 print "[DeviceManagerHotplugDevice] doMount"
471 if not path.exists(mountpoint):
472 os.system("mkdir %s"%mountpoint)
473 if path.exists(mountpoint):
474 if not path.ismount(mountpoint):
475 if filesystem == "ntfs":
476 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
477 elif filesystem is None:
478 cmd = "mount %s %s"%(devpath, mountpoint)
480 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
481 print "[DeviceManager] cmd : %s"%cmd
482 self.DeviceManagerConsole.ePopen(cmd, self.doMountFinished, (devpath, mountpoint) )
484 self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(device, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
486 def doMountFinished(self, result, retval, extra_args = None):
487 (devpath, mountpoint) = extra_args
489 if not deviceinfo.isMounted(devpath, mountpoint):
490 # print "[DeviceManager] %s doMount failed!"%devpath
491 self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(devpath, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
494 # make movie directory
495 if mountpoint == "/media/hdd":
496 movieDir = mountpoint + "/movie"
497 if not pathExists(movieDir):
498 print "[DeviceManager] make dir %s"%movieDir
499 os.makedirs(movieDir)
500 self.showPartitionList()
501 # update current mount state ,devicemanager.cfg
502 devicemanagerconfig.updateConfigList()
504 def MountpointBrowserCB(self, retval = None):
505 if retval and retval is not None:
506 mountPoint = retval.strip().replace(' ','')
507 if retval.endswith("/"):
508 mountPoint = retval[:-1]
509 print "Mount point from MountpointBrowser : %s"%mountPoint
510 if not path.exists(mountPoint):
511 self.session.open(MessageBox, _("Mount Point is not writeable.\nPath : %s")%mountPoint, MessageBox.TYPE_ERROR, timeout = 10)
514 self.doMount(self.currPartition, mountPoint)
517 # Initializing Start...
518 class DeviceInit(Screen):
519 skin = """<screen position="0,0" size="0,0"/>"""
520 def __init__(self, session, device, devicesize):
521 Screen.__init__(self, session)
522 self.session = session
523 self.deviceInitConsole = Console()
525 self.devicesize = int(devicesize)
526 self.inputbox_partitions = 1
527 self.inputbox_partitionSizeList = []
528 self.inputbox_partitionSizeTotal = int(self.devicesize/1024/1024)
529 self.msgWaiting = None
530 self.msgWaitingMkfs = None
531 self.devicenumber = 0
532 self.newpartitions = 0
533 self.onLayoutFinish.append(self.timerStart)
534 self.initStartTimer = eTimer()
535 self.initStartTimer.callback.append(self.confirmMessage)
536 self.createFSStartTimer = eTimer()
537 self.createFSStartTimer.callback.append(self.createFilesystemStart)
538 self.exitMessageTimer = eTimer()
539 self.exitMessageTimer.callback.append(self.exitMessage)
543 self.doMkfsTimer = eTimer()
544 self.doMkfsTimer.callback.append(self.doMkfs)
545 self.doInitializeTimer = eTimer()
546 self.doInitializeTimer.callback.append(self.doInitialize)
548 self.partitionType = "MBR"
550 self.inputbox_partitionSizeRemain = self.inputbox_partitionSizeTotal
553 def timerStart(self):
554 self.initStartTimer.start(100,True)
556 def confirmMessage(self):
557 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
558 self.session.openWithCallback(self.confirmed, MessageBox, message)
560 def confirmed(self, ret):
562 self.InitializeStart()
566 def exit(self, ret = True):
569 def unmountAll(self, device):
570 mounts = file('/proc/mounts').read().split('\n')
574 if not line.startswith("/dev/" + device):
576 cmd += "umount %s ;"% line.split()[0]
577 print "[DeviceManager] %s"%cmd
580 mounts = file('/proc/mounts').read().split('\n')
582 if line.startswith("/dev/" + device):
586 def InitializeStart(self):
587 if self.devicesize >= ( 2.2 * 1000 * 1000 * 1000 * 1000 ): # 2.2TB
588 self.partitionType = "GPT"
590 self.inputbox_partitionSizeRemain = 100
593 self.InputPartitionSize_step1()
595 def InputPartitionSize_step1(self):
596 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-%d)" % self.maxPartNum), text="1", maxSize=False, type=Input.NUMBER)
598 def InputPartitionSize_step1_CB(self, ret):
599 if ret is not None and int(ret) in range(1,self.maxPartNum+1): # MBR 1~4, GPT 1~20
600 self.inputbox_partitions = int(ret)
601 self.InputPartitionSize_step2()
603 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
605 def InputPartitionSize_step2(self):
606 current_partition = len(self.inputbox_partitionSizeList)+1
607 if self.inputbox_partitionSizeRemain == 0:
608 self.choiceBoxFstype()
609 elif current_partition == self.inputbox_partitions:
610 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
611 self.choiceBoxFstype()
613 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
614 self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Unit = %s, Max = %d %s)")%(current_partition, self.unit, self.inputbox_partitionSizeRemain, self.unit), text=text, maxSize=False, type=Input.NUMBER)
616 def InputPartitionSize_step2_CB(self, ret):
618 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
619 self.InputPartitionSize_step2()
621 self.inputbox_partitionSizeList.append(str(ret))
622 self.inputbox_partitionSizeRemain -= int(ret)
623 self.InputPartitionSize_step2()
625 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
627 def choiceBoxFstype(self):
629 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
630 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
631 menu.append((_("ext4 - experimental"), "ext4"))
632 menu.append((_("vfat - for USB flash memory"), "vfat"))
633 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
635 def choiceBoxFstypeCB(self, choice):
639 self.fstype = choice[1]
640 if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
643 self.initInitializeConfirm()
645 def initInitializeConfirm(self):
646 # print self.inputbox_partitionSizeList
648 for index in range(len(self.inputbox_partitionSizeList)):
649 print "partition %d : %s %s"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
650 partitionsInfo += "partition %d : %s %s\n"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
651 partitionsInfo += "filesystem type : %s"%(self.fstype)
652 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
654 def initInitializeConfirmCB(self,ret):
656 self.initInitialize()
660 def initInitialize(self):
661 if not self.unmountAll(self.device):
662 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
664 msg = _("InitInitializing, please wait ...")
665 msg += _("\nDevice : %s")%self.device
666 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
667 for index in range(len(self.inputbox_partitionSizeList)):
668 msg += _("\npartition %d : %s %s")%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
669 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
670 self.doInitializeTimer.start(500,True)
672 def doInitialize(self):
673 def CheckPartedVer():
674 cmd = 'parted --version'
675 lines = os.popen(cmd).readlines()
677 if l.find("parted (GNU parted)") != -1:
678 ver = l.split()[3].strip()
683 print "[CheckPartedVer] check parted version Failed!"
687 partitions = len(self.inputbox_partitionSizeList) # get num of partition
689 if self.partitionType == "MBR":
691 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
695 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
699 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
701 elif self.partitionType == "GPT": # partition type is GPT
703 partedVer = CheckPartedVer()
704 if partedVer >= 2.1: # align option is supported in version 2.1 or later
705 setAlign = "--align optimal"
708 cmd = 'parted %s /dev/%s --script mklabel gpt mkpart disk ext2 0%% 100%%' % (setAlign, self.device)
709 else: # has multiple partitions
711 for p in range(partitions):
714 p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 )
716 elif p > 0 and partitions > (p + 1):
718 p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 )+ p_start
720 elif partitions == (p + 1):
727 set += 'mkpart disk%d ext2 %d%% %d%% ' % (p + 1, p_start, p_end)
728 cmd = 'parted %s /dev/%s --script mklabel gpt %s' % (setAlign, self.device, set)
730 errorMsg = "Invalid partitioning type"
731 self.msgWaiting.run_close(False, errorMsg)
733 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
735 def initInitializeFinished(self, result, retval, extra_args = None):
737 if self.partitionType == "MBR":
738 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
741 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
743 errorMsg = "initInitializing device Error at /dev/%s"%self.device
744 self.msgWaiting.run_close(False, errorMsg)
746 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
747 cmd = "/bin/umount /dev/%s*" % (self.device)
748 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
750 def initInitializingUmountFinished(self, result, retval, extra_args = None):
751 partitions = open("/proc/partitions")
752 self.devicenumber = 0
753 self.newpartitions = 0
754 for part in partitions:
755 res = re.sub("\s+", " ", part).strip().split(" ")
756 if res and len(res) == 4 and res[3][:3] == self.device:
757 if len(res[3]) > 3 and res[3][:2] == "sd":
758 self.newpartitions += 1
760 partNum = len(self.inputbox_partitionSizeList) # get num of partition
761 if self.newpartitions != partNum:
762 errorMsg = "Partitioning device Error at /dev/%s"%self.device
763 self.msgWaiting.run_close(False, errorMsg)
765 self.msgWaiting.run_close(True)
766 # self.createFilesystem(self.newpartitions)
768 def createFilesystem(self, newpartitions):
769 self.devicenumber = self.devicenumber + 1
770 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
771 shortdevicename = self.device + str(self.devicenumber)
773 partitions = open("/proc/partitions")
774 for part in partitions:
775 res = re.sub("\s+", " ", part).strip().split(" ")
776 if res and len(res) == 4:
777 if res[3] == shortdevicename:
778 partitionsize = int(res[2])
782 if self.fstype == "ext4":
783 cmd = "/sbin/mkfs.ext4 -F "
784 if partitionsize > 2 * 1024 * 1024: # 2GB
785 cmd += "-T largefile "
786 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
787 elif self.fstype == "ext3":
788 cmd = "/sbin/mkfs.ext3 -F "
789 if partitionsize > 2 * 1024 * 1024:
790 cmd += "-T largefile "
791 cmd += "-m0 " + fulldevicename
792 elif self.fstype == "ext2":
793 cmd = "/sbin/mkfs.ext2 -F "
794 if partitionsize > 2 * 1024 * 1024:
795 cmd += "-T largefile "
796 cmd += "-m0 " + fulldevicename
797 elif self.fstype == "vfat":
798 if partitionsize > 4 * 1024 * 1024 * 1024:
799 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
801 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
802 if partitionsize > 2 * 1024 * 1024: # if partiton size larger then 2GB, use FAT32
806 self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
809 msg = _("Create filesystem, please wait ...")
810 msg += _("\nPartition : %s") % (fulldevicename)
811 msg += _("\nFilesystem : %s") % (self.fstype)
812 msg += _("\nDisk Size : %s MB") % (self.inputbox_partitionSizeTotal)
813 msg += _("\nPartition Size : %d %s\n") % (int(self.inputbox_partitionSizeList[self.devicenumber-1]), self.unit)
814 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
816 self.doMkfsTimer.start(500,True)
819 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
820 self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
822 def createFilesystemFinished(self, result, retval, extra_args = None):
823 device = extra_args[0]
824 fulldevicename = extra_args[1]
826 self.msgWaitingMkfs.run_close(True)
828 errorMsg = _("Creating filesystem Error")
829 if fulldevicename is not None:
830 errorMsg += _(" at /dev/%s")%fulldevicename
831 self.msgWaitingMkfs.run_close(False, errorMsg)
833 def createFilesystemStart(self):
834 self.createFilesystem(self.newpartitions)
836 def msgWaitingCB(self, ret, msg=""):
838 self.createFSStartTimer.start(100,True)
842 self.exitMessageTimer.start(100,True)
844 def msgWaitingMkfsCB(self, ret, msg=""):
845 if self.devicenumber < self.newpartitions:
846 self.createFSStartTimer.start(100,True)
850 self.msg = _("Device Initialization finished sucessfully!")
851 self.updateDeviceInfo()
852 self.exitMessageTimer.start(100,True)
856 self.exitMessageTimer.start(100,True)
858 def exitMessage(self):
860 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
862 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
864 def updateDeviceInfo(self):
865 # update devicemanager configs
866 devicemanagerconfig.updateConfigList()
870 # device check start..
871 class DeviceCheck(Screen):
872 skin = """<screen position="0,0" size="0,0"/>"""
873 def __init__(self, session, partition):
874 Screen.__init__(self, session)
875 self.session = session
876 self.deviceCheckConsole = Console()
877 self.partition = partition
878 self.onLayoutFinish.append(self.timerStart)
879 self.checkStartTimer = eTimer()
880 self.checkStartTimer.callback.append(self.confirmMessage)
881 self.umountTimer = eTimer()
882 self.umountTimer.callback.append(self.doUnmount)
884 def timerStart(self):
885 self.checkStartTimer.start(100,True)
887 def confirmMessage(self):
888 fssize = self.partition["size"]
889 if long(fssize) > 1024*1024*1024*16:
890 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
891 self.session.openWithCallback(self.confirmed, MessageBox, message)
893 self.deviceCheckStart()
895 def confirmed(self, ret):
896 print "confirmed : ",ret
898 self.deviceCheckStart()
902 def deviceCheckStart(self):
903 print "deviceCheckStart "
904 print "partition : ", self.partition
905 device = self.partition["partition"]
906 fstype = self.partition["fstype"]
907 fssize = self.partition["size"]
908 if device is not None and fstype.startswith("ext"):
909 msg = _("Check filesystem, please wait ...")
910 msg += _("\nDevice : /dev/%s")%(device)
911 msg += _("\nFilesystem : %s")%(fstype)
912 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
913 self.umountTimer.start(500,True)
918 device = self.partition["partition"]
919 mountpoint = self.partition["mountpoint"]
920 fstype = self.partition["fstype"]
922 self.doUmountFsck(device, mountpoint, fstype)
924 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
926 def doUmountFsck(self, device, mountpoint, fstype):
927 cmd = "umount /dev/%s" % device
928 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
930 def umountFsckFinished(self, result, retval, extra_args = None):
931 device = extra_args[0]
932 mountpoint = extra_args[1]
933 fstype = extra_args[2]
935 cmd = "fsck." + fstype + " -f -p /dev/" + device
936 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
938 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
939 self.msgWaiting.run_close(False,errorMsg)
941 def fsckFinished(self, result, retval, extra_args = None):
942 device = extra_args[0]
943 mountpoint = extra_args[1]
945 text = _("Filesystem check finished sucessfully")
946 self.msgWaiting.run_close(True, text)
948 text = _("Error checking disk. The disk or filesystem may be damaged")
949 self.msgWaiting.run_close(False, text)
951 def msgWaitingCB(self, ret, msg):
953 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
955 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
957 partition = self.partition["partition"]
958 mountpoint = self.partition["mountpoint"]
959 fstype = self.partition["fstype"]
962 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
964 cmd = "mount /dev/" + partition + " " + mountpoint
965 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
969 def mountPartitionFinished(self, result, retval, extra_args = None):
978 class DeviceFormat(Screen):
979 skin = """<screen position="0,0" size="0,0"/>"""
980 def __init__(self, session, partition, newfstype):
981 Screen.__init__(self, session)
982 self.session = session
983 self.deviceFormatConsole = Console()
984 self.partition = partition
985 self.newfstype = newfstype
986 self.unmountedList = []
987 self.onLayoutFinish.append(self.timerStart)
988 self.formatStartTimer = eTimer()
989 self.formatStartTimer.callback.append(self.DeviceFormatStart)
990 self.setHotplugDisabled = False
991 self.umountTimer = eTimer()
992 self.umountTimer.callback.append(self.doUnmount)
994 def timerStart(self):
995 self.formatStartTimer.start(100,True)
997 def DeviceFormatStart(self):
998 devicemanagerhotplug.setHotplugActive(False)
999 self.setHotplugDisabled = True
1000 print "DeviceFormatStart : ", self.partition,
1001 print "Filesystem : ",self.newfstype
1002 device = self.partition["partition"]
1003 devicepath = "/dev/"+device
1004 fssize = self.partition["size"]
1005 newfstype = self.newfstype
1006 msg = _("Format filesystem, please wait ...")
1007 msg += _("\nDevice : %s")%(devicepath)
1008 msg += _("\nFilesystem : %s")%(newfstype)
1009 msg += _("\nSize : %s")%(byteConversion(fssize))
1010 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
1011 self.umountTimer.start(500,True)
1013 def doUnmount(self):
1014 mountpoint = self.partition["mountpoint"]
1015 if mountpoint != "":
1016 self.doumountPartition()
1018 self.umountPartitionFinished("NORESULT", 0)
1020 def doumountPartition(self):
1021 oldfstype = self.partition["fstype"]
1022 newfstype = self.newfstype
1024 if newfstype == oldfstype:
1025 device = self.partition["partition"]
1027 device = self.partition["partition"][:3]
1029 mounts = file('/proc/mounts','r')
1030 for line in mounts.readlines():
1031 if line.startswith("/dev/%s"%device):
1032 cmd += "umount %s;"%line.split()[0]
1033 self.unmountedList.append([line.split()[0], line.split()[1]])
1034 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
1036 def umountPartitionFinished(self, result, retval, extra_args = None):
1037 partition = self.partition["partition"]
1038 oldfstype = self.partition["fstype"]
1039 newfstype = self.newfstype
1041 if oldfstype == newfstype:
1042 self.changePartitionIDFinished("NORESULT", 0)
1044 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
1045 if newfstype[:3] == "ext":
1049 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
1051 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
1052 self.msgWaiting.run_close(False,errorMsg)
1054 def changePartitionIDFinished(self, result, retval, extra_args = None):
1055 device = self.partition["partition"][:3]
1056 mountpoint = self.partition["mountpoint"]
1057 oldfstype = self.partition["fstype"]
1058 newfstype = self.newfstype
1060 if oldfstype == newfstype:
1061 self.refreshPartitionFinished("NORESULT", 0)
1063 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
1064 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
1066 if result and result.find("Use GNU Parted") > 0:
1067 print "[DeviceManager] /dev/%s use GNU Parted!" % device
1068 self.refreshPartitionFinished("NORESULT", 0)
1070 errorMsg = _("Can not change the partition ID for %s")%device
1071 self.msgWaiting.run_close(False,errorMsg)
1073 def refreshPartitionFinished(self, result, retval, extra_args = None):
1074 print "refreshPartitionFinished!"
1075 partition = self.partition["partition"]
1076 mountpoint = self.partition["mountpoint"]
1077 size = int(self.partition["size"])/1024/1024
1078 oldfstype = self.partition["fstype"]
1079 newfstype = self.newfstype
1081 if newfstype == "ext4":
1082 cmd = "/sbin/mkfs.ext4 -F "
1084 cmd += "-T largefile "
1085 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
1086 elif newfstype == "ext3":
1087 cmd = "/sbin/mkfs.ext3 -F "
1089 cmd += "-T largefile "
1090 cmd += "-m0 /dev/" + partition
1091 elif newfstype == "ext2":
1092 cmd = "/sbin/mkfs.ext2 -F "
1094 cmd += "-T largefile "
1095 cmd += "-m0 /dev/" + partition
1096 elif newfstype == "vfat":
1097 if size > 4 * 1024 * 1024:
1098 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
1100 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
1101 if size > 2 * 1024: # if partiton size larger then 2GB, use FAT32
1103 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
1105 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
1106 self.msgWaiting.run_close(False,errorMsg)
1108 def mkfsFinished(self, result, retval, extra_args = None):
1109 print "mkfsFinished!"
1110 partition = self.partition["partition"]
1113 if len(self.unmountedList) == 0:
1114 self.doMountFinished("NORESULT",0)
1115 for x in self.unmountedList:
1116 cmd += "mount %s %s;"%(x[0], x[1])
1117 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1119 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1120 self.msgWaiting.run_close(False, text)
1122 def doMountFinished(self, result, retval, extra_args = None):
1123 print "doMountFinished!"
1124 text = _("Format finished sucessfully.")
1125 self.msgWaiting.run_close(True, text)
1127 def msgWaitingCB(self, ret, msg):
1129 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1131 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1133 def exit(self, ret):
1134 if self.setHotplugDisabled == True:
1135 devicemanagerhotplug.setHotplugActive(True)
1136 self.setHotplugDisabled = False
1143 self.blockDeviceList = []
1145 def getBlockDevices(self):
1146 return self.blockDeviceList
1149 self.blockDeviceList = []
1150 self.getBlockDeviceList()
1152 def getBlockDeviceList(self):
1153 print "get block device Infomations..."
1154 for blockdev in listdir("/sys/block"):
1155 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1156 if not blacklisted and not error:
1157 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1159 blockDevice["blockdev"] = blockdev # str
1160 blockDevice["removable"] = removable # bool [True, False]
1161 blockDevice["partitions"] = partitions # list
1162 blockDevice["size"] = size # str
1163 blockDevice["model"] = model # str
1164 blockDevice["vendor"] = vendor # str
1165 self.blockDeviceList.append(blockDevice)
1167 def SortPartList(self, partList):
1168 length = len(partList)-1
1170 while sorted is False:
1172 for idx in range(length):
1173 if int(partList[idx][3:]) > int(partList[idx+1][3:]):
1175 partList[idx] , partList[idx+1] = partList[idx+1], partList[idx]
1177 def getBlockDeviceInfo(self, blockdev):
1178 devpath = "/sys/block/" + blockdev
1187 dev = int(readFile(devpath + "/dev").split(':')[0])
1188 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1190 return error, blacklisted, removable, partitions, size, model, vendor
1191 removable = bool(int(readFile(devpath + "/removable")))
1192 size = str(int(readFile(devpath + "/size").strip())*512)
1193 model = readFile(devpath + "/device/model")
1194 vendor = readFile(devpath + "/device/vendor")
1195 for partition in listdir(devpath):
1196 if partition[:len(blockdev)] != blockdev:
1198 partitions.append(partition)
1199 self.SortPartList(partitions)
1203 return error, blacklisted, removable, partitions, size, model, vendor
1205 def getPartitionInfo(self, partition):
1206 mountPoint = self.getPartitionMountpoint(partition)
1207 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1208 size_total = self.getPartitionSize(partition)
1210 if mountPoint != "":
1211 size_free = self.getPartitionFree(mountPoint)
1213 partitionInfo["partition"] = partition
1214 partitionInfo["mountpoint"] = mountPoint
1215 partitionInfo["uuid"] = uuid
1216 partitionInfo["fstype"] = fsType
1217 partitionInfo["size"] = size_total
1218 partitionInfo["free"] = size_free
1219 return partitionInfo
1221 def getPartitionMountpoint(self, partition):
1222 mounts = file('/proc/mounts').read().split('\n')
1224 if not x.startswith('/'):
1226 devpath, mountpoint, = x.split()[:2]
1227 if mountpoint.startswith('/autofs'):
1229 if path.basename(devpath) == partition:
1233 def getPartitionBlkidInfo(self, partition):
1234 parttionDev = "/dev/"+str(partition)
1237 cmd = "blkid -c /dev/null "+str(parttionDev)
1239 line = popen(cmd).readline().strip()
1240 if not line.startswith(parttionDev):
1241 return (uuid, partitionType)
1242 # print "Blikd %s : %s"%(parttionDev, line)
1243 if line.find(" UUID=") != -1:
1244 uuid = line.split(" UUID=")[1].split(' ')[0]
1245 if line.find(" TYPE=") != -1:
1246 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1248 print "get blkid info error (%s)"%cmd
1249 return (uuid, partitionType)
1251 def getPartitionSize(self, partition):
1252 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1254 size = readFile(devpath + "/size")
1255 return str(int(size)*512)
1259 def getPartitionFree(self, mountPoint):
1261 stat = statvfs(mountPoint)
1262 size_free = stat.f_bfree*stat.f_bsize
1267 def checkMountPoint(self, check_mountpoint):
1270 mounts = file('/proc/mounts').read().split('\n')
1272 if not x.startswith('/'):
1274 devpath, mountpoint = x.split()[:2]
1275 if mountpoint == check_mountpoint:
1281 def checkMountDev(self, device):
1284 mounts = file('/proc/mounts').read().split('\n')
1286 if not x.startswith('/'):
1288 devpath, mountpoint = x.split()[:2]
1289 if devpath == device:
1290 res.append(mountpoint)
1295 def isMounted(self, devpath, mountpoint):
1297 mounts = file('/proc/mounts').readlines()
1299 if not x.startswith('/'):
1301 _devpath, _mountpoint = x.split()[:2]
1302 if devpath == _devpath and mountpoint == _mountpoint:
1308 def isMounted_anymp(self, devpath):
1310 mounts = open('/proc/mounts', 'r').readlines()
1312 if not x.startswith('/'):
1314 _devPart, _mountpoint = x.split()[:2]
1315 if devpath == _devPart:
1321 # check partition type is extended or swap.
1322 def checkSwapExtended(self, partition):
1323 blockName = partition[:-1]
1324 partNum = partition[-1]
1325 data = os.popen("parted /dev/%s print" % blockName).readlines()
1327 info = x.strip().split()
1329 if len(info) > 0 and info[0] == str(partNum):
1330 if len(info) >= 5 and info[4].find('extended') != -1: # check Type is extended
1332 elif len(info) >= 6 and info[5].find('swap') != -1: # check File System is swap
1337 def isMountable(self, partition):
1338 if self.checkSwapExtended(partition):
1342 if self.isMounted_anymp('/dev/'+partition):
1345 elif os.access('/autofs/'+partition, 0):
1351 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1352 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1353 if mountpoint[-1] == '/':
1354 mountpoint = mountpoint[:-1]
1355 data = file('/etc/fstab').read().split('\n')
1357 if not line.startswith('/'):
1359 dev, mp, ms = line.split()[0:3]
1360 if uuid is not None and dev.startswith('UUID'):
1361 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1362 # print " >> line : ", line
1364 elif dev == devpath and mp == mountpoint and ms == 'auto':
1365 # print " >> line : ", line
1369 def umountByMountpoint(self, mountpoint):
1370 if mountpoint is None:
1373 if path.ismount(mountpoint):
1374 cmd = "umount " + mountpoint
1375 print "[DeviceManager] ", cmd
1378 print "Umount by mountpoint failed!"
1379 if not path.ismount(mountpoint):
1383 def umountByDevpath(self, devpath):
1384 cmd = "umount " + devpath
1385 print "[DeviceManager] ", cmd
1388 deviceinfo = DeviceInfo()
1390 class MountpointBrowser(Screen):
1392 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1393 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1394 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1395 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1396 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1397 <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" />
1398 <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" />
1399 <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" />
1400 <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" />
1401 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1402 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1405 def __init__(self, session):
1406 Screen.__init__(self, session)
1407 self["key_red"] = StaticText(_("Cancel"))
1408 self["key_green"] = StaticText(_("Select"))
1409 self["key_yellow"] = StaticText(_("Create directory"))
1410 self["key_blue"] = StaticText("Delete directory")
1411 directory = "/media/"
1412 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1413 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1414 self["filelist"] = self.filelist
1416 self["shortcuts"] = ActionMap(["ColorActions"],
1419 "green": self.select,
1420 "yellow": self.createDirectory,
1421 "blue": self.deleteDirectory,
1424 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1426 "cancel": self.exit,
1431 if self.filelist.canDescent():
1432 self.filelist.descent()
1435 if self["filelist"].getCurrentDirectory() is not None:
1436 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1437 self.filelist.descent()
1438 currDir = self["filelist"].getCurrentDirectory()
1441 self.close(self["filelist"].getFilename())
1443 def createDirectory(self):
1444 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1446 def createDirectoryCB(self, retval = None):
1449 if retval is not None:
1450 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1451 if not path.exists(newdir):
1452 os.system("mkdir %s"%newdir)
1453 self.filelist.refresh()
1456 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1458 def deleteDirectory(self):
1461 if self["filelist"].getCurrentDirectory() is not None:
1462 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1463 delDir = self["filelist"].getFilename()
1464 if path.exists(delDir):
1465 os.system("rmdir '%s'"%delDir)
1466 if path.exists(delDir):
1467 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1468 self.filelist.refresh()
1471 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1476 class MessageBoxConfirm(MessageBox):
1478 <screen position="center,center" size="620,10" title="Message">
1479 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1480 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1481 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1482 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1483 <widget name="list" position="100,100" size="380,375" transparent="1" />
1484 <applet type="onLayoutFinish">
1485 # this should be factored out into some helper code, but currently demonstrates applets.
1486 from enigma import eSize, ePoint
1488 orgwidth = self.instance.size().width()
1489 orgheight = self.instance.size().height()
1490 orgpos = self.instance.position()
1491 textsize = self["text"].getSize()
1493 # y size still must be fixed in font stuff...
1494 textsize = (textsize[0] + 50, textsize[1] + 50)
1496 if self.type == self.TYPE_YESNO:
1498 wsizex = textsize[0] + 60
1499 wsizey = textsize[1] + offset
1500 if (280 > wsizex):
1502 wsize = (wsizex, wsizey)
1505 self.instance.resize(eSize(*wsize))
1508 self["text"].instance.resize(eSize(*textsize))
1511 listsize = (wsizex, 50)
1512 self["list"].instance.move(ePoint(0, textsize[1]))
1513 self["list"].instance.resize(eSize(*listsize))
1517 newheight = wsize[1]
1518 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1523 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1524 class DeviceManagerConfig():
1526 self.configList = []
1528 def getConfigList(self):
1529 return self.configList
1531 def updateConfigList(self):
1533 self.configList = []
1534 file = open("/proc/mounts")
1535 mounts = file.readlines()
1538 if x.startswith("/dev/sd"):
1539 device = x.split()[0].split('/dev/')[1]
1540 mountpoint = x.split()[1]
1541 if mountpoint.startswith('/autofs'):
1543 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1544 if uuid != '' and mountpoint != '':
1545 self.configList.append([uuid, mountpoint])
1548 print "updateConfigList failed!"
1550 def loadConfig(self):
1551 if not fileExists(dmconfigfile):
1552 os.system("touch %s" % dmconfigfile)
1553 self.configList = []
1554 data = file(dmconfigfile).read().split('\n')
1556 if line.find(':') != -1:
1557 (uuid, mountpoint) = line.split(':')
1558 if uuid != '' and mountpoint != '':
1559 self.configList.append([uuid, mountpoint])
1561 def saveConfig(self):
1562 confFile = open(dmconfigfile,'w')
1564 for line in self.configList:
1565 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1566 confFile.write(data)
1569 def appendConfig(self, uuid, mountpoint):
1570 for x in self.configList:
1571 if x[0] == uuid or x[1] == mountpoint:
1572 self.configList.remove(x)
1573 self.configList.append([uuid, mountpoint])
1575 def removeConfig(self, value):
1576 for x in self.configList:
1577 if x[0] == value or x[1] == value:
1578 self.configList.remove(x)
1580 devicemanagerconfig = DeviceManagerConfig()
1582 class deviceManagerHotplug:
1584 self.hotplugActive = True
1586 def setHotplugActive(self,value=True):
1588 self.hotplugActive = True
1590 self.hotplugActive = False
1592 def printDebug(self):
1593 for p in harddiskmanager.partitions:
1594 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)
1596 def doMount(self, uuid, devpath, mountpoint, filesystem):
1597 # check current device mounted on another mountpoint.
1599 mp_list = deviceinfo.checkMountDev(devpath)
1601 if mp != mountpoint and path.ismount(mp):
1602 deviceinfo.umountByMountpoint(mp)
1603 # check another device mounted on configmountpoint
1605 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1606 for devpath_ in devpath_list:
1607 if devpath_ != devpath:
1608 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1611 # print "[DeviceManager] doMount"
1612 if not path.exists(mountpoint):
1613 os.system("mkdir %s"%mountpoint)
1614 if path.exists(mountpoint):
1615 if not path.ismount(mountpoint):
1616 if filesystem == "ntfs":
1617 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1618 elif filesystem is None:
1619 cmd = "mount %s %s"%(devpath, mountpoint)
1621 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1622 print "[DeviceManager] cmd : %s"%cmd
1624 if not deviceinfo.isMounted(devpath, mountpoint):
1625 print "[DeviceManager] %s doMount failed!"%devpath
1628 # Update partition Info, add
1629 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1631 def doUmount(self, device, mountpoint):
1632 devpath = "/dev/"+device
1633 mountpoints = deviceinfo.checkMountDev(devpath)
1634 if len(mountpoints) == 0:
1636 for mp in mountpoints:
1637 cmd = "umount %s"%devpath
1638 print "[DeviceManager] cmd : %s"%cmd
1641 def addHotPlugDevice(self, partition):
1642 device = partition.device
1643 devpath = "/dev/"+device
1645 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1648 os.system("sleep 1")
1649 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1651 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1654 devicemanagerconfig.loadConfig()
1655 configList = devicemanagerconfig.getConfigList()
1657 for line in configList:
1658 if uuid == line[0].strip():
1659 mountpoint = line[1].strip()
1661 if mountpoint is None:
1664 if deviceinfo.isMounted(devpath, mountpoint):
1666 # print "[DeviceManagerHotplug] already mounted"
1668 self.doMount(uuid, devpath, mountpoint, filesystem)
1670 def removeHotplugDevice(self, partition):
1671 self.doUmount(partition.device, partition.mountpoint)
1673 def getHotplugAction(self, action, partition):
1674 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1676 if partition.device is None or not partition.device.startswith("sd"):
1678 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1681 self.addHotPlugDevice(partition)
1682 elif action == 'remove':
1683 self.removeHotplugDevice(partition)
1685 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1686 device = path.basename(devpath)
1687 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1688 # check already appended to partition list
1689 for x in harddiskmanager.partitions:
1690 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1693 from Components.Harddisk import Partition
1694 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1695 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1696 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1697 harddiskmanager.partitions.append(p)
1698 harddiskmanager.on_partition_list_change("add", p)
1700 def autoMountOnStartup(self):
1701 devicemanagerconfig.loadConfig()
1702 configList = devicemanagerconfig.getConfigList()
1705 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1707 devpath = uuid = filesystem = ""
1708 devpath = line.split(':')[0]
1709 if line.find(" UUID=") != -1:
1710 uuid = line.split(" UUID=")[1].split(' ')[0]
1711 if line.find(" TYPE=") != -1:
1712 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1713 blkiddata.append((devpath, uuid, filesystem))
1715 for c in configList:
1716 uuid_cfg = c[0].strip()
1717 mountpoint_cfg = c[1].strip()
1718 for (devpath, uuid, filesystem) in blkiddata:
1719 if uuid_cfg == uuid:
1721 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1722 # print "[Devicemanager startup] already mounted"
1723 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1725 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1726 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1728 def umountOnShutdown(self):
1729 devicemanagerconfig.loadConfig()
1730 configList = devicemanagerconfig.getConfigList()
1733 data = file('/proc/mounts').read().split('\n')
1735 if not x.startswith('/dev/sd'):
1737 devpath, mountpoint = x.split()[:2]
1738 mounts.append((path.basename(devpath), mountpoint))
1740 data = self.getBlkidInfo()
1742 for c in configList:
1743 uuid_cfg = c[0].strip()
1744 mountpoint_cfg = c[1].strip()
1746 if uuid_cfg in data.keys():
1747 device_cfg = data[uuid_cfg]
1748 if device_cfg is None:
1750 for (device, mountpoint) in mounts:
1751 if device_cfg == device:
1752 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1753 self.doUmount(device, mountpoint)
1755 def getBlkidInfo(self):
1757 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1758 for line in blkid_data.split('\n'):
1759 # print "[DeviceManager] getBlkidInfo line : ",line
1761 device = path.basename(line.split(':')[0])
1762 if line.find(" UUID=") != -1:
1763 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1764 data[blkid_uuid] = device
1767 devicemanagerhotplug = deviceManagerHotplug()
1769 def DeviceManagerhotplugDeviceStart(action, device):
1770 devicemanagerhotplug.getHotplugAction(action, device)
1772 def callBackforDeviceManager(session, callback_result = False):
1773 if callback_result == True:
1774 session.open(DeviceManager)
1776 def checkMounts(session):
1778 noMountable_dev = ""
1779 for blockdev in listdir("/sys/block"):
1780 devpath = "/sys/block/" + blockdev
1781 dev = int(readFile(devpath + "/dev").split(':')[0])
1782 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1785 noMountable_partitions = []
1786 for partition in listdir(devpath):
1787 if not partition.startswith(blockdev):
1790 if deviceinfo.checkSwapExtended(partition):
1793 partitions.append(partition)
1795 if deviceinfo.isMounted_anymp('/dev/' + partition):
1798 if os.access('/autofs/'+partition, 0) is False:
1799 noMountable_partitions.append(partition)
1801 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1802 if noMountable_dev != "":
1803 noMountable_dev += ' '
1804 noMountable_dev += blockdev
1806 if noMountable_dev != "":
1807 print "Umountable partitions found."
1808 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
1809 AddNotificationWithCallback(
1810 boundFunction(callBackforDeviceManager, session),
1811 MessageBox, InfoText, timeout = 60, default = False
1814 print "checkMounts failed!"
1816 def sessionstart(reason, **kwargs):
1818 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1819 session = kwargs["session"]
1820 checkMounts(session)
1821 if config.plugins.devicemanager.hotplug_enable.value:
1822 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1824 if config.plugins.devicemanager.hotplug_enable.value:
1825 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1827 def autostart(reason, **kwargs):
1830 # check at first enigma2 start
1831 if not fileExists(dmconfigfile):
1832 print "[DeviceManager] autostart : check devices at first start"
1833 sda_isremovable = False
1835 os.system("touch %s"%dmconfigfile)
1837 sda_data = popen("cat /proc/partitions | grep sda1").read()
1839 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1840 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1841 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1844 cfg += '"%s":/media/hdd\n'%sda_UUID
1845 confFile = open(dmconfigfile,'w')
1848 if not path.exists("/media/hdd"):
1849 os.system("mkdir -p /media/hdd")
1851 devicemanagerhotplug.autoMountOnStartup()
1853 print "[DeviceManager] autostart failed!"
1855 devicemanagerhotplug.umountOnShutdown()
1857 def menu(menuid, **kwargs):
1858 if menuid == "system":
1859 return [(_("DeviceManager"), main, "device_manager", 50)]
1862 def main(session, **kwargs):
1863 session.open(DeviceManager)
1865 def Plugins(path, **kwargs):
1867 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1868 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1869 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1872 class MessageBox_2(MessageBox):
1873 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1874 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1875 self.skinName = "MessageBox"
1876 self.closeTimer = eTimer()
1877 self.closeTimer.callback.append(self.msg_close)
1878 self.devicemanager_ret = False
1879 self.devicemanager_msg = ""
1881 def msg_close(self):
1882 self.close(self.devicemanager_ret, self.devicemanager_msg)
1884 def run_close(self, ret, msg=""):
1885 self.devicemanager_ret = ret
1886 self.devicemanager_msg = msg
1887 self.closeTimer.start(100,True)
1889 def createSummary(self):
1890 return MessageBox_2_Summary
1892 class MessageBox_2_Summary(Screen):
1894 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1895 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />