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