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