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)
883 def timerStart(self):
884 self.formatStartTimer.start(100,True)
886 def DeviceFormatStart(self):
887 print "DeviceFormatStart : ", self.partition,
888 print "Filesystem : ",self.newfstype
889 device = self.partition["partition"]
890 devicepath = "/dev/"+device
891 mountpoint = self.partition["mountpoint"]
892 fssize = self.partition["size"]
893 newfstype = self.newfstype
895 msg = _("Format filesystem, please wait ...")
896 msg += _("\nDevice : %s")%(devicepath)
897 msg += _("\nFilesystem : %s")%(newfstype)
898 msg += _("\nSize : %s")%(byteConversion(fssize))
899 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
901 self.doumountPartition()
903 self.umountPartitionFinished("NORESULT", 0)
905 def doumountPartition(self):
906 oldfstype = self.partition["fstype"]
907 newfstype = self.newfstype
909 if newfstype == oldfstype:
910 device = self.partition["partition"]
912 device = self.partition["partition"][:3]
914 mounts = file('/proc/mounts','r')
915 for line in mounts.readlines():
916 if line.startswith("/dev/%s"%device):
917 cmd += "umount %s;"%line.split()[0]
918 self.unmountedList.append([line.split()[0], line.split()[1]])
919 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
921 def umountPartitionFinished(self, result, retval, extra_args = None):
922 partition = self.partition["partition"]
923 oldfstype = self.partition["fstype"]
924 newfstype = self.newfstype
926 if oldfstype == newfstype:
927 self.changePartitionIDFinished("NORESULT", 0)
929 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
930 if newfstype[:3] == "ext":
934 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
936 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
937 self.msgWaiting.run_close(False,errorMsg)
939 def changePartitionIDFinished(self, result, retval, extra_args = None):
940 device = self.partition["partition"][:3]
941 mountpoint = self.partition["mountpoint"]
942 oldfstype = self.partition["fstype"]
943 newfstype = self.newfstype
945 if oldfstype == newfstype:
946 self.refreshPartitionFinished("NORESULT", 0)
948 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
949 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
951 errorMsg = _("Can not change the partition ID for %s")%device
952 self.msgWaiting.run_close(False,errorMsg)
954 def refreshPartitionFinished(self, result, retval, extra_args = None):
955 print "refreshPartitionFinished!"
956 partition = self.partition["partition"]
957 mountpoint = self.partition["mountpoint"]
958 size = int(self.partition["size"])/1024/1024
959 oldfstype = self.partition["fstype"]
960 newfstype = self.newfstype
962 if newfstype == "ext4":
963 cmd = "/sbin/mkfs.ext4 -F "
965 cmd += "-T largefile "
966 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
967 elif newfstype == "ext3":
968 cmd = "/sbin/mkfs.ext3 -F "
970 cmd += "-T largefile "
971 cmd += "-m0 /dev/" + partition
972 elif newfstype == "ext2":
973 cmd = "/sbin/mkfs.ext2 -F "
975 cmd += "-T largefile "
976 cmd += "-m0 /dev/" + partition
977 elif newfstype == "vfat":
978 if size > 4 * 1024 * 1024:
979 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
981 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
982 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
984 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
985 self.msgWaiting.run_close(False,errorMsg)
987 def mkfsFinished(self, result, retval, extra_args = None):
988 print "mkfsFinished!"
989 partition = self.partition["partition"]
992 if len(self.unmountedList) == 0:
993 self.doMountFinished("NORESULT",0)
994 for x in self.unmountedList:
995 cmd += "mount %s %s;"%(x[0], x[1])
996 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
998 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
999 self.msgWaiting.run_close(False, text)
1001 def doMountFinished(self, result, retval, extra_args = None):
1002 print "doMountFinished!"
1003 text = _("Format finished sucessfully.")
1004 self.msgWaiting.run_close(True, text)
1006 def msgWaitingCB(self, ret, msg):
1008 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
1010 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
1012 def exit(self, ret):
1019 self.blockDeviceList = []
1021 def getBlockDevices(self):
1022 return self.blockDeviceList
1025 self.blockDeviceList = []
1026 self.getBlockDeviceList()
1028 def getBlockDeviceList(self):
1029 print "get block device Infomations..."
1030 for blockdev in listdir("/sys/block"):
1031 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
1032 if not blacklisted and not error:
1033 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1035 blockDevice["blockdev"] = blockdev # str
1036 blockDevice["removable"] = removable # bool [True, False]
1037 blockDevice["partitions"] = partitions # list
1038 blockDevice["size"] = size # str
1039 blockDevice["model"] = model # str
1040 blockDevice["vendor"] = vendor # str
1041 self.blockDeviceList.append(blockDevice)
1043 def getBlockDeviceInfo(self, blockdev):
1044 devpath = "/sys/block/" + blockdev
1053 dev = int(readFile(devpath + "/dev").split(':')[0])
1054 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1056 return error, blacklisted, removable, partitions, size, model, vendor
1057 removable = bool(int(readFile(devpath + "/removable")))
1058 size = str(int(readFile(devpath + "/size").strip())*512)
1059 model = readFile(devpath + "/device/model")
1060 vendor = readFile(devpath + "/device/vendor")
1061 for partition in listdir(devpath):
1062 if partition[:len(blockdev)] != blockdev:
1064 partitions.append(partition)
1067 return error, blacklisted, removable, partitions, size, model, vendor
1069 def getPartitionInfo(self, partition):
1070 mountPoint = self.getPartitionMountpoint(partition)
1071 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1072 size_total = self.getPartitionSize(partition)
1074 if mountPoint != "":
1075 size_free = self.getPartitionFree(mountPoint)
1077 partitionInfo["partition"] = partition
1078 partitionInfo["mountpoint"] = mountPoint
1079 partitionInfo["uuid"] = uuid
1080 partitionInfo["fstype"] = fsType
1081 partitionInfo["size"] = size_total
1082 partitionInfo["free"] = size_free
1083 return partitionInfo
1085 def getPartitionMountpoint(self, partition):
1086 mounts = file('/proc/mounts').read().split('\n')
1088 if not x.startswith('/'):
1090 devpath, mountpoint, = x.split()[:2]
1091 if mountpoint.startswith('/autofs'):
1093 if path.basename(devpath) == partition:
1097 def getPartitionBlkidInfo(self, partition):
1098 parttionDev = "/dev/"+str(partition)
1101 cmd = "blkid -c /dev/null "+str(parttionDev)
1103 line = popen(cmd).readline().strip()
1104 if not line.startswith(parttionDev):
1105 return (uuid, partitionType)
1106 # print "Blikd %s : %s"%(parttionDev, line)
1107 if line.find(" UUID=") != -1:
1108 uuid = line.split(" UUID=")[1].split(' ')[0]
1109 if line.find(" TYPE=") != -1:
1110 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1112 print "get blkid info error (%s)"%cmd
1113 return (uuid, partitionType)
1115 def getPartitionSize(self, partition):
1116 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1118 size = readFile(devpath + "/size")
1119 return str(int(size)*512)
1123 def getPartitionFree(self, mountPoint):
1125 stat = statvfs(mountPoint)
1126 size_free = stat.f_bfree*stat.f_bsize
1131 def checkMountPoint(self, check_mountpoint):
1134 mounts = file('/proc/mounts').read().split('\n')
1136 if not x.startswith('/'):
1138 devpath, mountpoint = x.split()[:2]
1139 if mountpoint == check_mountpoint:
1145 def checkMountDev(self, device):
1148 mounts = file('/proc/mounts').read().split('\n')
1150 if not x.startswith('/'):
1152 devpath, mountpoint = x.split()[:2]
1153 if devpath == device:
1154 res.append(mountpoint)
1159 def isMounted(self, devpath, mountpoint):
1161 mounts = file('/proc/mounts').read().split('\n')
1163 if not x.startswith('/'):
1165 _devpath, _mountpoint = x.split()[:2]
1166 if devpath == _devpath and mountpoint == _mountpoint:
1172 def isMountable(self, partition):
1173 autofsPath = "/autofs/"+partition.device
1176 os.listdir(autofsPath)
1182 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1183 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1184 if mountpoint[-1] == '/':
1185 mountpoint = mountpoint[:-1]
1186 data = file('/etc/fstab').read().split('\n')
1188 if not line.startswith('/'):
1190 dev, mp, ms = line.split()[0:3]
1191 if uuid is not None and dev.startswith('UUID'):
1192 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1193 # print " >> line : ", line
1195 elif dev == devpath and mp == mountpoint and ms == 'auto':
1196 # print " >> line : ", line
1200 def umountByMountpoint(self, mountpoint):
1201 if mountpoint is None:
1204 if path.ismount(mountpoint):
1205 cmd = "umount " + mountpoint
1206 print "[DeviceManager] ", cmd
1209 print "Umount by mountpoint failed!"
1210 if not path.ismount(mountpoint):
1214 def umountByDevpath(self, devpath):
1215 cmd = "umount " + devpath
1216 print "[DeviceManager] ", cmd
1219 deviceinfo = DeviceInfo()
1221 class MountpointBrowser(Screen):
1223 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1224 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1225 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1226 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1227 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1228 <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" />
1229 <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" />
1230 <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" />
1231 <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" />
1232 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1233 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1236 def __init__(self, session):
1237 Screen.__init__(self, session)
1238 self["key_red"] = StaticText(_("Cancel"))
1239 self["key_green"] = StaticText(_("Select"))
1240 self["key_yellow"] = StaticText(_("Create directory"))
1241 self["key_blue"] = StaticText("Delete directory")
1242 directory = "/media/"
1243 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1244 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1245 self["filelist"] = self.filelist
1247 self["shortcuts"] = ActionMap(["ColorActions"],
1250 "green": self.select,
1251 "yellow": self.createDirectory,
1252 "blue": self.deleteDirectory,
1255 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1257 "cancel": self.exit,
1262 if self.filelist.canDescent():
1263 self.filelist.descent()
1266 if self["filelist"].getCurrentDirectory() is not None:
1267 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1268 self.filelist.descent()
1269 currDir = self["filelist"].getCurrentDirectory()
1272 self.close(self["filelist"].getFilename())
1274 def createDirectory(self):
1275 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1277 def createDirectoryCB(self, retval = None):
1280 if retval is not None:
1281 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1282 if not path.exists(newdir):
1283 os.system("mkdir %s"%newdir)
1284 self.filelist.refresh()
1287 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1289 def deleteDirectory(self):
1292 if self["filelist"].getCurrentDirectory() is not None:
1293 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1294 delDir = self["filelist"].getFilename()
1295 if path.exists(delDir):
1296 os.system("rmdir '%s'"%delDir)
1297 if path.exists(delDir):
1298 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1299 self.filelist.refresh()
1302 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1307 class MessageBoxConfirm(MessageBox):
1309 <screen position="center,center" size="620,10" title="Message">
1310 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1311 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1312 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1313 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1314 <widget name="list" position="100,100" size="380,375" transparent="1" />
1315 <applet type="onLayoutFinish">
1316 # this should be factored out into some helper code, but currently demonstrates applets.
1317 from enigma import eSize, ePoint
1319 orgwidth = self.instance.size().width()
1320 orgheight = self.instance.size().height()
1321 orgpos = self.instance.position()
1322 textsize = self["text"].getSize()
1324 # y size still must be fixed in font stuff...
1325 textsize = (textsize[0] + 50, textsize[1] + 50)
1327 if self.type == self.TYPE_YESNO:
1329 wsizex = textsize[0] + 60
1330 wsizey = textsize[1] + offset
1331 if (280 > wsizex):
1333 wsize = (wsizex, wsizey)
1336 self.instance.resize(eSize(*wsize))
1339 self["text"].instance.resize(eSize(*textsize))
1342 listsize = (wsizex, 50)
1343 self["list"].instance.move(ePoint(0, textsize[1]))
1344 self["list"].instance.resize(eSize(*listsize))
1348 newheight = wsize[1]
1349 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1354 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1355 class DeviceManagerConfig():
1357 self.configList = []
1359 def getConfigList(self):
1360 return self.configList
1362 def updateConfigList(self):
1364 self.configList = []
1365 file = open("/proc/mounts")
1366 mounts = file.readlines()
1369 if x.startswith("/dev/sd"):
1370 device = x.split()[0].split('/dev/')[1]
1371 mountpoint = x.split()[1]
1372 if mountpoint.startswith('/autofs'):
1374 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1375 if uuid != '' and mountpoint != '':
1376 self.configList.append([uuid, mountpoint])
1379 print "updateConfigList failed!"
1381 def loadConfig(self):
1382 if not fileExists(dmconfigfile):
1383 os.system("touch %s" % dmconfigfile)
1384 self.configList = []
1385 data = file(dmconfigfile).read().split('\n')
1387 if line.find(':') != -1:
1388 (uuid, mountpoint) = line.split(':')
1389 if uuid != '' and mountpoint != '':
1390 self.configList.append([uuid, mountpoint])
1392 def saveConfig(self):
1393 confFile = open(dmconfigfile,'w')
1395 for line in self.configList:
1396 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1397 confFile.write(data)
1400 def appendConfig(self, uuid, mountpoint):
1401 for x in self.configList:
1402 if x[0] == uuid or x[1] == mountpoint:
1403 self.configList.remove(x)
1404 self.configList.append([uuid, mountpoint])
1406 def removeConfig(self, value):
1407 for x in self.configList:
1408 if x[0] == value or x[1] == value:
1409 self.configList.remove(x)
1411 devicemanagerconfig = DeviceManagerConfig()
1413 class deviceManagerHotplug:
1415 self.hotplugActive = True
1417 def printDebug(self):
1418 for p in harddiskmanager.partitions:
1419 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)
1421 def doMount(self, uuid, devpath, mountpoint, filesystem):
1422 # check current device mounted on another mountpoint.
1424 mp_list = deviceinfo.checkMountDev(devpath)
1426 if mp != mountpoint and path.ismount(mp):
1427 deviceinfo.umountByMountpoint(mp)
1428 # check another device mounted on configmountpoint
1430 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1431 for devpath_ in devpath_list:
1432 if devpath_ != devpath:
1433 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1436 # print "[DeviceManager] doMount"
1437 if not path.exists(mountpoint):
1438 os.system("mkdir %s"%mountpoint)
1439 if path.exists(mountpoint):
1440 if not path.ismount(mountpoint):
1441 if filesystem == "ntfs":
1442 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1443 elif filesystem is None:
1444 cmd = "mount %s %s"%(devpath, mountpoint)
1446 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1447 print "[DeviceManager] cmd : %s"%cmd
1449 if not deviceinfo.isMounted(devpath, mountpoint):
1450 print "[DeviceManager] %s doMount failed!"%devpath
1453 # Update partition Info, add
1454 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1456 def doUmount(self, device, mountpoint):
1457 devpath = "/dev/"+device
1458 mountpoints = deviceinfo.checkMountDev(devpath)
1459 if len(mountpoints) == 0:
1461 for mp in mountpoints:
1462 cmd = "umount %s"%devpath
1463 print "[DeviceManager] cmd : %s"%cmd
1466 def addHotPlugDevice(self, partition):
1467 device = partition.device
1468 devpath = "/dev/"+device
1470 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1473 os.system("sleep 1")
1474 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1476 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1479 devicemanagerconfig.loadConfig()
1480 configList = devicemanagerconfig.getConfigList()
1482 for line in configList:
1483 if uuid == line[0].strip():
1484 mountpoint = line[1].strip()
1486 if mountpoint is None:
1489 if deviceinfo.isMounted(devpath, mountpoint):
1491 # print "[DeviceManagerHotplug] already mounted"
1493 self.doMount(uuid, devpath, mountpoint, filesystem)
1495 def removeHotplugDevice(self, partition):
1496 self.doUmount(partition.device, partition.mountpoint)
1498 def getHotplugAction(self, action, partition):
1499 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1501 if partition.device is None or not partition.device.startswith("sd"):
1503 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1506 self.addHotPlugDevice(partition)
1507 elif action == 'remove':
1508 self.removeHotplugDevice(partition)
1510 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1511 device = path.basename(devpath)
1512 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1513 # check already appended to partition list
1514 for x in harddiskmanager.partitions:
1515 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1518 from Components.Harddisk import Partition
1519 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1520 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1521 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1522 harddiskmanager.partitions.append(p)
1523 harddiskmanager.on_partition_list_change("add", p)
1525 def autoMountOnStartup(self):
1526 devicemanagerconfig.loadConfig()
1527 configList = devicemanagerconfig.getConfigList()
1530 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1532 devpath = uuid = filesystem = ""
1533 devpath = line.split(':')[0]
1534 if line.find(" UUID=") != -1:
1535 uuid = line.split(" UUID=")[1].split(' ')[0]
1536 if line.find(" TYPE=") != -1:
1537 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1538 blkiddata.append((devpath, uuid, filesystem))
1540 for c in configList:
1541 uuid_cfg = c[0].strip()
1542 mountpoint_cfg = c[1].strip()
1543 for (devpath, uuid, filesystem) in blkiddata:
1544 if uuid_cfg == uuid:
1546 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1547 # print "[Devicemanager startup] already mounted"
1548 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1550 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1551 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1553 def umountOnShutdown(self):
1554 devicemanagerconfig.loadConfig()
1555 configList = devicemanagerconfig.getConfigList()
1558 data = file('/proc/mounts').read().split('\n')
1560 if not x.startswith('/dev/sd'):
1562 devpath, mountpoint = x.split()[:2]
1563 mounts.append((path.basename(devpath), mountpoint))
1565 data = self.getBlkidInfo()
1567 for c in configList:
1568 uuid_cfg = c[0].strip()
1569 mountpoint_cfg = c[1].strip()
1571 if uuid_cfg in data.keys():
1572 device_cfg = data[uuid_cfg]
1573 if device_cfg is None:
1575 for (device, mountpoint) in mounts:
1576 if device_cfg == device:
1577 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1578 self.doUmount(device, mountpoint)
1580 def getBlkidInfo(self):
1582 blkid_data = os.popen("blkid -c /dev/NULL /dev/sd*").read()
1583 for line in blkid_data.split('\n'):
1584 # print "[DeviceManager] getBlkidInfo line : ",line
1586 device = path.basename(line.split(':')[0])
1587 if line.find(" UUID=") != -1:
1588 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1589 data[blkid_uuid] = device
1592 devicemanagerhotplug = deviceManagerHotplug()
1594 def DeviceManagerhotplugDeviceStart(action, device):
1595 devicemanagerhotplug.getHotplugAction(action, device)
1597 def callBackforDeviceManager(session, callback_result = False):
1598 if callback_result == True:
1599 session.open(DeviceManager)
1601 def checkMounts(session):
1603 noMountable_dev = ""
1604 for blockdev in listdir("/sys/block"):
1605 devpath = "/sys/block/" + blockdev
1606 dev = int(readFile(devpath + "/dev").split(':')[0])
1607 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1610 noMountable_partitions = []
1611 for partition in listdir(devpath):
1612 if not partition.startswith(blockdev):
1614 partitions.append(partition)
1615 if os.access('/autofs/'+partition,0) is False:
1616 noMountable_partitions.append(partition)
1617 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1618 if noMountable_dev != "":
1619 noMountable_dev += ' '
1620 noMountable_dev += blockdev
1622 if noMountable_dev != "":
1623 print "Umountable partitions found."
1624 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
1625 AddNotificationWithCallback(
1626 boundFunction(callBackforDeviceManager, session),
1627 MessageBox, InfoText, timeout = 60, default = False
1630 print "checkMounts failed!"
1632 def sessionstart(reason, **kwargs):
1634 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1635 session = kwargs["session"]
1636 checkMounts(session)
1637 if config.plugins.devicemanager.hotplug_enable.value:
1638 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1640 if config.plugins.devicemanager.hotplug_enable.value:
1641 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1643 def autostart(reason, **kwargs):
1646 # check at first enigma2 start
1647 if not fileExists(dmconfigfile):
1648 print "[DeviceManager] autostart : check devices at first start"
1649 sda_isremovable = False
1651 os.system("touch %s"%dmconfigfile)
1653 sda_data = popen("cat /proc/partitions | grep sda1").read()
1655 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1656 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1657 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1660 cfg += '"%s":/media/hdd\n'%sda_UUID
1661 confFile = open(dmconfigfile,'w')
1664 if not path.exists("/media/hdd"):
1665 os.system("mkdir -p /media/hdd")
1667 devicemanagerhotplug.autoMountOnStartup()
1669 print "[DeviceManager] autostart failed!"
1671 devicemanagerhotplug.umountOnShutdown()
1673 def menu(menuid, **kwargs):
1674 if menuid == "system":
1675 return [(_("DeviceManager"), main, "device_manager", 50)]
1678 def main(session, **kwargs):
1679 session.open(DeviceManager)
1681 def Plugins(path, **kwargs):
1683 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1684 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1685 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1688 class MessageBox_2(MessageBox):
1689 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1690 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1691 self.skinName = "MessageBox"
1692 self.closeTimer = eTimer()
1693 self.closeTimer.callback.append(self.msg_close)
1694 self.devicemanager_ret = False
1695 self.devicemanager_msg = ""
1697 def msg_close(self):
1698 self.close(self.devicemanager_ret, self.devicemanager_msg)
1700 def run_close(self, ret, msg=""):
1701 self.devicemanager_ret = ret
1702 self.devicemanager_msg = msg
1703 self.closeTimer.start(100,True)
1705 def createSummary(self):
1706 return MessageBox_2_Summary
1708 class MessageBox_2_Summary(Screen):
1710 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1711 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />