Softwaremanager: *add missing define. refs #503
[enigma2.git] / 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.hardware_info = HardwareInfo()
34                 self.list = List([])
35                 self.NotifierCallback = None
36                 self.Console = Console()
37                 self.UpdateConsole = Console()
38                 self.cmdList = []
39                 self.unwanted_extensions = ('-dbg', '-dev', '-doc')
40                 self.ipkg = IpkgComponent()
41                 self.ipkg.addCallback(self.ipkgCallback)                
42
43         def statusCallback(self, status, progress):
44                 pass            
45
46         def startSoftwareTools(self, callback = None):
47                 if callback is not None:
48                         self.NotifierCallback = callback
49                 iNetwork.checkNetworkState(self.checkNetworkCB)
50                 
51         def checkNetworkCB(self,data):
52                 if data is not None:
53                         if data <= 2:
54                                 SoftwareTools.NetworkConnectionAvailable = True
55                                 self.getUpdates()
56                         else:
57                                 SoftwareTools.NetworkConnectionAvailable = False
58                                 self.getUpdates()
59
60         def getUpdates(self, callback = None):
61                 if SoftwareTools.NetworkConnectionAvailable == True:
62                         SoftwareTools.lastDownloadDate = time()
63                         if SoftwareTools.list_updating is False and callback is None:
64                                 SoftwareTools.list_updating = True
65                                 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
66                         elif SoftwareTools.list_updating is False and callback is not None:
67                                 SoftwareTools.list_updating = True
68                                 self.NotifierCallback = callback
69                                 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
70                         elif SoftwareTools.list_updating is True and callback is not None:
71                                 #update info collecting already in progress
72                                 self.NotifierCallback = callback
73                 else:
74                         SoftwareTools.list_updating = False
75                         if callback is not None:
76                                 callback(False)
77                         elif self.NotifierCallback is not None:
78                                 self.NotifierCallback(False)
79
80         def ipkgCallback(self, event, param):
81                 if event == IpkgComponent.EVENT_ERROR:
82                         SoftwareTools.list_updating = False
83                         if self.NotifierCallback is not None:
84                                 self.NotifierCallback(False)
85                 elif event == IpkgComponent.EVENT_DONE:
86                         if SoftwareTools.list_updating:
87                                 self.startIpkgListAvailable()
88                 #print event, "-", param                
89                 pass
90
91         def startIpkgListAvailable(self, callback = None):
92                 if callback is not None:
93                         SoftwareTools.list_updating = True
94                 if SoftwareTools.list_updating:
95                         if not self.UpdateConsole:
96                                 self.UpdateConsole = Console()
97                         cmd = "ipkg list"
98                         self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback)
99
100         def IpkgListAvailableCB(self, result, retval, extra_args = None):
101                 (callback) = extra_args
102                 if result:
103                         if SoftwareTools.list_updating:
104                                 SoftwareTools.available_packetlist = []
105                                 for x in result.splitlines():
106                                         tokens = x.split(' - ')
107                                         name = tokens[0].strip()
108                                         if not any(name.endswith(x) for x in self.unwanted_extensions):
109                                                 l = len(tokens)
110                                                 version = l > 1 and tokens[1].strip() or ""
111                                                 descr = l > 2 and tokens[2].strip() or ""
112                                                 SoftwareTools.available_packetlist.append([name, version, descr])
113                                 if callback is None:
114                                         self.startInstallMetaPackage()
115                                 else:
116                                         if self.UpdateConsole:
117                                                 if len(self.UpdateConsole.appContainers) == 0:
118                                                                 callback(True)
119                 else:
120                         SoftwareTools.list_updating = False
121                         if self.UpdateConsole:
122                                 if len(self.UpdateConsole.appContainers) == 0:
123                                         if callback is not None:
124                                                 callback(False)
125
126         def startInstallMetaPackage(self, callback = None):
127                 if callback is not None:
128                         SoftwareTools.list_updating = True
129                 if SoftwareTools.list_updating:
130                         if not self.UpdateConsole:
131                                 self.UpdateConsole = Console()
132                         cmd = "ipkg install enigma2-meta enigma2-plugins-meta enigma2-skins-meta"
133                         self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback)
134
135         def InstallMetaPackageCB(self, result, retval, extra_args = None):
136                 (callback) = extra_args
137                 if result:
138                         self.fillPackagesIndexList()
139                         if callback is None:
140                                 self.startIpkgListInstalled()
141                         else:
142                                 if self.UpdateConsole:
143                                         if len(self.UpdateConsole.appContainers) == 0:
144                                                         callback(True)
145                 else:
146                         SoftwareTools.list_updating = False
147                         if self.UpdateConsole:
148                                 if len(self.UpdateConsole.appContainers) == 0:
149                                         if callback is not None:
150                                                 callback(False)
151
152         def startIpkgListInstalled(self, callback = None):
153                 if callback is not None:
154                         SoftwareTools.list_updating = True
155                 if SoftwareTools.list_updating:
156                         if not self.UpdateConsole:
157                                 self.UpdateConsole = Console()
158                         cmd = "ipkg list_installed"
159                         self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback)
160
161         def IpkgListInstalledCB(self, result, retval, extra_args = None):
162                 (callback) = extra_args
163                 if result:
164                         SoftwareTools.installed_packetlist = {}
165                         for x in result.splitlines():
166                                 tokens = x.split(' - ')
167                                 name = tokens[0].strip()
168                                 if not any(name.endswith(x) for x in self.unwanted_extensions):
169                                         l = len(tokens)
170                                         version = l > 1 and tokens[1].strip() or ""
171                                         SoftwareTools.installed_packetlist[name] = version
172                         for package in self.packagesIndexlist[:]:
173                                 if not self.verifyPrerequisites(package[0]["prerequisites"]):
174                                         self.packagesIndexlist.remove(package)
175                         for package in self.packagesIndexlist[:]:
176                                 attributes = package[0]["attributes"]
177                                 if attributes.has_key("packagetype"):
178                                         if attributes["packagetype"] == "internal":
179                                                 self.packagesIndexlist.remove(package)
180                         if callback is None:
181                                 self.countUpdates()
182                         else:
183                                 if self.UpdateConsole:
184                                         if len(self.UpdateConsole.appContainers) == 0:
185                                                         callback(True)
186                 else:
187                         SoftwareTools.list_updating = False
188                         if self.UpdateConsole:
189                                 if len(self.UpdateConsole.appContainers) == 0:
190                                         if callback is not None:
191                                                 callback(False)
192
193         def countUpdates(self, callback = None):
194                 SoftwareTools.available_updates = 0
195                 SoftwareTools.available_updatelist  = []
196                 for package in self.packagesIndexlist[:]:
197                         attributes = package[0]["attributes"]
198                         packagename = attributes["packagename"]
199                         for x in SoftwareTools.available_packetlist:
200                                 if x[0] == packagename:
201                                         if SoftwareTools.installed_packetlist.has_key(packagename):
202                                                 if SoftwareTools.installed_packetlist[packagename] != x[1]:
203                                                         SoftwareTools.available_updates +=1
204                                                         SoftwareTools.available_updatelist.append([packagename])
205
206                 SoftwareTools.list_updating = False
207                 if self.UpdateConsole:
208                         if len(self.UpdateConsole.appContainers) == 0:
209                                 if callback is not None:
210                                         callback(True)
211                                         callback = None
212                                 elif self.NotifierCallback is not None:
213                                         self.NotifierCallback(True)
214                                         self.NotifierCallback = None
215
216         def startIpkgUpdate(self, callback = None):
217                 if not self.Console:
218                         self.Console = Console()
219                 cmd = "ipkg update"
220                 self.Console.ePopen(cmd, self.IpkgUpdateCB, callback)
221
222         def IpkgUpdateCB(self, result, retval, extra_args = None):
223                 (callback) = extra_args
224                 if result:
225                         if self.Console:
226                                 if len(self.Console.appContainers) == 0:
227                                         if callback is not None:
228                                                 callback(True)
229                                                 callback = None
230
231         def cleanupSoftwareTools(self):
232                 if self.NotifierCallback is not None:
233                         self.NotifierCallback = None
234                 self.ipkg.stop()
235                 if self.Console is not None:
236                         if len(self.Console.appContainers):
237                                 for name in self.Console.appContainers.keys():
238                                         self.Console.kill(name)
239                 if self.UpdateConsole is not None:
240                         if len(self.UpdateConsole.appContainers):
241                                 for name in self.UpdateConsole.appContainers.keys():
242                                         self.UpdateConsole.kill(name)
243
244         def verifyPrerequisites(self, prerequisites):
245                 if prerequisites.has_key("hardware"):
246                         hardware_found = False
247                         for hardware in prerequisites["hardware"]:
248                                 if hardware == self.hardware_info.device_name:
249                                         hardware_found = True
250                         if not hardware_found:
251                                 return False
252                 return True
253
254 iSoftwareTools = SoftwareTools()