add IpkgInstaller Media Scanner plugin
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / SoftwareUpdate / plugin.py
1 from Components.ActionMap import ActionMap, NumberActionMap
2 from Components.GUIComponent import GUIComponent
3 from Components.Input import Input
4 from Components.Ipkg import IpkgComponent
5 from Components.Label import Label
6 from Components.MenuList import MenuList
7 from Components.ScrollLabel import ScrollLabel
8 from Components.Slider import Slider
9 from Plugins.Plugin import PluginDescriptor
10 from Screens.Console import Console
11 from Screens.ImageWizard import ImageWizard
12 from Screens.MessageBox import MessageBox
13 from Screens.MessageBox import MessageBox
14 from Screens.Screen import Screen
15 from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont
16 from os import popen
17
18
19 class UpdatePluginMenu(Screen):
20         skin = """
21                 <screen position="200,100" size="300,250" title="Update..." >
22                         <widget name="menu" position="10,10" size="290,175" scrollbarMode="showOnDemand" />
23                 </screen>"""
24                 
25         def __init__(self, session, args = 0):
26                 self.skin = UpdatePluginMenu.skin
27                 Screen.__init__(self, session)
28                 
29                 self.menu = args
30                 
31                 list = []
32                 if self.menu == 0:
33                         list.append((_("Image-Upgrade"), "image"))
34                         list.append((_("Online-Upgrade"), "upgrade"))
35                         list.append((_("Advanced"), "advanced"))
36                 elif self.menu == 1:
37                         list.append((_("Choose source"), "source"))
38                         list.append((_("Packet management"), "ipkg"))
39                         list.append((_("Settings"), "setup"))
40                 
41                 self["menu"] = MenuList(list)
42                                 
43                 self["actions"] = ActionMap(["WizardActions", "DirectionActions"], 
44                 {
45                         "ok": self.go,
46                         "back": self.close,
47                 }, -1)
48                 
49         def go(self):
50                 if self.menu == 0:
51                         if (self["menu"].l.getCurrentSelection()[1] == "image"):
52                                 self.session.open(ImageWizard)
53                         if (self["menu"].l.getCurrentSelection()[1] == "upgrade"):
54                                 self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?\nAfter pressing OK, please wait!"))
55                         if (self["menu"].l.getCurrentSelection()[1] == "advanced"):
56                                 self.session.open(UpdatePluginMenu, 1)
57                 if self.menu == 1:
58                         if (self["menu"].l.getCurrentSelection()[1] == "source"):
59                                 self.session.open(IPKGSource)
60                         elif (self["menu"].l.getCurrentSelection()[1] == "ipkg"):
61                                 self.session.open(Ipkg)
62                         elif (self["menu"].l.getCurrentSelection()[1] == "setup"):
63                                 self.session.open(MessageBox, _("Function not yet implemented"), MessageBox.TYPE_ERROR)
64         
65         def runUpgrade(self, result):
66                 if result:
67                         self.session.open(Console, title = "Upgrade running...", cmdlist = ["ipkg update", "ipkg upgrade -force-defaults -force-overwrite"], finishedCallback = self.runFinished)
68
69         def runFinished(self):
70                 self.session.openWithCallback(self.reboot, MessageBox, _("Upgrade finished. Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
71                 
72         def reboot(self, result):
73                 if result is None:
74                         return
75                 if result:
76                         quitMainloop(3)
77
78 class IPKGSource(Screen):
79         skin = """
80                 <screen position="100,100" size="550,60" title="IPKG source" >
81                         <widget name="text" position="0,0" size="550,25" font="Regular;20" />
82                 </screen>"""
83                 
84         def __init__(self, session, args = None):
85                 self.skin = IPKGSource.skin
86                 Screen.__init__(self, session)
87                 
88                 fp = file('/etc/ipkg/official-feed.conf', 'r')
89                 sources = fp.readlines()
90                 fp.close()
91                 
92                 self["text"] = Input(sources[0], maxSize=False, type=Input.TEXT)
93                                 
94                 self["actions"] = NumberActionMap(["WizardActions", "InputActions"], 
95                 {
96                         "ok": self.go,
97                         "back": self.close,
98                         "left": self.keyLeft,
99                         "right": self.keyRight,
100                         "1": self.keyNumberGlobal,
101                         "2": self.keyNumberGlobal,
102                         "3": self.keyNumberGlobal,
103                         "4": self.keyNumberGlobal,
104                         "5": self.keyNumberGlobal,
105                         "6": self.keyNumberGlobal,
106                         "7": self.keyNumberGlobal,
107                         "8": self.keyNumberGlobal,
108                         "9": self.keyNumberGlobal,
109                         "0": self.keyNumberGlobal
110                 }, -1)
111                 
112         def go(self):
113                 fp = file('/etc/ipkg/official-feed.conf', 'w')
114                 fp.write(self["text"].getText())
115                 fp.close()
116                 self.close()
117                 
118         def keyLeft(self):
119                 self["text"].left()
120         
121         def keyRight(self):
122                 self["text"].right()
123         
124         def keyNumberGlobal(self, number):
125                 print "pressed", number
126                 self["text"].number(number)
127
128 def PacketEntryComponent(packet):
129         res = [ packet ]
130         
131         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0,250, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[0]))
132         res.append((eListboxPythonMultiContent.TYPE_TEXT, 250, 0, 200, 30, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[1]))
133         res.append((eListboxPythonMultiContent.TYPE_TEXT, 450, 0, 100, 30, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, packet[2]))
134         return res
135
136 class PacketList(GUIComponent):
137         def __init__(self, list):
138                 GUIComponent.__init__(self)
139                 self.l = eListboxPythonMultiContent()
140                 self.l.setList(list)
141                 self.l.setFont(0, gFont("Regular", 20))
142                 self.l.setFont(1, gFont("Regular", 18))
143         
144         def getCurrent(self):
145                 return self.l.getCurrentSelection()
146         
147         def GUIcreate(self, parent):
148                 self.instance = eListbox(parent)
149                 self.instance.setContent(self.l)
150                 self.instance.setItemHeight(30)
151         
152         def GUIdelete(self):
153                 self.instance.setContent(None)
154                 self.instance = None
155
156         def invalidate(self):
157                 self.l.invalidate()
158
159 class Ipkg2(Screen):
160         skin = """
161                 <screen position="100,100" size="550,400" title="IPKG upgrade..." >
162                         <widget name="list" position="0,0" size="550,400" scrollbarMode="showOnDemand" />
163                 </screen>"""
164                 
165         def __init__(self, session, args = None):
166                 self.skin = Ipkg.skin
167                 Screen.__init__(self, session)
168         
169                 list = []
170                 self.list = list
171                 self.fillPacketList()
172
173                 self["list"] = PacketList(self.list)
174                                 
175                 self["actions"] = ActionMap(["WizardActions"], 
176                 {
177                         "ok": self.close,
178                         "back": self.close
179                 }, -1)
180                 
181
182         def fillPacketList(self):
183                 lines = popen("ipkg list", "r").readlines()
184                 packetlist = []
185                 for x in lines:
186                         split = x.split(' - ')
187                         packetlist.append([split[0].strip(), split[1].strip()])
188                 
189                 lines = popen("ipkg list_installed", "r").readlines()
190                 
191                 installedlist = {}
192                 for x in lines:
193                         split = x.split(' - ')
194                         installedlist[split[0].strip()] = split[1].strip()
195                 
196                 for x in packetlist:
197                         status = ""
198                         if installedlist.has_key(x[0]):
199                                 if installedlist[x[0]] == x[1]:
200                                         status = "installed"
201                                 else:
202                                         status = "upgradable"
203                         self.list.append(PacketEntryComponent([x[0], x[1], status]))
204                 
205         def go(self):
206                 if self.update:
207                         self.session.openWithCallback(self.doUpdate, MessageBox, _("Do you want to update your Dreambox?\nAfter pressing OK, please wait!"))            
208                 else:
209                         self.close()
210         
211         def doUpdateDelay(self):
212                 lines = popen("ipkg update && ipkg upgrade", "r").readlines()
213                 string = ""
214                 for x in lines:
215                         string += x
216                 self["text"].setText(_("Updating finished. Here is the result:") + "\n\n" + string)
217                 self.update = False
218                         
219         
220         def doUpdate(self, val = False):
221                 if val == True:
222                         self["text"].setText(_("Updating... Please wait... This can take some minutes..."))
223                         self.delayTimer.start(0, 1)
224                 else:
225                         self.close()
226                         
227 class UpdatePlugin(Screen):
228         skin = """
229                 <screen position="100,100" size="550,200" title="Software Update..." >
230                         <widget name="activityslider" position="0,0" size="550,5"  />
231                         <widget name="slider" position="0,100" size="550,30"  />
232                         <widget name="package" position="10,30" size="420,20" font="Regular;18"/>
233                         <widget name="status" position="10,60" size="420,45" font="Regular;18"/>
234                 </screen>"""
235                 
236         def __init__(self, session, args = None):
237                 self.skin = UpdatePlugin.skin
238                 Screen.__init__(self, session)
239                 
240                 self.sliderPackages = { "dreambox-dvb-modules": 1, "enigma2": 2, "tuxbox-image-info": 3 }
241                 
242                 self.slider = Slider(0, 4)
243                 self["slider"] = self.slider
244                 self.activityslider = Slider(0, 100)
245                 self["activityslider"] = self.activityslider
246                 self.status = Label(_("Upgrading Dreambox... Please wait"))
247                 self["status"] = self.status
248                 self.package = Label()
249                 self["package"] = self.package
250                 
251                 self.packages = 0
252                 self.error = 0
253                 
254                 self.activity = 0
255                 self.activityTimer = eTimer()
256                 self.activityTimer.timeout.get().append(self.doActivityTimer)
257                 self.activityTimer.start(100, False)
258                                 
259                 self.ipkg = IpkgComponent()
260                 self.ipkg.addCallback(self.ipkgCallback)
261                 
262                 self.updating = True
263                 self.package.setText(_("Package list update"))
264                 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
265                         
266                 self["actions"] = ActionMap(["WizardActions"], 
267                 {
268                         "ok": self.exit,
269                         "back": self.exit
270                 }, -1)
271                 
272         def doActivityTimer(self):
273                 self.activity += 1
274                 if self.activity == 100:
275                         self.activity = 0
276                 self.activityslider.setValue(self.activity)
277                 
278         def ipkgCallback(self, event, param):
279                 if event == IpkgComponent.EVENT_DOWNLOAD:
280                         self.status.setText(_("Downloading"))
281                 elif event == IpkgComponent.EVENT_UPGRADE:
282                         if self.sliderPackages.has_key(param):
283                                 self.slider.setValue(self.sliderPackages[param])
284                         self.package.setText(param)
285                         self.status.setText(_("Upgrading"))
286                         self.packages += 1
287                 elif event == IpkgComponent.EVENT_INSTALL:
288                         self.package.setText(param)
289                         self.status.setText(_("Installing"))
290                         self.packages += 1
291                 elif event == IpkgComponent.EVENT_CONFIGURING:
292                         self.package.setText(param)
293                         self.status.setText(_("Configuring"))
294                 elif event == IpkgComponent.EVENT_ERROR:
295                         self.error += 1
296                 elif event == IpkgComponent.EVENT_DONE:
297                         if self.updating:
298                                 self.updating = False
299                                 self.ipkg.startCmd(Ipkg.CMD_UPGRADE, args = {'test_only': False})
300                         elif self.error == 0:
301                                 self.slider.setValue(4)
302                                 
303                                 self.activityTimer.stop()
304                                 self.activityslider.setValue(0)
305                                 
306                                 self.package.setText("")
307                                 self.status.setText(_("Done - Installed or upgraded %d packages") % self.packages)
308                         else:
309                                 self.activityTimer.stop()
310                                 self.activityslider.setValue(0)
311                                 error = _("your dreambox might be unusable now. Please consult the manual for further assistance before rebooting your dreambox.")
312                                 if self.packages == 0:
313                                         error = _("No packages were upgraded yet. So you can check your network and try again.")
314                                 if self.updating:
315                                         error = _("Your dreambox isn't connected to the internet properly. Please check it and try again.")
316                                 self.status.setText(_("Error") +  " - " + error)
317                 #print event, "-", param
318                 pass
319         
320         def exit(self):
321                 if not self.ipkg.isRunning():
322                         if self.packages != 0 and self.error == 0:
323                                 self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished. Do you want to reboot your Dreambox?"))
324                         else:
325                                 self.close()
326                         
327         def exitAnswer(self, result):
328                 if result is not None and result:
329                         quitMainloop(2)
330                 self.close()
331
332 def UpgradeMain(session, **kwargs):
333         session.open(UpdatePlugin)
334
335 def Plugins(**kwargs):
336         return PluginDescriptor(name="Softwareupdate", description=_("Updates your receiver's software"), icon="update.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=UpgradeMain)