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