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, CheckSfdiskVer, enableUdevEvent
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.mountcheck_enable = ConfigEnableDisable(default=True)
37 def readFile(filename):
39 data = file.read().strip()
43 def byteConversion(byte):
44 if type(byte) == str and len(byte) == 0:
46 if type(byte) != long:
48 if byte > 1024*1024*1024:
49 int_part = byte/1024/1024/1024
50 dec_part = byte%(1024*1024*1024)/(1024*1024)
51 return "%d.%d GB"%(int_part, dec_part)
53 int_part = byte/1024/1024
54 dec_part = byte%(1024*1024)/1024
55 return "%d.%d MB"%(int_part, dec_part)
57 def checkStrValue(value , empty = ""):
58 if type(value) != str or len(value) == 0:
62 class DeviceManagerConfiguration(Screen, ConfigListScreen):
63 def __init__(self,session):
64 self.session = session
65 Screen.__init__(self,session)
66 self.skinName = "Setup"
67 self.createConfigList()
68 ConfigListScreen.__init__(self, self.list, session = self.session)
69 self["key_red"] = StaticText(_("Cancel"))
70 self["key_green"] = StaticText(_("OK"))
71 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ],
74 "cancel": self.keyCancel,
75 "red": self.keyCancel,
76 "green": self.keySave,
78 self.onShown.append(self.setWindowTitle)
80 def setWindowTitle(self):
81 self.setTitle(_("DeviceManager configuration"))
83 def createConfigList(self):
85 self.list.append(getConfigListEntry(_("Enable mount check for HDD : "), config.plugins.devicemanager.mountcheck_enable))
86 self.list.append(getConfigListEntry(_("Harddisk standby after : "), config.usage.hdd_standby))
88 class DeviceManager(Screen):
90 <screen position="center,center" size="590,350" title="DeviceManager">
91 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
92 <ePixmap pixmap="skin_default/buttons/green.png" position="160,0" size="140,40" alphatest="on" />
93 <ePixmap pixmap="skin_default/buttons/yellow.png" position="300,0" size="140,40" alphatest="on" />
94 <ePixmap pixmap="skin_default/buttons/blue.png" position="440,0" size="140,40" alphatest="on" />
95 <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" />
96 <widget name="key_green" position="160,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
97 <widget name="key_yellow" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
98 <widget name="key_blue" position="440,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
99 <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="590,2" alphatest="on" />
100 <widget source="menu" render="Listbox" position="0,48" size="590,350" scrollbarMode="showOnDemand">
101 <convert type="TemplatedMultiContent">
104 MultiContentEntryText(pos = (50, 0), size = (510, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor - model
105 MultiContentEntryText(pos = (50, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
106 MultiContentEntryText(pos = (170, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
107 MultiContentEntryText(pos = (290, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
108 MultiContentEntryText(pos = (410, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
109 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # png 5 is the div pixmap
112 MultiContentEntryText(pos = (50, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
113 MultiContentEntryText(pos = (50, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
114 MultiContentEntryText(pos = (50, 54), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
115 MultiContentEntryText(pos = (50, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
116 MultiContentEntryText(pos = (180, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
117 MultiContentEntryText(pos = (310, 76), size = (190, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
118 MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (590, 2), png = 6), # png 6 is the div pixmap
121 MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture
122 MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name
123 MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path
124 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # index 5 is the div pixmap
127 "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)],
135 def __init__(self, session):
136 Screen.__init__(self, session)
137 self.session = session
138 self.currList = "default"
139 self.currDevice = None
140 self.currPartition = None
141 self.defaultMountPoint = "/media/hdd"
143 self["menu"] = List(self.deviceList)
144 self["key_red"] = Label(_("Close"))
145 self["key_green"] = Label(" ")
146 self["key_yellow"] = Label(" ")
147 self["key_blue"] = Label(" ")
149 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions", "MenuActions" ],
152 "cancel": self.keyCancel,
153 "red": self.keyCancel,
155 "yellow": self.keyYellow,
156 "blue": self.keyBlue,
157 "menu": self.keyMenu,
159 self.DeviceManagerConsole = Console()
161 if not self.selectionChanged in self["menu"].onSelectionChanged:
162 self["menu"].onSelectionChanged.append(self.selectionChanged)
163 self.onLayoutFinish.append(self.showDeviceList)
164 self.onLayoutFinish.append(self.addPartitionListChange)
165 self.onClose.append(self.removePartitionListChange)
166 self.onChangedEntry = []
167 self.blockDevices = {}
169 def addPartitionListChange(self):
170 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
172 def removePartitionListChange(self):
173 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
175 def partitionListChanged(self, action, device):
176 print "[Device manager] hotplug partitionListChanged"
177 if self.currList != "default" and device.device[:3] != self.currDevice["blockdev"]:
179 self.showDeviceList()
182 self.icon_button_green = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/button_green.png"))
183 self.divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
185 def selectionChanged(self):
186 if self.currList == "partitions":
187 currentPartition = self.getCurrentPartition()
188 if currentPartition is not None:
189 if currentPartition["fstype"] == "":
190 self["key_blue"].setText("")
191 elif currentPartition["fstype"][:3] == "ext":
192 self["key_blue"].setText(_("Check"))
194 self["key_blue"].setText("")
196 def showDeviceList(self):
198 self["key_red"].setText(_("Close"))
199 self["key_green"].setText(_("Ok"))
200 self["key_yellow"].setText(" ")
201 self["key_blue"].setText(_("Initialize"))
203 for device in deviceinfo.getBlockDevices():
205 "%s - %s"%(device["vendor"], device["model"]), # vendor : str, model : str, index 0
206 _("device : %s")%(device["blockdev"]), # str
207 _("Size : %s")%(byteConversion(device["size"])), # str, bytes
208 _("Partitions : %s")%(len(device["partitions"])), # list
209 _("Removable : %s")%(device["removable"] and 'Yes' or 'No'), # bool [True, False]
213 # print "[DeviceManager] deviceEntry : ", deviceEntry
214 self.deviceList.append(deviceEntry)
215 self.currList = "default"
216 self["menu"].style = "default"
217 self["menu"].setList(self.deviceList)
219 def showPartitionList(self):
220 if self.currDevice is None:
223 for partition in self.currDevice["partitions"]:
224 partitionInfo = deviceinfo.getPartitionInfo(partition)
226 _("Partition : /dev/%s")%partition, # index 0
227 _("Mounted on : %s")%checkStrValue(partitionInfo["mountpoint"], _("not mounted")),
228 _("UUID : %s")%checkStrValue(partitionInfo["uuid"], _("unknown")),
229 _("Type : %s")%checkStrValue(partitionInfo["fstype"], _("unknown")),
230 _("Size : %s")%checkStrValue(byteConversion(partitionInfo["size"]), _("unknown")),
231 _("Free : %s")%checkStrValue(byteConversion(partitionInfo["free"]), _("unknown")),
232 self.divpng, # index 6
233 partitionInfo, # index 7
235 # print "[DeviceManager] partitionEntry : ",partitionEntry
236 partitionList.append(partitionEntry)
237 if len(partitionList) != 0:
238 self["key_red"].setText(_("Devices"))
239 self["key_green"].setText(_(" "))
240 self["key_yellow"].setText(_("Format"))
241 self["key_blue"].setText(_("Check"))
242 self.currList = "partitions"
243 self["menu"].style = "partitions"
244 self["menu"].setList(partitionList)
245 self.selectionChanged()
247 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)
249 def getCurrentDevice(self):
251 return self["menu"].getCurrent()[6]
255 def getCurrentPartition(self):
257 return self["menu"].getCurrent()[7]
263 if self.currList == "default":
264 self.currDevice = self.getCurrentDevice()
265 if self.currDevice is not None:
266 if len(self.currDevice["partitions"]) == 0:
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 self.showPartitionList()
271 self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
272 elif self.currList == "partitions":
279 if self.DeviceManagerConsole is not None:
280 if len(self.DeviceManagerConsole.appContainers):
281 for name in self.DeviceManagerConsole.appContainers.keys():
282 self.DeviceManagerConsole.kill(name)
283 if self.currList == "partitions":
284 self.currDevice = None
285 self.showDeviceList()
286 else: # currList = "default"
290 if self.currList == "partitions":
291 self.choiceBoxFstype()
294 if self.currList == "default":
295 device = self.getCurrentDevice()
296 if device is not None:
297 self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
299 self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10)
300 elif self.currList == "partitions":
301 partition = self.getCurrentPartition()
302 if partition is not None:
303 self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
305 self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
308 self.session.open(DeviceManagerConfiguration)
310 def deviceInitCB(self, ret = True):
311 self.showDeviceList()
313 def deviceCheckCB(self, ret = True):
314 self.showPartitionList()
316 def deviceFormatCB(self, ret = True):
317 self.showPartitionList()
319 def choiceBoxFstype(self):
321 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
322 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
323 menu.append((_("ext4 - experimental"), "ext4"))
324 menu.append((_("vfat - for USB flash memory"), "vfat"))
325 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
327 def choiceBoxFstypeCB(self, choice):
331 partition = self.getCurrentPartition()
332 if partition is not None:
333 self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
335 self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10)
337 # Initializing Start...
338 class DeviceInit(Screen):
339 skin = """<screen position="0,0" size="0,0"/>"""
340 def __init__(self, session, device, devicesize):
341 Screen.__init__(self, session)
342 self.session = session
343 self.deviceInitConsole = Console()
345 self.devicesize = int(devicesize)
346 self.inputbox_partitions = 1
347 self.inputbox_partitionSizeList = []
348 self.inputbox_partitionSizeTotal = int(self.devicesize/1024/1024)
349 self.msgWaiting = None
350 self.msgWaitingMkfs = None
351 self.devicenumber = 0
352 self.newpartitions = 0
353 self.onLayoutFinish.append(self.timerStart)
354 self.initStartTimer = eTimer()
355 self.initStartTimer.callback.append(self.confirmMessage)
356 self.createFSStartTimer = eTimer()
357 self.createFSStartTimer.callback.append(self.createFilesystemStart)
358 self.exitMessageTimer = eTimer()
359 self.exitMessageTimer.callback.append(self.exitMessage)
363 self.doMkfsTimer = eTimer()
364 self.doMkfsTimer.callback.append(self.doMkfs)
365 self.doInitializeTimer = eTimer()
366 self.doInitializeTimer.callback.append(self.doInitialize)
368 self.partitionType = "MBR"
370 self.inputbox_partitionSizeRemain = self.inputbox_partitionSizeTotal
372 self.onClose.append(enableUdevEvent)
374 def timerStart(self):
375 enableUdevEvent(False)
376 self.initStartTimer.start(100,True)
378 def confirmMessage(self):
379 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
380 self.session.openWithCallback(self.confirmed, MessageBox, message)
382 def confirmed(self, ret):
384 self.InitializeStart()
388 def exit(self, ret = True):
391 def unmountAll(self, device):
392 mounts = file('/proc/mounts').read().split('\n')
396 if not line.startswith("/dev/" + device):
398 cmd += "umount %s ;"% line.split()[0]
399 print "[DeviceManager] %s"%cmd
402 mounts = file('/proc/mounts').read().split('\n')
404 if line.startswith("/dev/" + device):
408 def InitializeStart(self):
409 if self.devicesize >= ( 2.2 * 1000 * 1000 * 1000 * 1000 ): # 2.2TB
410 self.partitionType = "GPT"
412 self.inputbox_partitionSizeRemain = 100
415 self.InputPartitionSize_step1()
417 def InputPartitionSize_step1(self):
418 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-%d)" % self.maxPartNum), text="1", maxSize=False, type=Input.NUMBER)
420 def InputPartitionSize_step1_CB(self, ret):
421 if ret is not None and int(ret) in range(1,self.maxPartNum+1): # MBR 1~4, GPT 1~20
422 self.inputbox_partitions = int(ret)
423 self.InputPartitionSize_step2()
425 self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
427 def InputPartitionSize_step2(self):
428 current_partition = len(self.inputbox_partitionSizeList)+1
429 if self.inputbox_partitionSizeRemain == 0:
430 self.choiceBoxFstype()
431 elif current_partition == self.inputbox_partitions:
432 self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
433 self.choiceBoxFstype()
435 text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
436 self.session.openWithCallback(self.InputPartitionSize_step2_CB, InputBox, title=_("Input size of partition %s.(Unit = %s, Max = %d %s)")%(current_partition, self.unit, self.inputbox_partitionSizeRemain, self.unit), text=text, maxSize=False, type=Input.NUMBER)
438 def InputPartitionSize_step2_CB(self, ret):
440 if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
441 self.InputPartitionSize_step2()
443 self.inputbox_partitionSizeList.append(str(ret))
444 self.inputbox_partitionSizeRemain -= int(ret)
445 self.InputPartitionSize_step2()
447 self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
449 def choiceBoxFstype(self):
451 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
452 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
453 menu.append((_("ext4 - experimental"), "ext4"))
454 menu.append((_("vfat - for USB flash memory"), "vfat"))
455 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
457 def choiceBoxFstypeCB(self, choice):
461 self.fstype = choice[1]
462 if self.fstype not in ["ext2", "ext3", "ext4", "vfat"]:
465 self.initInitializeConfirm()
467 def initInitializeConfirm(self):
468 # print self.inputbox_partitionSizeList
470 for index in range(len(self.inputbox_partitionSizeList)):
471 print "partition %d : %s %s"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
472 partitionsInfo += "partition %d : %s %s\n"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
473 partitionsInfo += "filesystem type : %s"%(self.fstype)
474 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
476 def initInitializeConfirmCB(self,ret):
478 self.initInitialize()
482 def initInitialize(self):
483 if not self.unmountAll(self.device):
484 self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
486 msg = _("InitInitializing, please wait ...")
487 msg += _("\nDevice : %s")%self.device
488 msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
489 for index in range(len(self.inputbox_partitionSizeList)):
490 msg += _("\npartition %d : %s %s")%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit)
491 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
492 self.doInitializeTimer.start(500,True)
494 def doInitialize(self):
495 def CheckPartedVer():
496 cmd = 'parted --version'
497 lines = os.popen(cmd).readlines()
499 if l.find("parted (GNU parted)") != -1:
500 ver = l.split()[3].strip()
505 print "[DeviceManager] check parted version Failed!"
509 partitions = len(self.inputbox_partitionSizeList) # get num of partition
513 partedVer = CheckPartedVer()
514 if partedVer >= 2.1: # align option is supported in version 2.1 or later
515 setAlign = "--align optimal"
516 if self.devicesize < 1024 * 1000 * 1000: # 1GB
521 if self.partitionType == "GPT": # partition type is GPT
527 cmd = 'parted %s /dev/%s --script mklabel %s mkpart primary 0%% 100%%' % (setAlign, self.device, parttype)
528 else: # has multiple partitions
530 for p in range(partitions):
533 p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / self.inputbox_partitionSizeTotal )
535 elif p > 0 and partitions > (p + 1):
537 p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / self.inputbox_partitionSizeTotal )+ p_start
539 elif partitions == (p + 1):
548 set += 'mkpart primary ext2 %d%% %d%% ' % (p_start, p_end)
549 cmd = 'parted %s /dev/%s --script mklabel %s %s' % (setAlign, self.device, parttype, set)
551 self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
553 def initInitializeFinished(self, result, retval, extra_args = None):
555 if self.partitionType == "MBR":
556 sfdiskVer = CheckSfdiskVer()
557 if sfdiskVer < 2.26: # sfdisk -R option is deprecated at sfdiskVer >= 2.26
558 cmd = 'sfdisk -R /dev/%s; sleep 5' % (self.device)
559 elif path.exists('/usr/sbin/partprobe'):
560 cmd = 'partprobe /dev/%s; sleep 5' % (self.device)
561 elif path.exists('/usr/sbin/partx'):
562 cmd = 'partx -u /dev/%s; sleep 5' % (self.device)
564 cmd = 'sfdisk -R /dev/%s; sleep 5' % (self.device)
567 self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
569 errorMsg = "initInitializing device Error at /dev/%s"%self.device
570 self.msgWaiting.run_close(False, errorMsg)
572 def initInitializingRefreshFinished(self, result, retval, extra_args = None):
573 cmd = "/bin/umount /dev/%s*" % (self.device)
574 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
576 def initInitializingUmountFinished(self, result, retval, extra_args = None):
577 partitions = open("/proc/partitions")
578 self.devicenumber = 0
579 self.newpartitions = 0
580 for part in partitions:
581 res = re.sub("\s+", " ", part).strip().split(" ")
582 if res and len(res) == 4 and res[3][:3] == self.device:
583 if len(res[3]) > 3 and res[3][:2] == "sd":
584 self.newpartitions += 1
586 partNum = len(self.inputbox_partitionSizeList) # get num of partition
587 if self.newpartitions != partNum:
588 errorMsg = "Partitioning device Error at /dev/%s"%self.device
589 self.msgWaiting.run_close(False, errorMsg)
591 self.msgWaiting.run_close(True)
592 # self.createFilesystem(self.newpartitions)
594 def createFilesystem(self, newpartitions):
595 self.devicenumber = self.devicenumber + 1
596 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
597 shortdevicename = self.device + str(self.devicenumber)
599 partitions = open("/proc/partitions")
600 for part in partitions:
601 res = re.sub("\s+", " ", part).strip().split(" ")
602 if res and len(res) == 4:
603 if res[3] == shortdevicename:
604 partitionsize = int(res[2])
608 if self.fstype == "ext4":
609 cmd = "mkfs.ext4 -F "
610 if partitionsize > 2 * 1024 * 1024: # 2GB
611 cmd += "-T largefile "
612 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 " + fulldevicename
613 elif self.fstype == "ext3":
614 cmd = "mkfs.ext3 -F "
615 if partitionsize > 2 * 1024 * 1024:
616 cmd += "-T largefile "
617 cmd += "-m0 " + fulldevicename
618 elif self.fstype == "ext2":
619 cmd = "mkfs.ext2 -F "
620 if partitionsize > 2 * 1024 * 1024:
621 cmd += "-T largefile "
622 cmd += "-m0 " + fulldevicename
623 elif self.fstype == "vfat":
624 if partitionsize > 4 * 1024 * 1024 * 1024:
625 cmd = "mkfs.vfat -I -S4096 " + fulldevicename
627 cmd = "mkfs.vfat -I " + fulldevicename
628 if partitionsize > 2 * 1024 * 1024: # if partiton size larger then 2GB, use FAT32
632 self.createFilesystemFinished(None, -1, (self.device, fulldevicename))
635 msg = _("Create filesystem, please wait ...")
636 msg += _("\nPartition : %s") % (fulldevicename)
637 msg += _("\nFilesystem : %s") % (self.fstype)
638 msg += _("\nDisk Size : %s MB") % (self.inputbox_partitionSizeTotal)
639 msg += _("\nPartition Size : %d %s\n") % (int(self.inputbox_partitionSizeList[self.devicenumber-1]), self.unit)
640 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
642 self.doMkfsTimer.start(500,True)
645 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
646 self.deviceInitConsole.ePopen(self.mkfs_cmd, self.createFilesystemFinished, (self.device, fulldevicename))
648 def createFilesystemFinished(self, result, retval, extra_args = None):
649 device = extra_args[0]
650 fulldevicename = extra_args[1]
652 self.msgWaitingMkfs.run_close(True)
654 errorMsg = _("Creating filesystem Error")
655 if fulldevicename is not None:
656 errorMsg += _(" at /dev/%s")%fulldevicename
657 self.msgWaitingMkfs.run_close(False, errorMsg)
659 def createFilesystemStart(self):
660 self.createFilesystem(self.newpartitions)
662 def msgWaitingCB(self, ret, msg=""):
664 self.createFSStartTimer.start(100,True)
668 self.exitMessageTimer.start(100,True)
670 def msgWaitingMkfsCB(self, ret, msg=""):
671 if self.devicenumber < self.newpartitions:
672 self.createFSStartTimer.start(100,True)
676 self.msg = _("Device Initialization finished sucessfully!")
677 self.exitMessageTimer.start(100,True)
681 self.exitMessageTimer.start(100,True)
683 def exitMessage(self):
685 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
687 self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
691 # device check start..
692 class DeviceCheck(Screen):
693 skin = """<screen position="0,0" size="0,0"/>"""
694 def __init__(self, session, partition):
695 Screen.__init__(self, session)
696 self.session = session
697 self.deviceCheckConsole = Console()
698 self.partition = partition
699 self.onLayoutFinish.append(self.timerStart)
700 self.checkStartTimer = eTimer()
701 self.checkStartTimer.callback.append(self.confirmMessage)
702 self.umountTimer = eTimer()
703 self.umountTimer.callback.append(self.doUnmount)
705 def timerStart(self):
706 self.checkStartTimer.start(100,True)
708 def confirmMessage(self):
709 fssize = self.partition["size"]
710 if long(fssize) > 1024*1024*1024*16:
711 message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
712 self.session.openWithCallback(self.confirmed, MessageBox, message)
714 self.deviceCheckStart()
716 def confirmed(self, ret):
717 print "confirmed : ",ret
719 self.deviceCheckStart()
723 def deviceCheckStart(self):
724 print "deviceCheckStart "
725 print "partition : ", self.partition
726 device = self.partition["partition"]
727 fstype = self.partition["fstype"]
728 fssize = self.partition["size"]
729 if device is not None and fstype.startswith("ext"):
730 msg = _("Check filesystem, please wait ...")
731 msg += _("\nDevice : /dev/%s")%(device)
732 msg += _("\nFilesystem : %s")%(fstype)
733 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
734 self.umountTimer.start(500,True)
739 device = self.partition["partition"]
740 mountpoint = self.partition["mountpoint"]
741 fstype = self.partition["fstype"]
743 self.doUmountFsck(device, mountpoint, fstype)
745 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
747 def doUmountFsck(self, device, mountpoint, fstype):
748 cmd = "umount /dev/%s" % device
749 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
751 def umountFsckFinished(self, result, retval, extra_args = None):
752 device = extra_args[0]
753 mountpoint = extra_args[1]
754 fstype = extra_args[2]
756 cmd = "fsck." + fstype + " -f -p /dev/" + device
757 self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
759 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
760 self.msgWaiting.run_close(False,errorMsg)
762 def fsckFinished(self, result, retval, extra_args = None):
763 device = extra_args[0]
764 mountpoint = extra_args[1]
766 text = _("Filesystem check finished sucessfully")
767 self.msgWaiting.run_close(True, text)
769 text = _("Error checking disk. The disk or filesystem may be damaged")
770 self.msgWaiting.run_close(False, text)
772 def msgWaitingCB(self, ret, msg):
774 self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
776 self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
778 partition = self.partition["partition"]
779 mountpoint = self.partition["mountpoint"]
780 fstype = self.partition["fstype"]
783 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
785 cmd = "mount /dev/" + partition + " " + mountpoint
786 self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
790 def mountPartitionFinished(self, result, retval, extra_args = None):
799 class DeviceFormat(Screen):
800 skin = """<screen position="0,0" size="0,0"/>"""
801 def __init__(self, session, partition, newfstype):
802 Screen.__init__(self, session)
803 self.session = session
804 self.deviceFormatConsole = Console()
805 self.partition = partition
806 self.newfstype = newfstype
807 self.unmountedList = []
808 self.onLayoutFinish.append(self.timerStart)
809 self.formatStartTimer = eTimer()
810 self.formatStartTimer.callback.append(self.DeviceFormatStart)
811 self.umountTimer = eTimer()
812 self.umountTimer.callback.append(self.doUnmount)
813 self.onClose.append(enableUdevEvent)
815 def timerStart(self):
816 enableUdevEvent(False)
817 self.formatStartTimer.start(100,True)
819 def DeviceFormatStart(self):
820 print "DeviceFormatStart : ", self.partition,
821 print "Filesystem : ",self.newfstype
822 device = self.partition["partition"]
823 devicepath = "/dev/"+device
824 fssize = self.partition["size"]
825 newfstype = self.newfstype
826 msg = _("Format filesystem, please wait ...")
827 msg += _("\nDevice : %s")%(devicepath)
828 msg += _("\nFilesystem : %s")%(newfstype)
829 msg += _("\nSize : %s")%(byteConversion(fssize))
830 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False, msgBoxID = None)
831 self.umountTimer.start(500,True)
834 mountpoint = self.partition["mountpoint"]
836 self.doumountPartition()
838 self.umountPartitionFinished("NORESULT", 0)
840 def doumountPartition(self):
841 oldfstype = self.partition["fstype"]
842 newfstype = self.newfstype
844 if newfstype == oldfstype:
845 device = self.partition["partition"]
847 device = self.partition["partition"][:3]
849 mounts = file('/proc/mounts','r')
850 for line in mounts.readlines():
851 if line.startswith("/dev/%s"%device):
852 cmd += "umount %s;"%line.split()[0]
853 self.unmountedList.append([line.split()[0], line.split()[1]])
854 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
856 def umountPartitionFinished(self, result, retval, extra_args = None):
857 partition = self.partition["partition"]
858 oldfstype = self.partition["fstype"]
859 newfstype = self.newfstype
861 if oldfstype == newfstype:
862 self.changePartitionIDFinished("NORESULT", 0)
864 sfdiskVer = CheckSfdiskVer()
865 if sfdiskVer >= 2.26:
866 cmd = "sfdisk --part-type /dev/%s %s" % (partition[:3], partition[3:])
868 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
870 if newfstype[:3] == "ext":
874 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
876 errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
877 self.msgWaiting.run_close(False,errorMsg)
879 def changePartitionIDFinished(self, result, retval, extra_args = None):
880 device = self.partition["partition"][:3]
881 mountpoint = self.partition["mountpoint"]
882 oldfstype = self.partition["fstype"]
883 newfstype = self.newfstype
885 if oldfstype == newfstype:
886 self.refreshPartitionFinished("NORESULT", 0)
888 sfdiskVer = CheckSfdiskVer()
889 if sfdiskVer < 2.26: # sfdisk -R option is deprecated at sfdiskVer >= 2.26
890 cmd = "sfdisk -R /dev/%s; sleep 5" % (device)
891 elif path.exists('/usr/sbin/partprobe'):
892 cmd = 'partprobe /dev/%s; sleep 5' % (device)
893 elif path.exists('/usr/sbin/partx'):
894 cmd = 'partx -u /dev/%s; sleep 5' % (device)
896 cmd = "sfdisk -R /dev/%s; sleep 5" % (device)
898 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
900 if result and result.find("Use GNU Parted") > 0:
901 print "[DeviceManager] /dev/%s use GNU Parted!" % device
902 self.refreshPartitionFinished("NORESULT", 0)
904 errorMsg = _("Can not change the partition ID for %s")%device
905 self.msgWaiting.run_close(False,errorMsg)
907 def refreshPartitionFinished(self, result, retval, extra_args = None):
908 print "refreshPartitionFinished!"
909 partition = self.partition["partition"]
910 mountpoint = self.partition["mountpoint"]
911 size = int(self.partition["size"])/1024/1024
912 oldfstype = self.partition["fstype"]
913 newfstype = self.newfstype
915 if newfstype == "ext4":
916 cmd = "mkfs.ext4 -F "
918 cmd += "-T largefile "
919 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
920 elif newfstype == "ext3":
921 cmd = "mkfs.ext3 -F "
923 cmd += "-T largefile "
924 cmd += "-m0 /dev/" + partition
925 elif newfstype == "ext2":
926 cmd = "mkfs.ext2 -F "
928 cmd += "-T largefile "
929 cmd += "-m0 /dev/" + partition
930 elif newfstype == "vfat":
931 if size > 4 * 1024 * 1024:
932 cmd = "mkfs.vfat -I -S4096 /dev/" + partition
934 cmd = "mkfs.vfat -I /dev/" + partition
935 if size > 2 * 1024: # if partiton size larger then 2GB, use FAT32
937 self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
939 errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
940 self.msgWaiting.run_close(False,errorMsg)
942 def mkfsFinished(self, result, retval, extra_args = None):
943 print "mkfsFinished!"
944 partition = self.partition["partition"]
947 if len(self.unmountedList) == 0:
948 self.doMountFinished("NORESULT",0)
949 for x in self.unmountedList:
950 cmd += "mount %s %s;"%(x[0], x[1])
951 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
953 text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
954 self.msgWaiting.run_close(False, text)
956 def doMountFinished(self, result, retval, extra_args = None):
957 print "doMountFinished!"
958 text = _("Format finished sucessfully.")
959 self.msgWaiting.run_close(True, text)
961 def msgWaitingCB(self, ret, msg):
963 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
965 self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
974 self.blockDeviceList = []
976 def getBlockDevices(self):
977 return self.blockDeviceList
980 self.blockDeviceList = []
981 self.getBlockDeviceList()
983 def getBlockDeviceList(self):
984 print "get block device Infomations..."
985 for blockdev in listdir("/sys/block"):
986 (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
987 if not blacklisted and not error:
988 # print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
990 blockDevice["blockdev"] = blockdev # str
991 blockDevice["removable"] = removable # bool [True, False]
992 blockDevice["partitions"] = partitions # list
993 blockDevice["size"] = size # str
994 blockDevice["model"] = model # str
995 blockDevice["vendor"] = vendor # str
996 self.blockDeviceList.append(blockDevice)
998 def SortPartList(self, partList):
999 length = len(partList)-1
1001 while sorted is False:
1003 for idx in range(length):
1004 if int(partList[idx][3:]) > int(partList[idx+1][3:]):
1006 partList[idx] , partList[idx+1] = partList[idx+1], partList[idx]
1008 def getBlockDeviceInfo(self, blockdev):
1009 devpath = "/sys/block/" + blockdev
1018 dev = int(readFile(devpath + "/dev").split(':')[0])
1019 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1021 return error, blacklisted, removable, partitions, size, model, vendor
1022 removable = bool(int(readFile(devpath + "/removable")))
1023 size = str(int(readFile(devpath + "/size").strip())*512)
1024 model = readFile(devpath + "/device/model")
1025 vendor = readFile(devpath + "/device/vendor")
1026 for partition in listdir(devpath):
1027 if partition[:len(blockdev)] != blockdev:
1029 partitions.append(partition)
1030 self.SortPartList(partitions)
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').readlines()
1130 if not x.startswith('/'):
1132 _devpath, _mountpoint = x.split()[:2]
1133 if devpath == _devpath and mountpoint == _mountpoint:
1139 def isMounted_anymp(self, devpath):
1141 mounts = open('/proc/mounts', 'r').readlines()
1143 if not x.startswith('/'):
1145 _devPart, _mountpoint = x.split()[:2]
1146 if devpath == _devPart:
1152 # check partition type is extended or swap.
1153 def checkSwapExtended(self, partition):
1154 blockName = partition[:-1]
1155 partNum = partition[-1]
1156 data = os.popen("parted /dev/%s print" % blockName).readlines()
1158 info = x.strip().split()
1160 if len(info) > 0 and info[0] == str(partNum):
1161 if len(info) >= 5 and info[4].find('extended') != -1: # check Type is extended
1163 elif len(info) >= 6 and info[5].find('swap') != -1: # check File System is swap
1168 def isMountable(self, partition):
1169 if self.checkSwapExtended(partition):
1173 if self.isMounted_anymp('/dev/'+partition):
1176 elif os.access('/autofs/'+partition, 0):
1182 def isFstabAutoMounted(self, uuid, devpath, mountpoint):
1183 # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint)
1184 if mountpoint[-1] == '/':
1185 mountpoint = mountpoint[:-1]
1186 data = file('/etc/fstab').read().split('\n')
1188 if not line.startswith('/'):
1190 dev, mp, ms = line.split()[0:3]
1191 if uuid is not None and dev.startswith('UUID'):
1192 if dev.split('=')[1] == uuid.strip("\"") and mp == mountpoint and ms == 'auto':
1193 # print " >> line : ", line
1195 elif dev == devpath and mp == mountpoint and ms == 'auto':
1196 # print " >> line : ", line
1200 def umountByMountpoint(self, mountpoint):
1201 if mountpoint is None:
1204 if path.ismount(mountpoint):
1205 cmd = "umount " + mountpoint
1206 print "[DeviceManager] ", cmd
1209 print "Umount by mountpoint failed!"
1210 if not path.ismount(mountpoint):
1214 def umountByDevpath(self, devpath):
1215 cmd = "umount " + devpath
1216 print "[DeviceManager] ", cmd
1219 deviceinfo = DeviceInfo()
1221 class MountpointBrowser(Screen):
1223 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1224 <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1225 <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1226 <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1227 <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1228 <widget source="key_red" render = "Label" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
1229 <widget source="key_green" render = "Label" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
1230 <widget source="key_yellow" render = "Label" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
1231 <widget source="key_blue" render = "Label" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
1232 <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1233 <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1236 def __init__(self, session):
1237 Screen.__init__(self, session)
1238 self["key_red"] = StaticText(_("Cancel"))
1239 self["key_green"] = StaticText(_("Select"))
1240 self["key_yellow"] = StaticText(_("Create directory"))
1241 self["key_blue"] = StaticText("Delete directory")
1242 directory = "/media/"
1243 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1244 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1245 self["filelist"] = self.filelist
1247 self["shortcuts"] = ActionMap(["ColorActions"],
1250 "green": self.select,
1251 "yellow": self.createDirectory,
1252 "blue": self.deleteDirectory,
1255 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1257 "cancel": self.exit,
1262 if self.filelist.canDescent():
1263 self.filelist.descent()
1266 if self["filelist"].getCurrentDirectory() is not None:
1267 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1268 self.filelist.descent()
1269 currDir = self["filelist"].getCurrentDirectory()
1272 self.close(self["filelist"].getFilename())
1274 def createDirectory(self):
1275 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1277 def createDirectoryCB(self, retval = None):
1280 if retval is not None:
1281 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1282 if not path.exists(newdir):
1283 os.system("mkdir %s"%newdir)
1284 self.filelist.refresh()
1287 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1289 def deleteDirectory(self):
1292 if self["filelist"].getCurrentDirectory() is not None:
1293 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1294 delDir = self["filelist"].getFilename()
1295 if path.exists(delDir):
1296 os.system("rmdir '%s'"%delDir)
1297 if path.exists(delDir):
1298 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1299 self.filelist.refresh()
1302 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1307 class MessageBoxConfirm(MessageBox):
1309 <screen position="center,center" size="620,10" title="Message">
1310 <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1311 <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1312 <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1313 <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1314 <widget name="list" position="100,100" size="380,375" transparent="1" />
1315 <applet type="onLayoutFinish">
1316 # this should be factored out into some helper code, but currently demonstrates applets.
1317 from enigma import eSize, ePoint
1319 orgwidth = self.instance.size().width()
1320 orgheight = self.instance.size().height()
1321 orgpos = self.instance.position()
1322 textsize = self["text"].getSize()
1324 # y size still must be fixed in font stuff...
1325 textsize = (textsize[0] + 50, textsize[1] + 50)
1327 if self.type == self.TYPE_YESNO:
1329 wsizex = textsize[0] + 60
1330 wsizey = textsize[1] + offset
1331 if (280 > wsizex):
1333 wsize = (wsizex, wsizey)
1336 self.instance.resize(eSize(*wsize))
1339 self["text"].instance.resize(eSize(*textsize))
1342 listsize = (wsizex, 50)
1343 self["list"].instance.move(ePoint(0, textsize[1]))
1344 self["list"].instance.resize(eSize(*listsize))
1348 newheight = wsize[1]
1349 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1354 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1356 def callBackforDeviceManager(session, callback_result = False):
1357 if callback_result == True:
1358 session.open(DeviceManager)
1360 def checkMounts(session):
1362 noMountable_dev = ""
1363 for blockdev in listdir("/sys/block"):
1364 devpath = "/sys/block/" + blockdev
1365 dev = int(readFile(devpath + "/dev").split(':')[0])
1366 if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
1369 noMountable_partitions = []
1370 for partition in listdir(devpath):
1371 if not partition.startswith(blockdev):
1374 if deviceinfo.checkSwapExtended(partition):
1377 partitions.append(partition)
1379 if deviceinfo.isMounted_anymp('/dev/' + partition):
1382 if os.access('/autofs/'+partition, 0) is False:
1383 noMountable_partitions.append(partition)
1385 if len(partitions) == 0 or len(noMountable_partitions) != 0:
1386 if noMountable_dev != "":
1387 noMountable_dev += ' '
1388 noMountable_dev += blockdev
1390 if noMountable_dev != "":
1391 print "Umountable partitions found."
1392 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
1393 AddNotificationWithCallback(
1394 boundFunction(callBackforDeviceManager, session),
1395 MessageBox, InfoText, timeout = 60, default = False
1398 print "checkMounts failed!"
1400 def sessionstart(reason, **kwargs):
1402 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1403 session = kwargs["session"]
1404 checkMounts(session)
1408 def autostart(reason, **kwargs):
1411 # at first enigma2 start
1412 if config.misc.firstrun.value:
1413 print "[DeviceManager] autostart : check devices at first start"
1414 if not path.exists("/media/hdd"):
1415 cmd = "mkdir -p /media/hdd"
1419 print "[DeviceManager] autostart failed!"
1423 def menu(menuid, **kwargs):
1424 if menuid == "system":
1425 return [(_("DeviceManager"), main, "device_manager", 50)]
1428 def main(session, **kwargs):
1429 session.open(DeviceManager)
1431 def Plugins(path, **kwargs):
1433 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1434 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1435 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1438 class MessageBox_2(MessageBox):
1439 def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1440 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1441 self.skinName = "MessageBox"
1442 self.closeTimer = eTimer()
1443 self.closeTimer.callback.append(self.msg_close)
1444 self.devicemanager_ret = False
1445 self.devicemanager_msg = ""
1447 def msg_close(self):
1448 self.close(self.devicemanager_ret, self.devicemanager_msg)
1450 def run_close(self, ret, msg=""):
1451 self.devicemanager_ret = ret
1452 self.devicemanager_msg = msg
1453 self.closeTimer.start(100,True)
1455 def createSummary(self):
1456 return MessageBox_2_Summary
1458 class MessageBox_2_Summary(Screen):
1460 <screen name="MessageBox_2_Summary" position="0,0" size="%d,%d" id="1">
1461 <widget source="parent.Text" render="Label" position="0,0" size="%d,%d" font="Regular;%d" halign="center" valign="center" />
1464 def __init__(self, session, parent):
1465 w,h = session.summary_desktop.size().width(), session.summary_desktop.size().height()
1466 self.skin = self.skin % (w, h, w, h, h/7)
1467 Screen.__init__(self, session, parent = parent)