Merge remote-tracking branch 'remotes/origin/master' into webif_js_rewrite
[enigma2-plugins.git] / unwetterinfo / src / plugin.py
1 # -*- coding: utf-8 -*-
2 #
3 # Wetter Infos von
4 # www.unwetterzentrale.de und www.uwz.at
5 #
6 # Author: barabas
7 #
8
9 import xml.sax.saxutils as util
10
11 from Plugins.Plugin import PluginDescriptor
12 from twisted.web.client import getPage
13 from twisted.internet import reactor
14 from Screens.Screen import Screen
15 from Screens.Console import Console
16 from Components.ActionMap import ActionMap
17 from Components.Label import Label
18 from Components.MenuList import MenuList
19 from Components.AVSwitch import AVSwitch
20 from Components.Pixmap import Pixmap
21 from enigma import eTimer, ePicLoad
22 from re import sub, search, findall
23 from os import unlink
24
25 ###############################################################################
26
27 class PictureView(Screen):
28         skin = """
29                 <screen position="center,center" size="720,576" flags="wfNoBorder" title="UWZ" >
30                         <eLabel position="0,0" zPosition="1" size="720,576" backgroundColor="black" />
31                         <ePixmap position="655,540" zPosition="2" size="36,20" pixmap="skin_default/buttons/key_info.png" alphatest="on" />
32                         <widget name="picture" position="80,10" zPosition="2" size="550,550" />
33                 </screen>"""
34
35         def __init__(self, session):
36                 Screen.__init__(self, session)
37
38                 self.picfile = "/tmp/uwz.png"
39
40                 self["picture"] = Pixmap()
41
42                 self["actions"] = ActionMap(["OkCancelActions","MovieSelectionActions"],
43                 {
44                         "cancel": self.exit,
45                         "ok": self.exit,
46                         "showEventInfo": self.HelpView,
47                 }, -1)
48
49                 self.picload = ePicLoad()
50                 sc = AVSwitch().getFramebufferScale()
51                 self.picload.setPara((550, 550, sc[0], sc[1], 0, 0, '#ff000000'))
52                 self.picload.PictureData.get().append(self.gotPic)
53                 self.onLayoutFinish.append(self.getPic)
54
55         def getPic(self):
56                 self.picload.startDecode(self.picfile)
57
58         def gotPic(self, picInfo = None):
59                 ptr = self.picload.getData()
60                 if ptr:
61                         self["picture"].instance.setPixmap(ptr.__deref__())
62
63         def HelpView(self):
64                 self.session.openWithCallback(self.getPic, HelpPictureView)
65
66         def exit(self):
67                 self.close()
68
69 class HelpPictureView(Screen):
70         skin = """
71                 <screen position="center,center" size="700,320" title="Warnstufen" >
72                         <eLabel position="0,0" zPosition="1" size="700,320" backgroundColor="black" />
73                         <ePixmap position="80,270" zPosition="2" size="45,45" pixmap="skin_default/vkey_left.png" alphatest="on" />
74                         <ePixmap position="328,270" zPosition="2" size="45,45" pixmap="skin_default/vkey_esc.png" alphatest="on" />
75                         <ePixmap position="575,270" zPosition="2" size="45,45" pixmap="skin_default/vkey_right.png" alphatest="on" />
76                         <widget name="picture" position="5,20" zPosition="2" size="690,225" />
77                 </screen>"""
78
79         def __init__(self, session):
80                 Screen.__init__(self, session)
81
82                 self["picture"] = Pixmap()
83
84                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions"],
85                 {
86                         "cancel": self.exit,
87                         "ok": self.exit,
88                         "left": self.prevPic,
89                         "right": self.nextPic
90                 }, -1)
91
92                 self.list = (
93                         pluginpath + "/W_gruen.gif",
94                         pluginpath + "/W_gelb.gif",
95                         pluginpath + "/W_orange.gif",
96                         pluginpath + "/W_rot.gif",
97                         pluginpath + "/W_violett.gif"
98                 )
99                 self.index = 0
100
101                 self.picload = ePicLoad()
102                 sc = AVSwitch().getFramebufferScale()
103                 self.picload.setPara((690, 225, sc[0], sc[1], 0, 0, '#ff000000'))
104                 self.picload.PictureData.get().append(self.gotPic)
105
106                 self.onShown.append(self.getPic)
107
108         def getPic(self):
109                 self.picload.startDecode(self.list[self.index])
110
111         def gotPic(self, picInfo = None):
112                 ptr = self.picload.getData()
113                 if ptr:
114                         self["picture"].instance.setPixmap(ptr.__deref__())
115
116         def nextPic(self):
117                 self.index += 1
118                 if self.index > 4:
119                         self.index = 0
120                 self.getPic()
121
122         def prevPic(self):
123                 self.index -= 1
124                 if self.index < 0:
125                         self.index = 4
126                 self.getPic()
127
128         def exit(self):
129                 self.close()
130
131 class UnwetterMain(Screen):
132         skin = """
133                 <screen position="center,center" size="530,430" title="Unwetterzentrale" >
134                         <widget name="hmenu" position="5,0" zPosition="1" size="530,220" scrollbarMode="showOnDemand" />
135                         <widget name="thumbnail" position="185,250" zPosition="2" size="140,150" />
136                         <widget name="thumbland" position="435,390" zPosition="2" size="90,40" />
137                         <ePixmap position="20,380" zPosition="2" size="36,20" pixmap="skin_default/buttons/key_menu.png" alphatest="on" />
138                         <widget name="statuslabel" position="5,410" zPosition="2" size="530,20" font="Regular;16" halign="left"/>
139                 </screen>"""
140
141         def __init__(self, session):
142                 Screen.__init__(self, session)
143
144                 self["statuslabel"] = Label()
145                 self["thumbland"] = Pixmap()
146                 self["thumbnail"] = Pixmap()
147                 self["hmenu"] = MenuList([])
148                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"],
149                 {
150                         "ok":   self.ok,
151                         "up": self.up,
152                         "right": self.rightDown,
153                         "left": self.leftUp,
154                         "down": self.down,
155                         "cancel": self.exit,
156                         "contextMenu": self.switchDeA,
157                 }, -1)
158
159                 self.loadinginprogress = False
160                 self.picfile = "/tmp/uwz.png"
161                 self.picweatherfile = pluginpath + "/wetterreport.jpg"
162                 self.reportfile = "/tmp/uwz.report"
163
164                 self.picload = ePicLoad()
165
166 #               self.onLayoutFinish.append(self.go)
167
168                 self.ThumbTimer = eTimer()
169                 self.ThumbTimer.callback.append(self.showThumb)
170
171                 self.switchDeA(load=True)
172
173         def hauptmenu(self,output):
174                 self.loadinginprogress = False
175                 trans = { '&szlig;' : '' , '&auml;' : '' , '&ouml;' : '' , '&uuml;' : '' , '&Auml;' : '', '&Ouml;' : '' , '&Uuml;' : ''}
176                 output= util.unescape(output,trans)
177
178                 if self.land == "de":
179                         startpos = output.find('<div id="navigation">')
180                         endpos = output.find('<a class="section-link" title="FAQ"', startpos)
181                         bereich = output[startpos:endpos]
182                         a = findall(r'href=(?P<text>.*?)</a>',bereich)
183                         for x in a:
184                                 x = x.replace('">',"#").replace('"',"").split('#')
185                                 if not len(x) > 1:
186                                         break
187                                 if x[0] == "index.html":
188                                         continue
189                                 name = x[1]
190                                 link = self.baseurl + x[0]
191                                 self.menueintrag.append(name)
192                                 self.link.append(link)
193                 else:
194                         self.menueintrag.append("Lagebericht")
195                         self.link.append(self.weatherreporturl)
196
197                         startpos = output.find('<div id="select_dropdownprovinces"')
198                         endpos = output.find('</div>', startpos)
199                         bereich = output[startpos:endpos]
200                         a = findall(r'<a href=(?P<text>.*?)</a>',bereich)
201                         for x in a[1:13]:
202                                 x = x.replace('">',"#").replace('"',"")
203                                 if x != '#&nbsp;':
204                                                 x = x.split('#')
205                                                 if not len(x) > 1:
206                                                         break
207                                                 name = x[1]
208                                                 link = x[0]
209                                                 self.menueintrag.append(name)
210                                                 self.link.append(link)
211
212                 self["statuslabel"].setText("")
213                 self["hmenu"].l.setList(self.menueintrag)
214                 self["hmenu"].instance.moveSelectionTo(0)
215                 self.showThumbLand()
216
217         def ok(self):
218                 self.go()
219                 c = self["hmenu"].getCurrent()
220                 if c is not None:
221                         x = self.menueintrag.index(c)
222                         if x != 0:
223                                 self.session.open(PictureView)
224                         else:
225                                 self.downloadWeatherReport()
226
227         def go(self):
228                 c = self["hmenu"].getCurrent()
229                 if c is not None:
230                         x = self.menueintrag.index(c)
231                         # Wetterlagebericht ist Index 0
232                         if x != 0:
233                                 url = self.link[x]
234                                 self["statuslabel"].setText("Loading Data")
235                                 self.downloadPicUrl(url)
236                         self.ThumbTimer.start(1500, True)
237
238         def up(self):
239                 self["hmenu"].up()
240                 self.go()
241
242         def down(self):
243                 self["hmenu"].down()
244                 self.go()
245
246         def leftUp(self):
247                 self["hmenu"].pageUp()
248                 self.go()
249
250         def rightDown(self):
251                 self["hmenu"].pageDown()
252                 self.go()
253
254         def showThumbLand(self):
255                 picture = ""
256                 if self.land == "de":
257                         picture = pluginpath + "/uwz.png"
258                 else:
259                         picture = pluginpath + "/uwzat.png"
260                 picload = self.picload
261                 sc = AVSwitch().getFramebufferScale()
262                 picload.setPara((90, 40, sc[0], sc[1], 0, 0, '#ff000000'))
263                 l = picload.PictureData.get()
264                 del l[:]
265                 l.append(self.gotThumbLand)
266                 picload.startDecode(picture)
267
268         def gotThumbLand(self, picInfo = None):
269                 ptr = self.picload.getData()
270                 if ptr:
271                         self["thumbland"].instance.setPixmap(ptr.__deref__())
272
273         def showThumb(self):
274                 picture = ""
275                 if self.land == "de":
276                         width = 142
277                         height = 150
278                 else:
279                         width = 142
280                         height = 135
281                 c = self["hmenu"].getCurrent()
282                 if c is not None:
283                         x = self.menueintrag.index(c)
284                         if x != 0:
285                                 picture = self.picfile
286                         else:
287                                 picture = self.picweatherfile
288                                 height = 150
289
290                         picload = self.picload
291                         sc = AVSwitch().getFramebufferScale()
292                         picload.setPara((width, height, sc[0], sc[1], 0, 0, '#ff000000'))
293                         l = picload.PictureData.get()
294                         del l[:]
295                         l.append(self.gotThumb)
296                         picload.startDecode(picture)
297
298         def gotThumb(self, picInfo = None):
299                 ptr = self.picload.getData()
300                 if ptr:
301                         self["statuslabel"].setText("")
302                         self["thumbnail"].show()
303                         self["thumbnail"].instance.setPixmap(ptr.__deref__())
304                 else:
305                         self["thumbnail"].hide()
306
307         def getPicUrl(self,output):
308                 self.loadinginprogress = False
309                 if self.land == "de":
310                         startpos = output.find('<!-- Anfang msg_Box Content -->')
311                         endpos = output.find('<!-- Ende msg_Box Content -->', startpos)
312                         bereich = output[startpos:endpos]
313                         picurl = search(r'<img src="(?P<text>.*?)" width=',bereich)
314                         picurl = self.baseurl + picurl.group(1)
315                 else:
316                         picurl = search(r'<img class="map mapper" src="(?P<url>.*?)" lang=', output)
317                         picurl = self.baseurl + picurl.group(1).replace('&amp;','&')
318                 self.downloadPic(picurl)
319
320         def getPic(self,output):
321                 self.loadinginprogress = False
322                 f = open(self.picfile, "wb")
323                 f.write(output)
324                 f.close()
325
326         def getWeatherReport(self,output):
327                 self.loadinginprogress = False
328                 trans = { '&szlig;' : '' , '&auml;' : '' , '&ouml;' : '' , '&uuml;' : '' , '&Auml;' : '', '&Ouml;' : '' , '&Uuml;' : ''}
329                 output= util.unescape(output,trans)
330                 if self.land == "de":
331                         startpos = output.find('<!-- Anfang msg_Box Content -->')
332                         endpos = output.find('<!-- Ende msg_Box Content -->')
333                         bereich = output[startpos:endpos]
334                         bereich = bereich.replace('<strong>', '\n')
335                 else:
336                         startpos = output.find('<div class="content"')
337                         endpos = output.find('</div>', startpos)
338                         bereich = output[startpos:endpos]
339
340                 bereich = sub('<br\s*/?>',"\n",bereich)
341                 bereich = sub('<[^>]*>',"",bereich)
342                 bereich = sub('Fronten- und Isobarenkarte.*',"",bereich)
343                 bereich = bereich.strip()
344                 bereich = sub("\n[\s\n]+", "\n\n", bereich)
345
346                 f = open(self.reportfile, "w")
347                 f.write("%s" % bereich)
348                 f.close()
349                 self.session.open(Console,_("Warnlagebericht"),["cat %s" % self.reportfile])
350
351         def downloadError(self,output):
352                 self.loadinginprogress = False
353                 self["statuslabel"].setText("Fehler beim Download")
354
355         def downloadMenu(self):
356                 self.loadinginprogress = True
357                 getPage(self.menuurl).addCallback(self.hauptmenu).addErrback(self.downloadError)
358
359         def downloadPicUrl(self,url):
360                 self.loadinginprogress = True
361                 getPage(url).addCallback(self.getPicUrl).addErrback(self.downloadError)
362
363         def downloadPic(self,picurl):
364                 headers = {}
365                 self.loadinginprogress = True
366 #               self["statuslabel"].setText("Lade Bild: %s" % picurl)
367                 if self.land == "a":
368                         c = self["hmenu"].getCurrent()
369                         x = self.menueintrag.index(c)
370                         headers["Referer"] = self.link[x]
371                 getPage(picurl, headers=headers).addCallback(self.getPic).addErrback(self.downloadError)
372
373         def downloadWeatherReport(self):
374                 self.loadinginprogress = True
375 #               self["statuslabel"].setText("Lade Report: %s" % self.weatherreporturl)
376                 getPage(self.weatherreporturl).addCallback(self.getWeatherReport).addErrback(self.downloadError)
377
378         def switchDeA(self, load=False):
379                 if load:
380                         try:
381                                 f = open(pluginpath + "/last.cfg","r")
382                                 self.land = f.read()
383                                 f.close
384                         except:
385                                 self.land = "a"
386
387                 self.menueintrag = []
388                 self.link = []
389
390                 if self.land == "de":
391                         self.land = "a"
392                         self.baseurl = "http://www.uwz.at/"
393                         self.menuurl = self.baseurl + "karte/alle_warnungen"
394                         self.weatherreporturl = self.baseurl + "at/de/lagebericht/aktuelle-wetterlage"
395                 else:
396                         self.land = "de"
397                         self.baseurl = "http://www.unwetterzentrale.de/uwz/"
398                         self.menuurl = self.baseurl + "index.html"
399                         self.weatherreporturl = self.baseurl + "lagebericht.html"
400
401                 if not load:
402                         f = open(pluginpath + "/last.cfg","w")
403                         f.write(self.land)
404                         f.close
405
406                 self.downloadMenu()
407                 self.ThumbTimer.start(1500, True)
408
409         def exit(self):
410                 if self.loadinginprogress:
411                         reactor.callLater(1,self.exit)
412                 else:
413                         try:
414                                 unlink(self.picfile)
415                                 unlink(self.reportfile)
416                         except OSError:
417                                 pass
418                         self.close()
419
420 #############################
421
422 def main(session, **kwargs):
423         session.open(UnwetterMain)
424
425 def Plugins(path,**kwargs):
426         global pluginpath
427         pluginpath = path
428         return PluginDescriptor(
429                 name="Unwetterzentrale",
430                 description="www.unwetterzentrale.de und www.uwz.at",
431                 icon="uwz.png",
432                 where = PluginDescriptor.WHERE_PLUGINMENU,
433                 fnc=main)