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