Merge branch 'master' into master_internal
[enigma2-plugins.git] / meteoitalia / src / plugin.py
1 # -*- coding: iso-8859-1 -*-
2
3 #
4 # Meoteo Italia da
5 # www.google.it
6 #
7 # Author(s): Bacicciosat - Lupomeo
8 # Graphics: Army
9 # Package Maintainer: Spaeleus
10 #
11
12 from Screens.Screen import Screen
13 from Screens.MessageBox import MessageBox
14 from Plugins.Plugin import PluginDescriptor
15 from Components.ActionMap import ActionMap
16 from Components.Sources.List import List
17 from Components.Label import Label
18 from Components.Pixmap import Pixmap
19 from Tools.Directories import fileExists
20
21 from urllib2 import Request, urlopen, URLError, HTTPError
22 from xml.dom import minidom, Node
23 from enigma import loadPic, eTimer
24
25 METEOITALIA_ABOUT_TXT = "Meteo Italia Info Plugin v 0.1\n\nAuthor(s): Bacicciosat - Lupomeo\nGraphics: Army\nPackage Maintainer: Spaeleus\nRss Meteo: www.google.it\n"
26
27 class meteoitMain(Screen):
28         skin = """
29         <screen position="center,center" size="720,576" flags="wfNoBorder">
30                 <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MeteoItalia/backg.png" position="0,0" size="720,576" alphatest="on" />
31                 <widget name="lab1" position="10,100" halign="center" size="700,30" zPosition="1" font="Regular;24" valign="top" transparent="1" />
32                 <widget name="lab2" position="10,130" halign="center" size="700,30" zPosition="1" font="Regular;22" valign="top" transparent="1" />
33                 <widget name="lab3" position="340,180" size="40,40" zPosition="1" />
34                 <widget name="lab4" position="10,220" halign="center" size="700,30" zPosition="1" font="Regular;22" valign="top" transparent="1" />
35                 <widget name="lab5" position="10,260" halign="center" size="700,60" zPosition="1" font="Regular;22" valign="top" transparent="1" />
36                 <widget name="lab6" position="0,370" halign="center" size="240,30" zPosition="1" font="Regular;20" valign="top" transparent="1" />
37                 <widget name="lab7" position="100,400" size="40,40" zPosition="1" />
38                 <widget name="lab8" position="0,450" halign="center" size="240,80" zPosition="1" font="Regular;20" valign="top" transparent="1" />
39                 <widget name="lab9" position="240,370" halign="center" size="240,30" zPosition="1" font="Regular;20" valign="top" transparent="1" />
40                 <widget name="lab10" position="340,400" size="40,40" zPosition="1" />
41                 <widget name="lab11" position="240,450" halign="center" size="240,80" zPosition="1" font="Regular;20" valign="top" transparent="1" />
42                 <widget name="lab12" position="480,370" halign="center" size="240,30" zPosition="1" font="Regular;20" valign="top" transparent="1" />
43                 <widget name="lab13" position="580,400" size="40,40" zPosition="1" />
44                 <widget name="lab14" position="480,450" halign="center" size="240,80" zPosition="1" font="Regular;20" valign="top" transparent="1" />
45         </screen>"""
46
47
48         def __init__(self, session):
49                 Screen.__init__(self, session)
50
51                 self["lab1"] = Label("Attendere prego, connessione al server in corso...")
52                 self["lab2"] = Label("")
53                 self["lab3"] = Pixmap()
54                 self["lab4"] = Label("")
55                 self["lab5"] = Label("")
56                 self["lab6"] = Label("")
57                 self["lab7"] = Pixmap()
58                 self["lab8"] = Label("")
59                 self["lab9"] = Label("")
60                 self["lab10"] = Pixmap()
61                 self["lab11"] = Label("")
62                 self["lab12"] = Label("")
63                 self["lab13"] = Pixmap()
64                 self["lab14"] = Label("")
65                 
66                 
67                 self["actions"] = ActionMap(["WizardActions", "ColorActions"],
68                 {
69                         "red": self.key_red,
70                         "green": self.key_green,
71                         "back": self.close,
72                         "ok": self.close
73                 })
74                 
75                 self.activityTimer = eTimer()
76                 self.activityTimer_conn = self.activityTimer.timeout.connect(self.startConnection)
77                 self.onShow.append(self.startShow)
78                 self.onClose.append(self.delTimer)
79
80
81 #We use a timer to show the Window in the meanwhile we are connecting to google Server
82         def startShow(self):
83                 self["lab1"].setText("Attendere prego, connessione al server in corso...")
84                 self.activityTimer.start(10)
85                 
86         def startConnection(self):
87                 self.activityTimer.stop()
88                 self.updateInfo()
89
90 #We will use this for callbacks too
91         def updateInfo(self):
92                 myurl = self.get_Url()
93                 req = Request(myurl)
94                 try:
95                         handler = urlopen(req)
96                 except HTTPError, e:
97                         maintext = "Error: connection failed !"
98                 except URLError, e:
99                         maintext = "Error: Page not available !"
100                 else:
101                         xml_response = handler.read()
102                         #xml_response = handler.read().decode('iso-8859-1').encode('utf-8')
103                         xml_response = self.checkXmlSanity(xml_response)
104                         dom = minidom.parseString(xml_response)
105                         handler.close()
106                         
107                         maintext = ""
108                         tmptext = ""
109                         if (dom):
110                                 weather_data = {}
111                                 weather_dom = dom.getElementsByTagName('weather')[0]
112                                 data_structure = { 
113                                         'forecast_information': ('postal_code', 'current_date_time'),
114                                         'current_conditions': ('condition','temp_c', 'humidity', 'wind_condition', 'icon')
115                                 }
116                                 for (tag, list_of_tags2) in data_structure.iteritems():
117                                         tmp_conditions = {}
118                                         for tag2 in list_of_tags2:
119                                                 try: 
120                                                         tmp_conditions[tag2] =  weather_dom.getElementsByTagName(tag)[0].getElementsByTagName(tag2)[0].getAttribute('data')
121                                                 except IndexError:
122                                                         pass
123                                         weather_data[tag] = tmp_conditions
124
125                                 forecast_conditions = ('day_of_week', 'low', 'high', 'icon', 'condition')
126                                 forecasts = []
127
128                                 for forecast in dom.getElementsByTagName('forecast_conditions'):
129                                         tmp_forecast = {}
130                                         for tag in forecast_conditions:
131                                                 tmp_forecast[tag] = forecast.getElementsByTagName(tag)[0].getAttribute('data')
132                                         forecasts.append(tmp_forecast)
133
134                                 weather_data['forecasts'] = forecasts
135                                 dom.unlink()
136                                 
137                                 maintext = "Il tempo di oggi a " + str(weather_data['forecast_information']['postal_code'])
138                                 mytime =  str(weather_data['forecast_information']['current_date_time'])
139                                 parts = mytime.strip().split(" ")
140                                 mytime = parts[1]
141                                 self["lab2"].setText("Condizioni del tempo aggiornate alle ore " + mytime)
142                                 
143                                 myicon = self.checkIcon(str(weather_data['current_conditions']['icon']))
144 # Damn'ed Google gifs .... (we cannot use loadPixmap)                   
145                                 png = loadPic(myicon, 40, 40, 0, 0, 0, 1)
146                                 self["lab3"].instance.setPixmap(png)
147                                 
148                                 self["lab4"].setText(self.fixSlang(str(weather_data['current_conditions']['condition'])))
149                                 
150                                 tmptext = "Temperatura: " + str(weather_data['current_conditions']['temp_c']) + " gradi Celsius\n" + str(weather_data['current_conditions']['humidity']) + "   " + str(weather_data['current_conditions']['wind_condition'])
151                                 self["lab5"].setText(tmptext)
152                                 
153                                 tmptext = "Previsioni " + self.eXtendedDay(str(weather_data['forecasts'][1]['day_of_week']))
154                                 self["lab6"].setText(tmptext)
155                                 
156                                 myicon = self.checkIcon(str(weather_data['forecasts'][1]['icon']))
157                                 png = loadPic(myicon, 40, 40, 0, 0, 0, 1)
158                                 self["lab7"].instance.setPixmap(png)
159                                 
160                                 tmptext = self.fixSlang(str(weather_data['forecasts'][1]['condition'])) + "\nTemp. minima: " + str(weather_data['forecasts'][1]['low']) + "\nTemp. massima: " + str(weather_data['forecasts'][1]['high'])
161                                 self["lab8"].setText(tmptext)
162                                 
163                                 tmptext = "Previsioni " + self.eXtendedDay(str(weather_data['forecasts'][2]['day_of_week']))
164                                 self["lab9"].setText(tmptext)
165                                 
166                                 myicon = self.checkIcon(str(weather_data['forecasts'][2]['icon']))
167                                 png = loadPic(myicon, 40, 40, 0, 0, 0, 1)
168                                 self["lab10"].instance.setPixmap(png)
169                                 
170                                 tmptext = self.fixSlang(str(weather_data['forecasts'][2]['condition'])) + "\nTemp. minima: " + str(weather_data['forecasts'][2]['low']) + "\nTemp. massima: " + str(weather_data['forecasts'][2]['high'])
171                                 self["lab11"].setText(tmptext)
172                                 
173                                 tmptext = "Previsioni " + self.eXtendedDay(str(weather_data['forecasts'][3]['day_of_week']))
174                                 self["lab12"].setText(tmptext)
175                                 
176                                 myicon = self.checkIcon(str(weather_data['forecasts'][3]['icon']))
177                                 png = loadPic(myicon, 40, 40, 0, 0, 0, 1)
178                                 self["lab13"].instance.setPixmap(png)
179                                 
180                                 tmptext = self.fixSlang(str(weather_data['forecasts'][3]['condition'])) + "\nTemp. minima: " + str(weather_data['forecasts'][3]['low']) + "\nTemp. massima: " + str(weather_data['forecasts'][3]['high'])
181                                 self["lab14"].setText(tmptext)
182
183                         else:
184                                 maintext = "Error getting XML document!"
185                 
186                 
187                 self["lab1"].setText(maintext)
188                         
189
190
191
192 # Download icon from Google if we have not yet.
193         def checkIcon(self, filename):
194                 parts = filename.split("/")
195                 totsp = (len(parts) -1)
196                 localfile = pluginpath + "/" + parts[totsp]
197                 if fileExists(localfile):
198                         pass
199                 else:
200                         url = "http://www.google.it" + filename
201                         handler = urlopen(url)
202                         if (handler):
203                                 content = handler.read()
204                                 fileout = open(localfile, "wb")
205                                 fileout.write(content)
206                                 handler.close()
207                                 fileout.close()
208                 
209                 return localfile
210
211 # Bad Google translations (uff.....)
212         def fixSlang(self, word):
213                 if word.find('Chiaro') != -1:
214                         word = "Sereno"
215                 return word
216                 
217 # Google don't show expanded days
218         def eXtendedDay(self, day):
219                 if day.find('lun') != -1:
220                         day = "Lunedi'"
221                 elif day.find('mar') != -1:
222                         day = "Martedi'"
223                 elif day.find('mer') != -1:
224                         day = "Mercoledi'"
225                 elif day.find('gio') != -1:
226                         day = "Giovedi'"
227                 elif day.find('ven') != -1:
228                         day = "Venerdi'"
229                 elif day.find('sab') != -1:
230                         day = "Sabato"
231                 elif day.find('dom') != -1:
232                         day = "Domenica"
233                 return day
234                         
235 # Make text safe for xml parser (Google old xml format without the character set declaration)
236         def checkXmlSanity(self, content):
237                 content = content.replace('', 'a')
238                 content = content.replace('', 'e')
239                 content = content.replace('', 'e')
240                 content = content.replace('', 'i')
241                 content = content.replace('', 'o')
242                 content = content.replace('', 'u')
243                 return content
244
245         def get_Url(self):
246                 url = 'http://www.google.it/ig/api?weather='
247                 url2 = "Roma"
248                 cfgfile = pluginpath + "/" + "meteoitalia.cfg"
249                 if fileExists(cfgfile):
250                         f = open(cfgfile,'r')
251                         line = f.readline()
252                         url2 = line.strip()
253                         f.close()
254                 url = url + url2
255                 url = url.replace(' ', '%20')
256                 return url
257                 
258         def delTimer(self):
259                 del self.activityTimer_conn
260                 del self.activityTimer
261
262         def key_green(self):
263                 box = self.session.open(MessageBox, METEOITALIA_ABOUT_TXT, MessageBox.TYPE_INFO)
264                 box.setTitle(_("Informazioni"))
265                 
266         def key_red(self):
267                 self.session.openWithCallback(self.updateInfo, MeteoitSelectCity)
268
269 class MeteoitSelectCity(Screen):
270         skin = """
271         <screen position="center,center" size="720,576" flags="wfNoBorder">
272                 <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MeteoItalia/backg.png" position="0,0" size="720,576" alphatest="on" />
273                 <widget source="list" render="Listbox" position="40,110" zPosition="1" size="640,380" scrollbarMode="showOnDemand" transparent="1" >
274                         <convert type="StringList" />
275                 </widget>
276                 <widget name="lab1" position="10,520" halign="center" size="700,30" zPosition="1" font="Regular;24" valign="top" foregroundColor="#639ACB" transparent="1" />
277         </screen>"""
278
279
280         def __init__(self, session):
281                 Screen.__init__(self, session)
282
283                 self.list = ["Agrigento","Alessandria","Ancona","Andria","Aosta","Arezzo","Ascoli Piceno","Asti","Avellino","Bari",
284                                 "Barletta","Belluno","Benevento","Bergamo","Biella","Bologna","Bolzano","Brescia","Brindisi","Cagliari",
285                                 "Caltanissetta","Campobasso","Carbonia","Caserta","Catania","Catanzaro","Chieti","Como","Cosenza",
286                                 "Cremona","Crotone","Cuneo","Enna","Fermo","Ferrara","Firenze","Foggia","Forli","Frosinone","Genova",
287                                 "Gorizia","Grosseto","Iglesias","Imperia","Isernia","La Spezia","L'Aquila","Lanusei","Latina","Lecce",
288                                 "Lecco","Livorno","Lodi","Lucca","Macerata","Mantova","Massa","Matera","Messina","Milano","Modena",
289                                 "Monza","Napoli","Novara","Nuoro","Ogliastra","Olbia","Oristano","Padova","Palermo","Parma","Pavia",
290                                 "Perugia","Pesaro","Pescara","Piacenza","Pisa","Pistoia","Pordenone","Potenza","Prato","Ragusa","Ravenna",
291                                 "Reggio Calabria","Reggio Emilia","Rieti","Rimini","Roma","Rovigo","Salerno","Sanluri","Sassari","Savona",
292                                 "Siena","Siracusa","Sondrio","Taranto","Tempio Pausania","Teramo","Terni","Torino","Trani","Trapani",
293                                 "Trento","Treviso","Trieste","Udine","Urbino","Varese","Venezia","Verbania","Vercelli","Verona",
294                                 "Vibo Valenzia","Villacidro","Vicenza","Viterbo"]
295                                 
296                 self["list"] = List(self.list)
297                 self["lab1"] = Label("Ok per confermare")
298                 
299                 self["actions"] = ActionMap(["WizardActions", "ColorActions"],
300                 {
301                         "back": self.close,
302                         "ok": self.saveCfg,
303                         "green": self.key_green
304                 })
305
306         def key_green(self):
307                 box = self.session.open(MessageBox, METEOITALIA_ABOUT_TXT, MessageBox.TYPE_INFO)
308                 box.setTitle(_("Informazioni"))
309
310         def saveCfg(self):
311                 city = self["list"].getCurrent()
312                 if city:
313                         cfgfile = pluginpath + "/" + "meteoitalia.cfg"
314                         out = open(cfgfile, "w")
315                         out.write(city)
316                 self.close()
317
318
319
320 def main(session, **kwargs):
321         session.open(meteoitMain)       
322
323
324 def Plugins(path,**kwargs):
325         global pluginpath
326         pluginpath = path
327         return PluginDescriptor(name="MeteoItalia", description="Previsioni Meteo", icon="meteoitalia.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)