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