20d21999fbd9f90e1922253b17e6285808021fe4
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / DeviceManager / plugin.py
1 from Components.Label import Label
2 from Components.ActionMap import ActionMap
3 from Components.config import config, ConfigSelection, getConfigListEntry, ConfigSubsection, ConfigEnableDisable, ConfigYesNo, ConfigInteger
4 from Components.ConfigList import ConfigListScreen
5 from Components.Console import Console
6 from Components.GUIComponent import GUIComponent
7 from Components.Harddisk import harddiskmanager
8 from Components.MenuList import MenuList
9 from Components.Pixmap import Pixmap, MultiPixmap
10 from Components.Sources.List import List
11 from Components.Sources.StaticText import StaticText
12 from Plugins.Plugin import PluginDescriptor
13 from Screens.MessageBox import MessageBox
14 from Screens.Screen import Screen
15 from Screens.VirtualKeyBoard import VirtualKeyBoard
16 from Tools.BoundFunction import boundFunction
17 from Tools.LoadPixmap import LoadPixmap
18 from Tools.Notifications import AddNotificationWithCallback
19 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
20 from skin import loadSkin
21 from os import system, makedirs, path, listdir, statvfs, popen
22 import os
23 import re
24 import time
25
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 _
33
34 config.plugins.devicemanager = ConfigSubsection()
35 config.plugins.devicemanager.hotplug_enable = ConfigEnableDisable(default=True)
36 config.plugins.devicemanager.mountcheck_enable = ConfigEnableDisable(default=True)
37
38 def readFile(filename):
39         file = open(filename)
40         data = file.read().strip()
41         file.close()
42         return data
43
44 def byteConversion(byte):
45         if type(byte) == str and len(byte) == 0:
46                 return ""
47         if type(byte) != long:
48                 byte = long(byte)
49         if byte > 1024*1024*1024:
50                 int_part = byte/1024/1024/1024
51                 dec_part = byte%(1024*1024*1024)/(1024*1024)
52                 return "%d.%d GB"%(int_part, dec_part)
53         else:
54                 int_part = byte/1024/1024
55                 dec_part = byte%(1024*1024)/1024
56                 return "%d.%d MB"%(int_part, dec_part)
57
58 def checkStrValue(value , empty = ""):
59         if type(value) != str or len(value) == 0:
60                 return empty
61         return value
62
63 class DeviceManagerConfiguration(Screen, ConfigListScreen):
64         def __init__(self,session):
65                 self.session = session
66                 Screen.__init__(self,session)
67                 self.skinName = "Setup"
68                 self.createConfigList()
69                 ConfigListScreen.__init__(self, self.list, session = self.session)
70                 self["key_red"] = StaticText(_("Cancel"))
71                 self["key_green"] = StaticText(_("OK"))
72                 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ],
73                 {
74                         "ok": self.keySave,
75                         "cancel": self.keyCancel,
76                         "red": self.keyCancel,
77                         "green": self.keySave,
78                 }, -2)
79                 self.onShown.append(self.setWindowTitle)
80                 self.old_hotplug_enable = config.plugins.devicemanager.hotplug_enable.value
81                 
82         def setWindowTitle(self):
83                 self.setTitle(_("DeviceManager configuration"))
84
85         def createConfigList(self):
86                 self.list = []
87                 self.list.append(getConfigListEntry(_("Enable mount check for HDD : "), config.plugins.devicemanager.mountcheck_enable))
88                 self.list.append(getConfigListEntry(_("Harddisk standby after : "), config.usage.hdd_standby))
89                 self.list.append(getConfigListEntry(_("Mount known devices automatically : "), config.plugins.devicemanager.hotplug_enable))
90
91         def keySave(self):
92                 if config.plugins.devicemanager.hotplug_enable.value:
93                         if not DeviceManagerhotplugDeviceStart in harddiskmanager.on_partition_list_change:
94                                 harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
95                 else:
96                         if DeviceManagerhotplugDeviceStart in harddiskmanager.on_partition_list_change:
97                                 harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
98
99                 for x in self["config"].list:
100                         x[1].save()
101                 self.close()
102
103 class DeviceManager(Screen):
104         skin = """
105                 <screen position="center,center" size="670,400" title="DeviceManager">
106                         <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
107                         <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
108                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
109                         <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
110                         <widget name="key_red" position="20,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#9f1313" transparent="1" />
111                         <widget name="key_green" position="180,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#1f771f" transparent="1" />
112                         <widget name="key_yellow" position="340,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#a08500" transparent="1" />
113                         <widget name="key_blue" position="500,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" foregroundColor="#ffffff" backgroundColor="#18188b" transparent="1" />
114                         <ePixmap pixmap="skin_default/div-h.png" position="0,48" size="670,2" alphatest="on" />
115                         <widget source="menu" render="Listbox" position="0,48" size="670,350" scrollbarMode="showOnDemand">
116                                 <convert type="TemplatedMultiContent">
117                                 {"templates":
118                                         {"default": (54,[
119                                                         MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 0 is vendor  - model
120                                                         MultiContentEntryText(pos = (100, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 is Device
121                                                         MultiContentEntryText(pos = (230, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 is Size
122                                                         MultiContentEntryText(pos = (360, 32), size = (130, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 3 is Partitions
123                                                         MultiContentEntryText(pos = (490, 32), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 4 is Removable
124                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # png 5 is the div pixmap
125                                                 ]),
126                                         "partitions": (98, [
127                                                         MultiContentEntryText(pos = (100, 0), size = (560, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 0), # index 1 is Partition
128                                                         MultiContentEntryText(pos = (100, 32), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 2 is Mounted on
129                                                         MultiContentEntryText(pos = (100, 54), size = (560, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 3 UUID
130                                                         MultiContentEntryText(pos = (100, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 3), # index 4 Type
131                                                         MultiContentEntryText(pos = (230, 76), size = (140, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 4), # index 5 Size_total
132                                                         MultiContentEntryText(pos = (380, 76), size = (200, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 5), # index 6 Size_free
133                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 96), size = (670, 2), png = 6), # png 6 is the div pixmap
134                                                 ]),
135                                         "mountpoint": (54,[
136                                                         MultiContentEntryPixmapAlphaTest(pos = (10, 7), size = (30, 30), png = 0), # index 0: picture
137                                                         MultiContentEntryText(pos = (40, 0), size = (500, 30), font=0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 1), # index 1 name
138                                                         MultiContentEntryText(pos = (40, 32), size = (500, 20), font=1, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER, text = 2), # index 2 path
139                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (670, 2), png = 5), # index 5 is the div pixmap
140                                                 ])
141                                         },
142                                         "fonts": [gFont("Regular", 22),gFont("Regular", 16),gFont("Regular", 28)],
143                                         "itemHeight": 54
144                                 }
145                                 </convert>
146                         </widget>
147                 </screen>
148                 """
149
150         def __init__(self, session):
151                 Screen.__init__(self, session)
152                 self.session = session
153                 self.currList = "default"
154                 self.currDevice = None
155                 self.currPartition = None
156                 self.defaultMountPoint = "/media/hdd"
157                 self.deviceList = []
158                 self["menu"] = List(self.deviceList)
159                 self["key_red"] = Label(_("Close"))
160                 self["key_green"] = Label(" ")
161                 self["key_yellow"] = Label(" ")
162                 self["key_blue"] = Label(" ")
163
164                 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions", "MenuActions" ],
165                 {
166                         "ok": self.keyOk,
167                         "cancel": self.keyCancel,
168                         "red": self.keyCancel,
169                         "green": self.keyOk,
170                         "yellow": self.keyYellow,
171                         "blue": self.keyBlue,
172                         "menu": self.keyMenu,
173                 }, -2)
174                 self.DeviceManagerConsole = Console()
175                 self.loadIcon()
176                 if not self.selectionChanged in self["menu"].onSelectionChanged:
177                         self["menu"].onSelectionChanged.append(self.selectionChanged)
178                 self.onLayoutFinish.append(self.showDeviceList)
179                 self.onLayoutFinish.append(self.addPartitionListChange)
180                 self.onClose.append(self.removePartitionListChange)
181 #               self.onLayoutFinish.append(self.hotplugInactive)
182 #               self.onClose.append(self.hotplugActive)
183                 self.onChangedEntry = []
184                 self.blockDevices = {}
185
186         def addPartitionListChange(self):
187                 harddiskmanager.on_partition_list_change.append(self.partitionListChanged)
188
189         def removePartitionListChange(self):
190                 harddiskmanager.on_partition_list_change.remove(self.partitionListChanged)
191
192         def partitionListChanged(self, action, device):
193                 print "[Device manager] hotplug partitionListChanged"
194                 if self.currList != "default" and device.device[:3] != self.currDevice["blockdev"]:
195                         return
196                 self.showDeviceList()
197
198         def hotplugInactive(self):
199                 global devicemanagerhotplugactive
200                 print "[Device manager] hotplug Inctive"
201                 devicemanagerhotplugactive = False
202
203         def hotplugActive(self):
204                 global devicemanagerhotplugactive
205                 print "[Device manager] hotplug Active"
206                 devicemanagerhotplugactive = True
207
208         def loadIcon(self):
209                 self.icon_button_green = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/buttons/button_green.png"))
210                 self.divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
211
212         def selectionChanged(self):
213                 if self.currList == "partitions":
214                         currentPartition = self.getCurrentPartition()
215                         if currentPartition is not None:
216                                 if currentPartition["mountpoint"] != "":
217                                         self["key_green"].setText(_("Umount"))
218                                 else:
219                                         self["key_green"].setText(_("Mount"))
220
221                                 if currentPartition["fstype"] == "":
222                                         self["key_blue"].setText("")
223                                 elif currentPartition["fstype"][:3] == "ext":
224                                         self["key_blue"].setText(_("Check"))
225                                 else:
226                                         self["key_blue"].setText("")
227
228         def showDeviceList(self):
229                 self.deviceList = []
230                 self["key_red"].setText(_("Close"))
231                 self["key_green"].setText(_("Ok"))
232                 self["key_yellow"].setText(" ")
233                 self["key_blue"].setText(_("Initialize"))
234                 deviceinfo.refresh()
235                 for device in deviceinfo.getBlockDevices():
236                         deviceEntry = (
237                                 "%s - %s"%(device["vendor"], device["model"]), # vendor : str, model : str, index 0 
238                                 _("device : %s")%(device["blockdev"]), # str
239                                 _("Size : %s")%(byteConversion(device["size"])), # str, bytes
240                                 _("Partitions : %s")%(len(device["partitions"])), # list
241                                 _("Removable : %s")%(device["removable"] and 'Yes' or 'No'), # bool [True, False]
242                                 self.divpng, # png 5
243                                 device, # index 6
244                                 )
245 #                       print "[DeviceManager] deviceEntry : ", deviceEntry
246                         self.deviceList.append(deviceEntry)
247                 self.currList = "default"
248                 self["menu"].style = "default"
249                 self["menu"].setList(self.deviceList)
250
251         def showPartitionList(self):
252                 if self.currDevice is None:
253                         return
254                 self["key_red"].setText(_("Devices"))
255                 self["key_green"].setText(_("Mount"))
256                 self["key_yellow"].setText(_("Format"))
257                 self["key_blue"].setText(_("Check"))
258                 partitionList = []
259                 for partition in self.currDevice["partitions"]:
260                         partitionInfo = deviceinfo.getPartitionInfo(partition)
261                         partitionEntry = (
262                                 _("Partition : /dev/%s")%partition, # index 0
263                                 _("Mounted on : %s")%checkStrValue(partitionInfo["mountpoint"], _("not mounted")),
264                                 _("UUID : %s")%checkStrValue(partitionInfo["uuid"], _("unknown")),
265                                 _("Type : %s")%checkStrValue(partitionInfo["fstype"], _("unknown")),
266                                 _("Size : %s")%checkStrValue(byteConversion(partitionInfo["size"]), _("unknown")),
267                                 _("Free : %s")%checkStrValue(byteConversion(partitionInfo["free"]), _("unknown")),
268                                 self.divpng, # index 6
269                                 partitionInfo, # index 7
270                         )
271 #                       print "[DeviceManager] partitionEntry : ",partitionEntry
272                         partitionList.append(partitionEntry)
273                 self.currList = "partitions"
274                 self["menu"].style = "partitions"
275                 self["menu"].setList(partitionList)
276                 self.selectionChanged()
277
278         def showMountPointSetup(self):
279                 if self.currDevice is None or self.currPartition is None:
280                         return
281                 self["key_red"].setText(_("Partitions"))
282                 self["key_green"].setText(_("Ok"))
283                 self["key_yellow"].setText("")
284                 self["key_blue"].setText("")
285                 self.mountPointList = []
286                 currentMountPoint = self.currPartition["mountpoint"]
287                 if currentMountPoint == "":
288                         currentMountPoint = "'not mounted'"
289                 defaultMountPoint = self.getDefaultMountPoint()
290                 autoMountPoint = self.getAutoMountPoint()
291                 defaultMountPointEntry = (self.icon_button_green, _("Set up Default Mount Point"), _("Mount Point : %s ->%s")%(currentMountPoint, defaultMountPoint), "default", defaultMountPoint, self.divpng)
292                 autoMountPointEntry = (self.icon_button_green, _("Automatically set up a Mount Point"), _("Mount Point : %s -> %s")%(currentMountPoint, autoMountPoint), "auto", autoMountPoint, self.divpng)
293                 manuallyMountPointEntry = (self.icon_button_green, _("User manually Set up a Mount Point"), _("Mount Point : click ok button on here."), "manual", "", self.divpng)
294                 if not path.ismount(defaultMountPoint):
295                         self.mountPointList.append(defaultMountPointEntry)
296                 self.mountPointList.append(autoMountPointEntry)
297                 self.mountPointList.append(manuallyMountPointEntry)
298                 self.currList = "mountpoint"
299                 self["menu"].style = "mountpoint"
300                 self["menu"].setList(self.mountPointList)
301
302         def getCurrentDevice(self):
303                 if self.currList == "default":
304                         return self["menu"].getCurrent()[6]
305                 return None
306
307         def getCurrentPartition(self):
308                 if self.currList == "partitions":
309                         return self["menu"].getCurrent()[7]
310                 return None
311
312         def keyOk(self):
313 #               print "keyOk"
314                 if self.currList == "default":
315                         self.currDevice = self.getCurrentDevice()
316                         self.showPartitionList()
317                 elif self.currList == "partitions":
318                         currMountPoint = self.getCurrentPartition()["mountpoint"]
319                         currUuid = self.getCurrentPartition()["uuid"]
320                         if currMountPoint == "":
321                                 self.currPartition = self.getCurrentPartition()
322                                 self.showMountPointSetup()
323                         else:
324                                 self.doUmount(currMountPoint)
325                                 self.showPartitionList()
326                 elif self.currList == "mountpoint":
327 # self["menu"].getCurrent() : (green_button, "menu description", "mount point description, "default", mountpoint, self.divpng)
328                         currEntry = self["menu"].getCurrent()[3]
329                         if currEntry == "default":
330 #                               print "Setup mountpoint default!"
331                                 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
332                         elif currEntry == "auto":
333 #                               print "Setup mountpoint automatically!"
334                                 self.doMount(self.currPartition, self["menu"].getCurrent()[4])
335                         else:
336 #                               print "Setup mountpoint manually!"
337                                 self.session.openWithCallback(self.MountpointBrowserCB, MountpointBrowser)
338                 else:
339                         pass
340
341         def keyCancel(self):
342 #               print "keyCancel"
343                 if self.DeviceManagerConsole is not None:
344                         if len(self.DeviceManagerConsole.appContainers):
345                                 for name in self.DeviceManagerConsole.appContainers.keys():
346                                         self.DeviceManagerConsole.kill(name)
347                 if self.currList == "partitions":
348                         self.currDevice = None
349                         self.showDeviceList()
350                 elif self.currList == "mountpoint":
351                         self.currPartition = None
352                         self.showPartitionList()
353                 else: # currList = "default"
354                         self.close()
355
356         def keyYellow(self):
357                 if self.currList == "partitions":
358                         partition = self.getCurrentPartition()
359                         self.choiceBoxFstype()
360
361         def keyBlue(self):
362                 if self.currList == "default":
363                         device = self.getCurrentDevice()
364                         self.session.openWithCallback(self.deviceInitCB, DeviceInit, device["blockdev"], device["size"])
365                 elif self.currList == "partitions":
366                         partition = self.getCurrentPartition()
367                         self.session.openWithCallback(self.deviceCheckCB, DeviceCheck, partition)
368
369         def keyMenu(self):
370                 self.session.open(DeviceManagerConfiguration)
371
372         def deviceInitCB(self, ret = True):
373                 self.showDeviceList()
374
375         def deviceCheckCB(self, ret = True):
376                 self.showPartitionList()
377
378         def deviceFormatCB(self, ret = True):
379                 self.showPartitionList()
380
381         def choiceBoxFstype(self):
382                 menu = []
383                 menu.append((_("ext2 - recommended for USB flash memory"), "ext2"))
384                 menu.append((_("ext3 - recommended for harddisks"), "ext3"))
385                 menu.append((_("ext4 - experimental"), "ext4"))
386                 menu.append((_("vfat - for USB flash memory"), "vfat"))
387                 self.session.openWithCallback(self.choiceBoxFstypeCB, ChoiceBox, title=_("Choice filesystem."), list=menu)
388
389         def choiceBoxFstypeCB(self, choice):
390                 if choice is None:
391                         return
392                 else:
393                         partition = self.getCurrentPartition()
394                         self.session.openWithCallback(self.deviceFormatCB, DeviceFormat, partition, choice[1])
395
396 # about mount funcs..
397         def doUmount(self, mountpoint):
398                 cmd = "umount %s"%mountpoint
399                 print "[DeviceManager] cmd : %s"%cmd
400                 self.DeviceManagerConsole.ePopen(cmd, self.doUmountFinished, mountpoint)
401
402         def doUmountFinished(self, result, retval, extra_args = None):
403                 mountpoint = extra_args
404                 if retval == 0:
405 # update current mount state ,devicemanager.cfg
406                         devicemanagerconfig.updateConfigList()
407                 else:
408                         self.session.open(MessageBox, _("Can't umount %s. \nMaybe device or resource busy.")%mountpoint, MessageBox.TYPE_ERROR, timeout = 10)
409
410         def getDefaultMountPoint(self):
411                 return self.defaultMountPoint
412
413         def getAutoMountPoint(self):
414                 mountPoint = "/media/"+self.currDevice["model"]
415                 mountPoint = mountPoint.replace(' ','-')
416                 if path.ismount(mountPoint):
417                         partnum = 2
418                         while 1:
419                                 mountPoint_fix = mountPoint+str(partnum)
420                                 if not path.ismount(mountPoint_fix):
421                                         break
422                                 partnum +=1
423                         mountPoint = mountPoint_fix
424                 return mountPoint
425
426         def doMount(self, partition, mountpoint):
427                 try:
428                         device = partition["partition"]
429                         fstype = partition["fstype"]
430                         if mountpoint.endswith("/"):
431                                 mountpoint = retval[:-1]
432                         if mountpoint.find(' ') != -1:
433                                 mountpoint = mountpoint.replace(' ','-')
434                         dev = deviceinfo.checkMountPoint(mountpoint)
435                         if dev is None:
436                                 if not path.exists(mountpoint):
437                                         print "[deviceManager] make dir %s"%mountpoint
438                                         makedirs(mountpoint)
439                                 if fstype == "ntfs":
440                                         cmd = "ntfs-3g /dev/%s %s" % (device, mountpoint)
441                                 else:
442                                         cmd = "mount /dev/%s %s" % (device, mountpoint)
443                                 os.system(cmd)
444                                 print "[DeviceManager] cmd : %s"%cmd
445                                 if mountpoint == "/media/hdd":
446                                         movieDir = mountpoint + "/movie"
447                                         if not pathExists(movieDir):
448                                                 print "[DeviceManager] make dir %s"%movieDir
449                                                 os.makedirs(movieDir)
450                                 self.showPartitionList()
451 # update current mount state ,devicemanager.cfg
452                                 devicemanagerconfig.updateConfigList()
453                         else:
454                                 self.session.open(MessageBox, _("Mount Failed!\nCurrent path is already mounted by \"%s\"")%dev, MessageBox.TYPE_ERROR, timeout = 10)
455                 except:
456                         self.session.open(MessageBox, _("Mount Failed!(%s -> %s)")%(device, mountpoint), MessageBox.TYPE_ERROR, timeout = 10)
457
458         def MountpointBrowserCB(self, retval = None):
459                 if retval and retval is not None:
460                         mountPoint = retval.strip().replace(' ','')
461                         if retval.endswith("/"):
462                                 mountPoint = retval[:-1]
463                         print "Mount point from MountpointBrowser : %s"%mountPoint
464                         if not path.exists(mountPoint):
465                                 self.session.open(MessageBox, _("Mount Point is not writeable.\nPath : %s")%mountPoint, MessageBox.TYPE_ERROR, timeout = 10)
466
467                         else:
468                                 self.doMount(self.currPartition, mountPoint)
469 # mount funcs end..
470
471 # Initializing Start...
472 class DeviceInit(Screen):
473         skin = """<screen position="0,0" size="0,0"/>"""
474         def __init__(self, session, device, devicesize):
475                 Screen.__init__(self, session)
476                 self.session = session
477                 self.deviceInitConsole = Console()
478                 self.device = device
479                 self.devicesize = int(devicesize)
480                 self.inputbox_partitions = 1
481                 self.inputbox_partitionSizeList = []
482                 self.inputbox_partitionSizeTotal = self.inputbox_partitionSizeRemain = int(self.devicesize/1024/1024)
483                 self.msgWaiting = None
484                 self.msgWaitingMkfs = None
485                 self.devicenumber = 0
486                 self.newpartitions = 0
487                 self.onLayoutFinish.append(self.timerStart)
488                 self.initStartTimer = eTimer()
489                 self.initStartTimer.callback.append(self.confirmMessage)
490                 self.createFSStartTimer = eTimer()
491                 self.createFSStartTimer.callback.append(self.createFilesystemStart)
492                 self.exitMessageTimer = eTimer()
493                 self.exitMessageTimer.callback.append(self.exitMessage)
494                 self.msg = ""
495
496         def timerStart(self):
497                 self.initStartTimer.start(100,True)
498
499         def confirmMessage(self):
500                 message = _("Do you really want to initialize the device?\nAll data on the device will be lost!")
501                 self.session.openWithCallback(self.confirmed, MessageBox, message)
502
503         def confirmed(self, ret):
504                 if ret:
505                         self.InitializeStart()
506                 else:
507                         self.exit()
508
509         def exit(self, ret = True):
510                 self.close()
511
512         def unmountAll(self, device):
513                 mounts = file('/proc/mounts').read().split('\n')
514                 cmd = ""
515 # umount all
516                 for line in mounts:
517                         if not line.startswith("/dev/" + device):
518                                 continue
519                         cmd += "umount %s ;"% line.split()[0]
520                         os.system(cmd)
521 #recheck if umounted
522                 mounts = file('/proc/mounts').read().split('\n')
523                 for line in mounts:
524                         if line.startswith("/dev/" + device):
525                                 return False
526                 return True
527
528         def InitializeStart(self):
529                 self.InputPartitionSize_step1()
530
531         def InputPartitionSize_step1(self):
532                 self.session.openWithCallback(self.InputPartitionSize_step1_CB, InputBox, title=_("How many partitions do you want?(1-4)"), text="1", maxSize=False, type=Input.NUMBER)
533
534         def InputPartitionSize_step1_CB(self, ret):
535                 if ret is not None and int(ret) in range(1,5): # ret in 1~4
536                         self.inputbox_partitions = int(ret)
537                         self.InputPartitionSize_step2()
538                 else:
539                         self.session.openWithCallback(self.exit, MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
540
541         def InputPartitionSize_step2(self):
542                 current_partition = len(self.inputbox_partitionSizeList)+1
543                 if self.inputbox_partitionSizeRemain == 0:
544                         self.initInitializeConfirm()
545                 elif current_partition == self.inputbox_partitions:
546                         self.inputbox_partitionSizeList.append(str(self.inputbox_partitionSizeRemain))
547                         self.initInitializeConfirm()
548                 else:
549                         text = str(int(self.inputbox_partitionSizeRemain/(self.inputbox_partitions-len(self.inputbox_partitionSizeList) )))
550                         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)
551
552         def InputPartitionSize_step2_CB(self, ret):
553                 if ret is not None:
554                         if self.inputbox_partitionSizeRemain < int(ret) or int(ret) == 0:
555                                 self.InputPartitionSize_step2()
556                         else:
557                                 self.inputbox_partitionSizeList.append(str(ret))
558                                 self.inputbox_partitionSizeRemain -= int(ret)
559                                 self.InputPartitionSize_step2()
560                 else:
561                         self.session.openWithCallback(self.exit ,MessageBox, _("The number you entered is wrong!"), MessageBox.TYPE_ERROR, timeout = 10)
562
563         def initInitializeConfirm(self):
564 #               print self.inputbox_partitionSizeList
565                 partitionsInfo = ""
566                 for index in range(len(self.inputbox_partitionSizeList)):
567                         print "partition %d : %s Bytes"%(index+1, str(self.inputbox_partitionSizeList[index]))
568                         partitionsInfo += "partition %d : %s MB\n"%(index+1, str(self.inputbox_partitionSizeList[index]))
569                 self.session.openWithCallback(self.initInitializeConfirmCB, MessageBoxConfirm, _("%s\nStart Device Inititlization?") % partitionsInfo , MessageBox.TYPE_YESNO)
570
571         def initInitializeConfirmCB(self,ret):
572                 if ret:
573                         self.initInitialize()
574                 else:
575                         self.exit()
576         
577         def initInitialize(self):
578                 if not self.unmountAll(self.device):
579                         self.session.openWithCallback(self.exit, MessageBox, _("umounting failed!Maybe some files in mount point are open"), MessageBox.TYPE_ERROR, timeout = 10)
580                 else:
581                         msg = _("InitInitializing, please wait ...")
582                         msg += _("\nDevice : %s")%self.device
583                         msg += _("\nSize : %s MB\n")%self.inputbox_partitionSizeTotal
584                         for index in range(len(self.inputbox_partitionSizeList)):
585                                 msg += _("\npartition %d : %s MB")%(index+1, str(self.inputbox_partitionSizeList[index]))
586                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
587                         set = ""
588                         partitions = len(self.inputbox_partitionSizeList)
589                         if partitions == 1:
590                                 cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS /dev/' + self.device
591                         else:
592                                 for p in range(4):
593                                         if partitions > p+1:
594                                                 set += ",%s\n"%(self.inputbox_partitionSizeList[p])
595                                         else:
596                                                 set +=";\n"
597                                 set+="y\n"
598                                 cmd = 'printf "%s" | sfdisk -f -uM /dev/%s'%(set,self.device)
599                         self.deviceInitConsole.ePopen(cmd, self.initInitializeFinished)
600
601         def initInitializeFinished(self, result, retval, extra_args = None):
602                 if retval == 0:
603                         cmd = "sfdisk -R /dev/%s ; sleep 5" % (self.device)
604                         self.deviceInitConsole.ePopen(cmd, self.initInitializingRefreshFinished)
605                 else:
606                         errorMsg = "initInitializing device Error at /dev/%s"%self.device
607                         self.msgWaiting.run_close(False, errorMsg)
608
609         def initInitializingRefreshFinished(self, result, retval, extra_args = None):
610                 cmd = "/bin/umount /dev/%s*" % (self.device)
611                 self.deviceInitConsole.ePopen(cmd, self.initInitializingUmountFinished)
612
613         def initInitializingUmountFinished(self, result, retval, extra_args = None):
614                 partitions = open("/proc/partitions")
615                 self.devicenumber = 0
616                 self.newpartitions = 0
617                 for part in partitions:
618                         res = re.sub("\s+", " ", part).strip().split(" ")
619                         if res and len(res) == 4 and res[3][:3] == self.device:
620                                 if len(res[3]) > 3 and res[3][:2] == "sd":
621                                         self.newpartitions += 1
622                 partitions.close()
623                 self.msgWaiting.run_close(True)
624 #               self.createFilesystem(self.newpartitions)
625
626         def createFilesystem(self, newpartitions):
627                 self.devicenumber = self.devicenumber + 1
628                 fulldevicename = "/dev/" + self.device + str(self.devicenumber)
629                 shortdevicename = self.device + str(self.devicenumber)
630 # get partition size
631                 partitions = open("/proc/partitions")
632                 for part in partitions:
633                         res = re.sub("\s+", " ", part).strip().split(" ")
634                         if res and len(res) == 4:
635                                 if res[3] == shortdevicename:
636                                         partitionsize = int(res[2])
637                                         break
638                 partitions.close()
639
640                 if partitionsize > 64 * 1024 * 1024:
641                         cmd = "/sbin/mkfs.ext3 "
642                         filesystem = "ext3"
643                 else:
644                         cmd = "/sbin/mkfs.ext2 "
645                         filesystem = "ext2"
646                         
647                 if partitionsize > 2 * 1024 * 1024:
648                         cmd += "-T largefile "
649                 cmd += "-m0 " + fulldevicename
650
651                 msg = _("Create filesystem, please wait ...")
652                 msg += _("\nPartition : %s") % (fulldevicename)
653                 msg += _("\nFilesystem : %s") % (filesystem)
654                 msg += _("\nSize : %d MB\n")%int(self.inputbox_partitionSizeList[self.devicenumber-1])
655                 self.msgWaitingMkfs = self.session.openWithCallback(self.msgWaitingMkfsCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
656                 self.deviceInitConsole.ePopen(cmd, self.createFilesystemFinished, (self.device, fulldevicename))
657
658         def createFilesystemFinished(self, result, retval, extra_args = None):
659                 device = extra_args[0]
660                 fulldevicename = extra_args[1]
661                 if retval == 0:
662                         self.msgWaitingMkfs.run_close(True)
663                 else:
664                         errorMsg = _("Creating filesystem Error")
665                         if fulldevicename is not None:
666                                 errorMsg += _(" at /dev/%s")%fulldevicename
667                         self.msgWaitingMkfs.run_close(False, errorMsg)
668
669         def createFilesystemStart(self):
670                 self.createFilesystem(self.newpartitions)
671
672         def msgWaitingCB(self, ret, msg=""):
673                 if ret:
674                         self.createFSStartTimer.start(100,True)
675                 else:
676                         self.success = False
677                         self.msg = msg
678                         self.exitMessageTimer.start(100,True)
679
680         def msgWaitingMkfsCB(self, ret, msg=""):
681                 if self.devicenumber < self.newpartitions:
682                         self.createFSStartTimer.start(100,True)
683                 else:
684                         if ret == True:
685                                 self.success = True
686                                 self.msg = _("Device Initialization finished sucessfully!")
687                                 self.exitMessageTimer.start(100,True)
688                         else:
689                                 self.success = False
690                                 self.msg = msg
691                                 self.exitMessageTimer.start(100,True)
692
693         def exitMessage(self):
694                 if self.success:
695                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_INFO, timeout = 10)
696                 else:
697                         self.session.openWithCallback(self.exit, MessageBox, self.msg, MessageBox.TYPE_ERROR, timeout = 10)
698         
699 # Initializing end
700
701 # device check start..
702 class DeviceCheck(Screen):
703         skin = """<screen position="0,0" size="0,0"/>"""
704         def __init__(self, session, partition):
705                 Screen.__init__(self, session)
706                 self.session = session
707                 self.deviceCheckConsole = Console()
708                 self.partition = partition
709                 self.onLayoutFinish.append(self.timerStart)
710                 self.checkStartTimer = eTimer()
711                 self.checkStartTimer.callback.append(self.confirmMessage)
712
713         def timerStart(self):
714                 self.checkStartTimer.start(100,True)
715
716         def confirmMessage(self):
717                 fssize = self.partition["size"]
718                 if long(fssize) > 1024*1024*1024*16:
719                         message = _("Do you really want to check the filesystem?\nThis could take lots of time!")
720                         self.session.openWithCallback(self.confirmed, MessageBox, message)
721                 else:
722                         self.deviceCheckStart()
723
724         def confirmed(self, ret):
725                 print "confirmed : ",ret
726                 if ret:
727                         self.deviceCheckStart()
728                 else:
729                         self.exit()
730
731         def deviceCheckStart(self):
732                 print "deviceCheckStart "
733                 print "partition : ", self.partition
734                 device = self.partition["partition"]
735                 mountpoint = self.partition["mountpoint"]
736                 fstype = self.partition["fstype"]
737                 fssize = self.partition["size"]
738                 if device is not None and fstype.startswith("ext"):
739                         msg = _("Check filesystem, please wait ...")
740                         msg += _("\nDevice : /dev/%s")%(device)
741                         msg += _("\nFilesystem : %s")%(fstype)
742                         self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox.TYPE_INFO, enable_input = False)
743                         if mountpoint != "":
744                                 self.doUmountFsck(device, mountpoint, fstype)
745                         else:
746                                 self.umountFsckFinished("NORESULT", 0, (device, mountpoint, fstype))
747                 else:
748                         self.exit()
749
750         def doUmountFsck(self, device, mountpoint, fstype):
751                 cmd = "umount /dev/%s" % device
752                 self.deviceCheckConsole.ePopen(cmd, self.umountFsckFinished, (device, mountpoint, fstype))
753
754         def umountFsckFinished(self, result, retval, extra_args = None):
755                 device = extra_args[0]
756                 mountpoint = extra_args[1]
757                 fstype = extra_args[2]
758                 if retval == 0:
759                         cmd = "fsck." + fstype + " -f -p /dev/" + device
760                         self.deviceCheckConsole.ePopen(cmd, self.fsckFinished, extra_args)
761                 else:
762                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%device
763                         self.msgWaiting.run_close(False,errorMsg)
764                         
765         def fsckFinished(self, result, retval, extra_args = None):
766                 device = extra_args[0]
767                 mountpoint = extra_args[1]
768                 if retval == 0:
769                         text = _("Filesystem check finished sucessfully")
770                         self.msgWaiting.run_close(True, text)
771                 else:
772                         text = _("Error checking disk. The disk or filesystem may be damaged")
773                         self.msgWaiting.run_close(False, text)
774
775         def msgWaitingCB(self, ret, msg):
776                 if ret:
777                         self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
778                 else:
779                         self.session.open(MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
780
781                 partition = self.partition["partition"]
782                 mountpoint = self.partition["mountpoint"]
783                 fstype = self.partition["fstype"]
784                 if mountpoint != "":
785                         if fstype == "ntfs":
786                                 cmd = "ntfs-3g /dev/" + partition + " " + mountpoint
787                         else:
788                                 cmd = "mount /dev/" + partition + " " + mountpoint
789                         self.deviceCheckConsole.ePopen(cmd, self.mountPartitionFinished)
790                 else:
791                         self.exit()
792
793         def mountPartitionFinished(self, result, retval, extra_args = None):
794                 self.exit()
795
796         def exit(self):
797                 self.close()
798
799 #device check end
800
801 #device format start
802 class DeviceFormat(Screen):
803         skin = """<screen position="0,0" size="0,0"/>"""
804         def __init__(self, session, partition, newfstype):
805                 Screen.__init__(self, session)
806                 self.session = session
807                 self.deviceFormatConsole = Console()
808                 self.partition = partition
809                 self.newfstype = newfstype
810                 self.unmountedList = []
811                 self.onLayoutFinish.append(self.timerStart)
812                 self.formatStartTimer = eTimer()
813                 self.formatStartTimer.callback.append(self.DeviceFormatStart)
814
815         def timerStart(self):
816                 self.formatStartTimer.start(100,True)
817
818         def DeviceFormatStart(self):
819                 print "DeviceFormatStart : ", self.partition,
820                 print "Filesystem : ",self.newfstype
821                 device = self.partition["partition"]
822                 devicepath = "/dev/"+device
823                 mountpoint = self.partition["mountpoint"]
824                 fssize = self.partition["size"]
825                 newfstype = self.newfstype
826
827                 msg = _("Format filesystem, please wait ...")
828                 msg += _("\nDevice : %s")%(devicepath)
829                 msg += _("\nFilesystem : %s")%(newfstype)
830                 msg += _("\nSize : %s")%(byteConversion(fssize))
831                 self.msgWaiting = self.session.openWithCallback(self.msgWaitingCB, MessageBox_2, msg, type = MessageBox_2.TYPE_INFO, enable_input = False)
832                 if mountpoint != "":
833                         self.doumountPartition()
834                 else:
835                         self.umountPartitionFinished("NORESULT", 0)
836
837         def doumountPartition(self):
838                 oldfstype = self.partition["fstype"]
839                 newfstype = self.newfstype
840
841                 if newfstype == oldfstype:
842                         device = self.partition["partition"]
843                 else:
844                         device = self.partition["partition"][:3]
845                 cmd = ""
846                 mounts = file('/proc/mounts','r')
847                 for line in mounts.readlines():
848                         if line.startswith("/dev/%s"%device):
849                                 cmd += "umount %s;"%line.split()[0]
850                                 self.unmountedList.append([line.split()[0], line.split()[1]])
851                 self.deviceFormatConsole.ePopen(cmd, self.umountPartitionFinished)
852
853         def umountPartitionFinished(self, result, retval, extra_args = None):
854                 partition = self.partition["partition"]
855                 oldfstype = self.partition["fstype"]
856                 newfstype = self.newfstype
857                 if retval == 0:
858                         if oldfstype == newfstype:
859                                 self.changePartitionIDFinished("NORESULT", 0)
860                         else:
861                                 cmd = "sfdisk --change-id /dev/%s %s" % (partition[:3], partition[3:])
862                                 if newfstype[:3] == "ext":
863                                         cmd += " 83"
864                                 else:
865                                         cmd += " c"
866                                 self.deviceFormatConsole.ePopen(cmd, self.changePartitionIDFinished)
867                 else:
868                         errorMsg = _("Can not umount device /dev/%s.\nMaybe some files of the filesystem are open")%partition[:3]
869                         self.msgWaiting.run_close(False,errorMsg)
870
871         def changePartitionIDFinished(self, result, retval, extra_args = None):
872                 device = self.partition["partition"][:3]
873                 mountpoint = self.partition["mountpoint"]
874                 oldfstype = self.partition["fstype"]
875                 newfstype = self.newfstype
876                 if retval == 0:
877                         if oldfstype == newfstype:
878                                 self.refreshPartitionFinished("NORESULT", 0)
879                         else:
880                                 cmd = "sfdisk -R /dev/%s; sleep 5"%(device)
881                                 self.deviceFormatConsole.ePopen(cmd, self.refreshPartitionFinished)
882                 else:
883                         errorMsg = _("Can not change the partition ID for %s")%device
884                         self.msgWaiting.run_close(False,errorMsg)
885
886         def refreshPartitionFinished(self, result, retval, extra_args = None):
887                 print "refreshPartitionFinished!"
888                 partition = self.partition["partition"]
889                 mountpoint = self.partition["mountpoint"]
890                 size = int(self.partition["size"])/1024/1024
891                 oldfstype = self.partition["fstype"]
892                 newfstype = self.newfstype
893                 if retval == 0:
894                         if newfstype == "ext4":
895                                 cmd = "/sbin/mkfs.ext4 -F "
896                                 if size > 2 * 1024:
897                                         cmd += "-T largefile "
898                                 cmd += "-O extent,flex_bg,large_file,uninit_bg -m1 /dev/" + partition
899                         elif newfstype == "ext3":
900                                 cmd = "/sbin/mkfs.ext3 -F "
901                                 if size > 2 * 1024:
902                                         cmd += "-T largefile "
903                                 cmd += "-m0 /dev/" + partition
904                         elif newfstype == "ext2":
905                                 cmd = "/sbin/mkfs.ext2 -F "
906                                 if size > 2 * 1024:
907                                         cmd += "-T largefile "
908                                 cmd += "-m0 /dev/" + partition
909                         elif newfstype == "vfat":
910                                 if size > 4 * 1024 * 1024:
911                                         cmd = "/usr/sbin/mkfs.vfat -I -S4096 /dev/" + partition
912                                 else:
913                                         cmd = "/usr/sbin/mkfs.vfat -I /dev/" + partition
914                         self.deviceFormatConsole.ePopen(cmd, self.mkfsFinished)
915                 else:
916                         errorMsg = _("Can not format device /dev/%s.\nrefresh partition information failed!")%partition
917                         self.msgWaiting.run_close(False,errorMsg)
918                         
919         def mkfsFinished(self, result, retval, extra_args = None):
920                 print "mkfsFinished!"
921                 partition = self.partition["partition"]
922                 if retval == 0:
923                         cmd = ""
924                         if len(self.unmountedList) == 0:
925                                 self.doMountFinished("NORESULT",0)
926                         for x in self.unmountedList:
927                                 cmd += "mount %s %s;"%(x[0], x[1])
928                                 self.deviceFormatConsole.ePopen(cmd, self.doMountFinished)
929                 else:
930                         text = _("Make filesystem Error /dev/%s.\nPlease check your device.")%partition
931                         self.msgWaiting.run_close(False, text)
932
933         def doMountFinished(self, result, retval, extra_args = None):
934                 print "doMountFinished!"
935                 text = _("Format finished sucessfully.")
936                 self.msgWaiting.run_close(True, text)
937
938         def msgWaitingCB(self, ret, msg):
939                 if ret:
940                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_INFO, timeout = 10)
941                 else:
942                         self.session.openWithCallback(self.exit, MessageBox, msg, MessageBox.TYPE_ERROR, timeout = 10)
943
944         def exit(self, ret):
945                 self.close()
946
947 #device format end
948
949 class DeviceInfo():
950         def __init__(self):
951                 self.blockDeviceList = []
952
953         def getBlockDevices(self):
954                 return self.blockDeviceList
955
956         def refresh(self):
957                 self.blockDeviceList = []
958                 self.getBlockDeviceList()
959
960         def getBlockDeviceList(self):
961                 print "get block device Infomations..."
962                 for blockdev in listdir("/sys/block"):
963                         (error, blacklisted, removable, partitions, size, model, vendor) = self.getBlockDeviceInfo(blockdev)
964                         if not blacklisted and not error:
965 #                               print "%s : error %s, blacklisted %s, removable %s, partitions %s, size %s"%(blockdev, error, blacklisted, removable, partitions, size)
966                                 blockDevice = {}
967                                 blockDevice["blockdev"] = blockdev # str
968                                 blockDevice["removable"] = removable # bool [True, False]
969                                 blockDevice["partitions"] = partitions # list
970                                 blockDevice["size"] = size # str
971                                 blockDevice["model"] = model # str
972                                 blockDevice["vendor"] = vendor # str
973                                 self.blockDeviceList.append(blockDevice)
974
975         def getBlockDeviceInfo(self, blockdev):
976                 devpath = "/sys/block/" + blockdev
977                 error = False
978                 removable = False
979                 blacklisted = False
980                 partitions = []
981                 size =""
982                 model = ""
983                 vendor = ""
984                 try:
985                         dev = int(readFile(devpath + "/dev").split(':')[0])
986                         if dev in (7, 31) or blockdev[0:2] != 'sd': # 7: loop, 31 : mtdblock
987                                 blacklisted = True
988                                 return error, blacklisted, removable, partitions, size, model, vendor
989                         removable = bool(int(readFile(devpath + "/removable")))
990                         size = str(int(readFile(devpath + "/size").strip())*512)
991                         model = readFile(devpath + "/device/model")
992                         vendor = readFile(devpath + "/device/vendor")
993                         for partition in listdir(devpath):
994                                 if partition[:len(blockdev)] != blockdev:
995                                         continue
996                                 partitions.append(partition)
997                 except IOError:
998                         error = True
999                 return error, blacklisted, removable, partitions, size, model, vendor
1000
1001         def getPartitionInfo(self, partition):
1002                 mountPoint = self.getPartitionMountpoint(partition)
1003                 (uuid , fsType) = self.getPartitionBlkidInfo(partition)
1004                 size_total = self.getPartitionSize(partition)
1005                 size_free = ""
1006                 if mountPoint != "":
1007                         size_free = self.getPartitionFree(mountPoint)   
1008                 partitionInfo = {}
1009                 partitionInfo["partition"] = partition
1010                 partitionInfo["mountpoint"] = mountPoint
1011                 partitionInfo["uuid"] = uuid
1012                 partitionInfo["fstype"] = fsType
1013                 partitionInfo["size"] = size_total
1014                 partitionInfo["free"] = size_free
1015                 return partitionInfo
1016
1017         def getPartitionMountpoint(self, partition):
1018                 mounts = file('/proc/mounts').read().split('\n')
1019                 for x in mounts:
1020                         if not x.startswith('/'):
1021                                 continue
1022                         devpath, mountpoint,  = x.split()[:2]
1023                         if mountpoint.startswith('/autofs'):
1024                                 continue
1025                         if path.basename(devpath) == partition:
1026                                 return mountpoint
1027                 return ""
1028
1029         def getPartitionBlkidInfo(self, partition):
1030                 parttionDev = "/dev/"+str(partition)
1031                 uuid = ""
1032                 partitionType = ""
1033                 cmd = "blkid -c /dev/null "+str(parttionDev)
1034                 try:
1035                         line = popen(cmd).readline().strip()
1036                         if not line.startswith(parttionDev):
1037                                 return (uuid, partitionType)
1038 #                       print "Blikd %s : %s"%(parttionDev, line)
1039                         if line.find(" UUID=") != -1:
1040                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1041                         if line.find(" TYPE=") != -1:
1042                                 partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1043                 except:
1044                         print "get blkid info error (%s)"%cmd
1045                 return (uuid, partitionType)
1046
1047         def getPartitionSize(self, partition):          
1048                 devpath = "/sys/block/%s/%s"%( str(partition[:3]), str(partition) )
1049                 try:
1050                         size = readFile(devpath + "/size")
1051                         return str(int(size)*512)
1052                 except:
1053                         return ""
1054
1055         def getPartitionFree(self, mountPoint):
1056                 try:
1057                         stat = statvfs(mountPoint)
1058                         size_free = stat.f_bfree*stat.f_bsize
1059                         return size_free
1060                 except:
1061                         return ""
1062
1063         def checkMountPoint(self, check_mountpoint):
1064                 try:
1065                         mounts = file('/proc/mounts').read().split('\n')
1066                         for x in mounts:
1067                                 if not x.startswith('/'):
1068                                         continue
1069                                 devpath, mountpoint  = x.split()[:2]
1070                                 if mountpoint == check_mountpoint:
1071                                         return devpath
1072                 except:
1073                         pass
1074                 return None
1075
1076 deviceinfo = DeviceInfo()
1077
1078 class MountpointBrowser(Screen):
1079         skin="""
1080                 <screen name="MountpointBrowser" position="center,120" size="670,500" title="Select mountpoint">
1081                         <ePixmap pixmap="skin_default/buttons/red.png" position="20,0" size="140,40" alphatest="on" />
1082                         <ePixmap pixmap="skin_default/buttons/green.png" position="180,0" size="140,40" alphatest="on" />
1083                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="340,0" size="140,40" alphatest="on" />
1084                         <ePixmap pixmap="skin_default/buttons/blue.png" position="500,0" size="140,40" alphatest="on" />
1085                         <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" />
1086                         <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" />
1087                         <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" />
1088                         <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" />
1089                         <eLabel position="10,50" size="650,1" backgroundColor="#b3b3b9"/>
1090                         <widget name="filelist" position="10,60" size="650,440" itemHeight="30" scrollbarMode="showOnDemand"/>
1091                 </screen>
1092         """
1093         def __init__(self, session):
1094                 Screen.__init__(self, session)
1095                 self["key_red"] = StaticText(_("Cancel"))
1096                 self["key_green"] = StaticText(_("Select"))
1097                 self["key_yellow"] = StaticText(_("Create directory"))
1098                 self["key_blue"] = StaticText("Delete directory")
1099                 directory = "/media/"
1100                 inhibitDirs = ["/autofs", "/mnt", "/hdd", "/bin", "/boot", "/dev", "/etc", "/home", "/lib", "/proc", "/sbin", "/share", "/sys", "/tmp", "/usr", "/var"]
1101                 self.filelist = FileList(directory, matchingPattern="", inhibitDirs = inhibitDirs)
1102                 self["filelist"] = self.filelist
1103
1104                 self["shortcuts"] = ActionMap(["ColorActions"],
1105                         {
1106                         "red": self.exit,
1107                         "green": self.select,
1108                         "yellow": self.createDirectory,
1109                         "blue": self.deleteDirectory,
1110                         }, -2)
1111
1112                 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
1113                         {
1114                         "cancel": self.exit,
1115                         "ok": self.ok,
1116                         }, -2)
1117
1118         def ok(self):
1119                 if self.filelist.canDescent():
1120                         self.filelist.descent()
1121
1122         def select(self):
1123                 if self["filelist"].getCurrentDirectory() is not None:
1124                         if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1125                                 self.filelist.descent()
1126                                 currDir = self["filelist"].getCurrentDirectory()
1127                                 self.close(currDir)
1128                 else:
1129                         self.close(self["filelist"].getFilename())
1130
1131         def createDirectory(self):
1132                 self.session.openWithCallback(self.createDirectoryCB, VirtualKeyBoard, title = (_("Input mount point path.")), text = "")
1133
1134         def createDirectoryCB(self, retval = None):
1135                 newdir=None
1136                 try:
1137                         if retval is not None:
1138                                 newdir = self["filelist"].getCurrentDirectory()+'/'+retval
1139                                 if not path.exists(newdir):
1140                                         os.system("mkdir %s"%newdir)
1141                                 self.filelist.refresh()
1142                 except:
1143                         if newdir:
1144                                 self.session.open(MessageBox, _("Create directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1145
1146         def deleteDirectory(self):
1147                 delDir=None
1148                 try:
1149                         if self["filelist"].getCurrentDirectory() is not None:
1150                                 if self.filelist.canDescent() and self["filelist"].getFilename() and self["filelist"].getFilename().startswith(self["filelist"].getCurrentDirectory()):
1151                                         delDir = self["filelist"].getFilename()
1152                                         if path.exists(delDir):
1153                                                 os.system("rmdir '%s'"%delDir)
1154                                         if path.exists(delDir):
1155                                                 self.session.open(MessageBox, _("Delete directory failed!\nMaybe directory is not empty."), MessageBox.TYPE_ERROR, timeout = 10)
1156                                         self.filelist.refresh()
1157                 except:
1158                         if delDir:
1159                                 self.session.open(MessageBox, _("Delete directory failed!\n%s")%newdir, MessageBox.TYPE_ERROR, timeout = 10)
1160
1161         def exit(self):
1162                 self.close(False)
1163
1164 class MessageBoxConfirm(MessageBox):
1165         skin =  """
1166                 <screen position="center,center" size="620,10" title="Message">
1167                         <widget name="text" position="65,8" size="420,0" font="Regular;20" />
1168                         <widget name="ErrorPixmap" pixmap="skin_default/icons/input_error.png" position="5,5" size="53,53" alphatest="blend" />
1169                         <widget name="QuestionPixmap" pixmap="skin_default/icons/input_question.png" position="5,5" size="53,53" alphatest="blend" />
1170                         <widget name="InfoPixmap" pixmap="skin_default/icons/input_info.png" position="5,5" size="53,53" alphatest="blend" />
1171                         <widget name="list" position="100,100" size="380,375" transparent="1" />
1172                         <applet type="onLayoutFinish">
1173 # this should be factored out into some helper code, but currently demonstrates applets.
1174 from enigma import eSize, ePoint
1175
1176 orgwidth  = self.instance.size().width()
1177 orgheight = self.instance.size().height()
1178 orgpos    = self.instance.position()
1179 textsize  = self[&quot;text&quot;].getSize()
1180
1181 # y size still must be fixed in font stuff...
1182 textsize = (textsize[0] + 50, textsize[1] + 50)
1183 offset = 0
1184 if self.type == self.TYPE_YESNO:
1185         offset = 60
1186 wsizex = textsize[0] + 60
1187 wsizey = textsize[1] + offset
1188 if (280 &gt; wsizex):
1189         wsizex = 280
1190 wsize = (wsizex, wsizey)
1191
1192 # resize
1193 self.instance.resize(eSize(*wsize))
1194
1195 # resize label
1196 self[&quot;text&quot;].instance.resize(eSize(*textsize))
1197
1198 # move list
1199 listsize = (wsizex, 50)
1200 self[&quot;list&quot;].instance.move(ePoint(0, textsize[1]))
1201 self[&quot;list&quot;].instance.resize(eSize(*listsize))
1202
1203 # center window
1204 newwidth = wsize[0]
1205 newheight = wsize[1]
1206 self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y() + (orgheight - newheight)/2))
1207                         </applet>
1208                 </screen>
1209                 """
1210
1211 dmconfigfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/DeviceManager/devicemanager.cfg")
1212 class DeviceManagerConfig():
1213         def __init__(self):
1214                 self.configList = []
1215
1216         def getConfigList(self):
1217                 return self.configList
1218
1219         def updateConfigList(self):
1220                 try:
1221                         self.configList = []
1222                         file = open("/proc/mounts")
1223                         mounts = file.readlines()
1224                         file.close()
1225                         for x in mounts:
1226                                 if x.startswith("/dev/sd"):
1227                                         device = x.split()[0].split('/dev/')[1]
1228                                         mountpoint = x.split()[1]
1229                                         if mountpoint.startswith('/autofs'):
1230                                                 continue
1231                                         (uuid, partitionType) = deviceinfo.getPartitionBlkidInfo(device)
1232                                         if uuid != '' and mountpoint != '':
1233                                                 self.configList.append([uuid, mountpoint])
1234                         self.saveConfig()
1235                 except:
1236                         print "updateConfigList failed!"
1237
1238         def loadConfig(self):
1239                 if not fileExists(dmconfigfile):
1240                         os.system("touch %s" % dmconfigfile)
1241                 self.configList = []
1242                 data = file(dmconfigfile).read().split('\n')
1243                 for line in data:
1244                         if line.find(':') != -1:
1245                                 (uuid, mountpoint) = line.split(':')
1246                                 if uuid != '' and mountpoint != '':
1247                                         self.configList.append([uuid, mountpoint])
1248
1249         def saveConfig(self):
1250                 confFile = open(dmconfigfile,'w')
1251                 data = ""
1252                 for line in self.configList:
1253                         data += "%s:%s\n"%(line[0],line[1]) # uuid, mountpoint
1254                 confFile.write(data)
1255                 confFile.close()
1256
1257         def appendConfig(self, uuid, mountpoint):
1258                 for x in self.configList:
1259                         if x[0] == uuid or x[1] == mountpoint:
1260                                 self.configList.remove(x)
1261                 self.configList.append([uuid, mountpoint])
1262
1263         def removeConfig(self, value):
1264                 for x in self.configList:
1265                         if x[0] == value or x[1] == value:
1266                                 self.configList.remove(x)
1267
1268 devicemanagerconfig = DeviceManagerConfig()
1269
1270 devicemanagerhotplugactive = True
1271 def DeviceManagerhotplugDeviceStart(action, device):
1272         global devicemanagerhotplugactive
1273         if devicemanagerhotplugactive:
1274                 DeviceManagerHotplugDevice(action, device)
1275
1276 def DeviceManagerHotplugDevice(action, device):
1277         if not config.plugins.devicemanager.hotplug_enable.value:
1278                 return
1279         print "[DeviceManager Hotplug Device] action : %s, device : %s"%(action, device.device)
1280
1281         try:
1282                 if action == 'add' and device.is_hotplug and len(device.device) == 3:
1283                         if device.device.startswith("sd"):
1284                                 newdevice = "/dev/" + device.device
1285                                 cmd = "sleep 3 && blkid -c /dev/null " + newdevice + "*"
1286                                 data = popen(cmd).read().split('\n')
1287 #                               print "[DeviceManagerHotplugDevice] blkid data : ",data
1288                                 for line in data:
1289                                         uuid = ""
1290                                         partitionType = ""
1291                                         if line.startswith(newdevice):
1292                                                 if line.find(" UUID=") != -1:
1293                                                         uuid = line.split(" UUID=")[1].split(' ')[0]
1294                                                 if line.find(" TYPE=") != -1:
1295                                                         partitionType = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1296                                                 mountdev = line.split(':')[0]
1297                                                 devicemanagerconfig.loadConfig()
1298                                                 configList = devicemanagerconfig.getConfigList()
1299                                                 for c in configList:
1300                                                         if uuid == c[0].strip():
1301                                                                 mountpoint = c[1].strip()
1302                                                                 if not os.path.ismount(mountpoint):
1303                                                                         if partitionType == "ntfs":
1304                                                                                 cmd = "ntfs-3g %s %s"%(mountdev, mountpoint)
1305                                                                         else:
1306                                                                                 cmd = "mount %s %s"%(mountdev, mountpoint)
1307                                                                         print "[DeviceManagerHotplugDevice] try..'%s'"%cmd
1308                                                                         os.system(cmd)
1309
1310                 elif action == 'remove' and device.device is not None and len(device.device) == 3:
1311                         mounts = file('/proc/mounts').read().split('\n')
1312                         for x in mounts:
1313                                 if not x.startswith('/'):
1314                                         continue
1315                                 if x.startswith("/dev/"+device.device):
1316                                         cmd = "umount "+x.split()[0]
1317                                         print "[DeviceManagerHotplugDevice] try.. '%s'"%cmd
1318                                         os.system(cmd)
1319         except:
1320                 print "[DeviceManagerHotplug] hotplugDevice error."
1321
1322 def callBackforDeviceManager(session, callback_result = False):
1323         if callback_result == True:
1324                 session.open(DeviceManager)
1325
1326 def checkMounts(session):
1327         try:
1328                 file = open("/proc/partitions")
1329                 partitions = file.readlines()
1330                 file.close()
1331                 file = open("/proc/mounts")
1332                 mounts = file.readlines()
1333                 file.close()
1334                 not_mounted = False
1335                 for part in partitions:
1336                         res = re.sub("\s+", " ", part).strip().split(" ")
1337                         if res and len(res) == 4:
1338                                 if len(res[3]) == 3 and res[3][:2] == "sd":
1339                                         device = "/dev/" + res[3]
1340                                         print "found device %s"%device
1341                                         not_mounted = True
1342                                         for line in mounts:
1343                                                 if line.split()[1].startswith('/autofs'):
1344                                                         continue
1345                                                 if line.startswith(device):
1346                                                         print line
1347                                                         not_mounted = False
1348                                                         break
1349                         if not_mounted == True:
1350                                 break
1351
1352                 if not_mounted == True:
1353                         print "Umounted partitions found."
1354                         InfoText = _("umounted partitions found.!\nDo you want to open DeviceManager and set mount point?\n\n(Open 'Menu->Setup->System -> Harddisk -> DeviceManager'\n and press MENU button to deactivate this check.)")
1355                         AddNotificationWithCallback(
1356                                                         boundFunction(callBackforDeviceManager, session), 
1357                                                         MessageBox, InfoText, timeout = 60, default = False
1358                         )
1359         except:
1360                 print "checkMounts failed!"
1361
1362 def sessionstart(reason, **kwargs):
1363         if reason == 0:
1364                 if kwargs.has_key("session") and config.plugins.devicemanager.mountcheck_enable.value == True:
1365                         session = kwargs["session"]
1366                         checkMounts(session)
1367                 if config.plugins.devicemanager.hotplug_enable.value:
1368                         harddiskmanager.on_partition_list_change.append(DeviceManagerhotplugDeviceStart)
1369         elif reason == 1:
1370                 if config.plugins.devicemanager.hotplug_enable.value:
1371                         harddiskmanager.on_partition_list_change.remove(DeviceManagerhotplugDeviceStart)
1372
1373 def autostart(reason, **kwargs):
1374         if reason == 0:
1375                 try:
1376 # check at first enigma2 start  
1377                         if not fileExists(dmconfigfile):
1378                                 print "[DeviceManager] autostart : check devices at first start"
1379                                 sda_isremovable = False
1380 #                               sdb_isremovable = False
1381                                 sda_UUID = ""
1382 #                               sdb_UUID = ""
1383                                 os.system("touch %s"%dmconfigfile)
1384 # check sda
1385                                 sda_data = popen("cat /proc/partitions | grep sda1").read()
1386                                 if sda_data != '':
1387                                         sda_UUID = popen("blkid -o value -s UUID /dev/sda1").read().strip('\n')
1388                                         sda_isremovable = bool(int(readFile("/sys/block/sda/removable")))
1389                                         print "sda : %s, %s"%(sda_UUID, sda_isremovable)
1390 # check sdb 
1391 #                               sdb_data = popen("cat /proc/partitions | grep sdb1").read()
1392 #                               if sdb_data != '':
1393 #                                       sdb_UUID = popen("blkid -o value -s UUID /dev/sdb1").read().strip('\n')
1394 #                                       sdb_isremovable = bool(int(readFile("/sys/block/sdb/removable")))
1395 #                                       print "sdb : %s, %s"%(sdb_UUID, sdb_isremovable)
1396                                 cfg = ""
1397                                 if sda_data != '':
1398 #                                       if sdb_data != '':
1399 #                                               if not sda_isremovable:
1400 #                                                       cfg += '"%s":/media/hdd\n'%sda_UUID
1401 #                                                       cfg += '"%s":/media/usb\n'%sdb_UUID
1402 #                                               else:
1403 #                                                       if not sdb_isremovable:
1404 #                                                               cfg += '"%s":/media/hdd\n'%sdb_UUID
1405 #                                                               cfg += '"%s":/media/usb\n'%sda_UUID
1406 #                                                       else:
1407 #                                                               cfg += '"%s":/media/hdd\n'%sda_UUID
1408 #                                                               cfg += '"%s":/media/usb\n'%sdb_UUID
1409 #                                       else:
1410 #                                               cfg += '"%s":/media/hdd\n'%sda_UUID
1411                                         cfg += '"%s":/media/hdd\n'%sda_UUID
1412                                 confFile = open(dmconfigfile,'w')
1413                                 confFile.write(cfg)
1414                                 confFile.close()
1415 #                               if not path.exists("/media/usb"):
1416 #                                               os.system("mkdir -p /media/usb")
1417                                 if not path.exists("/media/hdd"):
1418                                         os.system("mkdir -p /media/hdd")
1419                                 
1420 # check at first enigma2 start - end
1421                         devicemanagerconfig.loadConfig()
1422                         configList = devicemanagerconfig.getConfigList()
1423                         if len(configList) != 0:
1424                                 print "[DeviceManager] automount from device manager configs"
1425                                 cmd = "blkid -c /dev/null /dev/sd*"
1426                                 data = popen(cmd).read().split('\n')
1427                                 for line in data:
1428                                         device = ""
1429                                         uuid = ""
1430                                         filesystem = ""
1431                                         device = line.split(':')[0]
1432                                         if line.find(" UUID=") != -1:
1433                                                 uuid = line.split(" UUID=")[1].split(' ')[0]
1434                                         if line.find(" TYPE=") != -1:
1435                                                 filesystem = line.split(" TYPE=")[1].split(' ')[0].strip('"')
1436                                         for line in configList:
1437                                                 configuuid = line[0].strip()
1438                                                 configmountpoint = line[1].strip()
1439                                                 if configuuid == uuid and path.exists(configmountpoint) and not path.ismount(configmountpoint):
1440                                                         if filesystem == "ntfs":
1441                                                                 cmd = "ntfs-3g %s %s"%(device, configmountpoint)
1442                                                         else:
1443                                                                 cmd = "mount -t %s %s %s"%(filesystem, device, configmountpoint)
1444                                                         print "[DeviceManager] ",cmd
1445                                                         os.system(cmd)
1446                                                         break
1447                 except:
1448                         print "[DeviceManager] autostart failed!"
1449
1450 def menu(menuid, **kwargs):
1451         if menuid == "harddisk":
1452                 return [(_("DeviceManager"), main, "device_manager", 1)]
1453         return []
1454
1455 def main(session, **kwargs):
1456         session.open(DeviceManager)
1457
1458 def Plugins(path, **kwargs):
1459         return [
1460                 PluginDescriptor(name = _("DeviceManager"), description = _("manage block devices of your VU+"), where = PluginDescriptor.WHERE_MENU,fnc=menu),
1461                 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, needsRestart = True, fnc = sessionstart),
1462                 PluginDescriptor(where = PluginDescriptor.WHERE_AUTOSTART, needsRestart = True, fnc = autostart)
1463                 ]
1464
1465 class MessageBox_2(MessageBox):
1466         def __init__(self, session, text, type = MessageBox.TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None):
1467                 MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default, enable_input, msgBoxID)
1468                 self.skinName = "MessageBox"
1469                 self.closeTimer = eTimer()
1470                 self.closeTimer.callback.append(self.msg_close)
1471                 self.devicemanager_ret = False
1472                 self.devicemanager_msg = ""
1473
1474         def msg_close(self):
1475                 self.close(self.devicemanager_ret, self.devicemanager_msg)
1476
1477         def run_close(self, ret, msg=""):
1478                 self.devicemanager_ret = ret
1479                 self.devicemanager_msg = msg
1480                 self.closeTimer.start(100,True)
1481
1482         def createSummary(self):
1483                 return MessageBox_2_Summary
1484
1485 class MessageBox_2_Summary(Screen):
1486         skin="""
1487                 <screen name="MessageBox_2_Summary" position="0,0" size="256,64" id="1">
1488                         <widget source="parent.Text" render="Label" position="0,0" size="256,64" font="Regular;13" halign="center" valign="center" />
1489                 </screen>
1490         """