Softwaremanager: * notify if updatefeed is not available and also verify HardwarePrer...
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / SoftwareManager / SoftwareTools.py
1 from enigma import eConsoleAppContainer
2 from Components.Console import Console
3 from Components.About import about
4 from Components.DreamInfoHandler import DreamInfoHandler
5 from Components.Language import language
6 from Components.Sources.List import List
7 from Components.Ipkg import IpkgComponent
8 from Components.Network import iNetwork
9 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_METADIR
10 from Tools.HardwareInfo import HardwareInfo
11
12 from time import time
13
14 class SoftwareTools(DreamInfoHandler):
15         lastDownloadDate = None
16         NetworkConnectionAvailable = None
17         list_updating = False
18         available_updates = 0
19         available_updatelist  = []
20         available_packetlist  = []
21         installed_packetlist = {}
22
23         
24         def __init__(self):
25                 aboutInfo = about.getImageVersionString()
26                 if aboutInfo.startswith("dev-"):
27                         self.ImageVersion = 'Experimental'
28                 else:
29                         self.ImageVersion = 'Stable'
30                 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
31                 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion, language = self.language)
32                 self.directory = resolveFilename(SCOPE_METADIR)
33                 self.list = List([])
34                 self.NotifierCallback = None
35                 self.Console = Console()
36                 self.UpdateConsole = Console()
37                 self.cmdList = []
38                 self.unwanted_extensions = ('-dbg', '-dev', '-doc')
39                 self.ipkg = IpkgComponent()
40                 self.ipkg.addCallback(self.ipkgCallback)                
41
42         def statusCallback(self, status, progress):
43                 pass            
44
45         def startSoftwareTools(self, callback = None):
46                 if callback is not None:
47                         self.NotifierCallback = callback
48                 iNetwork.checkNetworkState(self.checkNetworkCB)
49                 
50         def checkNetworkCB(self,data):
51                 if data is not None:
52                         if data <= 2:
53                                 SoftwareTools.NetworkConnectionAvailable = True
54                                 self.getUpdates()
55                         else:
56                                 SoftwareTools.NetworkConnectionAvailable = False
57                                 self.getUpdates()
58
59         def getUpdates(self, callback = None):
60                 if SoftwareTools.NetworkConnectionAvailable == True:
61                         SoftwareTools.lastDownloadDate = time()
62                         if SoftwareTools.list_updating is False and callback is None:
63                                 SoftwareTools.list_updating = True
64                                 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
65                         elif SoftwareTools.list_updating is False and callback is not None:
66                                 SoftwareTools.list_updating = True
67                                 self.NotifierCallback = callback
68                                 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
69                         elif SoftwareTools.list_updating is True and callback is not None:
70                                 #update info collecting already in progress
71                                 self.NotifierCallback = callback
72                 else:
73                         SoftwareTools.list_updating = False
74                         if callback is not None:
75                                 callback(False)
76                         elif self.NotifierCallback is not None:
77                                 self.NotifierCallback(False)
78
79         def ipkgCallback(self, event, param):
80                 if event == IpkgComponent.EVENT_ERROR:
81                         SoftwareTools.list_updating = False
82                         if self.NotifierCallback is not None:
83                                 self.NotifierCallback(False)
84                 elif event == IpkgComponent.EVENT_DONE:
85                         if SoftwareTools.list_updating:
86                                 self.startIpkgListAvailable()
87                 #print event, "-", param                
88                 pass
89
90         def startIpkgListAvailable(self, callback = None):
91                 if callback is not None:
92                         SoftwareTools.list_updating = True
93                 if SoftwareTools.list_updating:
94                         if not self.UpdateConsole:
95                                 self.UpdateConsole = Console()
96                         cmd = "ipkg list"
97                         self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback)
98
99         def IpkgListAvailableCB(self, result, retval, extra_args = None):
100                 (callback) = extra_args
101                 if result:
102                         if SoftwareTools.list_updating:
103                                 SoftwareTools.available_packetlist = []
104                                 for x in result.splitlines():
105                                         tokens = x.split(' - ')
106                                         name = tokens[0].strip()
107                                         if not any(name.endswith(x) for x in self.unwanted_extensions):
108                                                 l = len(tokens)
109                                                 version = l > 1 and tokens[1].strip() or ""
110                                                 descr = l > 2 and tokens[2].strip() or ""
111                                                 SoftwareTools.available_packetlist.append([name, version, descr])
112                                 if callback is None:
113                                         self.startInstallMetaPackage()
114                                 else:
115                                         if self.UpdateConsole:
116                                                 if len(self.UpdateConsole.appContainers) == 0:
117                                                                 callback(True)
118                 else:
119                         SoftwareTools.list_updating = False
120                         if self.UpdateConsole:
121                                 if len(self.UpdateConsole.appContainers) == 0:
122                                         if callback is not None:
123                                                 callback(False)
124
125         def startInstallMetaPackage(self, callback = None):
126                 if callback is not None:
127                         SoftwareTools.list_updating = True
128                 if SoftwareTools.list_updating:
129                         if not self.UpdateConsole:
130                                 self.UpdateConsole = Console()
131                         cmd = "ipkg install enigma2-meta enigma2-plugins-meta enigma2-skins-meta"
132                         self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback)
133
134         def InstallMetaPackageCB(self, result, retval, extra_args = None):
135                 (callback) = extra_args
136                 if result:
137                         self.fillPackagesIndexList()
138                         if callback is None:
139                                 self.startIpkgListInstalled()
140                         else:
141                                 if self.UpdateConsole:
142                                         if len(self.UpdateConsole.appContainers) == 0:
143                                                         callback(True)
144                 else:
145                         SoftwareTools.list_updating = False
146                         if self.UpdateConsole:
147                                 if len(self.UpdateConsole.appContainers) == 0:
148                                         if callback is not None:
149                                                 callback(False)
150
151         def startIpkgListInstalled(self, callback = None):
152                 if callback is not None:
153                         SoftwareTools.list_updating = True
154                 if SoftwareTools.list_updating:
155                         if not self.UpdateConsole:
156                                 self.UpdateConsole = Console()
157                         cmd = "ipkg list_installed"
158                         self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback)
159
160         def IpkgListInstalledCB(self, result, retval, extra_args = None):
161                 (callback) = extra_args
162                 if result:
163                         SoftwareTools.installed_packetlist = {}
164                         for x in result.splitlines():
165                                 tokens = x.split(' - ')
166                                 name = tokens[0].strip()
167                                 if not any(name.endswith(x) for x in self.unwanted_extensions):
168                                         l = len(tokens)
169                                         version = l > 1 and tokens[1].strip() or ""
170                                         SoftwareTools.installed_packetlist[name] = version
171                         for package in self.packagesIndexlist[:]:
172                                 if not self.verifyPrerequisites(package[0]["prerequisites"]):
173                                         self.packagesIndexlist.remove(package)
174                         for package in self.packagesIndexlist[:]:
175                                 attributes = package[0]["attributes"]
176                                 if attributes.has_key("packagetype"):
177                                         if attributes["packagetype"] == "internal":
178                                                 self.packagesIndexlist.remove(package)
179                         if callback is None:
180                                 self.countUpdates()
181                         else:
182                                 if self.UpdateConsole:
183                                         if len(self.UpdateConsole.appContainers) == 0:
184                                                         callback(True)
185                 else:
186                         SoftwareTools.list_updating = False
187                         if self.UpdateConsole:
188                                 if len(self.UpdateConsole.appContainers) == 0:
189                                         if callback is not None:
190                                                 callback(False)
191
192         def countUpdates(self, callback = None):
193                 SoftwareTools.available_updates = 0
194                 SoftwareTools.available_updatelist  = []
195                 for package in self.packagesIndexlist[:]:
196                         attributes = package[0]["attributes"]
197                         packagename = attributes["packagename"]
198                         for x in SoftwareTools.available_packetlist:
199                                 if x[0] == packagename:
200                                         if SoftwareTools.installed_packetlist.has_key(packagename):
201                                                 if SoftwareTools.installed_packetlist[packagename] != x[1]:
202                                                         SoftwareTools.available_updates +=1
203                                                         SoftwareTools.available_updatelist.append([packagename])
204
205                 SoftwareTools.list_updating = False
206                 if self.UpdateConsole:
207                         if len(self.UpdateConsole.appContainers) == 0:
208                                 if callback is not None:
209                                         callback(True)
210                                         callback = None
211                                 elif self.NotifierCallback is not None:
212                                         self.NotifierCallback(True)
213                                         self.NotifierCallback = None
214
215         def startIpkgUpdate(self, callback = None):
216                 if not self.Console:
217                         self.Console = Console()
218                 cmd = "ipkg update"
219                 self.Console.ePopen(cmd, self.IpkgUpdateCB, callback)
220
221         def IpkgUpdateCB(self, result, retval, extra_args = None):
222                 (callback) = extra_args
223                 if result:
224                         if self.Console:
225                                 if len(self.Console.appContainers) == 0:
226                                         if callback is not None:
227                                                 callback(True)
228                                                 callback = None
229
230         def cleanupSoftwareTools(self):
231                 if self.NotifierCallback is not None:
232                         self.NotifierCallback = None
233                 self.ipkg.stop()
234                 if self.Console is not None:
235                         if len(self.Console.appContainers):
236                                 for name in self.Console.appContainers.keys():
237                                         self.Console.kill(name)
238                 if self.UpdateConsole is not None:
239                         if len(self.UpdateConsole.appContainers):
240                                 for name in self.UpdateConsole.appContainers.keys():
241                                         self.UpdateConsole.kill(name)
242
243         def verifyPrerequisites(self, prerequisites):
244                 if prerequisites.has_key("hardware"):
245                         hardware_found = False
246                         for hardware in prerequisites["hardware"]:
247                                 if hardware == self.hardware_info.device_name:
248                                         hardware_found = True
249                         if not hardware_found:
250                                 return False
251                 return True
252
253 iSoftwareTools = SoftwareTools()