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 self.doMkfsTimer = eTimer()
527 self.doMkfsTimer.callback.append(self.doMkfs)
528 self.doInitializeTimer = eTimer()
529 self.doInitializeTimer.callback.append(self.doInitialize)
531 def timerStart(self):
532 self.initStartTimer.start(100,True)
534 def confirmMessage(self):
535 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
536 self.session.openWithCallback(self.confirmed, MessageBox, message)
538 def confirmed(self, ret):
540 self.InitializeStart()
544 def exit(self, ret = True):
547 def unmountAll(self, device):
548 mounts = file('/proc/mounts').read().split('\n')
552 if not line.startswith("/dev/" + device):
554 cmd += "umount %s ;"% line.split()[0]
555 print "[DeviceManager] %s"%cmd
558 mounts = file('/proc/mounts').read().split('\n')
560 if line.startswith("/dev/" + device):
564 def InitializeStart(self):
565 self.InputPartitionSize_step1()
567 def InputPartitionSize_step1(self):
568 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
570 def InputPartitionSize_step1_CB(self, ret):
571 if ret is not None and int(ret) in range(1,5): # ret in 1~4
572 self.inputbox_partitions = int(ret)
573 self.InputPartitionSize_step2()
575 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
577 def InputPartitionSize_step2(self):
578 current_partition = len(self.inputbox_partitionSizeList)+1
579 if self.inputbox_partitionSizeRemain == 0:
580 self.choiceBoxFstype()
581 elif current_partition == self.inputbox_partitions:
582 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
583 self.choiceBoxFstype()
585 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
586 self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Max = %d MB)")%(current_partition,self.inputbox_partitionSizeRemain ), text=text, maxSize=False, type=Input.NUMBER)
588 def InputPartitionSize_step2_CB(self, ret):
590 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
591 self.InputPartitionSize_step2()
593 self.inputbox_partitionSizeList.append(str(ret))
594 self.inputbox_partitionSizeRemain -= int(ret)
595 self.InputPartitionSize_step2()
597 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
599 def choiceBoxFstype(self):
601 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
602 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
603 menu.append((_("ext4 - experimental"), "ext4"))
604 menu.append((_("vfat - for USB flash memory"), "vfat"))
605 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
607 def choiceBoxFstypeCB(self, choice):
611 self.fstype = choice[1]
612 if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
615 self.initInitializeConfirm()
617 def initInitializeConfirm(self):
618 # print self.inputbox_partitionSizeList
620 for index in range(len(self.inputbox_partitionSizeList)):
621 print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
622 partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
623 partitionsInfo += "filesystem type : %s"%(self.fstype)
624 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
626 def initInitializeConfirmCB(self,ret):
628 self.initInitialize()
632 def initInitialize(self):
633 if not self.unmountAll(self.device):
634 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
636 msg = _("InitInitializing, please wait ...")
637 msg += _("\nDevice : %s")%self.device
638 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
639 for index in range(len(self.inputbox_partitionSizeList)):
640 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
641 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
642 self.doInitializeTimer.start(500,True)
644 def doInitialize(self):
646 partitions = len(self.inputbox_partitionSizeList)
648 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
652 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
656 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
657 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
659 def initInitializeFinished(self, result, retval, extra_args = None):
661 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
662 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
664 errorMsg = "initInitializing device Error at /dev/%s"%self.device
665 self.msgWaiting.run_close(False, errorMsg)
667 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
668 cmd = "/bin/umount /dev/%s*" % (self.device)
669 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
671 def initInitializingUmountFinished(self, result, retval, extra_args = None):
672 partitions = open("/proc/partitions")
673 self.devicenumber = 0
674 self.newpartitions = 0
675 for part in partitions:
676 res = re.sub("\s+", " ", part).strip().split(" ")
677 if res and len(res) == 4 and res[3][:3] == self.device:
678 if len(res[3]) > 3 and res[3][:2] == "sd":
679 self.newpartitions += 1
681 self.msgWaiting.run_close(True)
682 # self.createFilesystem(self.newpartitions)
684 def createFilesystem(self, newpartitions):
685 self.devicenumber = self.devicenumber + 1
686 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
687 shortdevicename = self.device + str(self.devicenumber)
689 partitions = open("/proc/partitions")
690 for part in partitions:
691 res = re.sub("\s+", " ", part).strip().split(" ")
692 if res and len(res) == 4:
693 if res[3] == shortdevicename:
694 partitionsize = int(res[2])
698 if self.fstype == "ext4":
699 cmd = "/sbin/mkfs.ext4 -F "
700 if partitionsize > 2 * 1024 * 1024: # 2GB
701 cmd += "-T largefile "
702 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
703 elif self.fstype == "ext3":
704 cmd = "/sbin/mkfs.ext3 -F "
705 if partitionsize > 2 * 1024 * 1024:
706 cmd += "-T largefile "
707 cmd += "-m0 " + fulldevicename
708 elif self.fstype == "ext2":
709 cmd = "/sbin/mkfs.ext2 -F "
710 if partitionsize > 2 * 1024 * 1024:
711 cmd += "-T largefile "
712 cmd += "-m0 " + fulldevicename
713 elif self.fstype == "vfat":
714 if partitionsize > 4 * 1024 * 1024 * 1024:
715 cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename
717 cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename
719 self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
722 msg = _("Create filesystem, please wait ...")
723 msg += _("\nPartition : %s") % (fulldevicename)
724 msg += _("\nFilesystem : %s") % (self.fstype)
725 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
726 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
728 self.doMkfsTimer.start(500,True)
731 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
732 self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
734 def createFilesystemFinished(self, result, retval, extra_args = None):
735 device = extra_args[0]
736 fulldevicename = extra_args[1]
738 self.msgWaitingMkfs.run_close(True)
740 errorMsg = _("Creating filesystem Error")
741 if fulldevicename is not None:
742 errorMsg += _(" at /dev/%s")%fulldevicename
743 self.msgWaitingMkfs.run_close(False, errorMsg)
745 def createFilesystemStart(self):
746 self.createFilesystem(self.newpartitions)
748 def msgWaitingCB(self, ret, msg=""):
750 self.createFSStartTimer.start(100,True)
754 self.exitMessageTimer.start(100,True)
756 def msgWaitingMkfsCB(self, ret, msg=""):
757 if self.devicenumber < self.newpartitions:
758 self.createFSStartTimer.start(100,True)
762 self.msg = _("Device Initialization finished sucessfully!")
763 self.updateDeviceInfo()
764 self.exitMessageTimer.start(100,True)
768 self.exitMessageTimer.start(100,True)
770 def exitMessage(self):
772 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
774 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
776 def updateDeviceInfo(self):
777 # update devicemanager configs
778 devicemanagerconfig.updateConfigList()
782 # device check start..
783 class DeviceCheck(Screen):
784 skin = """<screen position="0,0" size="0,0"/>"""
785 def __init__(self, session, partition):
786 Screen.__init__(self, session)
787 self.session = session
788 self.deviceCheckConsole = Console()
789 self.partition = partition
790 self.onLayoutFinish.append(self.timerStart)
791 self.checkStartTimer = eTimer()
792 self.checkStartTimer.callback.append(self.confirmMessage)
793 self.umountTimer = eTimer()
794 self.umountTimer.callback.append(self.doUnmount)
796 def timerStart(self):
797 self.checkStartTimer.start(100,True)
799 def confirmMessage(self):
800 fssize = self.partition["size"]
801 if long(fssize) > 1024*1024*1024*16:
802 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
803 self.session.openWithCallback(self.confirmed, MessageBox, message)
805 self.deviceCheckStart()
807 def confirmed(self, ret):
808 print "confirmed : ",ret
810 self.deviceCheckStart()
814 def deviceCheckStart(self):
815 print "deviceCheckStart "
816 print "partition : ", self.partition
817 device = self.partition["partition"]
818 fstype = self.partition["fstype"]
819 fssize = self.partition["size"]
820 if device is not None and fstype.startswith("ext"):
821 msg = _("Check filesystem, please wait ...")
822 msg += _("\nDevice : /dev/%s")%(device)
823 msg += _("\nFilesystem : %s")%(fstype)
824 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
825 self.umountTimer.start(500,True)
830 device = self.partition["partition"]
831 mountpoint = self.partition["mountpoint"]
832 fstype = self.partition["fstype"]
834 self.doUmountFsck(device, mountpoint, fstype)
836 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
838 def doUmountFsck(self, device, mountpoint, fstype):
839 cmd = "umount /dev/%s" % device
840 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
842 def umountFsckFinished(self, result, retval, extra_args = None):
843 device = extra_args[0]
844 mountpoint = extra_args[1]
845 fstype = extra_args[2]
847 cmd = "fsck." + fstype + " -f -p /dev/" + device
848 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
850 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
851 self.msgWaiting.run_close(False,errorMsg)
853 def fsckFinished(self, result, retval, extra_args = None):
854 device = extra_args[0]
855 mountpoint = extra_args[1]
857 text = _("Filesystem check finished sucessfully")
858 self.msgWaiting.run_close(True, text)
860 text = _("Error checking disk. The disk or filesystem may be damaged")
861 self.msgWaiting.run_close(False, text)
863 def msgWaitingCB(self, ret, msg):
865 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
867 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
869 partition = self.partition["partition"]
870 mountpoint = self.partition["mountpoint"]
871 fstype = self.partition["fstype"]
874 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
876 cmd = "mount /dev/" + partition + " " + mountpoint
877 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
881 def mountPartitionFinished(self, result, retval, extra_args = None):
890 class DeviceFormat(Screen):
891 skin = """<screen position="0,0" size="0,0"/>"""
892 def __init__(self, session, partition, newfstype):
893 Screen.__init__(self, session)
894 self.session = session
895 self.deviceFormatConsole = Console()
896 self.partition = partition
897 self.newfstype = newfstype
898 self.unmountedList = []
899 self.onLayoutFinish.append(self.timerStart)
900 self.formatStartTimer = eTimer()
901 self.formatStartTimer.callback.append(self.DeviceFormatStart)
902 self.setHotplugDisabled = False
903 self.umountTimer = eTimer()
904 self.umountTimer.callback.append(self.doUnmount)
906 def timerStart(self):
907 self.formatStartTimer.start(100,True)
909 def DeviceFormatStart(self):
910 devicemanagerhotplug.setHotplugActive(False)
911 self.setHotplugDisabled = True
912 print "DeviceFormatStart : ", self.partition,
913 print "Filesystem : ",self.newfstype
914 device = self.partition["partition"]
915 devicepath = "/dev/"+device
916 fssize = self.partition["size"]
917 newfstype = self.newfstype
918 msg = _("Format filesystem, please wait ...")
919 msg += _("\nDevice : %s")%(devicepath)
920 msg += _("\nFilesystem : %s")%(newfstype)
921 msg += _("\nSize : %s")%(byteConversion(fssize))
922 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
923 self.umountTimer.start(500,True)
926 mountpoint = self.partition["mountpoint"]
928 self.doumountPartition()
930 self.umountPartitionFinished("NORESULT", 0)
932 def doumountPartition(self):
933 oldfstype = self.partition["fstype"]
934 newfstype = self.newfstype
936 if newfstype == oldfstype:
937 device = self.partition["partition"]
939 device = self.partition["partition"][:3]
941 mounts = file('/proc/mounts','r')
942 for line in mounts.readlines():
943 if line.startswith("/dev/%s"%device):
944 cmd += "umount %s;"%line.split()[0]
945 self.unmountedList.append([line.split()[0], line.split()[1]])
946 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
948 def umountPartitionFinished(self, result, retval, extra_args = None):
949 partition = self.partition["partition"]
950 oldfstype = self.partition["fstype"]
951 newfstype = self.newfstype
953 if oldfstype == newfstype:
954 self.changePartitionIDFinished("NORESULT", 0)
956 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
957 if newfstype[:3] == "ext":
961 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
963 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
964 self.msgWaiting.run_close(False,errorMsg)
966 def changePartitionIDFinished(self, result, retval, extra_args = None):
967 device = self.partition["partition"][:3]
968 mountpoint = self.partition["mountpoint"]
969 oldfstype = self.partition["fstype"]
970 newfstype = self.newfstype
972 if oldfstype == newfstype:
973 self.refreshPartitionFinished("NORESULT", 0)
975 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
976 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
978 errorMsg = _("Can not change the partition ID for %s")%device
979 self.msgWaiting.run_close(False,errorMsg)
981 def refreshPartitionFinished(self, result, retval, extra_args = None):
982 print "refreshPartitionFinished!"
983 partition = self.partition["partition"]
984 mountpoint = self.partition["mountpoint"]
985 size = int(self.partition["size"])/1024/1024
986 oldfstype = self.partition["fstype"]
987 newfstype = self.newfstype
989 if newfstype == "ext4":
990 cmd = "/sbin/mkfs.ext4 -F "
992 cmd += "-T largefile "
993 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
994 elif newfstype == "ext3":
995 cmd = "/sbin/mkfs.ext3 -F "
997 cmd += "-T largefile "
998 cmd += "-m0 /dev/" + partition
999 elif newfstype == "ext2":
1000 cmd = "/sbin/mkfs.ext2 -F "
1002 cmd += "-T largefile "
1003 cmd += "-m0 /dev/" + partition
1004 elif newfstype == "vfat":
1005 if size > 4 * 1024 * 1024:
1006 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
1008 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
1009 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
1011 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
1012 self.msgWaiting.run_close(False,errorMsg)
1014 def mkfsFinished(self, result, retval, extra_args = None):
1015 print "mkfsFinished!"
1016 partition = self.partition["partition"]
1019 if len(self.unmountedList) == 0:
1020 self.doMountFinished("NORESULT",0)
1021 for x in self.unmountedList:
1022 cmd += "mount %s %s;"%(x[0], x[1])
1023 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
1025 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
1026 self.msgWaiting.run_close(False, text)
1028 def doMountFinished(self, result, retval, extra_args = None):
1029 print "doMountFinished!"
1030 text = _("Format finished sucessfully.")
1031 self.msgWaiting.run_close(True, text)
1033 def msgWaitingCB(self, ret, msg):
1035 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1037 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1039 def exit(self, ret):
1040 if self.setHotplugDisabled == True:
1041 devicemanagerhotplug.setHotplugActive(True)
1042 self.setHotplugDisabled = False
1049 self.blockDeviceList = []
1051 def getBlockDevices(self):
1052 return self.blockDeviceList
1055 self.blockDeviceList = []
1056 self.getBlockDeviceList()
1058 def getBlockDeviceList(self):
1059 print "get block device Infomations..."
1060 for blockdev in listdir("/sys/block"):
1061 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1062 if not blacklisted and not error:
1063 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1065 blockDevice["blockdev"] = blockdev # str
1066 blockDevice["removable"] = removable # bool [True, False]
1067 blockDevice["partitions"] = partitions # list
1068 blockDevice["size"] = size # str
1069 blockDevice["model"] = model # str
1070 blockDevice["vendor"] = vendor # str
1071 self.blockDeviceList.append(blockDevice)
1073 def getBlockDeviceInfo(self, blockdev):
1074 devpath = "/sys/block/" + blockdev
1083 dev = int(readFile(devpath + "/dev").split(':')[0])
1084 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1086 return error, blacklisted, removable, partitions, size, model, vendor
1087 removable = bool(int(readFile(devpath + "/removable")))
1088 size = str(int(readFile(devpath + "/size").strip())*512)
1089 model = readFile(devpath + "/device/model")
1090 vendor = readFile(devpath + "/device/vendor")
1091 for partition in listdir(devpath):
1092 if partition[:len(blockdev)] != blockdev:
1094 partitions.append(partition)
1097 return error, blacklisted, removable, partitions, size, model, vendor
1099 def getPartitionInfo(self, partition):
1100 mountPoint = self.getPartitionMountpoint(partition)
1101 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1102 size_total = self.getPartitionSize(partition)
1104 if mountPoint != "":
1105 size_free = self.getPartitionFree(mountPoint)
1107 partitionInfo["partition"] = partition
1108 partitionInfo["mountpoint"] = mountPoint
1109 partitionInfo["uuid"] = uuid
1110 partitionInfo["fstype"] = fsType
1111 partitionInfo["size"] = size_total
1112 partitionInfo["free"] = size_free
1113 return partitionInfo
1115 def getPartitionMountpoint(self, partition):
1116 mounts = file('/proc/mounts').read().split('\n')
1118 if not x.startswith('/'):
1120 devpath, mountpoint, = x.split()[:2]
1121 if mountpoint.startswith('/autofs'):
1123 if path.basename(devpath) == partition:
1127 def getPartitionBlkidInfo(self, partition):
1128 parttionDev = "/dev/"+str(partition)
1131 cmd = "blkid -c /dev/null "+str(parttionDev)
1133 line = popen(cmd).readline().strip()
1134 if not line.startswith(parttionDev):
1135 return (uuid, partitionType)
1136 # print "Blikd %s : %s"%(parttionDev, line)
1137 if line.find(" UUID=") != -1:
1138 uuid = line.split(" UUID=")[1].split(' ')[0]
1139 if line.find(" TYPE=") != -1:
1140 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1142 print "get blkid info error (%s)"%cmd
1143 return (uuid, partitionType)
1145 def getPartitionSize(self, partition):
1146 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1148 size = readFile(devpath + "/size")
1149 return str(int(size)*512)
1153 def getPartitionFree(self, mountPoint):
1155 stat = statvfs(mountPoint)
1156 size_free = stat.f_bfree*stat.f_bsize
1161 def checkMountPoint(self, check_mountpoint):
1164 mounts = file('/proc/mounts').read().split('\n')
1166 if not x.startswith('/'):
1168 devpath, mountpoint = x.split()[:2]
1169 if mountpoint == check_mountpoint:
1175 def checkMountDev(self, device):
1178 mounts = file('/proc/mounts').read().split('\n')
1180 if not x.startswith('/'):
1182 devpath, mountpoint = x.split()[:2]
1183 if devpath == device:
1184 res.append(mountpoint)
1189 def isMounted(self, devpath, mountpoint):
1191 mounts = file('/proc/mounts').read().split('\n')
1193 if not x.startswith('/'):
1195 _devpath, _mountpoint = x.split()[:2]
1196 if devpath == _devpath and mountpoint == _mountpoint:
1202 def isMountable(self, partition):
1203 autofsPath = "/autofs/"+partition.device
1206 os.listdir(autofsPath)
1212 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1213 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1214 if mountpoint[-1] == '/':
1215 mountpoint = mountpoint[:-1]
1216 data = file('/etc/fstab').read().split('\n')
1218 if not line.startswith('/'):
1220 dev, mp, ms = line.split()[0:3]
1221 if uuid is not None and dev.startswith('UUID'):
1222 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1223 # print " >> line : ", line
1225 elif dev == devpath and mp == mountpoint and ms == 'auto':
1226 # print " >> line : ", line
1230 def umountByMountpoint(self, mountpoint):
1231 if mountpoint is None:
1234 if path.ismount(mountpoint):
1235 cmd = "umount " + mountpoint
1236 print "[DeviceManager] ", cmd
1239 print "Umount by mountpoint failed!"
1240 if not path.ismount(mountpoint):
1244 def umountByDevpath(self, devpath):
1245 cmd = "umount " + devpath
1246 print "[DeviceManager] ", cmd
1249 deviceinfo = DeviceInfo()
1251 class MountpointBrowser(Screen):
1253 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1254 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1255 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1256 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1257 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1258 <widget source="key_red" render = "Label" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
1259 <widget source="key_green" render = "Label" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
1260 <widget source="key_yellow" render = "Label" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
1261 <widget source="key_blue" render = "Label" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
1262 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1263 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1266 def __init__(self, session):
1267 Screen.__init__(self, session)
1268 self["key_red"] = StaticText(_("Cancel"))
1269 self["key_green"] = StaticText(_("Select"))
1270 self["key_yellow"] = StaticText(_("Create directory"))
1271 self["key_blue"] = StaticText("Delete directory")
1272 directory = "/media/"
1273 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1274 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1275 self["filelist"] = self.filelist
1277 self["shortcuts"] = ActionMap(["ColorActions"],
1280 "green": self.select,
1281 "yellow": self.createDirectory,
1282 "blue": self.deleteDirectory,
1285 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1287 "cancel": self.exit,
1292 if self.filelist.canDescent():
1293 self.filelist.descent()
1296 if self["filelist"].getCurrentDirectory() is not None:
1297 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1298 self.filelist.descent()
1299 currDir = self["filelist"].getCurrentDirectory()
1302 self.close(self["filelist"].getFilename())
1304 def createDirectory(self):
1305 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1307 def createDirectoryCB(self, retval = None):
1310 if retval is not None:
1311 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1312 if not path.exists(newdir):
1313 os.system("mkdir %s"%newdir)
1314 self.filelist.refresh()
1317 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1319 def deleteDirectory(self):
1322 if self["filelist"].getCurrentDirectory() is not None:
1323 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1324 delDir = self["filelist"].getFilename()
1325 if path.exists(delDir):
1326 os.system("rmdir '%s'"%delDir)
1327 if path.exists(delDir):
1328 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1329 self.filelist.refresh()
1332 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1337 class MessageBoxConfirm(MessageBox):
1339 <screen position="center,center" size="620,10" title="Message">
1340 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1341 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1342 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1343 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1344 <widget name="list" position="100,100" size="380,375" transparent="1" />
1345 <applet type="onLayoutFinish">
1346 # this should be factored out into some helper code, but currently demonstrates applets.
1347 from enigma import eSize, ePoint
1349 orgwidth = self.instance.size().width()
1350 orgheight = self.instance.size().height()
1351 orgpos = self.instance.position()
1352 textsize = self["text"].getSize()
1354 # y size still must be fixed in font stuff...
1355 textsize = (textsize[0] + 50, textsize[1] + 50)
1357 if self.type == self.TYPE_YESNO:
1359 wsizex = textsize[0] + 60
1360 wsizey = textsize[1] + offset
1361 if (280 > wsizex):
1363 wsize = (wsizex, wsizey)
1366 self.instance.resize(eSize(*wsize))
1369 self["text"].instance.resize(eSize(*textsize))
1372 listsize = (wsizex, 50)
1373 self["list"].instance.move(ePoint(0, textsize[1]))
1374 self["list"].instance.resize(eSize(*listsize))
1378 newheight = wsize[1]
1379 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1384 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1385 class DeviceManagerConfig():
1387 self.configList = []
1389 def getConfigList(self):
1390 return self.configList
1392 def updateConfigList(self):
1394 self.configList = []
1395 file = open("/proc/mounts")
1396 mounts = file.readlines()
1399 if x.startswith("/dev/sd"):
1400 device = x.split()[0].split('/dev/')[1]
1401 mountpoint = x.split()[1]
1402 if mountpoint.startswith('/autofs'):
1404 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1405 if uuid != '' and mountpoint != '':
1406 self.configList.append([uuid, mountpoint])
1409 print "updateConfigList failed!"
1411 def loadConfig(self):
1412 if not fileExists(dmconfigfile):
1413 os.system("touch %s" % dmconfigfile)
1414 self.configList = []
1415 data = file(dmconfigfile).read().split('\n')
1417 if line.find(':') != -1:
1418 (uuid, mountpoint) = line.split(':')
1419 if uuid != '' and mountpoint != '':
1420 self.configList.append([uuid, mountpoint])
1422 def saveConfig(self):
1423 confFile = open(dmconfigfile,'w')
1425 for line in self.configList:
1426 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1427 confFile.write(data)
1430 def appendConfig(self, uuid, mountpoint):
1431 for x in self.configList:
1432 if x[0] == uuid or x[1] == mountpoint:
1433 self.configList.remove(x)
1434 self.configList.append([uuid, mountpoint])
1436 def removeConfig(self, value):
1437 for x in self.configList:
1438 if x[0] == value or x[1] == value:
1439 self.configList.remove(x)
1441 devicemanagerconfig = DeviceManagerConfig()
1443 class deviceManagerHotplug:
1445 self.hotplugActive = True
1447 def setHotplugActive(self,value=True):
1449 self.hotplugActive = True
1451 self.hotplugActive = False
1453 def printDebug(self):
1454 for p in harddiskmanager.partitions:
1455 print " # partition : %s %s %s %s %s(mp, des, f_mounted, is_hot, dev)"%(p.mountpoint, p.description, p.force_mounted, p.is_hotplug,p.device)
1457 def doMount(self, uuid, devpath, mountpoint, filesystem):
1458 # check current device mounted on another mountpoint.
1460 mp_list = deviceinfo.checkMountDev(devpath)
1462 if mp != mountpoint and path.ismount(mp):
1463 deviceinfo.umountByMountpoint(mp)
1464 # check another device mounted on configmountpoint
1466 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1467 for devpath_ in devpath_list:
1468 if devpath_ != devpath:
1469 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1472 # print "[DeviceManager] doMount"
1473 if not path.exists(mountpoint):
1474 os.system("mkdir %s"%mountpoint)
1475 if path.exists(mountpoint):
1476 if not path.ismount(mountpoint):
1477 if filesystem == "ntfs":
1478 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1479 elif filesystem is None:
1480 cmd = "mount %s %s"%(devpath, mountpoint)
1482 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1483 print "[DeviceManager] cmd : %s"%cmd
1485 if not deviceinfo.isMounted(devpath, mountpoint):
1486 print "[DeviceManager] %s doMount failed!"%devpath
1489 # Update partition Info, add
1490 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1492 def doUmount(self, device, mountpoint):
1493 devpath = "/dev/"+device
1494 mountpoints = deviceinfo.checkMountDev(devpath)
1495 if len(mountpoints) == 0:
1497 for mp in mountpoints:
1498 cmd = "umount %s"%devpath
1499 print "[DeviceManager] cmd : %s"%cmd
1502 def addHotPlugDevice(self, partition):
1503 device = partition.device
1504 devpath = "/dev/"+device
1506 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1509 os.system("sleep 1")
1510 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1512 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1515 devicemanagerconfig.loadConfig()
1516 configList = devicemanagerconfig.getConfigList()
1518 for line in configList:
1519 if uuid == line[0].strip():
1520 mountpoint = line[1].strip()
1522 if mountpoint is None:
1525 if deviceinfo.isMounted(devpath, mountpoint):
1527 # print "[DeviceManagerHotplug] already mounted"
1529 self.doMount(uuid, devpath, mountpoint, filesystem)
1531 def removeHotplugDevice(self, partition):
1532 self.doUmount(partition.device, partition.mountpoint)
1534 def getHotplugAction(self, action, partition):
1535 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1537 if partition.device is None or not partition.device.startswith("sd"):
1539 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1542 self.addHotPlugDevice(partition)
1543 elif action == 'remove':
1544 self.removeHotplugDevice(partition)
1546 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1547 device = path.basename(devpath)
1548 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1549 # check already appended to partition list
1550 for x in harddiskmanager.partitions:
1551 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1554 from Components.Harddisk import Partition
1555 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1556 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1557 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1558 harddiskmanager.partitions.append(p)
1559 harddiskmanager.on_partition_list_change("add", p)
1561 def autoMountOnStartup(self):
1562 devicemanagerconfig.loadConfig()
1563 configList = devicemanagerconfig.getConfigList()
1566 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1568 devpath = uuid = filesystem = ""
1569 devpath = line.split(':')[0]
1570 if line.find(" UUID=") != -1:
1571 uuid = line.split(" UUID=")[1].split(' ')[0]
1572 if line.find(" TYPE=") != -1:
1573 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1574 blkiddata.append((devpath, uuid, filesystem))
1576 for c in configList:
1577 uuid_cfg = c[0].strip()
1578 mountpoint_cfg = c[1].strip()
1579 for (devpath, uuid, filesystem) in blkiddata:
1580 if uuid_cfg == uuid:
1582 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1583 # print "[Devicemanager startup] already mounted"
1584 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1586 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1587 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1589 def umountOnShutdown(self):
1590 devicemanagerconfig.loadConfig()
1591 configList = devicemanagerconfig.getConfigList()
1594 data = file('/proc/mounts').read().split('\n')
1596 if not x.startswith('/dev/sd'):
1598 devpath, mountpoint = x.split()[:2]
1599 mounts.append((path.basename(devpath), mountpoint))
1601 data = self.getBlkidInfo()
1603 for c in configList:
1604 uuid_cfg = c[0].strip()
1605 mountpoint_cfg = c[1].strip()
1607 if uuid_cfg in data.keys():
1608 device_cfg = data[uuid_cfg]
1609 if device_cfg is None:
1611 for (device, mountpoint) in mounts:
1612 if device_cfg == device:
1613 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1614 self.doUmount(device, mountpoint)
1616 def getBlkidInfo(self):
1618 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1619 for line in blkid_data.split('\n'):
1620 # print "[DeviceManager] getBlkidInfo line : ",line
1622 device = path.basename(line.split(':')[0])
1623 if line.find(" UUID=") != -1:
1624 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1625 data[blkid_uuid] = device
1628 devicemanagerhotplug = deviceManagerHotplug()
1630 def DeviceManagerhotplugDeviceStart(action, device):
1631 devicemanagerhotplug.getHotplugAction(action, device)
1633 def callBackforDeviceManager(session, callback_result = False):
1634 if callback_result == True:
1635 session.open(DeviceManager)
1637 def checkMounts(session):
1639 noMountable_dev = ""
1640 for blockdev in listdir("/sys/block"):
1641 devpath = "/sys/block/" + blockdev
1642 dev = int(readFile(devpath + "/dev").split(':')[0])
1643 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1646 noMountable_partitions = []
1647 for partition in listdir(devpath):
1648 if not partition.startswith(blockdev):
1650 partitions.append(partition)
1651 if os.access('/autofs/'+partition,0) is False:
1652 noMountable_partitions.append(partition)
1653 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1654 if noMountable_dev != "":
1655 noMountable_dev += ' '
1656 noMountable_dev += blockdev
1658 if noMountable_dev != "":
1659 print "Umountable partitions found."
1660 InfoText = _("No mountable devices found.! (%s)\nDo you want to open DeviceManager and do initialize or format this device?\n\n(Open 'Menu->Setup->System -> Harddisk -> DeviceManager'\n and press MENU button to deactivate this check.)")%noMountable_dev
1661 AddNotificationWithCallback(
1662 boundFunction(callBackforDeviceManager, session),
1663 MessageBox, InfoText, timeout = 60, default = False
1666 print "checkMounts failed!"
1668 def sessionstart(reason, **kwargs):
1670 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1671 session = kwargs["session"]
1672 checkMounts(session)
1673 if config.plugins.devicemanager.hotplug_enable.value:
1674 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1676 if config.plugins.devicemanager.hotplug_enable.value:
1677 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1679 def autostart(reason, **kwargs):
1682 # check at first enigma2 start
1683 if not fileExists(dmconfigfile):
1684 print "[DeviceManager] autostart : check devices at first start"
1685 sda_isremovable = False
1687 os.system("touch %s"%dmconfigfile)
1689 sda_data = popen("cat /proc/partitions | grep sda1").read()
1691 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1692 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1693 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1696 cfg += '"%s":/media/hdd\n'%sda_UUID
1697 confFile = open(dmconfigfile,'w')
1700 if not path.exists("/media/hdd"):
1701 os.system("mkdir -p /media/hdd")
1703 devicemanagerhotplug.autoMountOnStartup()
1705 print "[DeviceManager] autostart failed!"
1707 devicemanagerhotplug.umountOnShutdown()
1709 def menu(menuid, **kwargs):
1710 if menuid == "system":
1711 return [(_("DeviceManager"), main, "device_manager", 50)]
1714 def main(session, **kwargs):
1715 session.open(DeviceManager)
1717 def Plugins(path, **kwargs):
1719 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1720 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1721 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1724 class MessageBox_2(MessageBox):
1725 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1726 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1727 self.skinName = "MessageBox"
1728 self.closeTimer = eTimer()
1729 self.closeTimer.callback.append(self.msg_close)
1730 self.devicemanager_ret = False
1731 self.devicemanager_msg = ""
1733 def msg_close(self):
1734 self.close(self.devicemanager_ret, self.devicemanager_msg)
1736 def run_close(self, ret, msg=""):
1737 self.devicemanager_ret = ret
1738 self.devicemanager_msg = msg
1739 self.closeTimer.start(100,True)
1741 def createSummary(self):
1742 return MessageBox_2_Summary
1744 class MessageBox_2_Summary(Screen):
1746 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1747 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />