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