drop plugin-local translations (in favor of the global ones in /po)
[enigma2-plugins.git] / weatherplugin / src / plugin.py
1 # -*- coding: utf-8 -*-
2 #
3 # WeatherPlugin E2
4 #
5 # Coded by Dr.Best (c) 2012
6 # Support: www.dreambox-tools.info
7 # E-Mail: dr.best@dreambox-tools.info
8 #
9 # This plugin is open source but it is NOT free software.
10 #
11 # This plugin may only be distributed to and executed on hardware which
12 # is licensed by Dream Multimedia GmbH.
13 # In other words:
14 # It's NOT allowed to distribute any parts of this plugin or its source code in ANY way
15 # to hardware which is NOT licensed by Dream Multimedia GmbH.
16 # It's NOT allowed to execute this plugin and its source code or even parts of it in ANY way
17 # on hardware which is NOT licensed by Dream Multimedia GmbH.
18 #
19 # If you want to use or modify the code or parts of it,
20 # you have to keep MY license and inform me about the modifications by mail.
21 #
22 from Plugins.Plugin import PluginDescriptor
23 from Screens.Screen import Screen
24 from Components.ActionMap import ActionMap
25 from Components.Sources.StaticText import StaticText
26 from Components.Pixmap import Pixmap
27 from enigma import ePicLoad, eRect, eSize, gPixmapPtr
28 from Components.AVSwitch import AVSwitch
29 from Components.config import ConfigSubsection, ConfigSubList, ConfigInteger, config
30 from setup import initConfig, MSNWeatherPluginEntriesListConfigScreen
31 from MSNWeather import MSNWeather
32 import time
33
34 try:
35         from Components.WeatherMSN import weathermsn
36         WeatherMSNComp = weathermsn
37 except:
38         WeatherMSNComp = None
39
40 config.plugins.WeatherPlugin = ConfigSubsection()
41 config.plugins.WeatherPlugin.entrycount =  ConfigInteger(0)
42 config.plugins.WeatherPlugin.Entry = ConfigSubList()
43 initConfig()
44
45
46 def main(session,**kwargs):
47         session.open(MSNWeatherPlugin)
48
49 def Plugins(**kwargs):
50         list = [PluginDescriptor(name=_("Weather Plugin"), description=_("Show Weather Forecast"), where = [PluginDescriptor.WHERE_PLUGINMENU, PluginDescriptor.WHERE_EXTENSIONSMENU], icon = "weather.png", fnc=main)]
51         return list
52
53 class MSNWeatherPlugin(Screen):
54
55         skin = """
56                 <screen name="MSNWeatherPlugin" position="center,center" size="720,400" title="Weather Plugin">
57                         <widget render="Label" source="caption" position="10,10" size="700,30" font="Regular;24"/>
58                         <widget render="Label" source="observationtime" position="430,45" size="280,25" font="Regular;16" halign="right" />
59                         <widget render="Label" source="observationpoint" position="110,70" size="600,25" font="Regular;16" halign="right" />
60                         <widget name="currenticon" position="10,115" size="55,45" alphatest="on"/>
61                         <widget render="Label" source="currentTemp" position="90,115" size="100,23" font="Regular;22"/>
62                         <widget render="Label" source="feelsliketemp" position="90,150" size="140,20" font="Regular;14"/>
63                         <widget render="Label" source="condition" position="320,115" size="380,20" font="Regular;18"/>
64                         <widget render="Label" source="wind_condition" position="320,145" size="380,20" font="Regular;18"/>
65                         <widget render="Label" source="humidity" position="320,165" size="380,20" font="Regular;18" valign="bottom"/>
66                         <widget render="Label" source="weekday1" position="35,210" size="105,40" halign="center" valign="center" font="Regular;18"/>
67                         <widget name="weekday1_icon" position="60,265" size="55,45" alphatest="on"/>
68                         <widget render="Label" source="weekday1_temp" position="35,320" size="105,60" halign="center" valign="top" font="Regular;16"/>
69                         <widget render="Label" source="weekday2" position="175,210" size="105,40" halign="center" valign="top" font="Regular;18"/>
70                         <widget name="weekday2_icon" position="200,265" size="55,45" alphatest="on"/>
71                         <widget render="Label" source="weekday2_temp" position="175,320" size="105,60" halign="center" valign="top" font="Regular;16"/>
72                         <widget render="Label" source="weekday3" position="315,210" size="105,40" halign="center" valign="top" font="Regular;18"/>
73                         <widget name="weekday3_icon" position="340,265" size="55,45" alphatest="on"/>
74                         <widget render="Label" source="weekday3_temp" position="315,320" size="105,60" halign="center" valign="top" font="Regular;16"/>
75                         <widget render="Label" source="weekday4" position="455,210" size="105,40" halign="center" valign="top" font="Regular;18"/>
76                         <widget name="weekday4_icon" position="480,265" size="55,45" alphatest="on"/>
77                         <widget render="Label" source="weekday4_temp" position="455,320" size="105,60" halign="center" valign="top" font="Regular;16"/>
78                         <widget render="Label" source="weekday5" position="595,210" size="105,40" halign="center" valign="top" font="Regular;18"/>
79                         <widget name="weekday5_icon" position="620,265" size="55,45" alphatest="on"/>
80                         <widget render="Label" source="weekday5_temp" position="595,320" size="105,60" halign="center" valign="top" font="Regular;16"/>
81                         <widget render="Label" source="statustext" position="0,0" size="720,400" font="Regular;20" halign="center" valign="center" transparent="1"/>
82                 </screen>"""
83         
84         def __init__(self, session):
85                 Screen.__init__(self, session)
86                 self.title = _("Weather Plugin")
87                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"],
88                 {
89                         "back": self.close,
90                         "input_date_time": self.config,
91                         "right": self.nextItem,
92                         "left": self.previousItem,
93                         "info": self.showWebsite
94                 }, -1)
95
96                 self["statustext"] = StaticText()
97                 self["currenticon"] = WeatherIcon()
98                 self["caption"] = StaticText()
99                 self["currentTemp"] = StaticText()
100                 self["condition"] = StaticText()
101                 self["wind_condition"] = StaticText()
102                 self["humidity"] = StaticText()
103                 self["observationtime"] = StaticText()
104                 self["observationpoint"] = StaticText()
105                 self["feelsliketemp"] = StaticText()
106                 
107                 i = 1
108                 while i <= 5:
109                         self["weekday%s" % i] = StaticText()
110                         self["weekday%s_icon" %i] = WeatherIcon()
111                         self["weekday%s_temp" % i] = StaticText()
112                         i += 1
113                 del i
114                 
115
116                 self.weatherPluginEntryIndex = -1
117                 self.weatherPluginEntryCount = config.plugins.WeatherPlugin.entrycount.value
118                 if self.weatherPluginEntryCount >= 1:
119                         self.weatherPluginEntry = config.plugins.WeatherPlugin.Entry[0]
120                         self.weatherPluginEntryIndex = 1
121                 else:
122                         self.weatherPluginEntry = None
123
124
125                 self.webSite = ""
126                 
127                 self.weatherData = None
128                 self.onLayoutFinish.append(self.startRun)
129                 self.onClose.append(self.__onClose)
130                 
131         def __onClose(self):
132                 if self.weatherData is not None:
133                         self.weatherData.cancel()
134
135         def startRun(self):
136                 if self.weatherPluginEntry is not None:
137                         self["statustext"].text = _("Getting weather information...")
138                         if self.weatherData is not None:
139                                 self.weatherData.cancel()
140                                 self.weatherData = None
141                         self.weatherData = MSNWeather()
142                         self.weatherData.getWeatherData(self.weatherPluginEntry.degreetype.value, self.weatherPluginEntry.weatherlocationcode.value, self.weatherPluginEntry.city.value, self.getWeatherDataCallback, self.showIcon)
143                 else:
144                         self["statustext"].text = _("No locations defined...\nPress 'Menu' to do that.")
145
146         def nextItem(self):
147                 if self.weatherPluginEntryCount != 0:
148                         if self.weatherPluginEntryIndex < self.weatherPluginEntryCount:
149                                 self.weatherPluginEntryIndex = self.weatherPluginEntryIndex + 1
150                         else:
151                                 self.weatherPluginEntryIndex = 1
152                         self.setItem()
153
154         def previousItem(self):
155                 if self.weatherPluginEntryCount != 0:
156                         if self.weatherPluginEntryIndex >= 2:
157                                 self.weatherPluginEntryIndex = self.weatherPluginEntryIndex - 1
158                         else:
159                                 self.weatherPluginEntryIndex = self.weatherPluginEntryCount
160                         self.setItem()
161
162         def setItem(self):
163                 self.weatherPluginEntry = config.plugins.WeatherPlugin.Entry[self.weatherPluginEntryIndex-1]
164                 self.clearFields()
165                 self.startRun()
166
167         def clearFields(self):
168                 self["caption"].text = ""
169                 self["currentTemp"].text = ""
170                 self["condition"].text = ""
171                 self["wind_condition"].text = ""
172                 self["humidity"].text = ""
173                 self["observationtime"].text = ""
174                 self["observationpoint"].text = ""
175                 self["feelsliketemp"].text = ""
176                 self["currenticon"].hide()
177                 self.webSite = ""
178                 i = 1
179                 while i <= 5:
180                         self["weekday%s" % i].text = ""
181                         self["weekday%s_icon" %i].hide()
182                         self["weekday%s_temp" % i].text = ""
183                         i += 1
184
185         def showIcon(self,index, filename):
186                 if index <> -1:
187                         self["weekday%s_icon" % index].updateIcon(filename)
188                         self["weekday%s_icon" % index].show()
189                 else:
190                         self["currenticon"].updateIcon(filename)
191                         self["currenticon"].show()
192
193         def getWeatherDataCallback(self, result, errortext):
194                 self["statustext"].text = ""
195                 if result == MSNWeather.ERROR:
196                         self.error(errortext)
197                 else:
198                         self["caption"].text = self.weatherData.city
199                         self.webSite = self.weatherData.url
200                         for weatherData in self.weatherData.weatherItems.items():
201                                 item = weatherData[1]
202                                 if weatherData[0] == "-1": # current
203                                         self["currentTemp"].text = "%s%s" % (item.temperature, self.weatherData.degreetype)
204                                         self["condition"].text = item.skytext
205                                         self["humidity"].text = _("Humidity: %s %%") % item.humidity
206                                         self["wind_condition"].text = item.winddisplay
207                                         c =  time.strptime(item.observationtime, "%H:%M:%S")
208                                         self["observationtime"].text = _("Observation time: %s") %  time.strftime("%H:%M",c)
209                                         self["observationpoint"].text = _("Observation point: %s") % item.observationpoint
210                                         self["feelsliketemp"].text = _("Feels like %s") % item.feelslike + "" +  self.weatherData.degreetype
211                                 else:
212                                         index = weatherData[0]
213                                         c = time.strptime(item.date,"%Y-%m-%d")
214                                         self["weekday%s" % index].text = "%s\n%s" % (item.day, time.strftime("%d. %b",c))
215                                         lowTemp = item.low
216                                         highTemp = item.high
217                                         self["weekday%s_temp" % index].text = "%s%s|%s%s\n%s" % (highTemp, self.weatherData.degreetype, lowTemp, self.weatherData.degreetype, item.skytextday)
218                 
219                 if self.weatherPluginEntryIndex == 1 and WeatherMSNComp is not None:
220                         WeatherMSNComp.updateWeather(self.weatherData, result, errortext)
221
222         def config(self):
223                 self.session.openWithCallback(self.setupFinished, MSNWeatherPluginEntriesListConfigScreen)
224
225         def setupFinished(self, index, entry = None):
226                 self.weatherPluginEntryCount = config.plugins.WeatherPlugin.entrycount.value
227                 if self.weatherPluginEntryCount >= 1:
228                         if entry is not None:
229                                 self.weatherPluginEntry = entry
230                                 self.weatherPluginEntryIndex = index + 1
231                         if self.weatherPluginEntry is None:
232                                 self.weatherPluginEntry = config.plugins.WeatherPlugin.Entry[0]
233                                 self.weatherPluginEntryIndex = 1
234                 else:
235                         self.weatherPluginEntry = None
236                         self.weatherPluginEntryIndex = -1
237
238                 self.clearFields()
239                 self.startRun()
240
241         def error(self, errortext):
242                 self.clearFields()
243                 self["statustext"].text = errortext
244
245         def showWebsite(self):
246                 try:
247                         from Plugins.Extensions.Browser.Browser import Browser
248                         if self.webSite:
249                                 self.session.open(Browser, config.plugins.WebBrowser.fullscreen.value, self.webSite, False)
250                 except: pass # I dont care if browser is installed or not...
251
252 class WeatherIcon(Pixmap):
253         def __init__(self):
254                 Pixmap.__init__(self)
255                 self.IconFileName = ""
256                 self.picload = ePicLoad()
257                 self.picload_conn = self.picload.PictureData.connect(self.paintIconPixmapCB)
258
259         def onShow(self):
260                 Pixmap.onShow(self)
261                 sc = AVSwitch().getFramebufferScale()
262                 self._aspectRatio = eSize(sc[0], sc[1])
263                 self._scaleSize = self.instance.size()
264                 self.picload.setPara((self._scaleSize.width(), self._scaleSize.height(), sc[0], sc[1], True, 2, '#ff000000'))
265
266         def paintIconPixmapCB(self, picInfo=None):
267                 ptr = self.picload.getData()
268                 if ptr is not None:
269                         pic_scale_size = eSize()
270                         # To be added in the future:
271                         if 'scale' in eSize.__dict__ and self._scaleSize.isValid() and self._aspectRatio.isValid():
272                                 pic_scale_size = ptr.size().scale(self._scaleSize, self._aspectRatio)
273                         # To be removed in the future:
274                         elif 'scaleSize' in gPixmapPtr.__dict__:
275                                 pic_scale_size = ptr.scaleSize()
276
277                         if pic_scale_size.isValid():
278                                 pic_scale_width = pic_scale_size.width()
279                                 pic_scale_height = pic_scale_size.height()
280                                 dest_rect = eRect(0, 0, pic_scale_width, pic_scale_height)
281                                 self.instance.setScale(1)
282                                 self.instance.setScaleDest(dest_rect)
283                         else:
284                                 self.instance.setScale(0)
285                         self.instance.setPixmap(ptr)
286                 else:
287                         self.instance.setPixmap(None)
288                 
289         def updateIcon(self, filename):
290                 new_IconFileName = filename
291                 if (self.IconFileName != new_IconFileName):
292                         self.IconFileName = new_IconFileName
293                         self.picload.startDecode(self.IconFileName)
294