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="670,400" title="DeviceManager">
106 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
107 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
108 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
109 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
110 <widget name="key_red" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
111 <widget name="key_green" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
112 <widget name="key_yellow" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
113 <widget name="key_blue" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
114 <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="670,2" alphatest="on" />
115 <widget source="menu" render="Listbox" position="0,48" size="670,350" scrollbarMode="showOnDemand">
116 <convert type="TemplatedMultiContent">
119 MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor - model
120 MultiContentEntryText(pos = (100, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
121 MultiContentEntryText(pos = (230, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
122 MultiContentEntryText(pos = (360, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
123 MultiContentEntryText(pos = (490, 32), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
124 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # png 5 is the div pixmap
127 MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
128 MultiContentEntryText(pos = (100, 32), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
129 MultiContentEntryText(pos = (100, 54), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
130 MultiContentEntryText(pos = (100, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
131 MultiContentEntryText(pos = (230, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
132 MultiContentEntryText(pos = (380, 76), size = (200, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
133 MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (670, 2), png = 6), # png 6 is the div pixmap
136 MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture
137 MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name
138 MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path
139 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # index 5 is the div pixmap
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):
298 if self.currList == "default":
299 return self["menu"].getCurrent()[6]
302 def getCurrentPartition(self):
303 if self.currList == "partitions":
304 return self["menu"].getCurrent()[7]
309 if self.currList == "default":
310 self.currDevice = self.getCurrentDevice()
311 if len(self.currDevice["partitions"]) == 0:
312 self.session.open(MessageBox, _("No partition list found on device.\nPlease click BLUE key and do Initialize to use this device."), MessageBox.TYPE_ERROR, timeout = 10)
314 self.showPartitionList()
315 elif self.currList == "partitions":
316 currMountPoint = self.getCurrentPartition()["mountpoint"]
317 currUuid = self.getCurrentPartition()["uuid"]
318 if currMountPoint == "":
319 self.currPartition = self.getCurrentPartition()
320 self.showMountPointSetup()
322 self.doUmount(currMountPoint, self.showPartitionList)
323 elif self.currList == "mountpoint":
324 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
325 currEntry = self["menu"].getCurrent()[3]
326 if currEntry == "default":
327 # print "Setup mountpoint default!"
328 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
329 elif currEntry == "auto":
330 # print "Setup mountpoint automatically!"
331 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
333 # print "Setup mountpoint manually!"
334 self.session.openWithCallback(self.MountpointBrowserCB, MountpointBrowser)
340 if self.DeviceManagerConsole is not None:
341 if len(self.DeviceManagerConsole.appContainers):
342 for name in self.DeviceManagerConsole.appContainers.keys():
343 self.DeviceManagerConsole.kill(name)
344 if self.currList == "partitions":
345 self.currDevice = None
346 self.showDeviceList()
347 elif self.currList == "mountpoint":
348 self.currPartition = None
349 self.showPartitionList()
350 else: # currList = "default"
354 if self.currList == "partitions":
355 partition = self.getCurrentPartition()
356 self.choiceBoxFstype()
359 if self.currList == "default":
360 device = self.getCurrentDevice()
361 self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
362 elif self.currList == "partitions":
363 partition = self.getCurrentPartition()
364 self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
367 self.session.open(DeviceManagerConfiguration)
369 def deviceInitCB(self, ret = True):
370 self.showDeviceList()
372 def deviceCheckCB(self, ret = True):
373 self.showPartitionList()
375 def deviceFormatCB(self, ret = True):
376 self.showPartitionList()
378 def choiceBoxFstype(self):
380 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
381 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
382 menu.append((_("ext4 - experimental"), "ext4"))
383 menu.append((_("vfat - for USB flash memory"), "vfat"))
384 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
386 def choiceBoxFstypeCB(self, choice):
390 partition = self.getCurrentPartition()
391 self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
393 # about mount funcs..
394 def doUmount(self, mountpoint, callback):
395 cmd = "umount %s"%mountpoint
396 print "[DeviceManager] cmd : %s"%cmd
398 if not path.ismount(mountpoint):
399 devicemanagerconfig.updateConfigList()
401 self.session.open(MessageBox, _("Can't umount %s. \nMaybe device or resource busy.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
404 def getDefaultMountPoint(self):
405 return self.defaultMountPoint
407 def getAutoMountPoint(self):
408 mountPoint = "/media/"+self.currDevice["model"]
409 mountPoint = mountPoint.replace(' ','-')
410 if path.ismount(mountPoint):
413 mountPoint_fix = mountPoint+str(partnum)
414 if not path.ismount(mountPoint_fix):
417 mountPoint = mountPoint_fix
420 def doMount(self, partition, mountpoint):
422 # check mountpoint is in partition list.
423 if mountpoint != self.getDefaultMountPoint():
424 for p in harddiskmanager.partitions:
425 if p.mountpoint == mountpoint:
426 self.session.open(MessageBox, _("Can not use this mount point.(%s) \nPlease select another mount point.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
429 device = partition["partition"]
430 filesystem = partition["fstype"]
431 uuid = partition["uuid"]
432 if mountpoint.endswith("/"):
433 mountpoint = retval[:-1]
434 if mountpoint.find(' ') != -1:
435 mountpoint = mountpoint.replace(' ','-')
436 devpath = "/dev/"+device
437 if deviceinfo.isMounted(devpath, mountpoint):
438 print "[DeviceManager] '%s -> %s' is already mounted."%(devpath, mountpoint)
441 # check current device mounted on another mountpoint.
442 mp_list = deviceinfo.checkMountDev(devpath)
444 if mp != mountpoint and path.ismount(mp):
445 deviceinfo.umountByMountpoint(mp)
446 # check another device mounted on configmountpoint
447 devpath_list = deviceinfo.checkMountPoint(mountpoint)
448 for devpath_ in devpath_list:
449 if devpath_ != devpath:
450 self.session.open(MessageBox, _("Mount Failed!\nCurrent path is already mounted by \"%s\"")%devpath_list[0], MessageBox.TYPE_ERROR, timeout = 10)
453 print "[DeviceManagerHotplugDevice] doMount"
454 if not path.exists(mountpoint):
455 os.system("mkdir %s"%mountpoint)
456 if path.exists(mountpoint):
457 if not path.ismount(mountpoint):
458 if filesystem == "ntfs":
459 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
460 elif filesystem is None:
461 cmd = "mount %s %s"%(devpath, mountpoint)
463 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
464 print "[DeviceManager] cmd : %s"%cmd
465 self.DeviceManagerConsole.ePopen(cmd, self.doMountFinished, (devpath, mountpoint) )
467 self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(device, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
469 def doMountFinished(self, result, retval, extra_args = None):
470 (devpath, mountpoint) = extra_args
472 if not deviceinfo.isMounted(devpath, mountpoint):
473 # print "[DeviceManager] %s doMount failed!"%devpath
474 self.session.open(MessageBox, _("Mount Failed!\n(%s -> %s)")%(devpath, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
477 # make movie directory
478 if mountpoint == "/media/hdd":
479 movieDir = mountpoint + "/movie"
480 if not pathExists(movieDir):
481 print "[DeviceManager] make dir %s"%movieDir
482 os.makedirs(movieDir)
483 self.showPartitionList()
484 # update current mount state ,devicemanager.cfg
485 devicemanagerconfig.updateConfigList()
487 def MountpointBrowserCB(self, retval = None):
488 if retval and retval is not None:
489 mountPoint = retval.strip().replace(' ','')
490 if retval.endswith("/"):
491 mountPoint = retval[:-1]
492 print "Mount point from MountpointBrowser : %s"%mountPoint
493 if not path.exists(mountPoint):
494 self.session.open(MessageBox, _("Mount Point is not writeable.\nPath : %s")%mountPoint, MessageBox.TYPE_ERROR, timeout = 10)
497 self.doMount(self.currPartition, mountPoint)
500 # Initializing Start...
501 class DeviceInit(Screen):
502 skin = """<screen position="0,0" size="0,0"/>"""
503 def __init__(self, session, device, devicesize):
504 Screen.__init__(self, session)
505 self.session = session
506 self.deviceInitConsole = Console()
508 self.devicesize = int(devicesize)
509 self.inputbox_partitions = 1
510 self.inputbox_partitionSizeList = []
511 self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024)
512 self.msgWaiting = None
513 self.msgWaitingMkfs = None
514 self.devicenumber = 0
515 self.newpartitions = 0
516 self.onLayoutFinish.append(self.timerStart)
517 self.initStartTimer = eTimer()
518 self.initStartTimer.callback.append(self.confirmMessage)
519 self.createFSStartTimer = eTimer()
520 self.createFSStartTimer.callback.append(self.createFilesystemStart)
521 self.exitMessageTimer = eTimer()
522 self.exitMessageTimer.callback.append(self.exitMessage)
526 def timerStart(self):
527 self.initStartTimer.start(100,True)
529 def confirmMessage(self):
530 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
531 self.session.openWithCallback(self.confirmed, MessageBox, message)
533 def confirmed(self, ret):
535 self.InitializeStart()
539 def exit(self, ret = True):
542 def unmountAll(self, device):
543 mounts = file('/proc/mounts').read().split('\n')
547 if not line.startswith("/dev/" + device):
549 cmd += "umount %s ;"% line.split()[0]
550 print "[DeviceManager] %s"%cmd
553 mounts = file('/proc/mounts').read().split('\n')
555 if line.startswith("/dev/" + device):
559 def InitializeStart(self):
560 self.InputPartitionSize_step1()
562 def InputPartitionSize_step1(self):
563 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
565 def InputPartitionSize_step1_CB(self, ret):
566 if ret is not None and int(ret) in range(1,5): # ret in 1~4
567 self.inputbox_partitions = int(ret)
568 self.InputPartitionSize_step2()
570 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
572 def InputPartitionSize_step2(self):
573 current_partition = len(self.inputbox_partitionSizeList)+1
574 if self.inputbox_partitionSizeRemain == 0:
575 self.choiceBoxFstype()
576 elif current_partition == self.inputbox_partitions:
577 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
578 self.choiceBoxFstype()
580 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
581 self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Max = %d MB)")%(current_partition,self.inputbox_partitionSizeRemain ), text=text, maxSize=False, type=Input.NUMBER)
583 def InputPartitionSize_step2_CB(self, ret):
585 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
586 self.InputPartitionSize_step2()
588 self.inputbox_partitionSizeList.append(str(ret))
589 self.inputbox_partitionSizeRemain -= 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 choiceBoxFstype(self):
596 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
597 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
598 menu.append((_("ext4 - experimental"), "ext4"))
599 menu.append((_("vfat - for USB flash memory"), "vfat"))
600 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
602 def choiceBoxFstypeCB(self, choice):
606 self.fstype = choice[1]
607 if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
610 self.initInitializeConfirm()
612 def initInitializeConfirm(self):
613 # print self.inputbox_partitionSizeList
615 for index in range(len(self.inputbox_partitionSizeList)):
616 print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
617 partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
618 partitionsInfo += "filesystem type : %s"%(self.fstype)
619 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
621 def initInitializeConfirmCB(self,ret):
623 self.initInitialize()
627 def initInitialize(self):
628 if not self.unmountAll(self.device):
629 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
631 msg = _("InitInitializing, please wait ...")
632 msg += _("\nDevice : %s")%self.device
633 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
634 for index in range(len(self.inputbox_partitionSizeList)):
635 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
636 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
638 partitions = len(self.inputbox_partitionSizeList)
640 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
644 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
648 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
649 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
651 def initInitializeFinished(self, result, retval, extra_args = None):
653 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
654 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
656 errorMsg = "initInitializing device Error at /dev/%s"%self.device
657 self.msgWaiting.run_close(False, errorMsg)
659 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
660 cmd = "/bin/umount /dev/%s*" % (self.device)
661 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
663 def initInitializingUmountFinished(self, result, retval, extra_args = None):
664 partitions = open("/proc/partitions")
665 self.devicenumber = 0
666 self.newpartitions = 0
667 for part in partitions:
668 res = re.sub("\s+", " ", part).strip().split(" ")
669 if res and len(res) == 4 and res[3][:3] == self.device:
670 if len(res[3]) > 3 and res[3][:2] == "sd":
671 self.newpartitions += 1
673 self.msgWaiting.run_close(True)
674 # self.createFilesystem(self.newpartitions)
676 def createFilesystem(self, newpartitions):
677 self.devicenumber = self.devicenumber + 1
678 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
679 shortdevicename = self.device + str(self.devicenumber)
681 partitions = open("/proc/partitions")
682 for part in partitions:
683 res = re.sub("\s+", " ", part).strip().split(" ")
684 if res and len(res) == 4:
685 if res[3] == shortdevicename:
686 partitionsize = int(res[2])
690 if self.fstype == "ext4":
691 cmd = "/sbin/mkfs.ext4 -F "
692 if partitionsize > 2 * 1024 * 1024: # 2GB
693 cmd += "-T largefile "
694 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
695 elif self.fstype == "ext3":
696 cmd = "/sbin/mkfs.ext3 -F "
697 if partitionsize > 2 * 1024 * 1024:
698 cmd += "-T largefile "
699 cmd += "-m0 " + fulldevicename
700 elif self.fstype == "ext2":
701 cmd = "/sbin/mkfs.ext2 -F "
702 if partitionsize > 2 * 1024 * 1024:
703 cmd += "-T largefile "
704 cmd += "-m0 " + fulldevicename
705 elif self.fstype == "vfat":
706 if partitionsize > 4 * 1024 * 1024 * 1024:
707 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
709 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
711 self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
714 msg = _("Create filesystem, please wait ...")
715 msg += _("\nPartition : %s") % (fulldevicename)
716 msg += _("\nFilesystem : %s") % (self.fstype)
717 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
718 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
719 self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
721 def createFilesystemFinished(self, result, retval, extra_args = None):
722 device = extra_args[0]
723 fulldevicename = extra_args[1]
725 self.msgWaitingMkfs.run_close(True)
727 errorMsg = _("Creating filesystem Error")
728 if fulldevicename is not None:
729 errorMsg += _(" at /dev/%s")%fulldevicename
730 self.msgWaitingMkfs.run_close(False, errorMsg)
732 def createFilesystemStart(self):
733 self.createFilesystem(self.newpartitions)
735 def msgWaitingCB(self, ret, msg=""):
737 self.createFSStartTimer.start(100,True)
741 self.exitMessageTimer.start(100,True)
743 def msgWaitingMkfsCB(self, ret, msg=""):
744 if self.devicenumber < self.newpartitions:
745 self.createFSStartTimer.start(100,True)
749 self.msg = _("Device Initialization finished sucessfully!")
750 self.updateDeviceInfo()
751 self.exitMessageTimer.start(100,True)
755 self.exitMessageTimer.start(100,True)
757 def exitMessage(self):
759 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
761 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
763 def updateDeviceInfo(self):
764 # update devicemanager configs
765 devicemanagerconfig.updateConfigList()
769 # device check start..
770 class DeviceCheck(Screen):
771 skin = """<screen position="0,0" size="0,0"/>"""
772 def __init__(self, session, partition):
773 Screen.__init__(self, session)
774 self.session = session
775 self.deviceCheckConsole = Console()
776 self.partition = partition
777 self.onLayoutFinish.append(self.timerStart)
778 self.checkStartTimer = eTimer()
779 self.checkStartTimer.callback.append(self.confirmMessage)
781 def timerStart(self):
782 self.checkStartTimer.start(100,True)
784 def confirmMessage(self):
785 fssize = self.partition["size"]
786 if long(fssize) > 1024*1024*1024*16:
787 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
788 self.session.openWithCallback(self.confirmed, MessageBox, message)
790 self.deviceCheckStart()
792 def confirmed(self, ret):
793 print "confirmed : ",ret
795 self.deviceCheckStart()
799 def deviceCheckStart(self):
800 print "deviceCheckStart "
801 print "partition : ", self.partition
802 device = self.partition["partition"]
803 mountpoint = self.partition["mountpoint"]
804 fstype = self.partition["fstype"]
805 fssize = self.partition["size"]
806 if device is not None and fstype.startswith("ext"):
807 msg = _("Check filesystem, please wait ...")
808 msg += _("\nDevice : /dev/%s")%(device)
809 msg += _("\nFilesystem : %s")%(fstype)
810 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
812 self.doUmountFsck(device, mountpoint, fstype)
814 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
818 def doUmountFsck(self, device, mountpoint, fstype):
819 cmd = "umount /dev/%s" % device
820 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
822 def umountFsckFinished(self, result, retval, extra_args = None):
823 device = extra_args[0]
824 mountpoint = extra_args[1]
825 fstype = extra_args[2]
827 cmd = "fsck." + fstype + " -f -p /dev/" + device
828 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
830 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
831 self.msgWaiting.run_close(False,errorMsg)
833 def fsckFinished(self, result, retval, extra_args = None):
834 device = extra_args[0]
835 mountpoint = extra_args[1]
837 text = _("Filesystem check finished sucessfully")
838 self.msgWaiting.run_close(True, text)
840 text = _("Error checking disk. The disk or filesystem may be damaged")
841 self.msgWaiting.run_close(False, text)
843 def msgWaitingCB(self, ret, msg):
845 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
847 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
849 partition = self.partition["partition"]
850 mountpoint = self.partition["mountpoint"]
851 fstype = self.partition["fstype"]
854 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
856 cmd = "mount /dev/" + partition + " " + mountpoint
857 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
861 def mountPartitionFinished(self, result, retval, extra_args = None):
870 class DeviceFormat(Screen):
871 skin = """<screen position="0,0" size="0,0"/>"""
872 def __init__(self, session, partition, newfstype):
873 Screen.__init__(self, session)
874 self.session = session
875 self.deviceFormatConsole = Console()
876 self.partition = partition
877 self.newfstype = newfstype
878 self.unmountedList = []
879 self.onLayoutFinish.append(self.timerStart)
880 self.formatStartTimer = eTimer()
881 self.formatStartTimer.callback.append(self.DeviceFormatStart)
882 self.setHotplugDisabled = False
884 def timerStart(self):
885 self.formatStartTimer.start(100,True)
887 def DeviceFormatStart(self):
888 devicemanagerhotplug.setHotplugActive(False)
889 self.setHotplugDisabled = True
890 print "DeviceFormatStart : ", self.partition,
891 print "Filesystem : ",self.newfstype
892 device = self.partition["partition"]
893 devicepath = "/dev/"+device
894 mountpoint = self.partition["mountpoint"]
895 fssize = self.partition["size"]
896 newfstype = self.newfstype
898 msg = _("Format filesystem, please wait ...")
899 msg += _("\nDevice : %s")%(devicepath)
900 msg += _("\nFilesystem : %s")%(newfstype)
901 msg += _("\nSize : %s")%(byteConversion(fssize))
902 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
904 self.doumountPartition()
906 self.umountPartitionFinished("NORESULT", 0)
908 def doumountPartition(self):
909 oldfstype = self.partition["fstype"]
910 newfstype = self.newfstype
912 if newfstype == oldfstype:
913 device = self.partition["partition"]
915 device = self.partition["partition"][:3]
917 mounts = file('/proc/mounts','r')
918 for line in mounts.readlines():
919 if line.startswith("/dev/%s"%device):
920 cmd += "umount %s;"%line.split()[0]
921 self.unmountedList.append([line.split()[0], line.split()[1]])
922 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
924 def umountPartitionFinished(self, result, retval, extra_args = None):
925 partition = self.partition["partition"]
926 oldfstype = self.partition["fstype"]
927 newfstype = self.newfstype
929 if oldfstype == newfstype:
930 self.changePartitionIDFinished("NORESULT", 0)
932 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
933 if newfstype[:3] == "ext":
937 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
939 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
940 self.msgWaiting.run_close(False,errorMsg)
942 def changePartitionIDFinished(self, result, retval, extra_args = None):
943 device = self.partition["partition"][:3]
944 mountpoint = self.partition["mountpoint"]
945 oldfstype = self.partition["fstype"]
946 newfstype = self.newfstype
948 if oldfstype == newfstype:
949 self.refreshPartitionFinished("NORESULT", 0)
951 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
952 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
954 errorMsg = _("Can not change the partition ID for %s")%device
955 self.msgWaiting.run_close(False,errorMsg)
957 def refreshPartitionFinished(self, result, retval, extra_args = None):
958 print "refreshPartitionFinished!"
959 partition = self.partition["partition"]
960 mountpoint = self.partition["mountpoint"]
961 size = int(self.partition["size"])/1024/1024
962 oldfstype = self.partition["fstype"]
963 newfstype = self.newfstype
965 if newfstype == "ext4":
966 cmd = "/sbin/mkfs.ext4 -F "
968 cmd += "-T largefile "
969 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
970 elif newfstype == "ext3":
971 cmd = "/sbin/mkfs.ext3 -F "
973 cmd += "-T largefile "
974 cmd += "-m0 /dev/" + partition
975 elif newfstype == "ext2":
976 cmd = "/sbin/mkfs.ext2 -F "
978 cmd += "-T largefile "
979 cmd += "-m0 /dev/" + partition
980 elif newfstype == "vfat":
981 if size > 4 * 1024 * 1024:
982 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
984 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
985 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
987 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
988 self.msgWaiting.run_close(False,errorMsg)
990 def mkfsFinished(self, result, retval, extra_args = None):
991 print "mkfsFinished!"
992 partition = self.partition["partition"]
995 if len(self.unmountedList) == 0:
996 self.doMountFinished("NORESULT",0)
997 for x in self.unmountedList:
998 cmd += "mount %s %s;"%(x[0], x[1])
999 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1001 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1002 self.msgWaiting.run_close(False, text)
1004 def doMountFinished(self, result, retval, extra_args = None):
1005 print "doMountFinished!"
1006 text = _("Format finished sucessfully.")
1007 self.msgWaiting.run_close(True, text)
1009 def msgWaitingCB(self, ret, msg):
1011 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1013 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1015 def exit(self, ret):
1016 if self.setHotplugDisabled == True:
1017 devicemanagerhotplug.setHotplugActive(True)
1018 self.setHotplugDisabled = False
1025 self.blockDeviceList = []
1027 def getBlockDevices(self):
1028 return self.blockDeviceList
1031 self.blockDeviceList = []
1032 self.getBlockDeviceList()
1034 def getBlockDeviceList(self):
1035 print "get block device Infomations..."
1036 for blockdev in listdir("/sys/block"):
1037 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1038 if not blacklisted and not error:
1039 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1041 blockDevice["blockdev"] = blockdev # str
1042 blockDevice["removable"] = removable # bool [True, False]
1043 blockDevice["partitions"] = partitions # list
1044 blockDevice["size"] = size # str
1045 blockDevice["model"] = model # str
1046 blockDevice["vendor"] = vendor # str
1047 self.blockDeviceList.append(blockDevice)
1049 def getBlockDeviceInfo(self, blockdev):
1050 devpath = "/sys/block/" + blockdev
1059 dev = int(readFile(devpath + "/dev").split(':')[0])
1060 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1062 return error, blacklisted, removable, partitions, size, model, vendor
1063 removable = bool(int(readFile(devpath + "/removable")))
1064 size = str(int(readFile(devpath + "/size").strip())*512)
1065 model = readFile(devpath + "/device/model")
1066 vendor = readFile(devpath + "/device/vendor")
1067 for partition in listdir(devpath):
1068 if partition[:len(blockdev)] != blockdev:
1070 partitions.append(partition)
1073 return error, blacklisted, removable, partitions, size, model, vendor
1075 def getPartitionInfo(self, partition):
1076 mountPoint = self.getPartitionMountpoint(partition)
1077 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1078 size_total = self.getPartitionSize(partition)
1080 if mountPoint != "":
1081 size_free = self.getPartitionFree(mountPoint)
1083 partitionInfo["partition"] = partition
1084 partitionInfo["mountpoint"] = mountPoint
1085 partitionInfo["uuid"] = uuid
1086 partitionInfo["fstype"] = fsType
1087 partitionInfo["size"] = size_total
1088 partitionInfo["free"] = size_free
1089 return partitionInfo
1091 def getPartitionMountpoint(self, partition):
1092 mounts = file('/proc/mounts').read().split('\n')
1094 if not x.startswith('/'):
1096 devpath, mountpoint, = x.split()[:2]
1097 if mountpoint.startswith('/autofs'):
1099 if path.basename(devpath) == partition:
1103 def getPartitionBlkidInfo(self, partition):
1104 parttionDev = "/dev/"+str(partition)
1107 cmd = "blkid -c /dev/null "+str(parttionDev)
1109 line = popen(cmd).readline().strip()
1110 if not line.startswith(parttionDev):
1111 return (uuid, partitionType)
1112 # print "Blikd %s : %s"%(parttionDev, line)
1113 if line.find(" UUID=") != -1:
1114 uuid = line.split(" UUID=")[1].split(' ')[0]
1115 if line.find(" TYPE=") != -1:
1116 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1118 print "get blkid info error (%s)"%cmd
1119 return (uuid, partitionType)
1121 def getPartitionSize(self, partition):
1122 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1124 size = readFile(devpath + "/size")
1125 return str(int(size)*512)
1129 def getPartitionFree(self, mountPoint):
1131 stat = statvfs(mountPoint)
1132 size_free = stat.f_bfree*stat.f_bsize
1137 def checkMountPoint(self, check_mountpoint):
1140 mounts = file('/proc/mounts').read().split('\n')
1142 if not x.startswith('/'):
1144 devpath, mountpoint = x.split()[:2]
1145 if mountpoint == check_mountpoint:
1151 def checkMountDev(self, device):
1154 mounts = file('/proc/mounts').read().split('\n')
1156 if not x.startswith('/'):
1158 devpath, mountpoint = x.split()[:2]
1159 if devpath == device:
1160 res.append(mountpoint)
1165 def isMounted(self, devpath, mountpoint):
1167 mounts = file('/proc/mounts').read().split('\n')
1169 if not x.startswith('/'):
1171 _devpath, _mountpoint = x.split()[:2]
1172 if devpath == _devpath and mountpoint == _mountpoint:
1178 def isMountable(self, partition):
1179 autofsPath = "/autofs/"+partition.device
1182 os.listdir(autofsPath)
1188 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1189 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1190 if mountpoint[-1] == '/':
1191 mountpoint = mountpoint[:-1]
1192 data = file('/etc/fstab').read().split('\n')
1194 if not line.startswith('/'):
1196 dev, mp, ms = line.split()[0:3]
1197 if uuid is not None and dev.startswith('UUID'):
1198 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1199 # print " >> line : ", line
1201 elif dev == devpath and mp == mountpoint and ms == 'auto':
1202 # print " >> line : ", line
1206 def umountByMountpoint(self, mountpoint):
1207 if mountpoint is None:
1210 if path.ismount(mountpoint):
1211 cmd = "umount " + mountpoint
1212 print "[DeviceManager] ", cmd
1215 print "Umount by mountpoint failed!"
1216 if not path.ismount(mountpoint):
1220 def umountByDevpath(self, devpath):
1221 cmd = "umount " + devpath
1222 print "[DeviceManager] ", cmd
1225 deviceinfo = DeviceInfo()
1227 class MountpointBrowser(Screen):
1229 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1230 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1231 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1232 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1233 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1234 <widget source="key_red" render = "Label" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
1235 <widget source="key_green" render = "Label" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
1236 <widget source="key_yellow" render = "Label" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
1237 <widget source="key_blue" render = "Label" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
1238 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1239 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1242 def __init__(self, session):
1243 Screen.__init__(self, session)
1244 self["key_red"] = StaticText(_("Cancel"))
1245 self["key_green"] = StaticText(_("Select"))
1246 self["key_yellow"] = StaticText(_("Create directory"))
1247 self["key_blue"] = StaticText("Delete directory")
1248 directory = "/media/"
1249 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1250 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1251 self["filelist"] = self.filelist
1253 self["shortcuts"] = ActionMap(["ColorActions"],
1256 "green": self.select,
1257 "yellow": self.createDirectory,
1258 "blue": self.deleteDirectory,
1261 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1263 "cancel": self.exit,
1268 if self.filelist.canDescent():
1269 self.filelist.descent()
1272 if self["filelist"].getCurrentDirectory() is not None:
1273 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1274 self.filelist.descent()
1275 currDir = self["filelist"].getCurrentDirectory()
1278 self.close(self["filelist"].getFilename())
1280 def createDirectory(self):
1281 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1283 def createDirectoryCB(self, retval = None):
1286 if retval is not None:
1287 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1288 if not path.exists(newdir):
1289 os.system("mkdir %s"%newdir)
1290 self.filelist.refresh()
1293 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1295 def deleteDirectory(self):
1298 if self["filelist"].getCurrentDirectory() is not None:
1299 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1300 delDir = self["filelist"].getFilename()
1301 if path.exists(delDir):
1302 os.system("rmdir '%s'"%delDir)
1303 if path.exists(delDir):
1304 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1305 self.filelist.refresh()
1308 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1313 class MessageBoxConfirm(MessageBox):
1315 <screen position="center,center" size="620,10" title="Message">
1316 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1317 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1318 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1319 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1320 <widget name="list" position="100,100" size="380,375" transparent="1" />
1321 <applet type="onLayoutFinish">
1322 # this should be factored out into some helper code, but currently demonstrates applets.
1323 from enigma import eSize, ePoint
1325 orgwidth = self.instance.size().width()
1326 orgheight = self.instance.size().height()
1327 orgpos = self.instance.position()
1328 textsize = self["text"].getSize()
1330 # y size still must be fixed in font stuff...
1331 textsize = (textsize[0] + 50, textsize[1] + 50)
1333 if self.type == self.TYPE_YESNO:
1335 wsizex = textsize[0] + 60
1336 wsizey = textsize[1] + offset
1337 if (280 > wsizex):
1339 wsize = (wsizex, wsizey)
1342 self.instance.resize(eSize(*wsize))
1345 self["text"].instance.resize(eSize(*textsize))
1348 listsize = (wsizex, 50)
1349 self["list"].instance.move(ePoint(0, textsize[1]))
1350 self["list"].instance.resize(eSize(*listsize))
1354 newheight = wsize[1]
1355 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1360 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1361 class DeviceManagerConfig():
1363 self.configList = []
1365 def getConfigList(self):
1366 return self.configList
1368 def updateConfigList(self):
1370 self.configList = []
1371 file = open("/proc/mounts")
1372 mounts = file.readlines()
1375 if x.startswith("/dev/sd"):
1376 device = x.split()[0].split('/dev/')[1]
1377 mountpoint = x.split()[1]
1378 if mountpoint.startswith('/autofs'):
1380 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1381 if uuid != '' and mountpoint != '':
1382 self.configList.append([uuid, mountpoint])
1385 print "updateConfigList failed!"
1387 def loadConfig(self):
1388 if not fileExists(dmconfigfile):
1389 os.system("touch %s" % dmconfigfile)
1390 self.configList = []
1391 data = file(dmconfigfile).read().split('\n')
1393 if line.find(':') != -1:
1394 (uuid, mountpoint) = line.split(':')
1395 if uuid != '' and mountpoint != '':
1396 self.configList.append([uuid, mountpoint])
1398 def saveConfig(self):
1399 confFile = open(dmconfigfile,'w')
1401 for line in self.configList:
1402 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1403 confFile.write(data)
1406 def appendConfig(self, uuid, mountpoint):
1407 for x in self.configList:
1408 if x[0] == uuid or x[1] == mountpoint:
1409 self.configList.remove(x)
1410 self.configList.append([uuid, mountpoint])
1412 def removeConfig(self, value):
1413 for x in self.configList:
1414 if x[0] == value or x[1] == value:
1415 self.configList.remove(x)
1417 devicemanagerconfig = DeviceManagerConfig()
1419 class deviceManagerHotplug:
1421 self.hotplugActive = True
1423 def setHotplugActive(self,value=True):
1425 self.hotplugActive = True
1427 self.hotplugActive = False
1429 def printDebug(self):
1430 for p in harddiskmanager.partitions:
1431 print " # partition : %s %s %s %s %s(mp, des, f_mounted, is_hot, dev)"%(p.mountpoint, p.description, p.force_mounted, p.is_hotplug,p.device)
1433 def doMount(self, uuid, devpath, mountpoint, filesystem):
1434 # check current device mounted on another mountpoint.
1436 mp_list = deviceinfo.checkMountDev(devpath)
1438 if mp != mountpoint and path.ismount(mp):
1439 deviceinfo.umountByMountpoint(mp)
1440 # check another device mounted on configmountpoint
1442 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1443 for devpath_ in devpath_list:
1444 if devpath_ != devpath:
1445 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1448 # print "[DeviceManager] doMount"
1449 if not path.exists(mountpoint):
1450 os.system("mkdir %s"%mountpoint)
1451 if path.exists(mountpoint):
1452 if not path.ismount(mountpoint):
1453 if filesystem == "ntfs":
1454 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1455 elif filesystem is None:
1456 cmd = "mount %s %s"%(devpath, mountpoint)
1458 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1459 print "[DeviceManager] cmd : %s"%cmd
1461 if not deviceinfo.isMounted(devpath, mountpoint):
1462 print "[DeviceManager] %s doMount failed!"%devpath
1465 # Update partition Info, add
1466 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1468 def doUmount(self, device, mountpoint):
1469 devpath = "/dev/"+device
1470 mountpoints = deviceinfo.checkMountDev(devpath)
1471 if len(mountpoints) == 0:
1473 for mp in mountpoints:
1474 cmd = "umount %s"%devpath
1475 print "[DeviceManager] cmd : %s"%cmd
1478 def addHotPlugDevice(self, partition):
1479 device = partition.device
1480 devpath = "/dev/"+device
1482 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1485 os.system("sleep 1")
1486 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1488 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1491 devicemanagerconfig.loadConfig()
1492 configList = devicemanagerconfig.getConfigList()
1494 for line in configList:
1495 if uuid == line[0].strip():
1496 mountpoint = line[1].strip()
1498 if mountpoint is None:
1501 if deviceinfo.isMounted(devpath, mountpoint):
1503 # print "[DeviceManagerHotplug] already mounted"
1505 self.doMount(uuid, devpath, mountpoint, filesystem)
1507 def removeHotplugDevice(self, partition):
1508 self.doUmount(partition.device, partition.mountpoint)
1510 def getHotplugAction(self, action, partition):
1511 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1513 if partition.device is None or not partition.device.startswith("sd"):
1515 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1518 self.addHotPlugDevice(partition)
1519 elif action == 'remove':
1520 self.removeHotplugDevice(partition)
1522 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1523 device = path.basename(devpath)
1524 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1525 # check already appended to partition list
1526 for x in harddiskmanager.partitions:
1527 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1530 from Components.Harddisk import Partition
1531 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1532 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1533 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1534 harddiskmanager.partitions.append(p)
1535 harddiskmanager.on_partition_list_change("add", p)
1537 def autoMountOnStartup(self):
1538 devicemanagerconfig.loadConfig()
1539 configList = devicemanagerconfig.getConfigList()
1542 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1544 devpath = uuid = filesystem = ""
1545 devpath = line.split(':')[0]
1546 if line.find(" UUID=") != -1:
1547 uuid = line.split(" UUID=")[1].split(' ')[0]
1548 if line.find(" TYPE=") != -1:
1549 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1550 blkiddata.append((devpath, uuid, filesystem))
1552 for c in configList:
1553 uuid_cfg = c[0].strip()
1554 mountpoint_cfg = c[1].strip()
1555 for (devpath, uuid, filesystem) in blkiddata:
1556 if uuid_cfg == uuid:
1558 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1559 # print "[Devicemanager startup] already mounted"
1560 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1562 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1563 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1565 def umountOnShutdown(self):
1566 devicemanagerconfig.loadConfig()
1567 configList = devicemanagerconfig.getConfigList()
1570 data = file('/proc/mounts').read().split('\n')
1572 if not x.startswith('/dev/sd'):
1574 devpath, mountpoint = x.split()[:2]
1575 mounts.append((path.basename(devpath), mountpoint))
1577 data = self.getBlkidInfo()
1579 for c in configList:
1580 uuid_cfg = c[0].strip()
1581 mountpoint_cfg = c[1].strip()
1583 if uuid_cfg in data.keys():
1584 device_cfg = data[uuid_cfg]
1585 if device_cfg is None:
1587 for (device, mountpoint) in mounts:
1588 if device_cfg == device:
1589 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1590 self.doUmount(device, mountpoint)
1592 def getBlkidInfo(self):
1594 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1595 for line in blkid_data.split('\n'):
1596 # print "[DeviceManager] getBlkidInfo line : ",line
1598 device = path.basename(line.split(':')[0])
1599 if line.find(" UUID=") != -1:
1600 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1601 data[blkid_uuid] = device
1604 devicemanagerhotplug = deviceManagerHotplug()
1606 def DeviceManagerhotplugDeviceStart(action, device):
1607 devicemanagerhotplug.getHotplugAction(action, device)
1609 def callBackforDeviceManager(session, callback_result = False):
1610 if callback_result == True:
1611 session.open(DeviceManager)
1613 def checkMounts(session):
1615 noMountable_dev = ""
1616 for blockdev in listdir("/sys/block"):
1617 devpath = "/sys/block/" + blockdev
1618 dev = int(readFile(devpath + "/dev").split(':')[0])
1619 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1622 noMountable_partitions = []
1623 for partition in listdir(devpath):
1624 if not partition.startswith(blockdev):
1626 partitions.append(partition)
1627 if os.access('/autofs/'+partition,0) is False:
1628 noMountable_partitions.append(partition)
1629 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1630 if noMountable_dev != "":
1631 noMountable_dev += ' '
1632 noMountable_dev += blockdev
1634 if noMountable_dev != "":
1635 print "Umountable partitions found."
1636 InfoText = _("No mountable devices found.! (%s)\nDo you want to open DeviceManager and do initialize or format this device?\n\n(Open 'Menu->Setup->System -> Harddisk -> DeviceManager'\n and press MENU button to deactivate this check.)")%noMountable_dev
1637 AddNotificationWithCallback(
1638 boundFunction(callBackforDeviceManager, session),
1639 MessageBox, InfoText, timeout = 60, default = False
1642 print "checkMounts failed!"
1644 def sessionstart(reason, **kwargs):
1646 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1647 session = kwargs["session"]
1648 checkMounts(session)
1649 if config.plugins.devicemanager.hotplug_enable.value:
1650 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1652 if config.plugins.devicemanager.hotplug_enable.value:
1653 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1655 def autostart(reason, **kwargs):
1658 # check at first enigma2 start
1659 if not fileExists(dmconfigfile):
1660 print "[DeviceManager] autostart : check devices at first start"
1661 sda_isremovable = False
1663 os.system("touch %s"%dmconfigfile)
1665 sda_data = popen("cat /proc/partitions | grep sda1").read()
1667 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1668 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1669 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1672 cfg += '"%s":/media/hdd\n'%sda_UUID
1673 confFile = open(dmconfigfile,'w')
1676 if not path.exists("/media/hdd"):
1677 os.system("mkdir -p /media/hdd")
1679 devicemanagerhotplug.autoMountOnStartup()
1681 print "[DeviceManager] autostart failed!"
1683 devicemanagerhotplug.umountOnShutdown()
1685 def menu(menuid, **kwargs):
1686 if menuid == "system":
1687 return [(_("DeviceManager"), main, "device_manager", 50)]
1690 def main(session, **kwargs):
1691 session.open(DeviceManager)
1693 def Plugins(path, **kwargs):
1695 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1696 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1697 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1700 class MessageBox_2(MessageBox):
1701 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1702 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1703 self.skinName = "MessageBox"
1704 self.closeTimer = eTimer()
1705 self.closeTimer.callback.append(self.msg_close)
1706 self.devicemanager_ret = False
1707 self.devicemanager_msg = ""
1709 def msg_close(self):
1710 self.close(self.devicemanager_ret, self.devicemanager_msg)
1712 def run_close(self, ret, msg=""):
1713 self.devicemanager_ret = ret
1714 self.devicemanager_msg = msg
1715 self.closeTimer.start(100,True)
1717 def createSummary(self):
1718 return MessageBox_2_Summary
1720 class MessageBox_2_Summary(Screen):
1722 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1723 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />