X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fpython%2FPlugins%2FSystemPlugins%2FDeviceManager%2Fplugin.py;h=c83d1615448e497d95966409c6e7141f00053006;hp=9076321f12c9dec82204a7d3400156ddf53a246b;hb=f3685dcfbbf65fe723403c32f2389fd9c0479d0d;hpb=6d3258af62bab3572154538c239ebefcf0f91df1 diff --git a/lib/python/Plugins/SystemPlugins/DeviceManager/plugin.py b/lib/python/Plugins/SystemPlugins/DeviceManager/plugin.py index 9076321..c83d161 100755 --- a/lib/python/Plugins/SystemPlugins/DeviceManager/plugin.py +++ b/lib/python/Plugins/SystemPlugins/DeviceManager/plugin.py @@ -102,41 +102,41 @@ class DeviceManagerConfiguration(Screen, ConfigListScreen): class DeviceManager(Screen): skin = """ - + - - - + + + - - - - - + + + + + {"templates": {"default": (54,[ - MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor - model - MultiContentEntryText(pos = (100, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device - MultiContentEntryText(pos = (230, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size - MultiContentEntryText(pos = (360, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions - MultiContentEntryText(pos = (490, 32), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable - MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # png 5 is the div pixmap + MultiContentEntryText(pos = (50, 0), size = (510, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor - model + MultiContentEntryText(pos = (50, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device + MultiContentEntryText(pos = (170, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size + MultiContentEntryText(pos = (290, 32), size = (120, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions + MultiContentEntryText(pos = (410, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable + MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # png 5 is the div pixmap ]), "partitions": (98, [ - MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition - MultiContentEntryText(pos = (100, 32), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on - MultiContentEntryText(pos = (100, 54), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID - MultiContentEntryText(pos = (100, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type - MultiContentEntryText(pos = (230, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total - MultiContentEntryText(pos = (380, 76), size = (200, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free - MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (670, 2), png = 6), # png 6 is the div pixmap + MultiContentEntryText(pos = (50, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition + MultiContentEntryText(pos = (50, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on + MultiContentEntryText(pos = (50, 54), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID + MultiContentEntryText(pos = (50, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type + MultiContentEntryText(pos = (180, 76), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total + MultiContentEntryText(pos = (310, 76), size = (190, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free + MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (590, 2), png = 6), # png 6 is the div pixmap ]), "mountpoint": (54,[ MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path - MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # index 5 is the div pixmap + MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (590, 2), png = 5), # index 5 is the div pixmap ]) }, "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)], @@ -270,7 +270,7 @@ class DeviceManager(Screen): if self.currDevice is None or self.currPartition is None: return partition = self.currPartition["partition"] - if not os.access("/autofs/%s"%partition,0): + if deviceinfo.isMountable(partition) is False: self.session.open(MessageBox, _("This partition is not mountable.\nYou need to check or format this partition."), MessageBox.TYPE_ERROR, timeout = 10) return self["key_red"].setText(_("Partitions")) @@ -295,31 +295,40 @@ class DeviceManager(Screen): self["menu"].setList(self.mountPointList) def getCurrentDevice(self): - if self.currList == "default": + try: return self["menu"].getCurrent()[6] - return None + except: + return None def getCurrentPartition(self): - if self.currList == "partitions": + try: return self["menu"].getCurrent()[7] - return None + except: + return None def keyOk(self): # print "keyOk" if self.currList == "default": self.currDevice = self.getCurrentDevice() - if len(self.currDevice["partitions"]) == 0: - 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) + if self.currDevice is not None: + if len(self.currDevice["partitions"]) == 0: + 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) + else: + self.showPartitionList() else: - self.showPartitionList() + self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10) elif self.currList == "partitions": - currMountPoint = self.getCurrentPartition()["mountpoint"] - currUuid = self.getCurrentPartition()["uuid"] - if currMountPoint == "": - self.currPartition = self.getCurrentPartition() - self.showMountPointSetup() + currentPartition = self.getCurrentPartition() + if currentPartition is not None: + currMountPoint = currentPartition["mountpoint"] + currUuid = currentPartition["uuid"] + if currMountPoint == "": + self.currPartition = currentPartition + self.showMountPointSetup() + else: + self.doUmount(currMountPoint, self.showPartitionList) else: - self.doUmount(currMountPoint, self.showPartitionList) + self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10) elif self.currList == "mountpoint": # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng) currEntry = self["menu"].getCurrent()[3] @@ -352,16 +361,21 @@ class DeviceManager(Screen): def keyYellow(self): if self.currList == "partitions": - partition = self.getCurrentPartition() self.choiceBoxFstype() def keyBlue(self): if self.currList == "default": device = self.getCurrentDevice() - self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"]) + if device is not None: + self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"]) + else: + self.session.open(MessageBox, _("Device not found."), MessageBox.TYPE_ERROR, timeout = 10) elif self.currList == "partitions": partition = self.getCurrentPartition() - self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition) + if partition is not None: + self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition) + else: + self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10) def keyMenu(self): self.session.open(DeviceManagerConfiguration) @@ -388,7 +402,10 @@ class DeviceManager(Screen): return else: partition = self.getCurrentPartition() - self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1]) + if partition is not None: + self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1]) + else: + self.session.open(MessageBox, _("Partition info is not found."), MessageBox.TYPE_ERROR, timeout = 10) # about mount funcs.. def doUmount(self, mountpoint, callback): @@ -508,7 +525,7 @@ class DeviceInit(Screen): self.devicesize = int(devicesize) self.inputbox_partitions = 1 self.inputbox_partitionSizeList = [] - self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024) + self.inputbox_partitionSizeTotal = int(self.devicesize/1024/1024) self.msgWaiting = None self.msgWaitingMkfs = None self.devicenumber = 0 @@ -528,6 +545,11 @@ class DeviceInit(Screen): self.doInitializeTimer = eTimer() self.doInitializeTimer.callback.append(self.doInitialize) + self.partitionType = "MBR" + self.maxPartNum = 4 + self.inputbox_partitionSizeRemain = self.inputbox_partitionSizeTotal + self.unit = "MB" + def timerStart(self): self.initStartTimer.start(100,True) @@ -562,13 +584,19 @@ class DeviceInit(Screen): return True def InitializeStart(self): + if self.devicesize >= ( 2.2 * 1000 * 1000 * 1000 * 1000 ): # 2.2TB + self.partitionType = "GPT" + self.maxPartNum = 20 + self.inputbox_partitionSizeRemain = 100 + self.unit = "%" + self.InputPartitionSize_step1() def InputPartitionSize_step1(self): - self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER) + 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) def InputPartitionSize_step1_CB(self, ret): - if ret is not None and int(ret) in range(1,5): # ret in 1~4 + if ret is not None and int(ret) in range(1,self.maxPartNum+1): # MBR 1~4, GPT 1~20 self.inputbox_partitions = int(ret) self.InputPartitionSize_step2() else: @@ -583,7 +611,7 @@ class DeviceInit(Screen): self.choiceBoxFstype() else: text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) ))) - 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) + 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) def InputPartitionSize_step2_CB(self, ret): if ret is not None: @@ -618,8 +646,8 @@ class DeviceInit(Screen): # print self.inputbox_partitionSizeList partitionsInfo = "" for index in range(len(self.inputbox_partitionSizeList)): - print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index])) - partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index])) + print "partition %d : %s %s"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit) + partitionsInfo += "partition %d : %s %s\n"%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit) partitionsInfo += "filesystem type : %s"%(self.fstype) self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO) @@ -637,28 +665,79 @@ class DeviceInit(Screen): msg += _("\nDevice : %s")%self.device msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal for index in range(len(self.inputbox_partitionSizeList)): - msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index])) + msg += _("\npartition %d : %s %s")%(index+1, str(self.inputbox_partitionSizeList[index]), self.unit) self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False) self.doInitializeTimer.start(500,True) def doInitialize(self): + def CheckPartedVer(): + cmd = 'parted --version' + lines = os.popen(cmd).readlines() + for l in lines: + if l.find("parted (GNU parted)") != -1: + ver = l.split()[3].strip() + break + try: + ver = float(ver) + except: + print "[CheckPartedVer] check parted version Failed!" + return 0 + return ver + + partitions = len(self.inputbox_partitionSizeList) # get num of partition set = "" - partitions = len(self.inputbox_partitionSizeList) - if partitions == 1: - cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device + if self.partitionType == "MBR": + if partitions == 1: + cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device + else: + for p in range(4): + if partitions > p+1: + set += ",%s\n"%(self.inputbox_partitionSizeList[p]) + else: + set +=";\n" + set+="y\n" + cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device) + + elif self.partitionType == "GPT": # partition type is GPT + setAlign = "" + partedVer = CheckPartedVer() + if partedVer >= 2.1: # align option is supported in version 2.1 or later + setAlign = "--align optimal" + + if partitions == 1: + cmd = 'parted %s /dev/%s --script mklabel gpt mkpart disk ext2 0%% 100%%' % (setAlign, self.device) + else: # has multiple partitions + p_current = 0 + for p in range(partitions): + if p == 0: + p_start = p_current + p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 ) + p_current = p_end + elif p > 0 and partitions > (p + 1): + p_start = p_current + p_end = int( (long(self.inputbox_partitionSizeList[p]) * 100) / 100 )+ p_start + p_current = p_end + elif partitions == (p + 1): + p_start = p_current + p_end = 100 + if p_start == p_end: + p_end +=1 + if p_end > 100: + continue + set += 'mkpart disk%d ext2 %d%% %d%% ' % (p + 1, p_start, p_end) + cmd = 'parted %s /dev/%s --script mklabel gpt %s' % (setAlign, self.device, set) else: - for p in range(4): - if partitions > p+1: - set += ",%s\n"%(self.inputbox_partitionSizeList[p]) - else: - set +=";\n" - set+="y\n" - cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device) + errorMsg = "Invalid partitioning type" + self.msgWaiting.run_close(False, errorMsg) + return self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished) def initInitializeFinished(self, result, retval, extra_args = None): if retval == 0: - cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device) + if self.partitionType == "MBR": + cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device) + else: # is GPT + cmd = "sleep 5" self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished) else: errorMsg = "initInitializing device Error at /dev/%s"%self.device @@ -678,7 +757,12 @@ class DeviceInit(Screen): if len(res[3]) > 3 and res[3][:2] == "sd": self.newpartitions += 1 partitions.close() - self.msgWaiting.run_close(True) + partNum = len(self.inputbox_partitionSizeList) # get num of partition + if self.newpartitions != partNum: + errorMsg = "Partitioning device Error at /dev/%s"%self.device + self.msgWaiting.run_close(False, errorMsg) + else: + self.msgWaiting.run_close(True) # self.createFilesystem(self.newpartitions) def createFilesystem(self, newpartitions): @@ -715,6 +799,9 @@ class DeviceInit(Screen): cmd = "/usr/sbin/mkfs.vfat -I -S4096 " + fulldevicename else: cmd = "/usr/sbin/mkfs.vfat -I " + fulldevicename + if partitionsize > 2 * 1024 * 1024: # if partiton size larger then 2GB, use FAT32 + cmd += " -F 32" + else: self.createFilesystemFinished(None, -1, (self.device, fulldevicename)) return @@ -722,7 +809,8 @@ class DeviceInit(Screen): msg = _("Create filesystem, please wait ...") msg += _("\nPartition : %s") % (fulldevicename) msg += _("\nFilesystem : %s") % (self.fstype) - msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1]) + msg += _("\nDisk Size : %s MB") % (self.inputbox_partitionSizeTotal) + msg += _("\nPartition Size : %d %s\n") % (int(self.inputbox_partitionSizeList[self.devicenumber-1]), self.unit) self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False) self.mkfs_cmd = cmd self.doMkfsTimer.start(500,True) @@ -975,8 +1063,12 @@ class DeviceFormat(Screen): cmd = "sfdisk -R /dev/%s; sleep 5"%(device) self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished) else: - errorMsg = _("Can not change the partition ID for %s")%device - self.msgWaiting.run_close(False,errorMsg) + if result and result.find("Use GNU Parted") > 0: + print "[DeviceManager] /dev/%s use GNU Parted!" % device + self.refreshPartitionFinished("NORESULT", 0) + else: + errorMsg = _("Can not change the partition ID for %s")%device + self.msgWaiting.run_close(False,errorMsg) def refreshPartitionFinished(self, result, retval, extra_args = None): print "refreshPartitionFinished!" @@ -1006,6 +1098,8 @@ class DeviceFormat(Screen): cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition else: cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition + if size > 2 * 1024: # if partiton size larger then 2GB, use FAT32 + cmd += " -F 32" self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished) else: errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition @@ -1070,6 +1164,16 @@ class DeviceInfo(): blockDevice["vendor"] = vendor # str self.blockDeviceList.append(blockDevice) + def SortPartList(self, partList): + length = len(partList)-1 + sorted = False + while sorted is False: + sorted = True + for idx in range(length): + if int(partList[idx][3:]) > int(partList[idx+1][3:]): + sorted = False + partList[idx] , partList[idx+1] = partList[idx+1], partList[idx] + def getBlockDeviceInfo(self, blockdev): devpath = "/sys/block/" + blockdev error = False @@ -1092,6 +1196,8 @@ class DeviceInfo(): if partition[:len(blockdev)] != blockdev: continue partitions.append(partition) + self.SortPartList(partitions) + except IOError: error = True return error, blacklisted, removable, partitions, size, model, vendor @@ -1188,7 +1294,7 @@ class DeviceInfo(): def isMounted(self, devpath, mountpoint): try: - mounts = file('/proc/mounts').read().split('\n') + mounts = file('/proc/mounts').readlines() for x in mounts: if not x.startswith('/'): continue @@ -1199,15 +1305,48 @@ class DeviceInfo(): pass return False + def isMounted_anymp(self, devpath): + try: + mounts = open('/proc/mounts', 'r').readlines() + for x in mounts: + if not x.startswith('/'): + continue + _devPart, _mountpoint = x.split()[:2] + if devPart == _devPart: + return True + except: + pass + return False + + # check partition ID in extended or swap. + def checkSwapExtended(self, partition): + partID_Extended = ("5", "0f", "85", "c5", "d5") + partID_swap = ("82", "42") + data = os.popen("fdisk -l /dev/%s |grep %s" % (partition[:-1], partition )).readline().split() + if data[1] == '*': + partID = str(data[5]) + else: + partID = str(data[4]) +# print "partID: " ,partID +# print "checkIDS : ", partID_Extended + partID_swap + if partID in partID_Extended + partID_swap: + return True + else: + return False + def isMountable(self, partition): - autofsPath = "/autofs/"+partition.device - mountable = False + if self.checkSwapExtended(partition): + return False + try: - os.listdir(autofsPath) - mountable = True + if self.isMounted_anymp('/dev/'+partition): + return True + + elif os.access('/autofs/'+partition, 0): + return True except: pass - return mountable + return False def isFstabAutoMounted(self, uuid, devpath, mountpoint): # print " >> isFstabMounted, uuid : %s, devpath : %s, mountpoint : %s"%(uuid, devpath, mountpoint) @@ -1647,9 +1786,18 @@ def checkMounts(session): for partition in listdir(devpath): if not partition.startswith(blockdev): continue + + if deviceinfo.checkSwapExtended(partition): + continue + partitions.append(partition) - if os.access('/autofs/'+partition,0) is False: + + if deviceinfo.isMounted_anymp('/dev/' + partition): + continue + + if os.access('/autofs/'+partition, 0) is False: noMountable_partitions.append(partition) + if len(partitions) == 0 or len(noMountable_partitions) != 0: if noMountable_dev != "": noMountable_dev += ' '