1 # -*- coding: utf-8 -*-
3 from enigma import eTimer
5 from Screens.Screen import Screen
6 from Screens.MessageBox import MessageBox
8 from Components.Label import Label
9 from Components.Pixmap import MultiPixmap
10 from Components.Sources.StaticText import StaticText
11 from Components.Sources.List import List
12 from Components.ActionMap import ActionMap
13 from Components.MenuList import MenuList
14 from Components.Console import Console
15 from Tools.Directories import pathExists, createDir
16 from Tools.BoundFunction import boundFunction
17 from Tools.LoadPixmap import LoadPixmap
19 from Tools.Directories import resolveFilename, SCOPE_SKIN
20 SkinDefaultPath = resolveFilename(SCOPE_SKIN, "skin_default/icons/")
22 from Components.ConfigList import ConfigListScreen
23 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText, ConfigSelection, NoSave
24 config.plugins.eparted = ConfigSubsection()
26 from os import system as os_system, path as os_path, listdir
28 #from Plugins.Bp.geminimain.gTools import cleanexit
47 #-----------------------------------------------------------------------------
49 def getInt_epart(val):
51 return int(float(val[0:-2]))#Einheit abschneiden
60 for x in result.split('\n'):
62 if x.find("BYT;") >= 0:
65 if addok and len(entry):
70 if addok and len(x) > 1 and x[len(x) - 1] == ';':
73 l.insert(0, LIST_TYPE_PAR)
74 l[PA_START] = getInt_epart(l[PA_START])
75 l[PA_END] = getInt_epart(l[PA_END])
76 l[PA_SIZE] = getInt_epart(l[PA_SIZE])
78 if l[PA_FS].find("linux-swap") == 0:
79 l[PA_FS] = "linux-swap"
81 elif len(l) == 8:#Device
82 if l[0].find("/dev/mtd") < 0:
83 l.insert(0, LIST_TYPE_DEV)
86 print "[eParted] <parse error>"
90 def myExecute(cmd, session, test=False):
92 from time import sleep
98 print "[eParted]", result, cmd
99 if result != 0 and session is not None:
100 session.open(MessageBox, _("Error command '%s'") % cmd, MessageBox.TYPE_ERROR, timeout=8)
105 mounts = open("/proc/mounts")
109 lines = mounts.readlines()
114 for x in getMountP():
115 parts = x.strip().split(" ")
117 realpath = os_path.realpath(parts[0])
122 rereaddevices = False
123 #-------------------------------------------------------------------------------------
125 class Ceparted(Screen):
126 skin = """<screen position="center,center" size="820,320" title="eParted v0.13">
127 <widget name="list" position="10,10" size="800,300" enableWrapAround="1" scrollbarMode="showOnDemand"/>
129 def __init__(self, session):
130 Screen.__init__(self, session)
132 self["actions"] = ActionMap(["OkCancelActions"],
138 self["list"] = MenuList(list=[])
139 self.Console = Console()
145 sel = self["list"].getCurrent()
148 rereaddevices = False
149 self.session.openWithCallback(self.__readDev, Cpart, sel[1])
154 self.Console.ePopen("parted -m -l", self.__FinishedConsole)
157 self.Console.killAll()
161 def __FinishedConsole(self, result, retval, extra_args=None):
162 if retval == 0 and '\n' in result:
164 for x in parseCmd(result):
165 if x[0][LIST_TYPE] == LIST_TYPE_DEV:
166 name = x[0][DEV_NAME]
168 name = x[0][DEV_PATH]
170 tstr += " (%s - %d %s %s)" % (x[0][DEV_SIZE], len(x) - 1, _("partition(s)"), x[0][DEV_PATH])
171 list.append((tstr, (name, x[0][DEV_PATH], x[0][DEV_SIZE])))
172 self["list"].setList(list)
174 #-------------------------------------------------------------------------------------
176 class AddPart(Screen, ConfigListScreen):
177 skin = """<screen name="AddPart" position="center,center" size="820,320" title="add Partition" >
178 <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
179 <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
180 <widget render="Label" source="key_red" position="10,5" size="200,40" zPosition="1" valign="center" halign="center" backgroundColor="#9f1313" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
181 <widget render="Label" source="key_green" position="210,5" size="200,40" zPosition="1" valign="center" halign="center" backgroundColor="#1f771f" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
182 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
183 <widget name="config" position="10,60" size="800,240" enableWrapAround="1" scrollbarMode="showOnDemand" />
186 def __init__(self, session, maxsize, unit, countpart):
187 Screen.__init__(self, session)
188 self.session = session
189 self.setup_title = _("add partition")
193 if pathExists("/sbin/mkfs.ext2"):
195 if pathExists("/sbin/mkfs.ext3"):
197 if pathExists("/sbin/mkfs.ext4"):
200 if pathExists("/sbin/mkfs.xfs"):
202 if pathExists("/sbin/mkswap"):
203 menu.append("linux-swap")
204 if pathExists("/sbin/mkfs.vfat"):
206 if pathExists("/usr/sbin/mkfs.msdos"):
208 config.plugins.eparted.fs = NoSave(ConfigSelection(default=default, choices=menu))
209 config.plugins.eparted.size = NoSave(ConfigInteger(default=maxsize, limits=[1, maxsize]))
212 if countpart < 4:#nur 4 parts möglich bei primary
213 list.append(getConfigListEntry(_("size in %s (max %d %s):") % (unit, maxsize, unit), config.plugins.eparted.size))
214 list.append(getConfigListEntry(_("filesystem:"), config.plugins.eparted.fs))
215 ConfigListScreen.__init__(self, list, session=session)
217 self["key_red"] = StaticText(_("cancel"))
218 self["key_green"] = StaticText(_("ok"))
220 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
222 "red": self.keyCancel,
223 "cancel": self.keyCancel,
224 "green": self.keySave,
225 "save": self.keySave,
233 if config.plugins.eparted.size.value > 0:
234 self.close((config.plugins.eparted.size.value, config.plugins.eparted.fs.value))
236 #-------------------------------------------------------------------------------------
243 skin = """<screen position="center,center" size="820,320" title="eParted">
244 <widget name="PixmapRed" pixmaps="skin_default/buttons/button_off.png,skin_default/buttons/button_red.png" position="10,12" size="25,25" alphatest="on" />
245 <widget name="PixmapGreen" pixmaps="skin_default/buttons/button_off.png,skin_default/buttons/button_green.png" position="290,12" size="25,25" alphatest="on" />
246 <widget name="PixmapBlue" pixmaps="skin_default/buttons/button_off.png,skin_default/buttons/button_blue.png" position="570,12" size="25,25" alphatest="on" />
247 <widget name="LabelRed" position="50,5" size="200,40" valign="center" backgroundColor="background" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
248 <widget name="LabelGreen" position="330,5" size="200,40" valign="center" backgroundColor="background" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
249 <widget name="LabelBlue" position="610,5" size="200,40" valign="center" backgroundColor="background" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
250 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
251 <widget source="list" render="Listbox" position="10,60" size="800,240" enableWrapAround="1" scrollbarMode="showOnDemand">
252 <convert type="TemplatedMultiContent">
254 MultiContentEntryText(pos = (10,2), size = (60, 30), font=0, flags = RT_HALIGN_LEFT, text=0),
255 MultiContentEntryText(pos = (80,2), size = (170, 30), font=0, flags = RT_HALIGN_LEFT, text=1),
256 MultiContentEntryText(pos = (260,2), size = (170, 30), font=0, flags = RT_HALIGN_LEFT, text=2),
257 MultiContentEntryText(pos = (440,2), size = (170, 30), font=0, flags = RT_HALIGN_LEFT, text=3),
258 MultiContentEntryText(pos = (620,2), size = (180, 30), font=0, flags = RT_HALIGN_LEFT, text=4)
260 "fonts": [gFont("Regular", 21)],
267 def __init__(self, session, entry):
268 Screen.__init__(self, session)
270 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
273 "green": self.KeyGreen,
274 "blue": self.KeyBlue,
278 self["list"] = List(list=[])
279 self["list"].onSelectionChanged.append(self.__SetLabels)
280 self["PixmapRed"] = MultiPixmap()
281 self["PixmapGreen"] = MultiPixmap()
282 self["PixmapBlue"] = MultiPixmap()
283 self["LabelRed"] = Label()
284 self["LabelGreen"] = Label()
285 self["LabelBlue"] = Label()
287 self.__devpath = entry[DEV_PATH]
289 self.__old_part_list = []
290 self.__new_part_list = []
292 self.__unit = entry[2][len(entry[2]) - 2:]
294 self.Console = Console()
298 self.Console.killAll()
301 def __getPartInfo(self, val=None):
302 self.Console.ePopen("parted -m %s unit %s print" % (self.__devpath, self.__unit), self.__FinishedConsole)
304 def __Filllist(self):
306 index = self["list"].getIndex()
307 for x in self.__new_part_list:
308 if x[LIST_TYPE] == LIST_TYPE_PAR:
310 p0 = "%s: %s" % (_("Nr"), x[PA_NR])
311 p1 = "%s: %d%s" % (_("Start"), x[PA_START], self.__unit)
312 p2 = "%s: %d%s" % (_("End"), x[PA_END], self.__unit)
313 p3 = "%s: %d%s" % (_("Size"), x[PA_SIZE], self.__unit)
314 p4 = "%s: %s" % (_("Type"), x[PA_FS])
315 list.append((p0, p1, p2, p3, p4, x))
316 self["list"].setList(list)
317 self["list"].setIndex(index)
318 self.__createCommandList()
320 def __SetLabels(self):
321 sel = self["list"].getCurrent()
322 self["LabelGreen"].setText("")
323 self["LabelRed"].setText("")
325 if sel[5][PA_TYPE] & self.PA_TYPE_FREE and len(self.__new_part_list) < 6:
326 self["PixmapGreen"].setPixmapNum(1)
327 self["LabelGreen"].setText(_("add"))
329 self["PixmapGreen"].setPixmapNum(0)
330 if sel[5][PA_TYPE] & self.PA_TYPE_LAST and bool(sel[5][PA_TYPE] & self.PA_TYPE_FREE) == False:
331 self["PixmapRed"].setPixmapNum(1)
332 self["LabelRed"].setText(_("delete"))
334 self["PixmapRed"].setPixmapNum(0)
336 def __addFreePart(self, plist, lastPartEnd):
337 x = [LIST_TYPE_PAR, str(len(plist)), lastPartEnd, self.__fullsize, 0, _("free"), (self.PA_TYPE_FREE | self.PA_TYPE_LAST), ";"]
340 def __FinishedConsole(self, result, retval, extra_args=None):
341 if retval == 0 and '\n' in result:
342 tlist = parseCmd(result)
344 self.__old_part_list = tlist[0][:]
345 self.__new_part_list = tlist[0][:]
349 for x in self.__old_part_list:
350 if x[LIST_TYPE] == LIST_TYPE_DEV:
351 self.__fullsize = getInt_epart(x[DEV_SIZE])
355 name += " (%s)" % x[DEV_SIZE]
358 lastPartEnd = x[PA_END]
359 x[PA_TYPE] = self.PA_TYPE_USE
360 if count == len(self.__old_part_list):#is letzte part
361 x[PA_TYPE] |= self.PA_TYPE_LAST
364 if lastPartEnd < self.__fullsize:#Wenn noch Frei, Part erstellen
365 self.__addFreePart(self.__old_part_list, lastPartEnd)
366 self.__addFreePart(self.__new_part_list, lastPartEnd)
371 if len(self.__comlist):
372 self.session.openWithCallback(self.__getPartInfo, Cpartexe, self.__comlist)
375 sel = self["list"].getCurrent()
376 if sel and sel[1] and sel[5][PA_TYPE] & self.PA_TYPE_LAST and bool(sel[5][PA_TYPE] & self.PA_TYPE_FREE) == False:
378 self.__new_part_list.remove(sel[5])#aktuelle part löschen
379 for x in self.__new_part_list:
380 if x[LIST_TYPE] == LIST_TYPE_PAR:
381 if x[PA_TYPE] & self.PA_TYPE_FREE:#letzte Freie suchen und auch löschen
382 self.__new_part_list.remove(x)
385 x[PA_TYPE] = self.PA_TYPE_USE
388 if len(self.__new_part_list) > 1:#von letzter Part, TYp setzen und Ende ermitteln
389 self.__new_part_list[len(self.__new_part_list) - 1][PA_TYPE] = self.PA_TYPE_USE | self.PA_TYPE_LAST
390 lastPartEnd = self.__new_part_list[len(self.__new_part_list) - 1][PA_END]
392 if lastPartEnd < self.__fullsize:#Wenn noch Frei, Part erstellen
393 self.__addFreePart(self.__new_part_list, lastPartEnd)
394 #for x in self.__new_part_list:
395 # if x[LIST_TYPE]==LIST_TYPE_PAR:
398 print "[eParted] <remove part>"
402 sel = self["list"].getCurrent()
403 if sel and sel[5] and sel[5][PA_TYPE] & self.PA_TYPE_FREE and sel[5][PA_START] < sel[5][PA_END] and len(self.__new_part_list) < 6:
404 self.session.openWithCallback(self.__CallbackAddPart, AddPart, sel[5][PA_END] - sel[5][PA_START], self.__unit, len(self.__new_part_list) - 1)
406 def __CallbackAddPart(self, val=None):
408 for x in self.__new_part_list:
409 if x[LIST_TYPE] == LIST_TYPE_PAR:
410 if x[PA_TYPE] & self.PA_TYPE_FREE:
413 x[PA_END] = x[PA_START] + x[PA_SIZE]
414 x[PA_TYPE] = self.PA_TYPE_USE | self.PA_TYPE_LAST
415 if x[PA_END] < self.__fullsize:#Wenn noch Frei, Part erstellen
416 self.__addFreePart(self.__new_part_list, x[PA_END])
419 x[PA_TYPE] = self.PA_TYPE_USE
422 def __addPart2Comlist(self, list, val, mkpart=True):
427 com = "parted -s -a optimal %s mkpart primary %s %s%s %s%s" % (self.__devpath, fs, val[PA_START], self.__unit, val[PA_END], self.__unit)
428 list.append((com , _("create partition %s") % partnr, None))
431 if val[PA_FS] == "linux-swap":
432 mkfs = "/sbin/mkswap"
433 elif val[PA_FS] == "fat16":
434 mkfs = "/usr/sbin/mkfs.msdos -F 16"
435 elif val[PA_FS] == "fat32":
436 mkfs = "/sbin/mkfs.vfat"
438 mkfs = "/sbin/mkfs." + val[PA_FS]
439 mountdev = self.__devpath + partnr
440 if val[PA_FS] == "xfs":
443 com = "%s %s%s" % (mkfs, self.__devpath, partnr)
444 list.append((com , _("make filesystem '%s' on partition %s (%d %s)") % (val[PA_FS], partnr, val[PA_SIZE], self.__unit), mountdev))
446 def __delPart2Comlist(self, list, val):
448 dev = "%s%s" % (self.__devpath, partnr)
451 if myExecute("umount %s" % mp, self.session):
453 list.insert(0, ("parted -s -a none %s rm %s" % (self.__devpath, partnr), _("delete partition %s") % partnr, None))
455 def __createCommandList(self):
457 #welche parts sollen gelöscht werden
458 for x in range(len(self.__old_part_list)):
459 if self.__old_part_list[x][LIST_TYPE] == LIST_TYPE_PAR:
460 if bool(self.__old_part_list[x][PA_TYPE] & self.PA_TYPE_FREE) == False:
461 if len(self.__new_part_list) > x:
462 if self.__old_part_list[x][PA_SIZE] != self.__new_part_list[x][PA_SIZE]:
463 #print self.__old_part_list[x], self.__new_part_list[x]
464 self.__delPart2Comlist(self.__comlist, self.__old_part_list[x])
466 self.__delPart2Comlist(self.__comlist, self.__old_part_list[x])
468 #welche parts sollen erstellt werden
469 for x in range(len(self.__new_part_list)):
470 if self.__new_part_list[x][LIST_TYPE] == LIST_TYPE_PAR:
471 if bool(self.__new_part_list[x][PA_TYPE] & self.PA_TYPE_FREE) == False:
472 if len(self.__old_part_list) > x and bool(self.__old_part_list[x][PA_TYPE] & self.PA_TYPE_FREE) == False:
473 if self.__new_part_list[x][PA_SIZE] != self.__old_part_list[x][PA_SIZE]:
474 #print self.__new_part_list[x], self.__old_part_list[x]
475 self.__addPart2Comlist(self.__comlist, self.__new_part_list[x])
477 if self.__new_part_list[x][PA_FS] != self.__old_part_list[x][PA_FS]:
478 self.__addPart2Comlist(self.__comlist, self.__new_part_list[x], False)
480 self.__addPart2Comlist(self.__comlist, self.__new_part_list[x])
483 #for x in self.__comlist: print "[eParted] com =",x
484 if len(self.__comlist):
485 self["PixmapBlue"].setPixmapNum(1)
486 self["LabelBlue"].setText(_("execute"))
488 self["PixmapBlue"].setPixmapNum(0)
489 self["LabelBlue"].setText("")
491 class Cpartexe(Screen):
492 skin = """<screen position="center,center" size="820,320" title=" ">
493 <widget name="PixmapButton" pixmaps="skin_default/buttons/button_green.png,skin_default/buttons/button_off.png" position="10,12" size="25,25" alphatest="on" />
494 <widget name="LabelButton" position="50,5" size="200,40" valign="center" backgroundColor="background" font="Regular;21" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
495 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
496 <widget source="list" render="Listbox" position="10,60" size="800,252" enableWrapAround="1" scrollbarMode="showOnDemand">
497 <convert type="TemplatedMultiContent">
499 MultiContentEntryText(pos = (40,0), size = (760,36), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=0),
500 MultiContentEntryPixmapAlphaTest(pos = (2,2), size = (32,32), png=1),
502 "fonts": [gFont("Regular", 21)],
509 def __init__(self, session, comlist):
510 Screen.__init__(self, session)
512 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
515 "green": self.KeyGreen,
519 self.setTitle(_("execute"))
520 self["PixmapButton"] = MultiPixmap()
521 self["LabelButton"] = Label(_("Start") + " ?")
527 list.append((x[1], None, x[0]))
529 self.mountlist.append(x[2])
530 self["list"] = List(list)
532 self.__Stimer = eTimer()
533 self.__Stimer_conn = self.__Stimer.timeout.connect(self.__exeList)
536 def __getPartitionUUID(self, device):
538 if os_path.exists("/dev/disk/by-uuid"):
539 for uuid in listdir("/dev/disk/by-uuid/"):
540 if not os_path.exists("/dev/disk/by-uuid/" + uuid):
542 if os_path.realpath("/dev/disk/by-uuid/" + uuid) == device:
543 return ("/dev/disk/by-uuid/" + uuid, uuid)
545 return (device, device[5:])
547 print "[eParted] <error get UUID>"
550 def __mountDevice(self):
551 for x in self.mountlist:
552 dev = self.__getPartitionUUID(x)
554 if os_path.exists("/media/" + dev[1]) == False:
555 createDir("/media/" + dev[1], True)
556 cmd = "mount %s /media/%s" % (dev[0], dev[1])
561 del self.__Stimer_conn
567 if len(self["list"].list) > self.__state and self.__state > -1:
568 res = myExecute(self["list"].list[self.__state][2], self.session)
571 pic = "selectioncross.png"
573 self["list"].list[self.__state] = (self["list"].list[self.__state][0], LoadPixmap(path=SkinDefaultPath + pic), self["list"].list[self.__state][2], self["list"].list[self.__state][2])
574 self["list"].updateList(self["list"].list)
575 self["list"].setIndex(self.__state)
580 self.__state = len(self["list"].list)#bei fehler ans Ende der liste
581 self["PixmapButton"].setPixmapNum(0)
582 self["LabelButton"].setText(_("quit"))
584 self.__Stimer.start(500, True)
587 self["PixmapButton"].setPixmapNum(0)
588 self["LabelButton"].setText(_("quit"))
591 if self.__state == -1:
595 self["PixmapButton"].setPixmapNum(1)
596 self["LabelButton"].setText(_("Please Wait"))
597 self["list"].setIndex(0)
598 self.__Stimer.start(500, True)
599 elif self.__state == -2: