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 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)
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 = self.inputbox_partitionSizeRemain = 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 def timerStart(self):
549 self.initStartTimer.start(100,True)
551 def confirmMessage(self):
552 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
553 self.session.openWithCallback(self.confirmed, MessageBox, message)
555 def confirmed(self, ret):
557 self.InitializeStart()
561 def exit(self, ret = True):
564 def unmountAll(self, device):
565 mounts = file('/proc/mounts').read().split('\n')
569 if not line.startswith("/dev/" + device):
571 cmd += "umount %s ;"% line.split()[0]
572 print "[DeviceManager] %s"%cmd
575 mounts = file('/proc/mounts').read().split('\n')
577 if line.startswith("/dev/" + device):
581 def InitializeStart(self):
582 self.InputPartitionSize_step1()
584 def InputPartitionSize_step1(self):
585 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
587 def InputPartitionSize_step1_CB(self, ret):
588 if ret is not None and int(ret) in range(1,5): # ret in 1~4
589 self.inputbox_partitions = int(ret)
590 self.InputPartitionSize_step2()
592 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
594 def InputPartitionSize_step2(self):
595 current_partition = len(self.inputbox_partitionSizeList)+1
596 if self.inputbox_partitionSizeRemain == 0:
597 self.choiceBoxFstype()
598 elif current_partition == self.inputbox_partitions:
599 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
600 self.choiceBoxFstype()
602 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
603 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)
605 def InputPartitionSize_step2_CB(self, ret):
607 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
608 self.InputPartitionSize_step2()
610 self.inputbox_partitionSizeList.append(str(ret))
611 self.inputbox_partitionSizeRemain -= int(ret)
612 self.InputPartitionSize_step2()
614 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
616 def choiceBoxFstype(self):
618 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
619 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
620 menu.append((_("ext4 - experimental"), "ext4"))
621 menu.append((_("vfat - for USB flash memory"), "vfat"))
622 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
624 def choiceBoxFstypeCB(self, choice):
628 self.fstype = choice[1]
629 if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
632 self.initInitializeConfirm()
634 def initInitializeConfirm(self):
635 # print self.inputbox_partitionSizeList
637 for index in range(len(self.inputbox_partitionSizeList)):
638 print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
639 partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
640 partitionsInfo += "filesystem type : %s"%(self.fstype)
641 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
643 def initInitializeConfirmCB(self,ret):
645 self.initInitialize()
649 def initInitialize(self):
650 if not self.unmountAll(self.device):
651 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
653 msg = _("InitInitializing, please wait ...")
654 msg += _("\nDevice : %s")%self.device
655 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
656 for index in range(len(self.inputbox_partitionSizeList)):
657 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
658 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
659 self.doInitializeTimer.start(500,True)
661 def doInitialize(self):
663 partitions = len(self.inputbox_partitionSizeList)
665 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
669 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
673 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
674 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
676 def initInitializeFinished(self, result, retval, extra_args = None):
678 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
679 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
681 errorMsg = "initInitializing device Error at /dev/%s"%self.device
682 self.msgWaiting.run_close(False, errorMsg)
684 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
685 cmd = "/bin/umount /dev/%s*" % (self.device)
686 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
688 def initInitializingUmountFinished(self, result, retval, extra_args = None):
689 partitions = open("/proc/partitions")
690 self.devicenumber = 0
691 self.newpartitions = 0
692 for part in partitions:
693 res = re.sub("\s+", " ", part).strip().split(" ")
694 if res and len(res) == 4 and res[3][:3] == self.device:
695 if len(res[3]) > 3 and res[3][:2] == "sd":
696 self.newpartitions += 1
698 self.msgWaiting.run_close(True)
699 # self.createFilesystem(self.newpartitions)
701 def createFilesystem(self, newpartitions):
702 self.devicenumber = self.devicenumber + 1
703 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
704 shortdevicename = self.device + str(self.devicenumber)
706 partitions = open("/proc/partitions")
707 for part in partitions:
708 res = re.sub("\s+", " ", part).strip().split(" ")
709 if res and len(res) == 4:
710 if res[3] == shortdevicename:
711 partitionsize = int(res[2])
715 if self.fstype == "ext4":
716 cmd = "/sbin/mkfs.ext4 -F "
717 if partitionsize > 2 * 1024 * 1024: # 2GB
718 cmd += "-T largefile "
719 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
720 elif self.fstype == "ext3":
721 cmd = "/sbin/mkfs.ext3 -F "
722 if partitionsize > 2 * 1024 * 1024:
723 cmd += "-T largefile "
724 cmd += "-m0 " + fulldevicename
725 elif self.fstype == "ext2":
726 cmd = "/sbin/mkfs.ext2 -F "
727 if partitionsize > 2 * 1024 * 1024:
728 cmd += "-T largefile "
729 cmd += "-m0 " + fulldevicename
730 elif self.fstype == "vfat":
731 if partitionsize > 4 * 1024 * 1024 * 1024:
732 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
734 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
736 self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
739 msg = _("Create filesystem, please wait ...")
740 msg += _("\nPartition : %s") % (fulldevicename)
741 msg += _("\nFilesystem : %s") % (self.fstype)
742 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
743 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
745 self.doMkfsTimer.start(500,True)
748 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
749 self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
751 def createFilesystemFinished(self, result, retval, extra_args = None):
752 device = extra_args[0]
753 fulldevicename = extra_args[1]
755 self.msgWaitingMkfs.run_close(True)
757 errorMsg = _("Creating filesystem Error")
758 if fulldevicename is not None:
759 errorMsg += _(" at /dev/%s")%fulldevicename
760 self.msgWaitingMkfs.run_close(False, errorMsg)
762 def createFilesystemStart(self):
763 self.createFilesystem(self.newpartitions)
765 def msgWaitingCB(self, ret, msg=""):
767 self.createFSStartTimer.start(100,True)
771 self.exitMessageTimer.start(100,True)
773 def msgWaitingMkfsCB(self, ret, msg=""):
774 if self.devicenumber < self.newpartitions:
775 self.createFSStartTimer.start(100,True)
779 self.msg = _("Device Initialization finished sucessfully!")
780 self.updateDeviceInfo()
781 self.exitMessageTimer.start(100,True)
785 self.exitMessageTimer.start(100,True)
787 def exitMessage(self):
789 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
791 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
793 def updateDeviceInfo(self):
794 # update devicemanager configs
795 devicemanagerconfig.updateConfigList()
799 # device check start..
800 class DeviceCheck(Screen):
801 skin = """<screen position="0,0" size="0,0"/>"""
802 def __init__(self, session, partition):
803 Screen.__init__(self, session)
804 self.session = session
805 self.deviceCheckConsole = Console()
806 self.partition = partition
807 self.onLayoutFinish.append(self.timerStart)
808 self.checkStartTimer = eTimer()
809 self.checkStartTimer.callback.append(self.confirmMessage)
810 self.umountTimer = eTimer()
811 self.umountTimer.callback.append(self.doUnmount)
813 def timerStart(self):
814 self.checkStartTimer.start(100,True)
816 def confirmMessage(self):
817 fssize = self.partition["size"]
818 if long(fssize) > 1024*1024*1024*16:
819 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
820 self.session.openWithCallback(self.confirmed, MessageBox, message)
822 self.deviceCheckStart()
824 def confirmed(self, ret):
825 print "confirmed : ",ret
827 self.deviceCheckStart()
831 def deviceCheckStart(self):
832 print "deviceCheckStart "
833 print "partition : ", self.partition
834 device = self.partition["partition"]
835 fstype = self.partition["fstype"]
836 fssize = self.partition["size"]
837 if device is not None and fstype.startswith("ext"):
838 msg = _("Check filesystem, please wait ...")
839 msg += _("\nDevice : /dev/%s")%(device)
840 msg += _("\nFilesystem : %s")%(fstype)
841 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
842 self.umountTimer.start(500,True)
847 device = self.partition["partition"]
848 mountpoint = self.partition["mountpoint"]
849 fstype = self.partition["fstype"]
851 self.doUmountFsck(device, mountpoint, fstype)
853 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
855 def doUmountFsck(self, device, mountpoint, fstype):
856 cmd = "umount /dev/%s" % device
857 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
859 def umountFsckFinished(self, result, retval, extra_args = None):
860 device = extra_args[0]
861 mountpoint = extra_args[1]
862 fstype = extra_args[2]
864 cmd = "fsck." + fstype + " -f -p /dev/" + device
865 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
867 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
868 self.msgWaiting.run_close(False,errorMsg)
870 def fsckFinished(self, result, retval, extra_args = None):
871 device = extra_args[0]
872 mountpoint = extra_args[1]
874 text = _("Filesystem check finished sucessfully")
875 self.msgWaiting.run_close(True, text)
877 text = _("Error checking disk. The disk or filesystem may be damaged")
878 self.msgWaiting.run_close(False, text)
880 def msgWaitingCB(self, ret, msg):
882 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
884 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
886 partition = self.partition["partition"]
887 mountpoint = self.partition["mountpoint"]
888 fstype = self.partition["fstype"]
891 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
893 cmd = "mount /dev/" + partition + " " + mountpoint
894 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
898 def mountPartitionFinished(self, result, retval, extra_args = None):
907 class DeviceFormat(Screen):
908 skin = """<screen position="0,0" size="0,0"/>"""
909 def __init__(self, session, partition, newfstype):
910 Screen.__init__(self, session)
911 self.session = session
912 self.deviceFormatConsole = Console()
913 self.partition = partition
914 self.newfstype = newfstype
915 self.unmountedList = []
916 self.onLayoutFinish.append(self.timerStart)
917 self.formatStartTimer = eTimer()
918 self.formatStartTimer.callback.append(self.DeviceFormatStart)
919 self.setHotplugDisabled = False
920 self.umountTimer = eTimer()
921 self.umountTimer.callback.append(self.doUnmount)
923 def timerStart(self):
924 self.formatStartTimer.start(100,True)
926 def DeviceFormatStart(self):
927 devicemanagerhotplug.setHotplugActive(False)
928 self.setHotplugDisabled = True
929 print "DeviceFormatStart : ", self.partition,
930 print "Filesystem : ",self.newfstype
931 device = self.partition["partition"]
932 devicepath = "/dev/"+device
933 fssize = self.partition["size"]
934 newfstype = self.newfstype
935 msg = _("Format filesystem, please wait ...")
936 msg += _("\nDevice : %s")%(devicepath)
937 msg += _("\nFilesystem : %s")%(newfstype)
938 msg += _("\nSize : %s")%(byteConversion(fssize))
939 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
940 self.umountTimer.start(500,True)
943 mountpoint = self.partition["mountpoint"]
945 self.doumountPartition()
947 self.umountPartitionFinished("NORESULT", 0)
949 def doumountPartition(self):
950 oldfstype = self.partition["fstype"]
951 newfstype = self.newfstype
953 if newfstype == oldfstype:
954 device = self.partition["partition"]
956 device = self.partition["partition"][:3]
958 mounts = file('/proc/mounts','r')
959 for line in mounts.readlines():
960 if line.startswith("/dev/%s"%device):
961 cmd += "umount %s;"%line.split()[0]
962 self.unmountedList.append([line.split()[0], line.split()[1]])
963 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
965 def umountPartitionFinished(self, result, retval, extra_args = None):
966 partition = self.partition["partition"]
967 oldfstype = self.partition["fstype"]
968 newfstype = self.newfstype
970 if oldfstype == newfstype:
971 self.changePartitionIDFinished("NORESULT", 0)
973 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
974 if newfstype[:3] == "ext":
978 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
980 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
981 self.msgWaiting.run_close(False,errorMsg)
983 def changePartitionIDFinished(self, result, retval, extra_args = None):
984 device = self.partition["partition"][:3]
985 mountpoint = self.partition["mountpoint"]
986 oldfstype = self.partition["fstype"]
987 newfstype = self.newfstype
989 if oldfstype == newfstype:
990 self.refreshPartitionFinished("NORESULT", 0)
992 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
993 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
995 errorMsg = _("Can not change the partition ID for %s")%device
996 self.msgWaiting.run_close(False,errorMsg)
998 def refreshPartitionFinished(self, result, retval, extra_args = None):
999 print "refreshPartitionFinished!"
1000 partition = self.partition["partition"]
1001 mountpoint = self.partition["mountpoint"]
1002 size = int(self.partition["size"])/1024/1024
1003 oldfstype = self.partition["fstype"]
1004 newfstype = self.newfstype
1006 if newfstype == "ext4":
1007 cmd = "/sbin/mkfs.ext4 -F "
1009 cmd += "-T largefile "
1010 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
1011 elif newfstype == "ext3":
1012 cmd = "/sbin/mkfs.ext3 -F "
1014 cmd += "-T largefile "
1015 cmd += "-m0 /dev/" + partition
1016 elif newfstype == "ext2":
1017 cmd = "/sbin/mkfs.ext2 -F "
1019 cmd += "-T largefile "
1020 cmd += "-m0 /dev/" + partition
1021 elif newfstype == "vfat":
1022 if size > 4 * 1024 * 1024:
1023 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
1025 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
1026 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
1028 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
1029 self.msgWaiting.run_close(False,errorMsg)
1031 def mkfsFinished(self, result, retval, extra_args = None):
1032 print "mkfsFinished!"
1033 partition = self.partition["partition"]
1036 if len(self.unmountedList) == 0:
1037 self.doMountFinished("NORESULT",0)
1038 for x in self.unmountedList:
1039 cmd += "mount %s %s;"%(x[0], x[1])
1040 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1042 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1043 self.msgWaiting.run_close(False, text)
1045 def doMountFinished(self, result, retval, extra_args = None):
1046 print "doMountFinished!"
1047 text = _("Format finished sucessfully.")
1048 self.msgWaiting.run_close(True, text)
1050 def msgWaitingCB(self, ret, msg):
1052 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1054 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1056 def exit(self, ret):
1057 if self.setHotplugDisabled == True:
1058 devicemanagerhotplug.setHotplugActive(True)
1059 self.setHotplugDisabled = False
1066 self.blockDeviceList = []
1068 def getBlockDevices(self):
1069 return self.blockDeviceList
1072 self.blockDeviceList = []
1073 self.getBlockDeviceList()
1075 def getBlockDeviceList(self):
1076 print "get block device Infomations..."
1077 for blockdev in listdir("/sys/block"):
1078 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1079 if not blacklisted and not error:
1080 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1082 blockDevice["blockdev"] = blockdev # str
1083 blockDevice["removable"] = removable # bool [True, False]
1084 blockDevice["partitions"] = partitions # list
1085 blockDevice["size"] = size # str
1086 blockDevice["model"] = model # str
1087 blockDevice["vendor"] = vendor # str
1088 self.blockDeviceList.append(blockDevice)
1090 def getBlockDeviceInfo(self, blockdev):
1091 devpath = "/sys/block/" + blockdev
1100 dev = int(readFile(devpath + "/dev").split(':')[0])
1101 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1103 return error, blacklisted, removable, partitions, size, model, vendor
1104 removable = bool(int(readFile(devpath + "/removable")))
1105 size = str(int(readFile(devpath + "/size").strip())*512)
1106 model = readFile(devpath + "/device/model")
1107 vendor = readFile(devpath + "/device/vendor")
1108 for partition in listdir(devpath):
1109 if partition[:len(blockdev)] != blockdev:
1111 partitions.append(partition)
1114 return error, blacklisted, removable, partitions, size, model, vendor
1116 def getPartitionInfo(self, partition):
1117 mountPoint = self.getPartitionMountpoint(partition)
1118 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1119 size_total = self.getPartitionSize(partition)
1121 if mountPoint != "":
1122 size_free = self.getPartitionFree(mountPoint)
1124 partitionInfo["partition"] = partition
1125 partitionInfo["mountpoint"] = mountPoint
1126 partitionInfo["uuid"] = uuid
1127 partitionInfo["fstype"] = fsType
1128 partitionInfo["size"] = size_total
1129 partitionInfo["free"] = size_free
1130 return partitionInfo
1132 def getPartitionMountpoint(self, partition):
1133 mounts = file('/proc/mounts').read().split('\n')
1135 if not x.startswith('/'):
1137 devpath, mountpoint, = x.split()[:2]
1138 if mountpoint.startswith('/autofs'):
1140 if path.basename(devpath) == partition:
1144 def getPartitionBlkidInfo(self, partition):
1145 parttionDev = "/dev/"+str(partition)
1148 cmd = "blkid -c /dev/null "+str(parttionDev)
1150 line = popen(cmd).readline().strip()
1151 if not line.startswith(parttionDev):
1152 return (uuid, partitionType)
1153 # print "Blikd %s : %s"%(parttionDev, line)
1154 if line.find(" UUID=") != -1:
1155 uuid = line.split(" UUID=")[1].split(' ')[0]
1156 if line.find(" TYPE=") != -1:
1157 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1159 print "get blkid info error (%s)"%cmd
1160 return (uuid, partitionType)
1162 def getPartitionSize(self, partition):
1163 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1165 size = readFile(devpath + "/size")
1166 return str(int(size)*512)
1170 def getPartitionFree(self, mountPoint):
1172 stat = statvfs(mountPoint)
1173 size_free = stat.f_bfree*stat.f_bsize
1178 def checkMountPoint(self, check_mountpoint):
1181 mounts = file('/proc/mounts').read().split('\n')
1183 if not x.startswith('/'):
1185 devpath, mountpoint = x.split()[:2]
1186 if mountpoint == check_mountpoint:
1192 def checkMountDev(self, device):
1195 mounts = file('/proc/mounts').read().split('\n')
1197 if not x.startswith('/'):
1199 devpath, mountpoint = x.split()[:2]
1200 if devpath == device:
1201 res.append(mountpoint)
1206 def isMounted(self, devpath, mountpoint):
1208 mounts = file('/proc/mounts').read().split('\n')
1210 if not x.startswith('/'):
1212 _devpath, _mountpoint = x.split()[:2]
1213 if devpath == _devpath and mountpoint == _mountpoint:
1219 def isMountable(self, partition):
1220 autofsPath = "/autofs/"+partition.device
1223 os.listdir(autofsPath)
1229 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1230 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1231 if mountpoint[-1] == '/':
1232 mountpoint = mountpoint[:-1]
1233 data = file('/etc/fstab').read().split('\n')
1235 if not line.startswith('/'):
1237 dev, mp, ms = line.split()[0:3]
1238 if uuid is not None and dev.startswith('UUID'):
1239 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1240 # print " >> line : ", line
1242 elif dev == devpath and mp == mountpoint and ms == 'auto':
1243 # print " >> line : ", line
1247 def umountByMountpoint(self, mountpoint):
1248 if mountpoint is None:
1251 if path.ismount(mountpoint):
1252 cmd = "umount " + mountpoint
1253 print "[DeviceManager] ", cmd
1256 print "Umount by mountpoint failed!"
1257 if not path.ismount(mountpoint):
1261 def umountByDevpath(self, devpath):
1262 cmd = "umount " + devpath
1263 print "[DeviceManager] ", cmd
1266 deviceinfo = DeviceInfo()
1268 class MountpointBrowser(Screen):
1270 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1271 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1272 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1273 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1274 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1275 <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" />
1276 <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" />
1277 <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" />
1278 <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" />
1279 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1280 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1283 def __init__(self, session):
1284 Screen.__init__(self, session)
1285 self["key_red"] = StaticText(_("Cancel"))
1286 self["key_green"] = StaticText(_("Select"))
1287 self["key_yellow"] = StaticText(_("Create directory"))
1288 self["key_blue"] = StaticText("Delete directory")
1289 directory = "/media/"
1290 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1291 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1292 self["filelist"] = self.filelist
1294 self["shortcuts"] = ActionMap(["ColorActions"],
1297 "green": self.select,
1298 "yellow": self.createDirectory,
1299 "blue": self.deleteDirectory,
1302 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1304 "cancel": self.exit,
1309 if self.filelist.canDescent():
1310 self.filelist.descent()
1313 if self["filelist"].getCurrentDirectory() is not None:
1314 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1315 self.filelist.descent()
1316 currDir = self["filelist"].getCurrentDirectory()
1319 self.close(self["filelist"].getFilename())
1321 def createDirectory(self):
1322 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1324 def createDirectoryCB(self, retval = None):
1327 if retval is not None:
1328 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1329 if not path.exists(newdir):
1330 os.system("mkdir %s"%newdir)
1331 self.filelist.refresh()
1334 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1336 def deleteDirectory(self):
1339 if self["filelist"].getCurrentDirectory() is not None:
1340 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1341 delDir = self["filelist"].getFilename()
1342 if path.exists(delDir):
1343 os.system("rmdir '%s'"%delDir)
1344 if path.exists(delDir):
1345 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1346 self.filelist.refresh()
1349 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1354 class MessageBoxConfirm(MessageBox):
1356 <screen position="center,center" size="620,10" title="Message">
1357 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1358 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1359 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1360 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1361 <widget name="list" position="100,100" size="380,375" transparent="1" />
1362 <applet type="onLayoutFinish">
1363 # this should be factored out into some helper code, but currently demonstrates applets.
1364 from enigma import eSize, ePoint
1366 orgwidth = self.instance.size().width()
1367 orgheight = self.instance.size().height()
1368 orgpos = self.instance.position()
1369 textsize = self["text"].getSize()
1371 # y size still must be fixed in font stuff...
1372 textsize = (textsize[0] + 50, textsize[1] + 50)
1374 if self.type == self.TYPE_YESNO:
1376 wsizex = textsize[0] + 60
1377 wsizey = textsize[1] + offset
1378 if (280 > wsizex):
1380 wsize = (wsizex, wsizey)
1383 self.instance.resize(eSize(*wsize))
1386 self["text"].instance.resize(eSize(*textsize))
1389 listsize = (wsizex, 50)
1390 self["list"].instance.move(ePoint(0, textsize[1]))
1391 self["list"].instance.resize(eSize(*listsize))
1395 newheight = wsize[1]
1396 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1401 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1402 class DeviceManagerConfig():
1404 self.configList = []
1406 def getConfigList(self):
1407 return self.configList
1409 def updateConfigList(self):
1411 self.configList = []
1412 file = open("/proc/mounts")
1413 mounts = file.readlines()
1416 if x.startswith("/dev/sd"):
1417 device = x.split()[0].split('/dev/')[1]
1418 mountpoint = x.split()[1]
1419 if mountpoint.startswith('/autofs'):
1421 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1422 if uuid != '' and mountpoint != '':
1423 self.configList.append([uuid, mountpoint])
1426 print "updateConfigList failed!"
1428 def loadConfig(self):
1429 if not fileExists(dmconfigfile):
1430 os.system("touch %s" % dmconfigfile)
1431 self.configList = []
1432 data = file(dmconfigfile).read().split('\n')
1434 if line.find(':') != -1:
1435 (uuid, mountpoint) = line.split(':')
1436 if uuid != '' and mountpoint != '':
1437 self.configList.append([uuid, mountpoint])
1439 def saveConfig(self):
1440 confFile = open(dmconfigfile,'w')
1442 for line in self.configList:
1443 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1444 confFile.write(data)
1447 def appendConfig(self, uuid, mountpoint):
1448 for x in self.configList:
1449 if x[0] == uuid or x[1] == mountpoint:
1450 self.configList.remove(x)
1451 self.configList.append([uuid, mountpoint])
1453 def removeConfig(self, value):
1454 for x in self.configList:
1455 if x[0] == value or x[1] == value:
1456 self.configList.remove(x)
1458 devicemanagerconfig = DeviceManagerConfig()
1460 class deviceManagerHotplug:
1462 self.hotplugActive = True
1464 def setHotplugActive(self,value=True):
1466 self.hotplugActive = True
1468 self.hotplugActive = False
1470 def printDebug(self):
1471 for p in harddiskmanager.partitions:
1472 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)
1474 def doMount(self, uuid, devpath, mountpoint, filesystem):
1475 # check current device mounted on another mountpoint.
1477 mp_list = deviceinfo.checkMountDev(devpath)
1479 if mp != mountpoint and path.ismount(mp):
1480 deviceinfo.umountByMountpoint(mp)
1481 # check another device mounted on configmountpoint
1483 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1484 for devpath_ in devpath_list:
1485 if devpath_ != devpath:
1486 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1489 # print "[DeviceManager] doMount"
1490 if not path.exists(mountpoint):
1491 os.system("mkdir %s"%mountpoint)
1492 if path.exists(mountpoint):
1493 if not path.ismount(mountpoint):
1494 if filesystem == "ntfs":
1495 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1496 elif filesystem is None:
1497 cmd = "mount %s %s"%(devpath, mountpoint)
1499 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1500 print "[DeviceManager] cmd : %s"%cmd
1502 if not deviceinfo.isMounted(devpath, mountpoint):
1503 print "[DeviceManager] %s doMount failed!"%devpath
1506 # Update partition Info, add
1507 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1509 def doUmount(self, device, mountpoint):
1510 devpath = "/dev/"+device
1511 mountpoints = deviceinfo.checkMountDev(devpath)
1512 if len(mountpoints) == 0:
1514 for mp in mountpoints:
1515 cmd = "umount %s"%devpath
1516 print "[DeviceManager] cmd : %s"%cmd
1519 def addHotPlugDevice(self, partition):
1520 device = partition.device
1521 devpath = "/dev/"+device
1523 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1526 os.system("sleep 1")
1527 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1529 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1532 devicemanagerconfig.loadConfig()
1533 configList = devicemanagerconfig.getConfigList()
1535 for line in configList:
1536 if uuid == line[0].strip():
1537 mountpoint = line[1].strip()
1539 if mountpoint is None:
1542 if deviceinfo.isMounted(devpath, mountpoint):
1544 # print "[DeviceManagerHotplug] already mounted"
1546 self.doMount(uuid, devpath, mountpoint, filesystem)
1548 def removeHotplugDevice(self, partition):
1549 self.doUmount(partition.device, partition.mountpoint)
1551 def getHotplugAction(self, action, partition):
1552 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1554 if partition.device is None or not partition.device.startswith("sd"):
1556 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1559 self.addHotPlugDevice(partition)
1560 elif action == 'remove':
1561 self.removeHotplugDevice(partition)
1563 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1564 device = path.basename(devpath)
1565 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1566 # check already appended to partition list
1567 for x in harddiskmanager.partitions:
1568 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1571 from Components.Harddisk import Partition
1572 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1573 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1574 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1575 harddiskmanager.partitions.append(p)
1576 harddiskmanager.on_partition_list_change("add", p)
1578 def autoMountOnStartup(self):
1579 devicemanagerconfig.loadConfig()
1580 configList = devicemanagerconfig.getConfigList()
1583 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1585 devpath = uuid = filesystem = ""
1586 devpath = line.split(':')[0]
1587 if line.find(" UUID=") != -1:
1588 uuid = line.split(" UUID=")[1].split(' ')[0]
1589 if line.find(" TYPE=") != -1:
1590 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1591 blkiddata.append((devpath, uuid, filesystem))
1593 for c in configList:
1594 uuid_cfg = c[0].strip()
1595 mountpoint_cfg = c[1].strip()
1596 for (devpath, uuid, filesystem) in blkiddata:
1597 if uuid_cfg == uuid:
1599 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1600 # print "[Devicemanager startup] already mounted"
1601 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1603 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1604 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1606 def umountOnShutdown(self):
1607 devicemanagerconfig.loadConfig()
1608 configList = devicemanagerconfig.getConfigList()
1611 data = file('/proc/mounts').read().split('\n')
1613 if not x.startswith('/dev/sd'):
1615 devpath, mountpoint = x.split()[:2]
1616 mounts.append((path.basename(devpath), mountpoint))
1618 data = self.getBlkidInfo()
1620 for c in configList:
1621 uuid_cfg = c[0].strip()
1622 mountpoint_cfg = c[1].strip()
1624 if uuid_cfg in data.keys():
1625 device_cfg = data[uuid_cfg]
1626 if device_cfg is None:
1628 for (device, mountpoint) in mounts:
1629 if device_cfg == device:
1630 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1631 self.doUmount(device, mountpoint)
1633 def getBlkidInfo(self):
1635 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1636 for line in blkid_data.split('\n'):
1637 # print "[DeviceManager] getBlkidInfo line : ",line
1639 device = path.basename(line.split(':')[0])
1640 if line.find(" UUID=") != -1:
1641 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1642 data[blkid_uuid] = device
1645 devicemanagerhotplug = deviceManagerHotplug()
1647 def DeviceManagerhotplugDeviceStart(action, device):
1648 devicemanagerhotplug.getHotplugAction(action, device)
1650 def callBackforDeviceManager(session, callback_result = False):
1651 if callback_result == True:
1652 session.open(DeviceManager)
1654 def checkMounts(session):
1656 noMountable_dev = ""
1657 for blockdev in listdir("/sys/block"):
1658 devpath = "/sys/block/" + blockdev
1659 dev = int(readFile(devpath + "/dev").split(':')[0])
1660 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1663 noMountable_partitions = []
1664 for partition in listdir(devpath):
1665 if not partition.startswith(blockdev):
1667 partitions.append(partition)
1668 if os.access('/autofs/'+partition,0) is False:
1669 noMountable_partitions.append(partition)
1670 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1671 if noMountable_dev != "":
1672 noMountable_dev += ' '
1673 noMountable_dev += blockdev
1675 if noMountable_dev != "":
1676 print "Umountable partitions found."
1677 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
1678 AddNotificationWithCallback(
1679 boundFunction(callBackforDeviceManager, session),
1680 MessageBox, InfoText, timeout = 60, default = False
1683 print "checkMounts failed!"
1685 def sessionstart(reason, **kwargs):
1687 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1688 session = kwargs["session"]
1689 checkMounts(session)
1690 if config.plugins.devicemanager.hotplug_enable.value:
1691 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1693 if config.plugins.devicemanager.hotplug_enable.value:
1694 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1696 def autostart(reason, **kwargs):
1699 # check at first enigma2 start
1700 if not fileExists(dmconfigfile):
1701 print "[DeviceManager] autostart : check devices at first start"
1702 sda_isremovable = False
1704 os.system("touch %s"%dmconfigfile)
1706 sda_data = popen("cat /proc/partitions | grep sda1").read()
1708 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1709 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1710 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1713 cfg += '"%s":/media/hdd\n'%sda_UUID
1714 confFile = open(dmconfigfile,'w')
1717 if not path.exists("/media/hdd"):
1718 os.system("mkdir -p /media/hdd")
1720 devicemanagerhotplug.autoMountOnStartup()
1722 print "[DeviceManager] autostart failed!"
1724 devicemanagerhotplug.umountOnShutdown()
1726 def menu(menuid, **kwargs):
1727 if menuid == "system":
1728 return [(_("DeviceManager"), main, "device_manager", 50)]
1731 def main(session, **kwargs):
1732 session.open(DeviceManager)
1734 def Plugins(path, **kwargs):
1736 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1737 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1738 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1741 class MessageBox_2(MessageBox):
1742 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1743 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1744 self.skinName = "MessageBox"
1745 self.closeTimer = eTimer()
1746 self.closeTimer.callback.append(self.msg_close)
1747 self.devicemanager_ret = False
1748 self.devicemanager_msg = ""
1750 def msg_close(self):
1751 self.close(self.devicemanager_ret, self.devicemanager_msg)
1753 def run_close(self, ret, msg=""):
1754 self.devicemanager_ret = ret
1755 self.devicemanager_msg = msg
1756 self.closeTimer.start(100,True)
1758 def createSummary(self):
1759 return MessageBox_2_Summary
1761 class MessageBox_2_Summary(Screen):
1763 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1764 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />