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.onLayoutFinish.append(self.hotplugInactive)
182 # self.onClose.append(self.hotplugActive)
183 self.onChangedEntry = []
184 self.blockDevices = {}
186 def addPartitionListChange(self):
187 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
189 def removePartitionListChange(self):
190 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
192 def partitionListChanged(self, action, device):
193 print "[Device manager] hotplug partitionListChanged"
194 if self.currList != "default" and device.device[:3] != self.currDevice["blockdev"]:
196 self.showDeviceList()
198 def hotplugInactive(self):
199 global devicemanagerhotplugactive
200 print "[Device manager] hotplug Inctive"
201 devicemanagerhotplugactive = False
203 def hotplugActive(self):
204 global devicemanagerhotplugactive
205 print "[Device manager] hotplug Active"
206 devicemanagerhotplugactive = True
209 self.icon_button_green = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/button_green.png"))
210 self.divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
212 def selectionChanged(self):
213 if self.currList == "partitions":
214 currentPartition = self.getCurrentPartition()
215 if currentPartition is not None:
216 if currentPartition["mountpoint"] != "":
217 self["key_green"].setText(_("Umount"))
219 self["key_green"].setText(_("Mount"))
221 if currentPartition["fstype"] == "":
222 self["key_blue"].setText("")
223 elif currentPartition["fstype"][:3] == "ext":
224 self["key_blue"].setText(_("Check"))
226 self["key_blue"].setText("")
228 def showDeviceList(self):
230 self["key_red"].setText(_("Close"))
231 self["key_green"].setText(_("Ok"))
232 self["key_yellow"].setText(" ")
233 self["key_blue"].setText(_("Initialize"))
235 for device in deviceinfo.getBlockDevices():
237 "%s - %s"%(device["vendor"], device["model"]), # vendor : str, model : str, index 0
238 _("device : %s")%(device["blockdev"]), # str
239 _("Size : %s")%(byteConversion(device["size"])), # str, bytes
240 _("Partitions : %s")%(len(device["partitions"])), # list
241 _("Removable : %s")%(device["removable"] and 'Yes' or 'No'), # bool [True, False]
245 # print "[DeviceManager] deviceEntry : ", deviceEntry
246 self.deviceList.append(deviceEntry)
247 self.currList = "default"
248 self["menu"].style = "default"
249 self["menu"].setList(self.deviceList)
251 def showPartitionList(self):
252 if self.currDevice is None:
255 for partition in self.currDevice["partitions"]:
256 partitionInfo = deviceinfo.getPartitionInfo(partition)
258 _("Partition : /dev/%s")%partition, # index 0
259 _("Mounted on : %s")%checkStrValue(partitionInfo["mountpoint"], _("not mounted")),
260 _("UUID : %s")%checkStrValue(partitionInfo["uuid"], _("unknown")),
261 _("Type : %s")%checkStrValue(partitionInfo["fstype"], _("unknown")),
262 _("Size : %s")%checkStrValue(byteConversion(partitionInfo["size"]), _("unknown")),
263 _("Free : %s")%checkStrValue(byteConversion(partitionInfo["free"]), _("unknown")),
264 self.divpng, # index 6
265 partitionInfo, # index 7
267 # print "[DeviceManager] partitionEntry : ",partitionEntry
268 partitionList.append(partitionEntry)
269 if len(partitionList) != 0:
270 self["key_red"].setText(_("Devices"))
271 self["key_green"].setText(_("Mount"))
272 self["key_yellow"].setText(_("Format"))
273 self["key_blue"].setText(_("Check"))
274 self.currList = "partitions"
275 self["menu"].style = "partitions"
276 self["menu"].setList(partitionList)
277 self.selectionChanged()
279 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)
282 def showMountPointSetup(self):
283 if self.currDevice is None or self.currPartition is None:
285 partition = self.currPartition["partition"]
286 if not os.access("/autofs/%s"%partition,0):
287 self.session.open(MessageBox, _("This partition is not mountable.\nYou need to check or format this partition."), MessageBox.TYPE_ERROR, timeout = 10)
289 self["key_red"].setText(_("Partitions"))
290 self["key_green"].setText(_("Ok"))
291 self["key_yellow"].setText("")
292 self["key_blue"].setText("")
293 self.mountPointList = []
294 currentMountPoint = self.currPartition["mountpoint"]
295 if currentMountPoint == "":
296 currentMountPoint = "'not mounted'"
297 defaultMountPoint = self.getDefaultMountPoint()
298 autoMountPoint = self.getAutoMountPoint()
299 defaultMountPointEntry = (self.icon_button_green, _("Set up Default Mount Point"), _("Mount Point : %s ->%s")%(currentMountPoint, defaultMountPoint), "default", defaultMountPoint, self.divpng)
300 autoMountPointEntry = (self.icon_button_green, _("Automatically set up a Mount Point"), _("Mount Point : %s -> %s")%(currentMountPoint, autoMountPoint), "auto", autoMountPoint, self.divpng)
301 manuallyMountPointEntry = (self.icon_button_green, _("User manually Set up a Mount Point"), _("Mount Point : click ok button on here."), "manual", "", self.divpng)
302 if not path.ismount(defaultMountPoint):
303 self.mountPointList.append(defaultMountPointEntry)
304 self.mountPointList.append(autoMountPointEntry)
305 self.mountPointList.append(manuallyMountPointEntry)
306 self.currList = "mountpoint"
307 self["menu"].style = "mountpoint"
308 self["menu"].setList(self.mountPointList)
310 def getCurrentDevice(self):
311 if self.currList == "default":
312 return self["menu"].getCurrent()[6]
315 def getCurrentPartition(self):
316 if self.currList == "partitions":
317 return self["menu"].getCurrent()[7]
322 if self.currList == "default":
323 self.currDevice = self.getCurrentDevice()
324 if len(self.currDevice["partitions"]) == 0:
325 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)
327 self.showPartitionList()
328 elif self.currList == "partitions":
329 currMountPoint = self.getCurrentPartition()["mountpoint"]
330 currUuid = self.getCurrentPartition()["uuid"]
331 if currMountPoint == "":
332 self.currPartition = self.getCurrentPartition()
333 self.showMountPointSetup()
335 self.doUmount(currMountPoint, self.showPartitionList)
336 elif self.currList == "mountpoint":
337 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
338 currEntry = self["menu"].getCurrent()[3]
339 if currEntry == "default":
340 # print "Setup mountpoint default!"
341 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
342 elif currEntry == "auto":
343 # print "Setup mountpoint automatically!"
344 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
346 # print "Setup mountpoint manually!"
347 self.session.openWithCallback(self.MountpointBrowserCB, MountpointBrowser)
353 if self.DeviceManagerConsole is not None:
354 if len(self.DeviceManagerConsole.appContainers):
355 for name in self.DeviceManagerConsole.appContainers.keys():
356 self.DeviceManagerConsole.kill(name)
357 if self.currList == "partitions":
358 self.currDevice = None
359 self.showDeviceList()
360 elif self.currList == "mountpoint":
361 self.currPartition = None
362 self.showPartitionList()
363 else: # currList = "default"
367 if self.currList == "partitions":
368 partition = self.getCurrentPartition()
369 self.choiceBoxFstype()
372 if self.currList == "default":
373 device = self.getCurrentDevice()
374 self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
375 elif self.currList == "partitions":
376 partition = self.getCurrentPartition()
377 self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
380 self.session.open(DeviceManagerConfiguration)
382 def deviceInitCB(self, ret = True):
383 self.showDeviceList()
385 def deviceCheckCB(self, ret = True):
386 self.showPartitionList()
388 def deviceFormatCB(self, ret = True):
389 self.showPartitionList()
391 def choiceBoxFstype(self):
393 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
394 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
395 menu.append((_("ext4 - experimental"), "ext4"))
396 menu.append((_("vfat - for USB flash memory"), "vfat"))
397 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
399 def choiceBoxFstypeCB(self, choice):
403 partition = self.getCurrentPartition()
404 self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
406 # about mount funcs..
407 def doUmount(self, mountpoint, callback):
408 cmd = "umount %s"%mountpoint
409 print "[DeviceManager] cmd : %s"%cmd
410 self.DeviceManagerConsole.ePopen(cmd, self.doUmountFinished, (mountpoint, callback))
412 def doUmountFinished(self, result, retval, extra_args = None):
413 (mountpoint, callback) = extra_args
415 # update current mount state ,devicemanager.cfg
416 devicemanagerconfig.updateConfigList()
418 self.session.open(MessageBox, _("Can't umount %s. \nMaybe device or resource busy.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
421 def getDefaultMountPoint(self):
422 return self.defaultMountPoint
424 def getAutoMountPoint(self):
425 mountPoint = "/media/"+self.currDevice["model"]
426 mountPoint = mountPoint.replace(' ','-')
427 if path.ismount(mountPoint):
430 mountPoint_fix = mountPoint+str(partnum)
431 if not path.ismount(mountPoint_fix):
434 mountPoint = mountPoint_fix
437 def doMount(self, partition, mountpoint):
439 device = partition["partition"]
440 fstype = partition["fstype"]
441 if mountpoint.endswith("/"):
442 mountpoint = retval[:-1]
443 if mountpoint.find(' ') != -1:
444 mountpoint = mountpoint.replace(' ','-')
445 dev = deviceinfo.checkMountPoint(mountpoint)
447 if not path.exists(mountpoint):
448 print "[deviceManager] make dir %s"%mountpoint
451 cmd = "ntfs-3g /dev/%s %s" % (device, mountpoint)
453 cmd = "mount /dev/%s %s" % (device, mountpoint)
455 print "[DeviceManager] cmd : %s"%cmd
456 if mountpoint == "/media/hdd":
457 movieDir = mountpoint + "/movie"
458 if not pathExists(movieDir):
459 print "[DeviceManager] make dir %s"%movieDir
460 os.makedirs(movieDir)
461 self.showPartitionList()
462 # update current mount state ,devicemanager.cfg
463 devicemanagerconfig.updateConfigList()
465 self.session.open(MessageBox, _("Mount Failed!\nCurrent path is already mounted by \"%s\"")%dev, MessageBox.TYPE_ERROR, timeout = 10)
467 self.session.open(MessageBox, _("Mount Failed!(%s -> %s)")%(device, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
469 def MountpointBrowserCB(self, retval = None):
470 if retval and retval is not None:
471 mountPoint = retval.strip().replace(' ','')
472 if retval.endswith("/"):
473 mountPoint = retval[:-1]
474 print "Mount point from MountpointBrowser : %s"%mountPoint
475 if not path.exists(mountPoint):
476 self.session.open(MessageBox, _("Mount Point is not writeable.\nPath : %s")%mountPoint, MessageBox.TYPE_ERROR, timeout = 10)
479 self.doMount(self.currPartition, mountPoint)
482 # Initializing Start...
483 class DeviceInit(Screen):
484 skin = """<screen position="0,0" size="0,0"/>"""
485 def __init__(self, session, device, devicesize):
486 Screen.__init__(self, session)
487 self.session = session
488 self.deviceInitConsole = Console()
490 self.devicesize = int(devicesize)
491 self.inputbox_partitions = 1
492 self.inputbox_partitionSizeList = []
493 self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024)
494 self.msgWaiting = None
495 self.msgWaitingMkfs = None
496 self.devicenumber = 0
497 self.newpartitions = 0
498 self.onLayoutFinish.append(self.timerStart)
499 self.initStartTimer = eTimer()
500 self.initStartTimer.callback.append(self.confirmMessage)
501 self.createFSStartTimer = eTimer()
502 self.createFSStartTimer.callback.append(self.createFilesystemStart)
503 self.exitMessageTimer = eTimer()
504 self.exitMessageTimer.callback.append(self.exitMessage)
507 def timerStart(self):
508 self.initStartTimer.start(100,True)
510 def confirmMessage(self):
511 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
512 self.session.openWithCallback(self.confirmed, MessageBox, message)
514 def confirmed(self, ret):
516 self.InitializeStart()
520 def exit(self, ret = True):
523 def unmountAll(self, device):
524 mounts = file('/proc/mounts').read().split('\n')
528 if not line.startswith("/dev/" + device):
530 cmd += "umount %s ;"% line.split()[0]
533 mounts = file('/proc/mounts').read().split('\n')
535 if line.startswith("/dev/" + device):
539 def InitializeStart(self):
540 self.InputPartitionSize_step1()
542 def InputPartitionSize_step1(self):
543 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
545 def InputPartitionSize_step1_CB(self, ret):
546 if ret is not None and int(ret) in range(1,5): # ret in 1~4
547 self.inputbox_partitions = int(ret)
548 self.InputPartitionSize_step2()
550 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
552 def InputPartitionSize_step2(self):
553 current_partition = len(self.inputbox_partitionSizeList)+1
554 if self.inputbox_partitionSizeRemain == 0:
555 self.initInitializeConfirm()
556 elif current_partition == self.inputbox_partitions:
557 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
558 self.initInitializeConfirm()
560 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
561 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)
563 def InputPartitionSize_step2_CB(self, ret):
565 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
566 self.InputPartitionSize_step2()
568 self.inputbox_partitionSizeList.append(str(ret))
569 self.inputbox_partitionSizeRemain -= int(ret)
570 self.InputPartitionSize_step2()
572 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
574 def initInitializeConfirm(self):
575 # print self.inputbox_partitionSizeList
577 for index in range(len(self.inputbox_partitionSizeList)):
578 print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
579 partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
580 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
582 def initInitializeConfirmCB(self,ret):
584 self.initInitialize()
588 def initInitialize(self):
589 if not self.unmountAll(self.device):
590 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
592 msg = _("InitInitializing, please wait ...")
593 msg += _("\nDevice : %s")%self.device
594 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
595 for index in range(len(self.inputbox_partitionSizeList)):
596 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
597 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
599 partitions = len(self.inputbox_partitionSizeList)
601 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
605 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
609 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
610 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
612 def initInitializeFinished(self, result, retval, extra_args = None):
614 cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
615 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
617 errorMsg = "initInitializing device Error at /dev/%s"%self.device
618 self.msgWaiting.run_close(False, errorMsg)
620 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
621 cmd = "/bin/umount /dev/%s*" % (self.device)
622 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
624 def initInitializingUmountFinished(self, result, retval, extra_args = None):
625 partitions = open("/proc/partitions")
626 self.devicenumber = 0
627 self.newpartitions = 0
628 for part in partitions:
629 res = re.sub("\s+", " ", part).strip().split(" ")
630 if res and len(res) == 4 and res[3][:3] == self.device:
631 if len(res[3]) > 3 and res[3][:2] == "sd":
632 self.newpartitions += 1
634 self.msgWaiting.run_close(True)
635 # self.createFilesystem(self.newpartitions)
637 def createFilesystem(self, newpartitions):
638 self.devicenumber = self.devicenumber + 1
639 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
640 shortdevicename = self.device + str(self.devicenumber)
642 partitions = open("/proc/partitions")
643 for part in partitions:
644 res = re.sub("\s+", " ", part).strip().split(" ")
645 if res and len(res) == 4:
646 if res[3] == shortdevicename:
647 partitionsize = int(res[2])
651 if partitionsize > 64 * 1024 * 1024:
652 cmd = "/sbin/mkfs.ext3 "
655 cmd = "/sbin/mkfs.ext2 "
658 if partitionsize > 2 * 1024 * 1024:
659 cmd += "-T largefile "
660 cmd += "-m0 " + fulldevicename
662 msg = _("Create filesystem, please wait ...")
663 msg += _("\nPartition : %s") % (fulldevicename)
664 msg += _("\nFilesystem : %s") % (filesystem)
665 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
666 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
667 self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
669 def createFilesystemFinished(self, result, retval, extra_args = None):
670 device = extra_args[0]
671 fulldevicename = extra_args[1]
673 self.msgWaitingMkfs.run_close(True)
675 errorMsg = _("Creating filesystem Error")
676 if fulldevicename is not None:
677 errorMsg += _(" at /dev/%s")%fulldevicename
678 self.msgWaitingMkfs.run_close(False, errorMsg)
680 def createFilesystemStart(self):
681 self.createFilesystem(self.newpartitions)
683 def msgWaitingCB(self, ret, msg=""):
685 self.createFSStartTimer.start(100,True)
689 self.exitMessageTimer.start(100,True)
691 def msgWaitingMkfsCB(self, ret, msg=""):
692 if self.devicenumber < self.newpartitions:
693 self.createFSStartTimer.start(100,True)
697 self.msg = _("Device Initialization finished sucessfully!")
698 self.exitMessageTimer.start(100,True)
702 self.exitMessageTimer.start(100,True)
704 def exitMessage(self):
706 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
708 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
712 # device check start..
713 class DeviceCheck(Screen):
714 skin = """<screen position="0,0" size="0,0"/>"""
715 def __init__(self, session, partition):
716 Screen.__init__(self, session)
717 self.session = session
718 self.deviceCheckConsole = Console()
719 self.partition = partition
720 self.onLayoutFinish.append(self.timerStart)
721 self.checkStartTimer = eTimer()
722 self.checkStartTimer.callback.append(self.confirmMessage)
724 def timerStart(self):
725 self.checkStartTimer.start(100,True)
727 def confirmMessage(self):
728 fssize = self.partition["size"]
729 if long(fssize) > 1024*1024*1024*16:
730 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
731 self.session.openWithCallback(self.confirmed, MessageBox, message)
733 self.deviceCheckStart()
735 def confirmed(self, ret):
736 print "confirmed : ",ret
738 self.deviceCheckStart()
742 def deviceCheckStart(self):
743 print "deviceCheckStart "
744 print "partition : ", self.partition
745 device = self.partition["partition"]
746 mountpoint = self.partition["mountpoint"]
747 fstype = self.partition["fstype"]
748 fssize = self.partition["size"]
749 if device is not None and fstype.startswith("ext"):
750 msg = _("Check filesystem, please wait ...")
751 msg += _("\nDevice : /dev/%s")%(device)
752 msg += _("\nFilesystem : %s")%(fstype)
753 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
755 self.doUmountFsck(device, mountpoint, fstype)
757 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
761 def doUmountFsck(self, device, mountpoint, fstype):
762 cmd = "umount /dev/%s" % device
763 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
765 def umountFsckFinished(self, result, retval, extra_args = None):
766 device = extra_args[0]
767 mountpoint = extra_args[1]
768 fstype = extra_args[2]
770 cmd = "fsck." + fstype + " -f -p /dev/" + device
771 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
773 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
774 self.msgWaiting.run_close(False,errorMsg)
776 def fsckFinished(self, result, retval, extra_args = None):
777 device = extra_args[0]
778 mountpoint = extra_args[1]
780 text = _("Filesystem check finished sucessfully")
781 self.msgWaiting.run_close(True, text)
783 text = _("Error checking disk. The disk or filesystem may be damaged")
784 self.msgWaiting.run_close(False, text)
786 def msgWaitingCB(self, ret, msg):
788 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
790 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
792 partition = self.partition["partition"]
793 mountpoint = self.partition["mountpoint"]
794 fstype = self.partition["fstype"]
797 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
799 cmd = "mount /dev/" + partition + " " + mountpoint
800 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
804 def mountPartitionFinished(self, result, retval, extra_args = None):
813 class DeviceFormat(Screen):
814 skin = """<screen position="0,0" size="0,0"/>"""
815 def __init__(self, session, partition, newfstype):
816 Screen.__init__(self, session)
817 self.session = session
818 self.deviceFormatConsole = Console()
819 self.partition = partition
820 self.newfstype = newfstype
821 self.unmountedList = []
822 self.onLayoutFinish.append(self.timerStart)
823 self.formatStartTimer = eTimer()
824 self.formatStartTimer.callback.append(self.DeviceFormatStart)
826 def timerStart(self):
827 self.formatStartTimer.start(100,True)
829 def DeviceFormatStart(self):
830 print "DeviceFormatStart : ", self.partition,
831 print "Filesystem : ",self.newfstype
832 device = self.partition["partition"]
833 devicepath = "/dev/"+device
834 mountpoint = self.partition["mountpoint"]
835 fssize = self.partition["size"]
836 newfstype = self.newfstype
838 msg = _("Format filesystem, please wait ...")
839 msg += _("\nDevice : %s")%(devicepath)
840 msg += _("\nFilesystem : %s")%(newfstype)
841 msg += _("\nSize : %s")%(byteConversion(fssize))
842 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
844 self.doumountPartition()
846 self.umountPartitionFinished("NORESULT", 0)
848 def doumountPartition(self):
849 oldfstype = self.partition["fstype"]
850 newfstype = self.newfstype
852 if newfstype == oldfstype:
853 device = self.partition["partition"]
855 device = self.partition["partition"][:3]
857 mounts = file('/proc/mounts','r')
858 for line in mounts.readlines():
859 if line.startswith("/dev/%s"%device):
860 cmd += "umount %s;"%line.split()[0]
861 self.unmountedList.append([line.split()[0], line.split()[1]])
862 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
864 def umountPartitionFinished(self, result, retval, extra_args = None):
865 partition = self.partition["partition"]
866 oldfstype = self.partition["fstype"]
867 newfstype = self.newfstype
869 if oldfstype == newfstype:
870 self.changePartitionIDFinished("NORESULT", 0)
872 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
873 if newfstype[:3] == "ext":
877 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
879 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
880 self.msgWaiting.run_close(False,errorMsg)
882 def changePartitionIDFinished(self, result, retval, extra_args = None):
883 device = self.partition["partition"][:3]
884 mountpoint = self.partition["mountpoint"]
885 oldfstype = self.partition["fstype"]
886 newfstype = self.newfstype
888 if oldfstype == newfstype:
889 self.refreshPartitionFinished("NORESULT", 0)
891 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
892 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
894 errorMsg = _("Can not change the partition ID for %s")%device
895 self.msgWaiting.run_close(False,errorMsg)
897 def refreshPartitionFinished(self, result, retval, extra_args = None):
898 print "refreshPartitionFinished!"
899 partition = self.partition["partition"]
900 mountpoint = self.partition["mountpoint"]
901 size = int(self.partition["size"])/1024/1024
902 oldfstype = self.partition["fstype"]
903 newfstype = self.newfstype
905 if newfstype == "ext4":
906 cmd = "/sbin/mkfs.ext4 -F "
908 cmd += "-T largefile "
909 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
910 elif newfstype == "ext3":
911 cmd = "/sbin/mkfs.ext3 -F "
913 cmd += "-T largefile "
914 cmd += "-m0 /dev/" + partition
915 elif newfstype == "ext2":
916 cmd = "/sbin/mkfs.ext2 -F "
918 cmd += "-T largefile "
919 cmd += "-m0 /dev/" + partition
920 elif newfstype == "vfat":
921 if size > 4 * 1024 * 1024:
922 cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
924 cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
925 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
927 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
928 self.msgWaiting.run_close(False,errorMsg)
930 def mkfsFinished(self, result, retval, extra_args = None):
931 print "mkfsFinished!"
932 partition = self.partition["partition"]
935 if len(self.unmountedList) == 0:
936 self.doMountFinished("NORESULT",0)
937 for x in self.unmountedList:
938 cmd += "mount %s %s;"%(x[0], x[1])
939 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
941 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
942 self.msgWaiting.run_close(False, text)
944 def doMountFinished(self, result, retval, extra_args = None):
945 print "doMountFinished!"
946 text = _("Format finished sucessfully.")
947 self.msgWaiting.run_close(True, text)
949 def msgWaitingCB(self, ret, msg):
951 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
953 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
962 self.blockDeviceList = []
964 def getBlockDevices(self):
965 return self.blockDeviceList
968 self.blockDeviceList = []
969 self.getBlockDeviceList()
971 def getBlockDeviceList(self):
972 print "get block device Infomations..."
973 for blockdev in listdir("/sys/block"):
974 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
975 if not blacklisted and not error:
976 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
978 blockDevice["blockdev"] = blockdev # str
979 blockDevice["removable"] = removable # bool [True, False]
980 blockDevice["partitions"] = partitions # list
981 blockDevice["size"] = size # str
982 blockDevice["model"] = model # str
983 blockDevice["vendor"] = vendor # str
984 self.blockDeviceList.append(blockDevice)
986 def getBlockDeviceInfo(self, blockdev):
987 devpath = "/sys/block/" + blockdev
996 dev = int(readFile(devpath + "/dev").split(':')[0])
997 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
999 return error, blacklisted, removable, partitions, size, model, vendor
1000 removable = bool(int(readFile(devpath + "/removable")))
1001 size = str(int(readFile(devpath + "/size").strip())*512)
1002 model = readFile(devpath + "/device/model")
1003 vendor = readFile(devpath + "/device/vendor")
1004 for partition in listdir(devpath):
1005 if partition[:len(blockdev)] != blockdev:
1007 partitions.append(partition)
1010 return error, blacklisted, removable, partitions, size, model, vendor
1012 def getPartitionInfo(self, partition):
1013 mountPoint = self.getPartitionMountpoint(partition)
1014 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1015 size_total = self.getPartitionSize(partition)
1017 if mountPoint != "":
1018 size_free = self.getPartitionFree(mountPoint)
1020 partitionInfo["partition"] = partition
1021 partitionInfo["mountpoint"] = mountPoint
1022 partitionInfo["uuid"] = uuid
1023 partitionInfo["fstype"] = fsType
1024 partitionInfo["size"] = size_total
1025 partitionInfo["free"] = size_free
1026 return partitionInfo
1028 def getPartitionMountpoint(self, partition):
1029 mounts = file('/proc/mounts').read().split('\n')
1031 if not x.startswith('/'):
1033 devpath, mountpoint, = x.split()[:2]
1034 if mountpoint.startswith('/autofs'):
1036 if path.basename(devpath) == partition:
1040 def getPartitionBlkidInfo(self, partition):
1041 parttionDev = "/dev/"+str(partition)
1044 cmd = "blkid -c /dev/null "+str(parttionDev)
1046 line = popen(cmd).readline().strip()
1047 if not line.startswith(parttionDev):
1048 return (uuid, partitionType)
1049 # print "Blikd %s : %s"%(parttionDev, line)
1050 if line.find(" UUID=") != -1:
1051 uuid = line.split(" UUID=")[1].split(' ')[0]
1052 if line.find(" TYPE=") != -1:
1053 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1055 print "get blkid info error (%s)"%cmd
1056 return (uuid, partitionType)
1058 def getPartitionSize(self, partition):
1059 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1061 size = readFile(devpath + "/size")
1062 return str(int(size)*512)
1066 def getPartitionFree(self, mountPoint):
1068 stat = statvfs(mountPoint)
1069 size_free = stat.f_bfree*stat.f_bsize
1074 def checkMountPoint(self, check_mountpoint):
1076 mounts = file('/proc/mounts').read().split('\n')
1078 if not x.startswith('/'):
1080 devpath, mountpoint = x.split()[:2]
1081 if mountpoint == check_mountpoint:
1087 deviceinfo = DeviceInfo()
1089 class MountpointBrowser(Screen):
1091 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1092 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1093 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1094 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1095 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1096 <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" />
1097 <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" />
1098 <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" />
1099 <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" />
1100 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1101 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1104 def __init__(self, session):
1105 Screen.__init__(self, session)
1106 self["key_red"] = StaticText(_("Cancel"))
1107 self["key_green"] = StaticText(_("Select"))
1108 self["key_yellow"] = StaticText(_("Create directory"))
1109 self["key_blue"] = StaticText("Delete directory")
1110 directory = "/media/"
1111 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1112 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1113 self["filelist"] = self.filelist
1115 self["shortcuts"] = ActionMap(["ColorActions"],
1118 "green": self.select,
1119 "yellow": self.createDirectory,
1120 "blue": self.deleteDirectory,
1123 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1125 "cancel": self.exit,
1130 if self.filelist.canDescent():
1131 self.filelist.descent()
1134 if self["filelist"].getCurrentDirectory() is not None:
1135 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1136 self.filelist.descent()
1137 currDir = self["filelist"].getCurrentDirectory()
1140 self.close(self["filelist"].getFilename())
1142 def createDirectory(self):
1143 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1145 def createDirectoryCB(self, retval = None):
1148 if retval is not None:
1149 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1150 if not path.exists(newdir):
1151 os.system("mkdir %s"%newdir)
1152 self.filelist.refresh()
1155 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1157 def deleteDirectory(self):
1160 if self["filelist"].getCurrentDirectory() is not None:
1161 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1162 delDir = self["filelist"].getFilename()
1163 if path.exists(delDir):
1164 os.system("rmdir '%s'"%delDir)
1165 if path.exists(delDir):
1166 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1167 self.filelist.refresh()
1170 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1175 class MessageBoxConfirm(MessageBox):
1177 <screen position="center,center" size="620,10" title="Message">
1178 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1179 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1180 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1181 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1182 <widget name="list" position="100,100" size="380,375" transparent="1" />
1183 <applet type="onLayoutFinish">
1184 # this should be factored out into some helper code, but currently demonstrates applets.
1185 from enigma import eSize, ePoint
1187 orgwidth = self.instance.size().width()
1188 orgheight = self.instance.size().height()
1189 orgpos = self.instance.position()
1190 textsize = self["text"].getSize()
1192 # y size still must be fixed in font stuff...
1193 textsize = (textsize[0] + 50, textsize[1] + 50)
1195 if self.type == self.TYPE_YESNO:
1197 wsizex = textsize[0] + 60
1198 wsizey = textsize[1] + offset
1199 if (280 > wsizex):
1201 wsize = (wsizex, wsizey)
1204 self.instance.resize(eSize(*wsize))
1207 self["text"].instance.resize(eSize(*textsize))
1210 listsize = (wsizex, 50)
1211 self["list"].instance.move(ePoint(0, textsize[1]))
1212 self["list"].instance.resize(eSize(*listsize))
1216 newheight = wsize[1]
1217 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1222 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1223 class DeviceManagerConfig():
1225 self.configList = []
1227 def getConfigList(self):
1228 return self.configList
1230 def updateConfigList(self):
1232 self.configList = []
1233 file = open("/proc/mounts")
1234 mounts = file.readlines()
1237 if x.startswith("/dev/sd"):
1238 device = x.split()[0].split('/dev/')[1]
1239 mountpoint = x.split()[1]
1240 if mountpoint.startswith('/autofs'):
1242 (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1243 if uuid != '' and mountpoint != '':
1244 self.configList.append([uuid, mountpoint])
1247 print "updateConfigList failed!"
1249 def loadConfig(self):
1250 if not fileExists(dmconfigfile):
1251 os.system("touch %s" % dmconfigfile)
1252 self.configList = []
1253 data = file(dmconfigfile).read().split('\n')
1255 if line.find(':') != -1:
1256 (uuid, mountpoint) = line.split(':')
1257 if uuid != '' and mountpoint != '':
1258 self.configList.append([uuid, mountpoint])
1260 def saveConfig(self):
1261 confFile = open(dmconfigfile,'w')
1263 for line in self.configList:
1264 data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1265 confFile.write(data)
1268 def appendConfig(self, uuid, mountpoint):
1269 for x in self.configList:
1270 if x[0] == uuid or x[1] == mountpoint:
1271 self.configList.remove(x)
1272 self.configList.append([uuid, mountpoint])
1274 def removeConfig(self, value):
1275 for x in self.configList:
1276 if x[0] == value or x[1] == value:
1277 self.configList.remove(x)
1279 devicemanagerconfig = DeviceManagerConfig()
1281 devicemanagerhotplugactive = True
1282 def DeviceManagerhotplugDeviceStart(action, device):
1283 global devicemanagerhotplugactive
1284 if devicemanagerhotplugactive:
1285 DeviceManagerHotplugDevice(action, device)
1287 def DeviceManagerHotplugDevice(action, device):
1288 if not config.plugins.devicemanager.hotplug_enable.value:
1290 print "[DeviceManager Hotplug Device] action : %s, device : %s"%(action, device.device)
1293 if action == 'add' and device.is_hotplug and len(device.device) == 3:
1294 if device.device.startswith("sd"):
1295 newdevice = "/dev/" + device.device
1296 cmd = "sleep 3 && blkid -c /dev/null " + newdevice + "*"
1297 data = popen(cmd).read().split('\n')
1298 # print "[DeviceManagerHotplugDevice] blkid data : ",data
1302 if line.startswith(newdevice):
1303 if line.find(" UUID=") != -1:
1304 uuid = line.split(" UUID=")[1].split(' ')[0]
1305 if line.find(" TYPE=") != -1:
1306 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1307 mountdev = line.split(':')[0]
1308 devicemanagerconfig.loadConfig()
1309 configList = devicemanagerconfig.getConfigList()
1310 for c in configList:
1311 if uuid == c[0].strip():
1312 mountpoint = c[1].strip()
1313 if not os.path.ismount(mountpoint):
1314 if partitionType == "ntfs":
1315 cmd = "ntfs-3g %s %s"%(mountdev, mountpoint)
1317 cmd = "mount %s %s"%(mountdev, mountpoint)
1318 print "[DeviceManagerHotplugDevice] try..'%s'"%cmd
1321 elif action == 'remove' and device.device is not None and len(device.device) == 3:
1322 mounts = file('/proc/mounts').read().split('\n')
1324 if not x.startswith('/'):
1326 if x.startswith("/dev/"+device.device):
1327 cmd = "umount "+x.split()[0]
1328 print "[DeviceManagerHotplugDevice] try.. '%s'"%cmd
1331 print "[DeviceManagerHotplug] hotplugDevice error."
1333 def callBackforDeviceManager(session, callback_result = False):
1334 if callback_result == True:
1335 session.open(DeviceManager)
1337 def checkMounts(session):
1339 notMountable_dev = ""
1340 for blockdev in listdir("/sys/block"):
1341 devpath = "/sys/block/" + blockdev
1342 dev = int(readFile(devpath + "/dev").split(':')[0])
1343 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1346 notMountable_partitions = []
1347 for partition in listdir(devpath):
1348 if not partition.startswith(blockdev):
1350 partitions.append(partition)
1351 if os.access('/autofs/'+partition,0) is False:
1352 notMountable_partitions.append(partition)
1353 if len(partitions) == 0 or len(notMountable_partitions) != 0:
1354 if notMountable_dev != "":
1355 notMountable_dev += ' '
1356 notMountable_dev += blockdev
1358 if notMountable_dev != "":
1359 # print "Not mountable partitions found."
1360 InfoText = _("Not 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.)"%notMountable_dev)
1361 AddNotificationWithCallback(
1362 boundFunction(callBackforDeviceManager, session),
1363 MessageBox, InfoText, timeout = 60, default = False
1366 print "checkMounts failed!"
1368 def sessionstart(reason, **kwargs):
1370 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1371 session = kwargs["session"]
1372 checkMounts(session)
1373 if config.plugins.devicemanager.hotplug_enable.value:
1374 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1376 if config.plugins.devicemanager.hotplug_enable.value:
1377 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1379 def autostart(reason, **kwargs):
1382 # check at first enigma2 start
1383 if not fileExists(dmconfigfile):
1384 print "[DeviceManager] autostart : check devices at first start"
1385 sda_isremovable = False
1386 # sdb_isremovable = False
1389 os.system("touch %s"%dmconfigfile)
1391 sda_data = popen("cat /proc/partitions | grep sda1").read()
1393 sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1394 sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1395 print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1397 # sdb_data = popen("cat /proc/partitions | grep sdb1").read()
1398 # if sdb_data != '':
1399 # sdb_UUID = popen("blkid -o value -s UUID /dev/sdb1").read().strip('\n')
1400 # sdb_isremovable = bool(int(readFile("/sys/block/sdb/removable")))
1401 # print "sdb : %s, %s"%(sdb_UUID, sdb_isremovable)
1404 # if sdb_data != '':
1405 # if not sda_isremovable:
1406 # cfg += '"%s":/media/hdd\n'%sda_UUID
1407 # cfg += '"%s":/media/usb\n'%sdb_UUID
1409 # if not sdb_isremovable:
1410 # cfg += '"%s":/media/hdd\n'%sdb_UUID
1411 # cfg += '"%s":/media/usb\n'%sda_UUID
1413 # cfg += '"%s":/media/hdd\n'%sda_UUID
1414 # cfg += '"%s":/media/usb\n'%sdb_UUID
1416 # cfg += '"%s":/media/hdd\n'%sda_UUID
1417 cfg += '"%s":/media/hdd\n'%sda_UUID
1418 confFile = open(dmconfigfile,'w')
1421 # if not path.exists("/media/usb"):
1422 # os.system("mkdir -p /media/usb")
1423 if not path.exists("/media/hdd"):
1424 os.system("mkdir -p /media/hdd")
1426 # check at first enigma2 start - end
1427 devicemanagerconfig.loadConfig()
1428 configList = devicemanagerconfig.getConfigList()
1429 if len(configList) != 0:
1430 print "[DeviceManager] automount from device manager configs"
1431 cmd = "blkid -c /dev/null /dev/sd*"
1432 data = popen(cmd).read().split('\n')
1437 device = line.split(':')[0]
1438 if line.find(" UUID=") != -1:
1439 uuid = line.split(" UUID=")[1].split(' ')[0]
1440 if line.find(" TYPE=") != -1:
1441 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1442 for line in configList:
1443 configuuid = line[0].strip()
1444 configmountpoint = line[1].strip()
1445 if configuuid == uuid and path.exists(configmountpoint) and not path.ismount(configmountpoint):
1446 if filesystem == "ntfs":
1447 cmd = "ntfs-3g %s %s"%(device, configmountpoint)
1449 cmd = "mount -t %s %s %s"%(filesystem, device, configmountpoint)
1450 print "[DeviceManager] ",cmd
1454 print "[DeviceManager] autostart failed!"
1456 def menu(menuid, **kwargs):
1457 if menuid == "harddisk":
1458 return [(_("DeviceManager"), main, "device_manager", 1)]
1461 def main(session, **kwargs):
1462 session.open(DeviceManager)
1464 def Plugins(path, **kwargs):
1466 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1467 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1468 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1471 class MessageBox_2(MessageBox):
1472 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1473 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1474 self.skinName = "MessageBox"
1475 self.closeTimer = eTimer()
1476 self.closeTimer.callback.append(self.msg_close)
1477 self.devicemanager_ret = False
1478 self.devicemanager_msg = ""
1480 def msg_close(self):
1481 self.close(self.devicemanager_ret, self.devicemanager_msg)
1483 def run_close(self, ret, msg=""):
1484 self.devicemanager_ret = ret
1485 self.devicemanager_msg = msg
1486 self.closeTimer.start(100,True)
1488 def createSummary(self):
1489 return MessageBox_2_Summary
1491 class MessageBox_2_Summary(Screen):
1493 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1494 <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />