cut away 1/4th of enigma loading time by loading languages when they are used
[enigma2.git] / lib / python / Components / Harddisk.py
1 from os import system, listdir, statvfs, popen, makedirs
2
3 from Tools.Directories import SCOPE_HDD, resolveFilename
4 from Tools.CList import CList
5
6 from SystemInfo import SystemInfo
7
8 def tryOpen(filename):
9         try:
10                 procFile = open(filename)
11         except IOError:
12                 return ""
13         return procFile
14
15 def num2prochdx(num):
16         return "/proc/ide/hd" + ("a","b","c","d","e","f","g","h","i")[num] + "/"
17
18 class Harddisk:
19         def __init__(self, index):
20                 self.index = index
21
22                 host = (self.index & 2) >> 1
23                 bus = 0
24                 target = (self.index & 1)
25
26                 self.prochdx = num2prochdx(index)
27                 self.devidex = "/dev/ide/host%d/bus%d/target%d/lun0/" % (host, bus, target)
28
29         def getIndex(self):
30                 return self.index
31
32         def bus(self):
33                 ret = ""
34
35                 if self.index & 2:
36                         ret = "External (CF) - "
37                 else:
38                         ret = "Internal - "
39                 
40                 if self.index & 1:
41                         return ret + "Slave"
42                 else:
43                         return ret + "Master"
44
45         def capacity(self):
46                 procfile = tryOpen(self.prochdx + "capacity")
47                 
48                 if procfile == "":
49                         return ""
50
51                 line = procfile.readline()
52                 procfile.close()
53                 
54                 try:
55                         cap = int(line)
56                 except:
57                         return ""
58                 
59                 cap = cap / 1000 * 512 / 1000
60                 
61                 return "%d.%03d GB" % (cap/1024, cap%1024)
62                                                                 
63         def model(self):
64                 procfile = tryOpen(self.prochdx + "model")
65
66                 if procfile == "":
67                         return ""
68
69                 line = procfile.readline()
70                 procfile.close()
71
72                 return line.strip()
73
74         def free(self):
75                 procfile = tryOpen("/proc/mounts")
76                 
77                 if procfile == "":
78                         return -1
79
80                 free = -1
81                 while 1:
82                         line = procfile.readline()
83                         if line == "":
84                                 break
85                         if line.startswith(self.devidex):
86                                 parts = line.strip().split(" ")
87                                 try:
88                                         stat = statvfs(parts[1])
89                                 except OSError:
90                                         continue
91                                 free = stat.f_bfree/1000 * stat.f_bsize/1000
92                                 break
93                 procfile.close()
94                 return free             
95
96         def numPartitions(self):
97                 try:
98                         idedir = listdir(self.devidex)
99                 except OSError:
100                         return -1
101                 numPart = -1
102                 for filename in idedir:
103                         if filename.startswith("disc"):
104                                 numPart += 1
105                         if filename.startswith("part"):
106                                 numPart += 1
107                 return numPart
108
109         def unmount(self):
110                 cmd = "/bin/umount " + self.devidex + "part*"
111                 res = system(cmd)
112                 return (res >> 8)
113
114         def createPartition(self):
115                 cmd = "/sbin/sfdisk -f " + self.devidex + "disc"
116                 sfdisk = popen(cmd, "w")
117                 sfdisk.write("0,\n;\n;\n;\ny\n")
118                 sfdisk.close()
119                 return 0
120
121         def mkfs(self):
122                 cmd = "/sbin/mkfs.ext3 -T largefile -m0 " + self.devidex + "part1"
123                 res = system(cmd)
124                 return (res >> 8)
125
126         def mount(self):
127                 cmd = "/bin/mount -t ext3 " + self.devidex + "part1"
128                 res = system(cmd)
129                 return (res >> 8)
130
131         def createMovieFolder(self):
132                 try:
133                         makedirs(resolveFilename(SCOPE_HDD))
134                 except OSError:
135                         return -1
136                 return 0
137
138         errorList = [ _("Everything is fine"), _("Creating partition failed"), _("Mkfs failed"), _("Mount failed"), _("Create movie folder failed"), _("Unmount failed")]
139
140         def initialize(self):
141                 self.unmount()
142
143                 if self.createPartition() != 0:
144                         return -1
145
146                 if self.mkfs() != 0:
147                         return -2
148
149                 if self.mount() != 0:
150                         return -3
151
152                 #only create a movie folder on the internal hdd
153                 if not self.index & 2 and self.createMovieFolder() != 0:
154                         return -4
155                 
156                 return 0
157                 
158 def existHDD(num):
159         mediafile = tryOpen(num2prochdx(num) + "media")
160
161         if mediafile == "":
162                 return -1
163
164         line = mediafile.readline()
165         mediafile.close()
166         
167         if line.startswith("disk"):
168                 return 1
169         
170         return -1
171
172 class Partition:
173         def __init__(self, mountpoint, description = "", force_mounted = False):
174                 self.mountpoint = mountpoint
175                 self.description = description
176                 self.force_mounted = force_mounted
177
178         def stat(self):
179                 return statvfs(self.mountpoint)
180
181         def free(self):
182                 try:
183                         s = self.stat()
184                         return s.f_bavail * s.f_bsize
185                 except OSError:
186                         return None
187         
188         def total(self):
189                 try:
190                         s = self.stat()
191                         return s.f_blocks * s.f_bsize
192                 except OSError:
193                         return None
194
195         def mounted(self):
196                 # THANK YOU PYTHON FOR STRIPPING AWAY f_fsid.
197                 # TODO: can os.path.ismount be used?
198                 if self.force_mounted:
199                         return True
200                 procfile = tryOpen("/proc/mounts")
201                 for n in procfile.readlines():
202                         if n.split(' ')[1] == self.mountpoint:
203                                 return True
204                 return False
205
206 class HarddiskManager:
207         def __init__(self):
208                 hddNum = 0
209                 self.hdd = [ ]
210                 
211                 self.partitions = [ ]
212                 
213                 self.on_partition_list_change = CList()
214                 
215                 for hddNum in range(8):
216                         if existHDD(hddNum):
217                                 hdd = Harddisk(hddNum)
218                                 self.hdd.append(hdd)
219
220                 SystemInfo["Harddisc"] = len(self.hdd) > 0
221
222                 # currently, this is just an enumeration of what's possible,
223                 # this probably has to be changed to support automount stuff.
224                 # still, if stuff is mounted into the correct mountpoints by
225                 # external tools, everything is fine (until somebody inserts 
226                 # a second usb stick.)
227                 p = [
228                                         ("/media/hdd", _("Harddisk")), 
229                                         ("/media/card", _("Card")), 
230                                         ("/media/cf", _("Compact Flash")),
231                                         ("/media/mmc1", _("MMC Card")),
232                                         ("/media/net", _("Network Mount")),
233                                         ("/media/ram", _("Ram Disk")),
234                                         ("/media/usb", _("USB Stick")),
235                                         ("/", _("Internal Flash"))
236                                 ]
237                 
238                 for x in p:
239                         self.partitions.append(Partition(mountpoint = x[0], description = x[1]))
240
241         def getAutofsMountpoint(self, device):
242                 return "/autofs/%s/" % (device)
243
244         def addHotplugPartition(self, device, description):
245                 p = Partition(mountpoint = self.getAutofsMountpoint(device), description = description, force_mounted = True)
246                 self.partitions.append(p)
247                 self.on_partition_list_change("add", p)
248
249         def removeHotplugPartition(self, device):
250                 mountpoint = self.getAutofsMountpoint(device)
251                 for x in self.partitions[:]:
252                         if x.mountpoint == mountpoint:
253                                 self.partitions.remove(x)
254                                 self.on_partition_list_change("remove", x)
255
256         def HDDCount(self):
257                 return len(self.hdd)
258
259         def HDDList(self):
260                 list = [ ]
261                 for hd in self.hdd:
262                         hdd = hd.model() + " (" 
263                         hdd += hd.bus()
264                         cap = hd.capacity()     
265                         if cap != "":
266                                 hdd += ", " + cap
267                         hdd += ")"
268                         list.append((hdd, hd))
269
270                 return list
271
272         def getMountedPartitions(self):
273                 return [x for x in self.partitions if x.mounted()]
274
275 harddiskmanager = HarddiskManager()