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