1 # -*- coding: utf-8 -*-
4 from enigma import eTimer
6 from Screens.Screen import Screen
7 from Screens.MessageBox import MessageBox
9 from Components.Label import Label
10 from Components.Pixmap import MultiPixmap
11 from Components.Sources.StaticText import StaticText
12 from Components.Sources.List import List
13 from Components.ActionMap import ActionMap
14 from Components.MenuList import MenuList
15 from Components.Console import Console
16 from Tools.Directories import pathExists, createDir
17 from Tools.BoundFunction import boundFunction
18 from Tools.LoadPixmap import LoadPixmap
20 from Tools.Directories import resolveFilename, SCOPE_SKIN
21 SkinDefaultPath = resolveFilename(SCOPE_SKIN, "skin_default/")
23 from Components.ConfigList import ConfigListScreen
24 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText, ConfigSelection, NoSave
25 config.plugins.eparted = ConfigSubsection()
28 from os import system as os_system, path as os_path, listdir
30 #from Plugins.Bp.geminimain.gTools import cleanexit
49 #-----------------------------------------------------------------------------
51 def getInt_epart(val):
53 return int(float(val[0:-2]))#Einheit abschneiden
62 for x in result.split('\n'):
64 if x.find("BYT;") >= 0:
67 if addok and len(entry):
72 if addok and len(x) > 1 and x[len(x) - 1] == ';':
75 l.insert(0, LIST_TYPE_PAR)
76 l[PA_START] = getInt_epart(l[PA_START])
77 l[PA_END] = getInt_epart(l[PA_END])
78 l[PA_SIZE] = getInt_epart(l[PA_SIZE])
80 if l[PA_FS].find("linux-swap") == 0:
81 l[PA_FS] = "linux-swap"
83 elif len(l) == 8:#Device
84 if l[0].find("/dev/mtd") < 0:
85 l.insert(0, LIST_TYPE_DEV)
88 print "[eParted] <parse error>"
92 def myExecute(cmd, session, test=False):
94 from time import sleep
100 print "[eParted]", result, cmd
101 if result != 0 and session is not None:
102 session.open(MessageBox, _("Error command '%s'") % cmd, MessageBox.TYPE_ERROR, timeout=8)
107 mounts = open("/proc/mounts")
111 lines = mounts.readlines()
116 for x in getMountP():
117 parts = x.strip().split(" ")
119 realpath = os_path.realpath(parts[0])
124 rereaddevices = False
125 #-------------------------------------------------------------------------------------
127 class Ceparted(Screen):
128 skin = """<screen position="center,center" size="600,200" title="eParted v0.13">
129 <widget name="list" position="5,5" size="590,190" />
131 def __init__(self, session):
132 Screen.__init__(self, session)
134 self["actions"] = ActionMap(["OkCancelActions"],
140 self["list"] = MenuList(list=[])
141 self.Console = Console()
147 sel = self["list"].getCurrent()
150 rereaddevices = False
151 self.session.openWithCallback(self.__readDev, Cpart, sel[1])
156 self.Console.ePopen("parted -m -l", self.__FinishedConsole)
159 self.Console.killAll()
163 def __FinishedConsole(self, result, retval, extra_args=None):
164 if retval == 0 and '\n' in result:
166 for x in parseCmd(result):
167 if x[0][LIST_TYPE] == LIST_TYPE_DEV:
168 name = x[0][DEV_NAME]
170 name = x[0][DEV_PATH]
172 tstr += " (%s - %d %s %s)" % (x[0][DEV_SIZE], len(x) - 1, _("partition(s)"), x[0][DEV_PATH])
173 list.append((tstr, (name, x[0][DEV_PATH], x[0][DEV_SIZE])))
174 self["list"].setList(list)
176 #-------------------------------------------------------------------------------------
178 class AddPart(Screen, ConfigListScreen):
179 skin = """<screen name="AddPart" position="center,center" size="600,190" title="add Partition" >
180 <ePixmap pixmap="skin_default/buttons/red.png" position="5,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
181 <ePixmap pixmap="skin_default/buttons/green.png" position="155,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
182 <widget render="Label" source="key_red" position="5,5" size="140,40" zPosition="2" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" />
183 <widget render="Label" source="key_green" position="155,5" size="140,40" zPosition="2" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" />
184 <widget name="config" position="5,60" size="590,120" scrollbarMode="showOnDemand" />
187 def __init__(self, session, maxsize, unit, countpart):
188 Screen.__init__(self, session)
189 self.session = session
190 self.setup_title = _("add partition")
194 if pathExists("/sbin/mkfs.ext2"):
196 if pathExists("/sbin/mkfs.ext3"):
198 if pathExists("/sbin/mkfs.ext4"):
201 if pathExists("/sbin/mkfs.xfs"):
203 if pathExists("/sbin/mkswap"):
204 menu.append("linux-swap")
205 if pathExists("/sbin/mkfs.vfat"):
207 if pathExists("/usr/sbin/mkfs.msdos"):
209 config.plugins.eparted.fs = NoSave(ConfigSelection(default=default, choices=menu))
210 config.plugins.eparted.size = NoSave(ConfigInteger(default=maxsize, limits=[1, maxsize]))
213 if countpart < 4:#nur 4 parts möglich bei primary
214 list.append(getConfigListEntry(_("size in %s (max %d %s):") % (unit, maxsize, unit), config.plugins.eparted.size))
215 list.append(getConfigListEntry(_("filesystem:"), config.plugins.eparted.fs))
216 ConfigListScreen.__init__(self, list, session=session)
218 self["key_red"] = StaticText(_("cancel"))
219 self["key_green"] = StaticText(_("ok"))
221 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
223 "red": self.keyCancel,
224 "cancel": self.keyCancel,
225 "green": self.keySave,
226 "save": self.keySave,
234 if config.plugins.eparted.size.value > 0:
235 self.close((config.plugins.eparted.size.value, config.plugins.eparted.fs.value))
237 #-------------------------------------------------------------------------------------
244 skin = """<screen position="center,center" size="670,200" title="eParted">
245 <widget source="list" render="Listbox" position="0,0" size="670,160" scrollbarMode="showOnDemand" enableWrapAround="on">
246 <convert type="TemplatedMultiContent">
248 MultiContentEntryText(pos = (0,5), size = (50, 30), font=0, flags = RT_HALIGN_LEFT, text=0),
249 MultiContentEntryText(pos = (60,5), size = (150, 30), font=0, flags = RT_HALIGN_LEFT, text=1),
250 MultiContentEntryText(pos = (210,5), size = (150, 30), font=0, flags = RT_HALIGN_LEFT, text=2),
251 MultiContentEntryText(pos = (360,5), size = (150, 30), font=0, flags = RT_HALIGN_LEFT, text=3),
252 MultiContentEntryText(pos = (510,5), size = (160, 30), font=0, flags = RT_HALIGN_LEFT, text=4)
254 "fonts": [gFont("Regular", 20)],
259 <widget name="PixmapRed" position="25,170" size="15,16" pixmaps="skin_default/buttons/button_red_off.png,skin_default/buttons/button_red.png" transparent="1" alphatest="on" />
260 <widget name="LabelRed" position="50,160" size="150,40" font="Regular;19" valign="center" />
261 <widget name="PixmapGreen" position="225,170" size="15,16" pixmaps="skin_default/buttons/button_green_off.png,skin_default/buttons/button_green.png" transparent="1" alphatest="on" />
262 <widget name="LabelGreen" position="250,160" size="150,40" font="Regular;19" valign="center" />
263 <widget name="PixmapBlue" position="425,170" size="15,16" pixmaps="skin_default/buttons/button_blue_off.png,skin_default/buttons/button_blue.png" transparent="1" alphatest="on" />
264 <widget name="LabelBlue" position="450,160" size="150,40" font="Regular;19" valign="center" />
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="670,400" title=" ">
493 <widget source="list" render="Listbox" position="0,0" size="670,360" scrollbarMode="showOnDemand" enableWrapAround="on">
494 <convert type="TemplatedMultiContent">
496 MultiContentEntryText(pos = (40,5), size = (630, 30), font=0, flags = RT_HALIGN_LEFT, text=0),
497 MultiContentEntryPixmapAlphaTest(pos = (5, 5), size = (35,35), png=1),
499 "fonts": [gFont("Regular", 22)],
504 <widget name="PixmapButton" position="25,370" size="15,16" pixmaps="skin_default/buttons/button_green.png,skin_default/buttons/button_green_off.png" transparent="1" alphatest="on" />
505 <widget name="LabelButton" position="50,360" size="620,40" font="Regular;19" valign="center" />
508 def __init__(self, session, comlist):
509 Screen.__init__(self, session)
511 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
514 "green": self.KeyGreen,
518 self.setTitle(_("execute"))
519 self["PixmapButton"] = MultiPixmap()
520 self["LabelButton"] = Label(_("Start") + " ?")
526 list.append((x[1], None, x[0]))
528 self.mountlist.append(x[2])
529 self["list"] = List(list)
531 self.__Stimer = eTimer()
532 self.__Stimer.callback.append(self.__exeList)
535 def __getPartitionUUID(self, device):
537 if os_path.exists("/dev/disk/by-uuid"):
538 for uuid in listdir("/dev/disk/by-uuid/"):
539 if not os_path.exists("/dev/disk/by-uuid/" + uuid):
541 if os_path.realpath("/dev/disk/by-uuid/" + uuid) == device:
542 return ("/dev/disk/by-uuid/" + uuid, uuid)
544 return (device, device[5:])
546 print "[eParted] <error get UUID>"
549 def __mountDevice(self):
550 for x in self.mountlist:
551 dev = self.__getPartitionUUID(x)
553 if os_path.exists("/media/" + dev[1]) == False:
554 createDir("/media/" + dev[1], True)
555 cmd = "mount %s /media/%s" % (dev[0], dev[1])
565 if len(self["list"].list) > self.__state and self.__state > -1:
566 res = myExecute(self["list"].list[self.__state][2], self.session)
567 pic = "test_false.png"
569 pic = "test_true.png"
571 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])
572 self["list"].updateList(self["list"].list)
573 self["list"].setIndex(self.__state)
578 self.__state = len(self["list"].list)#bei fehler ans Ende der liste
579 self["PixmapButton"].setPixmapNum(0)
580 self["LabelButton"].setText(_("quit"))
582 self.__Stimer.start(500, True)
585 self["PixmapButton"].setPixmapNum(0)
586 self["LabelButton"].setText(_("quit"))
589 if self.__state == -1:
593 self["PixmapButton"].setPixmapNum(1)
594 self["LabelButton"].setText(_("Please Wait"))
595 self["list"].setIndex(0)
596 self.__Stimer.start(500, True)
597 elif self.__state == -2: