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)
525 def timerStart(self):
526 self.initStartTimer.start(100,True)
528 def confirmMessage(self):
529 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
530 self.session.openWithCallback(self.confirmed, MessageBox, message)
532 def confirmed(self, ret):
534 self.InitializeStart()
538 def exit(self, ret = True):
541 def unmountAll(self, device):
542 mounts = file('/proc/mounts').read().split('\n')
546 if not line.startswith("/dev/" + device):
548 cmd += "umount %s ;"% line.split()[0]
549 print "[DeviceManager] %s"%cmd
552 mounts = file('/proc/mounts').read().split('\n')
554 if line.startswith("/dev/" + device):
558 def InitializeStart(self):
559 self.InputPartitionSize_step1()
561 def InputPartitionSize_step1(self):
562 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
564 def InputPartitionSize_step1_CB(self, ret):
565 if ret is not None and int(ret) in range(1,5): # ret in 1~4
566 self.inputbox_partitions = int(ret)
567 self.InputPartitionSize_step2()
569 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
571 def InputPartitionSize_step2(self):
572 current_partition = len(self.inputbox_partitionSizeList)+1
573 if self.inputbox_partitionSizeRemain == 0:
574 self.initInitializeConfirm()
575 elif current_partition == self.inputbox_partitions:
576 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
577 self.initInitializeConfirm()
579 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
580 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)
582 def InputPartitionSize_step2_CB(self, ret):
584 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
585 self.InputPartitionSize_step2()
587 self.inputbox_partitionSizeList.append(str(ret))
588 self.inputbox_partitionSizeRemain -= int(ret)
589 self.InputPartitionSize_step2()
591 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
593 def initInitializeConfirm(self):
594 # print self.inputbox_partitionSizeList
596 for index in range(len(self.inputbox_partitionSizeList)):
597 print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
598 partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
599 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
601 def initInitializeConfirmCB(self,ret):
603 self.initInitialize()
607 def initInitialize(self):
608 if not self.unmountAll(self.device):
609 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
611 msg = _("InitInitializing, please wait ...")
612 msg += _("\nDevice : %s")%self.device
613 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
614 for index in range(len(self.inputbox_partitionSizeList)):
615 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
616 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
618 partitions = len(self.inputbox_partitionSizeList)
620 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
624 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
628 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
629 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
631 def initInitializeFinished(self, result, retval, extra_args = None):
633 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
634 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
636 errorMsg = "initInitializing device Error at /dev/%s"%self.device
637 self.msgWaiting.run_close(False, errorMsg)
639 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
640 cmd = "/bin/umount /dev/%s*" % (self.device)
641 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
643 def initInitializingUmountFinished(self, result, retval, extra_args = None):
644 partitions = open("/proc/partitions")
645 self.devicenumber = 0
646 self.newpartitions = 0
647 for part in partitions:
648 res = re.sub("\s+", " ", part).strip().split(" ")
649 if res and len(res) == 4 and res[3][:3] == self.device:
650 if len(res[3]) > 3 and res[3][:2] == "sd":
651 self.newpartitions += 1
653 self.msgWaiting.run_close(True)
654 # self.createFilesystem(self.newpartitions)
656 def createFilesystem(self, newpartitions):
657 self.devicenumber = self.devicenumber + 1
658 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
659 shortdevicename = self.device + str(self.devicenumber)
661 partitions = open("/proc/partitions")
662 for part in partitions:
663 res = re.sub("\s+", " ", part).strip().split(" ")
664 if res and len(res) == 4:
665 if res[3] == shortdevicename:
666 partitionsize = int(res[2])
670 if partitionsize > 64 * 1024 * 1024:
671 cmd = "/sbin/mkfs.ext3 "
674 cmd = "/sbin/mkfs.ext2 "
677 if partitionsize > 2 * 1024 * 1024:
678 cmd += "-T largefile "
679 cmd += "-m0 " + fulldevicename
681 msg = _("Create filesystem, please wait ...")
682 msg += _("\nPartition : %s") % (fulldevicename)
683 msg += _("\nFilesystem : %s") % (filesystem)
684 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
685 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
686 self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
688 def createFilesystemFinished(self, result, retval, extra_args = None):
689 device = extra_args[0]
690 fulldevicename = extra_args[1]
692 self.msgWaitingMkfs.run_close(True)
694 errorMsg = _("Creating filesystem Error")
695 if fulldevicename is not None:
696 errorMsg += _(" at /dev/%s")%fulldevicename
697 self.msgWaitingMkfs.run_close(False, errorMsg)
699 def createFilesystemStart(self):
700 self.createFilesystem(self.newpartitions)
702 def msgWaitingCB(self, ret, msg=""):
704 self.createFSStartTimer.start(100,True)
708 self.exitMessageTimer.start(100,True)
710 def msgWaitingMkfsCB(self, ret, msg=""):
711 if self.devicenumber < self.newpartitions:
712 self.createFSStartTimer.start(100,True)
716 self.msg = _("Device Initialization finished sucessfully!")
717 self.updateDeviceInfo()
718 self.exitMessageTimer.start(100,True)
722 self.exitMessageTimer.start(100,True)
724 def exitMessage(self):
726 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
728 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
730 def updateDeviceInfo(self):
731 # update devicemanager configs
732 devicemanagerconfig.updateConfigList()
736 # device check start..
737 class DeviceCheck(Screen):
738 skin = """<screen position="0,0" size="0,0"/>"""
739 def __init__(self, session, partition):
740 Screen.__init__(self, session)
741 self.session = session
742 self.deviceCheckConsole = Console()
743 self.partition = partition
744 self.onLayoutFinish.append(self.timerStart)
745 self.checkStartTimer = eTimer()
746 self.checkStartTimer.callback.append(self.confirmMessage)
748 def timerStart(self):
749 self.checkStartTimer.start(100,True)
751 def confirmMessage(self):
752 fssize = self.partition["size"]
753 if long(fssize) > 1024*1024*1024*16:
754 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
755 self.session.openWithCallback(self.confirmed, MessageBox, message)
757 self.deviceCheckStart()
759 def confirmed(self, ret):
760 print "confirmed : ",ret
762 self.deviceCheckStart()
766 def deviceCheckStart(self):
767 print "deviceCheckStart "
768 print "partition : ", self.partition
769 device = self.partition["partition"]
770 mountpoint = self.partition["mountpoint"]
771 fstype = self.partition["fstype"]
772 fssize = self.partition["size"]
773 if device is not None and fstype.startswith("ext"):
774 msg = _("Check filesystem, please wait ...")
775 msg += _("\nDevice : /dev/%s")%(device)
776 msg += _("\nFilesystem : %s")%(fstype)
777 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
779 self.doUmountFsck(device, mountpoint, fstype)
781 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
785 def doUmountFsck(self, device, mountpoint, fstype):
786 cmd = "umount /dev/%s" % device
787 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
789 def umountFsckFinished(self, result, retval, extra_args = None):
790 device = extra_args[0]
791 mountpoint = extra_args[1]
792 fstype = extra_args[2]
794 cmd = "fsck." + fstype + " -f -p /dev/" + device
795 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
797 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
798 self.msgWaiting.run_close(False,errorMsg)
800 def fsckFinished(self, result, retval, extra_args = None):
801 device = extra_args[0]
802 mountpoint = extra_args[1]
804 text = _("Filesystem check finished sucessfully")
805 self.msgWaiting.run_close(True, text)
807 text = _("Error checking disk. The disk or filesystem may be damaged")
808 self.msgWaiting.run_close(False, text)
810 def msgWaitingCB(self, ret, msg):
812 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
814 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
816 partition = self.partition["partition"]
817 mountpoint = self.partition["mountpoint"]
818 fstype = self.partition["fstype"]
821 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
823 cmd = "mount /dev/" + partition + " " + mountpoint
824 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
828 def mountPartitionFinished(self, result, retval, extra_args = None):
837 class DeviceFormat(Screen):
838 skin = """<screen position="0,0" size="0,0"/>"""
839 def __init__(self, session, partition, newfstype):
840 Screen.__init__(self, session)
841 self.session = session
842 self.deviceFormatConsole = Console()
843 self.partition = partition
844 self.newfstype = newfstype
845 self.unmountedList = []
846 self.onLayoutFinish.append(self.timerStart)
847 self.formatStartTimer = eTimer()
848 self.formatStartTimer.callback.append(self.DeviceFormatStart)
850 def timerStart(self):
851 self.formatStartTimer.start(100,True)
853 def DeviceFormatStart(self):
854 print "DeviceFormatStart : ", self.partition,
855 print "Filesystem : ",self.newfstype
856 device = self.partition["partition"]
857 devicepath = "/dev/"+device
858 mountpoint = self.partition["mountpoint"]
859 fssize = self.partition["size"]
860 newfstype = self.newfstype
862 msg = _("Format filesystem, please wait ...")
863 msg += _("\nDevice : %s")%(devicepath)
864 msg += _("\nFilesystem : %s")%(newfstype)
865 msg += _("\nSize : %s")%(byteConversion(fssize))
866 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
868 self.doumountPartition()
870 self.umountPartitionFinished("NORESULT", 0)
872 def doumountPartition(self):
873 oldfstype = self.partition["fstype"]
874 newfstype = self.newfstype
876 if newfstype == oldfstype:
877 device = self.partition["partition"]
879 device = self.partition["partition"][:3]
881 mounts = file('/proc/mounts','r')
882 for line in mounts.readlines():
883 if line.startswith("/dev/%s"%device):
884 cmd += "umount %s;"%line.split()[0]
885 self.unmountedList.append([line.split()[0], line.split()[1]])
886 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
888 def umountPartitionFinished(self, result, retval, extra_args = None):
889 partition = self.partition["partition"]
890 oldfstype = self.partition["fstype"]
891 newfstype = self.newfstype
893 if oldfstype == newfstype:
894 self.changePartitionIDFinished("NORESULT", 0)
896 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
897 if newfstype[:3] == "ext":
901 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
903 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
904 self.msgWaiting.run_close(False,errorMsg)
906 def changePartitionIDFinished(self, result, retval, extra_args = None):
907 device = self.partition["partition"][:3]
908 mountpoint = self.partition["mountpoint"]
909 oldfstype = self.partition["fstype"]
910 newfstype = self.newfstype
912 if oldfstype == newfstype:
913 self.refreshPartitionFinished("NORESULT", 0)
915 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
916 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
918 errorMsg = _("Can not change the partition ID for %s")%device
919 self.msgWaiting.run_close(False,errorMsg)
921 def refreshPartitionFinished(self, result, retval, extra_args = None):
922 print "refreshPartitionFinished!"
923 partition = self.partition["partition"]
924 mountpoint = self.partition["mountpoint"]
925 size = int(self.partition["size"])/1024/1024
926 oldfstype = self.partition["fstype"]
927 newfstype = self.newfstype
929 if newfstype == "ext4":
930 cmd = "/sbin/mkfs.ext4 -F "
932 cmd += "-T largefile "
933 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
934 elif newfstype == "ext3":
935 cmd = "/sbin/mkfs.ext3 -F "
937 cmd += "-T largefile "
938 cmd += "-m0 /dev/" + partition
939 elif newfstype == "ext2":
940 cmd = "/sbin/mkfs.ext2 -F "
942 cmd += "-T largefile "
943 cmd += "-m0 /dev/" + partition
944 elif newfstype == "vfat":
945 if size > 4 * 1024 * 1024:
946 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
948 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
949 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
951 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
952 self.msgWaiting.run_close(False,errorMsg)
954 def mkfsFinished(self, result, retval, extra_args = None):
955 print "mkfsFinished!"
956 partition = self.partition["partition"]
959 if len(self.unmountedList) == 0:
960 self.doMountFinished("NORESULT",0)
961 for x in self.unmountedList:
962 cmd += "mount %s %s;"%(x[0], x[1])
963 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
965 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
966 self.msgWaiting.run_close(False, text)
968 def doMountFinished(self, result, retval, extra_args = None):
969 print "doMountFinished!"
970 text = _("Format finished sucessfully.")
971 self.msgWaiting.run_close(True, text)
973 def msgWaitingCB(self, ret, msg):
975 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
977 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
986 self.blockDeviceList = []
988 def getBlockDevices(self):
989 return self.blockDeviceList
992 self.blockDeviceList = []
993 self.getBlockDeviceList()
995 def getBlockDeviceList(self):
996 print "get block device Infomations..."
997 for blockdev in listdir("/sys/block"):
998 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
999 if not blacklisted and not error:
1000 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
1002 blockDevice["blockdev"] = blockdev # str
1003 blockDevice["removable"] = removable # bool [True, False]
1004 blockDevice["partitions"] = partitions # list
1005 blockDevice["size"] = size # str
1006 blockDevice["model"] = model # str
1007 blockDevice["vendor"] = vendor # str
1008 self.blockDeviceList.append(blockDevice)
1010 def getBlockDeviceInfo(self, blockdev):
1011 devpath = "/sys/block/" + blockdev
1020 dev = int(readFile(devpath + "/dev").split(':')[0])
1021 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1023 return error, blacklisted, removable, partitions, size, model, vendor
1024 removable = bool(int(readFile(devpath + "/removable")))
1025 size = str(int(readFile(devpath + "/size").strip())*512)
1026 model = readFile(devpath + "/device/model")
1027 vendor = readFile(devpath + "/device/vendor")
1028 for partition in listdir(devpath):
1029 if partition[:len(blockdev)] != blockdev:
1031 partitions.append(partition)
1034 return error, blacklisted, removable, partitions, size, model, vendor
1036 def getPartitionInfo(self, partition):
1037 mountPoint = self.getPartitionMountpoint(partition)
1038 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1039 size_total = self.getPartitionSize(partition)
1041 if mountPoint != "":
1042 size_free = self.getPartitionFree(mountPoint)
1044 partitionInfo["partition"] = partition
1045 partitionInfo["mountpoint"] = mountPoint
1046 partitionInfo["uuid"] = uuid
1047 partitionInfo["fstype"] = fsType
1048 partitionInfo["size"] = size_total
1049 partitionInfo["free"] = size_free
1050 return partitionInfo
1052 def getPartitionMountpoint(self, partition):
1053 mounts = file('/proc/mounts').read().split('\n')
1055 if not x.startswith('/'):
1057 devpath, mountpoint, = x.split()[:2]
1058 if mountpoint.startswith('/autofs'):
1060 if path.basename(devpath) == partition:
1064 def getPartitionBlkidInfo(self, partition):
1065 parttionDev = "/dev/"+str(partition)
1068 cmd = "blkid -c /dev/null "+str(parttionDev)
1070 line = popen(cmd).readline().strip()
1071 if not line.startswith(parttionDev):
1072 return (uuid, partitionType)
1073 # print "Blikd %s : %s"%(parttionDev, line)
1074 if line.find(" UUID=") != -1:
1075 uuid = line.split(" UUID=")[1].split(' ')[0]
1076 if line.find(" TYPE=") != -1:
1077 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1079 print "get blkid info error (%s)"%cmd
1080 return (uuid, partitionType)
1082 def getPartitionSize(self, partition):
1083 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1085 size = readFile(devpath + "/size")
1086 return str(int(size)*512)
1090 def getPartitionFree(self, mountPoint):
1092 stat = statvfs(mountPoint)
1093 size_free = stat.f_bfree*stat.f_bsize
1098 def checkMountPoint(self, check_mountpoint):
1101 mounts = file('/proc/mounts').read().split('\n')
1103 if not x.startswith('/'):
1105 devpath, mountpoint = x.split()[:2]
1106 if mountpoint == check_mountpoint:
1112 def checkMountDev(self, device):
1115 mounts = file('/proc/mounts').read().split('\n')
1117 if not x.startswith('/'):
1119 devpath, mountpoint = x.split()[:2]
1120 if devpath == device:
1121 res.append(mountpoint)
1126 def isMounted(self, devpath, mountpoint):
1128 mounts = file('/proc/mounts').read().split('\n')
1130 if not x.startswith('/'):
1132 _devpath, _mountpoint = x.split()[:2]
1133 if devpath == _devpath and mountpoint == _mountpoint:
1139 def isMountable(self, partition):
1140 autofsPath = "/autofs/"+partition.device
1143 os.listdir(autofsPath)
1149 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1150 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1151 if mountpoint[-1] == '/':
1152 mountpoint = mountpoint[:-1]
1153 data = file('/etc/fstab').read().split('\n')
1155 if not line.startswith('/'):
1157 dev, mp, ms = line.split()[0:3]
1158 if uuid is not None and dev.startswith('UUID'):
1159 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1160 # print " >> line : ", line
1162 elif dev == devpath and mp == mountpoint and ms == 'auto':
1163 # print " >> line : ", line
1167 def umountByMountpoint(self, mountpoint):
1168 if mountpoint is None:
1171 if path.ismount(mountpoint):
1172 cmd = "umount " + mountpoint
1173 print "[DeviceManager] ", cmd
1176 print "Umount by mountpoint failed!"
1177 if not path.ismount(mountpoint):
1181 def umountByDevpath(self, devpath):
1182 cmd = "umount " + devpath
1183 print "[DeviceManager] ", cmd
1186 deviceinfo = DeviceInfo()
1188 class MountpointBrowser(Screen):
1190 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1191 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1192 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1193 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1194 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1195 <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" />
1196 <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" />
1197 <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" />
1198 <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" />
1199 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1200 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1203 def __init__(self, session):
1204 Screen.__init__(self, session)
1205 self["key_red"] = StaticText(_("Cancel"))
1206 self["key_green"] = StaticText(_("Select"))
1207 self["key_yellow"] = StaticText(_("Create directory"))
1208 self["key_blue"] = StaticText("Delete directory")
1209 directory = "/media/"
1210 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1211 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1212 self["filelist"] = self.filelist
1214 self["shortcuts"] = ActionMap(["ColorActions"],
1217 "green": self.select,
1218 "yellow": self.createDirectory,
1219 "blue": self.deleteDirectory,
1222 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1224 "cancel": self.exit,
1229 if self.filelist.canDescent():
1230 self.filelist.descent()
1233 if self["filelist"].getCurrentDirectory() is not None:
1234 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1235 self.filelist.descent()
1236 currDir = self["filelist"].getCurrentDirectory()
1239 self.close(self["filelist"].getFilename())
1241 def createDirectory(self):
1242 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1244 def createDirectoryCB(self, retval = None):
1247 if retval is not None:
1248 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1249 if not path.exists(newdir):
1250 os.system("mkdir %s"%newdir)
1251 self.filelist.refresh()
1254 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1256 def deleteDirectory(self):
1259 if self["filelist"].getCurrentDirectory() is not None:
1260 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1261 delDir = self["filelist"].getFilename()
1262 if path.exists(delDir):
1263 os.system("rmdir '%s'"%delDir)
1264 if path.exists(delDir):
1265 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1266 self.filelist.refresh()
1269 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1274 class MessageBoxConfirm(MessageBox):
1276 <screen position="center,center" size="620,10" title="Message">
1277 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1278 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1279 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1280 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1281 <widget name="list" position="100,100" size="380,375" transparent="1" />
1282 <applet type="onLayoutFinish">
1283 # this should be factored out into some helper code, but currently demonstrates applets.
1284 from enigma import eSize, ePoint
1286 orgwidth = self.instance.size().width()
1287 orgheight = self.instance.size().height()
1288 orgpos = self.instance.position()
1289 textsize = self["text"].getSize()
1291 # y size still must be fixed in font stuff...
1292 textsize = (textsize[0] + 50, textsize[1] + 50)
1294 if self.type == self.TYPE_YESNO:
1296 wsizex = textsize[0] + 60
1297 wsizey = textsize[1] + offset
1298 if (280 > wsizex):
1300 wsize = (wsizex, wsizey)
1303 self.instance.resize(eSize(*wsize))
1306 self["text"].instance.resize(eSize(*textsize))
1309 listsize = (wsizex, 50)
1310 self["list"].instance.move(ePoint(0, textsize[1]))
1311 self["list"].instance.resize(eSize(*listsize))
1315 newheight = wsize[1]
1316 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1321 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1322 class DeviceManagerConfig():
1324 self.configList = []
1326 def getConfigList(self):
1327 return self.configList
1329 def updateConfigList(self):
1331 self.configList = []
1332 file = open("/proc/mounts")
1333 mounts = file.readlines()
1336 if x.startswith("/dev/sd"):
1337 device = x.split()[0].split('/dev/')[1]
1338 mountpoint = x.split()[1]
1339 if mountpoint.startswith('/autofs'):
1341 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1342 if uuid != '' and mountpoint != '':
1343 self.configList.append([uuid, mountpoint])
1346 print "updateConfigList failed!"
1348 def loadConfig(self):
1349 if not fileExists(dmconfigfile):
1350 os.system("touch %s" % dmconfigfile)
1351 self.configList = []
1352 data = file(dmconfigfile).read().split('\n')
1354 if line.find(':') != -1:
1355 (uuid, mountpoint) = line.split(':')
1356 if uuid != '' and mountpoint != '':
1357 self.configList.append([uuid, mountpoint])
1359 def saveConfig(self):
1360 confFile = open(dmconfigfile,'w')
1362 for line in self.configList:
1363 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1364 confFile.write(data)
1367 def appendConfig(self, uuid, mountpoint):
1368 for x in self.configList:
1369 if x[0] == uuid or x[1] == mountpoint:
1370 self.configList.remove(x)
1371 self.configList.append([uuid, mountpoint])
1373 def removeConfig(self, value):
1374 for x in self.configList:
1375 if x[0] == value or x[1] == value:
1376 self.configList.remove(x)
1378 devicemanagerconfig = DeviceManagerConfig()
1380 class deviceManagerHotplug:
1382 self.hotplugActive = True
1384 def printDebug(self):
1385 for p in harddiskmanager.partitions:
1386 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)
1388 def doMount(self, uuid, devpath, mountpoint, filesystem):
1389 # check current device mounted on another mountpoint.
1391 mp_list = deviceinfo.checkMountDev(devpath)
1393 if mp != mountpoint and path.ismount(mp):
1394 deviceinfo.umountByMountpoint(mp)
1395 # check another device mounted on configmountpoint
1397 devpath_list = deviceinfo.checkMountPoint(mountpoint)
1398 for devpath_ in devpath_list:
1399 if devpath_ != devpath:
1400 print "[DeviceManager] Mount Failed. (Another device is already mounted)"
1403 print "[DeviceManager] doMount"
1404 if not path.exists(mountpoint):
1405 os.system("mkdir %s"%mountpoint)
1406 if path.exists(mountpoint):
1407 if not path.ismount(mountpoint):
1408 if filesystem == "ntfs":
1409 cmd = "ntfs-3g %s %s"%(devpath, mountpoint)
1410 elif filesystem is None:
1411 cmd = "mount %s %s"%(devpath, mountpoint)
1413 cmd = "mount -t %s %s %s"%(filesystem, devpath, mountpoint)
1414 print "[DeviceManager] cmd : %s"%cmd
1416 if not deviceinfo.isMounted(devpath, mountpoint):
1417 print "[DeviceManager] %s doMount failed!"%devpath
1420 # Update partition Info, add
1421 self.addPartitionAutofsMountpoint(devpath, mountpoint)
1423 def doUmount(self, device, mountpoint):
1424 devpath = "/dev/"+device
1425 if len(deviceinfo.checkMountDev(devpath)) == 0:
1427 cmd = "umount %s"%devpath
1428 print "[DeviceManager] cmd : %s"%cmd
1431 def addHotPlugDevice(self, partition):
1432 device = partition.device
1433 devpath = "/dev/"+device
1435 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1438 os.system("sleep 1")
1439 (uuid, filesystem) = deviceinfo.getPartitionBlkidInfo(device)
1441 print "[DeviceManagerHotplug] getBlkidInfo failed!"
1444 devicemanagerconfig.loadConfig()
1445 configList = devicemanagerconfig.getConfigList()
1447 for line in configList:
1448 if uuid == line[0].strip():
1449 mountpoint = line[1].strip()
1451 if mountpoint is None:
1454 if deviceinfo.isMounted(devpath, mountpoint):
1455 print "[DeviceManagerHotplug] already mounted"
1457 self.doMount(uuid, devpath, mountpoint, filesystem)
1459 def removeHotplugDevice(self, partition):
1460 self.doUmount(partition.device, partition.mountpoint)
1462 def getHotplugAction(self, action, partition):
1463 if not self.hotplugActive or not config.plugins.devicemanager.hotplug_enable.value:
1465 if partition.device is None or not partition.device.startswith("sd"):
1467 print "[DeviceManagerHotplug] action : %s, device : %s"%(action, partition.device)
1470 self.addHotPlugDevice(partition)
1471 elif action == 'remove':
1472 self.removeHotplugDevice(partition)
1474 def addPartitionAutofsMountpoint(self, devpath, mountpoint):
1475 device = path.basename(devpath)
1476 autofsMountpoint = harddiskmanager.getAutofsMountpoint(device)
1477 # check already appended to partition list
1478 for x in harddiskmanager.partitions:
1479 if x.mountpoint == autofsMountpoint or x.mountpoint == mountpoint:
1482 from Components.Harddisk import Partition
1483 physdev = path.realpath('/sys/block/' + device[:3] + '/device')[4:]
1484 description = harddiskmanager.getUserfriendlyDeviceName(device, physdev)
1485 p = Partition(mountpoint = autofsMountpoint, description = description, force_mounted = True, device = device)
1486 harddiskmanager.partitions.append(p)
1487 harddiskmanager.on_partition_list_change("add", p)
1489 def autoMountOnStartup(self):
1490 devicemanagerconfig.loadConfig()
1491 configList = devicemanagerconfig.getConfigList()
1494 data = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1496 devpath = uuid = filesystem = ""
1497 devpath = line.split(':')[0]
1498 if line.find(" UUID=") != -1:
1499 uuid = line.split(" UUID=")[1].split(' ')[0]
1500 if line.find(" TYPE=") != -1:
1501 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1502 blkiddata.append((devpath, uuid, filesystem))
1504 for c in configList:
1505 uuid_cfg = c[0].strip()
1506 mountpoint_cfg = c[1].strip()
1507 for (devpath, uuid, filesystem) in blkiddata:
1508 if uuid_cfg == uuid:
1510 if deviceinfo.isMounted(devpath, mountpoint_cfg):
1511 print "[Devicemanager startup] already mounted"
1512 self.addPartitionAutofsMountpoint(devpath, mountpoint_cfg)
1514 # print "[autoMountOnStartup] do mount(%s %s %s)"%(devpath, configmountpoint, filesystem)
1515 self.doMount(uuid, devpath, mountpoint_cfg, filesystem)
1517 def umountOnShutdown(self):
1518 devicemanagerconfig.loadConfig()
1519 configList = devicemanagerconfig.getConfigList()
1522 data = file('/proc/mounts').read().split('\n')
1524 if not x.startswith('/dev/sd'):
1526 devpath, mountpoint = x.split()[:2]
1527 mounts.append((path.basename(devpath), mountpoint))
1528 # print "[DeviceManager] mounts : ",mounts
1529 data = self.getBlkidInfo()
1531 for c in configList:
1532 uuid_cfg = c[0].strip()
1533 mountpoint_cfg = c[1].strip()
1535 if uuid_cfg in data.keys():
1536 device_cfg = data[uuid_cfg]
1537 if device_cfg is None:
1539 for (device, mountpoint) in mounts:
1540 if device_cfg == device:
1541 if not deviceinfo.isFstabAutoMounted(uuid_cfg, "/dev/"+device_cfg, mountpoint_cfg):
1542 self.doUmount(device, mountpoint)
1544 def getBlkidInfo(self):
1546 blkid_lines = os.popen("blkid -c /dev/NULL /dev/sd*").readlines()
1547 for line in blkid_lines:
1549 device = path.basename(line.split(':')[0])
1550 if line.find(" UUID=") != -1:
1551 blkid_uuid = line.split(" UUID=")[1].split(' ')[0]
1552 data[blkid_uuid] = device
1555 devicemanagerhotplug = deviceManagerHotplug()
1557 def DeviceManagerhotplugDeviceStart(action, device):
1558 devicemanagerhotplug.getHotplugAction(action, device)
1560 def callBackforDeviceManager(session, callback_result = False):
1561 if callback_result == True:
1562 session.open(DeviceManager)
1564 def checkMounts(session):
1566 noMountable_dev = ""
1567 for blockdev in listdir("/sys/block"):
1568 devpath = "/sys/block/" + blockdev
1569 dev = int(readFile(devpath + "/dev").split(':')[0])
1570 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1573 noMountable_partitions = []
1574 for partition in listdir(devpath):
1575 if not partition.startswith(blockdev):
1577 partitions.append(partition)
1578 if os.access('/autofs/'+partition,0) is False:
1579 noMountable_partitions.append(partition)
1580 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1581 if noMountable_dev != "":
1582 noMountable_dev += ' '
1583 noMountable_dev += blockdev
1585 if noMountable_dev != "":
1586 print "Umountable partitions found."
1587 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)
1588 AddNotificationWithCallback(
1589 boundFunction(callBackforDeviceManager, session),
1590 MessageBox, InfoText, timeout = 60, default = False
1593 print "checkMounts failed!"
1595 def sessionstart(reason, **kwargs):
1597 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1598 session = kwargs["session"]
1599 checkMounts(session)
1600 if config.plugins.devicemanager.hotplug_enable.value:
1601 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1603 if config.plugins.devicemanager.hotplug_enable.value:
1604 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1606 def autostart(reason, **kwargs):
1609 # check at first enigma2 start
1610 if not fileExists(dmconfigfile):
1611 print "[DeviceManager] autostart : check devices at first start"
1612 sda_isremovable = False
1614 os.system("touch %s"%dmconfigfile)
1616 sda_data = popen("cat /proc/partitions | grep sda1").read()
1618 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1619 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1620 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1623 cfg += '"%s":/media/hdd\n'%sda_UUID
1624 confFile = open(dmconfigfile,'w')
1627 if not path.exists("/media/hdd"):
1628 os.system("mkdir -p /media/hdd")
1630 devicemanagerhotplug.autoMountOnStartup()
1632 print "[DeviceManager] autostart failed!"
1634 devicemanagerhotplug.umountOnShutdown()
1636 def menu(menuid, **kwargs):
1637 if menuid == "harddisk":
1638 return [(_("DeviceManager"), main, "device_manager", 1)]
1641 def main(session, **kwargs):
1642 session.open(DeviceManager)
1644 def Plugins(path, **kwargs):
1646 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1647 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1648 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1651 class MessageBox_2(MessageBox):
1652 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1653 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1654 self.skinName = "MessageBox"
1655 self.closeTimer = eTimer()
1656 self.closeTimer.callback.append(self.msg_close)
1657 self.devicemanager_ret = False
1658 self.devicemanager_msg = ""
1660 def msg_close(self):
1661 self.close(self.devicemanager_ret, self.devicemanager_msg)
1663 def run_close(self, ret, msg=""):
1664 self.devicemanager_ret = ret
1665 self.devicemanager_msg = msg
1666 self.closeTimer.start(100,True)
1668 def createSummary(self):
1669 return MessageBox_2_Summary
1671 class MessageBox_2_Summary(Screen):
1673 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1674 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />