Description: Fixes crash after changes of the received data (xml structure)
 * backported from current upstream
 * some minor string changes
 * reflect changed openweathermap datastructure
 * fix crash when wind direction is not available
 * shows UV when available
 * handle download errors and missing values
 * fix logging handling
 * fix crash when 6 days forcast is not available
 * fix crash if applying settings and start minimized
 * catch unhandled exceptions and write them into log file
 * fix crash when UV index has two decimals

Author: Alf Gaida <aga...@siduction.org>

---
Bug-Debian: https://bugs.debian.org/939651
Forwarded: not-needed
Last-Update: 2019-09-07

--- meteo-qt-1.0.0.orig/CHANGELOG
+++ meteo-qt-1.0.0/CHANGELOG
@@ -1,3 +1,11 @@
+1.1
+- Option to show the window at start-up
+- Fixes for crashes
+- Show wind info when Bft unit option is unchecked
+- Use unicode arrows for hPa and T° trend
+- Wrap weather information of the day on panel
+- Update translations [German, Slovak, Czech]
+
 1.0.0
 - Automatic detection of the geolocation
 - Reenable UV Ozone in weather information
--- meteo-qt-1.0.0.orig/meteo_qt/about_dlg.py
+++ meteo-qt-1.0.0/meteo_qt/about_dlg.py
@@ -102,7 +102,8 @@ class AboutDialog(QDialog):
                 '',
                 '<p>werthad <a href="mailto:wert...@gmail.com">'
                 'wert...@gmail.com</a>'
-                '<br/> [hu] Hungarian translation', ''
+                '<br/> [hu] Hungarian translation',
+                ''
             )
             + QCoreApplication.translate(
                 '',
@@ -129,27 +130,44 @@ class AboutDialog(QDialog):
                 '<a href="mailto:rw4...@yandex.ru">rw4...@yandex.ru</a>'
                 '<br/>Alexey Zakaldaev '
                 '<a href="mailto:nelex...@gmail.com">nelex...@gmail.com</a>'
-                '<br/>Liliya Panova<br/> [ru] Russian translation', ''
+                '<br/>Liliya Panova<br/> [ru] Russian translation',
+                ''
+            )
+            + QCoreApplication.translate(
+                '',
+                '<p>jose1711 '
+                '<a href="mailto:jose1...@gmail.com">'
+                'jose1...@gmail.com</a>'
+                '<br> [sk] Slovak translation, Project',
+                ''
             )
             + QCoreApplication.translate(
                 '',
                 '<p>Atilla Öntaş '
                 '<a href="mailto:tarakbu...@gmail.com">'
                 'tarakbu...@gmail.com</a>'
-                '<br/> [tr] Turkish translation', ''
+                '<br/> [tr] Turkish translation',
+                ''
             )
             + QCoreApplication.translate(
                 '',
                 '<p>Yuri Chornoivan '
                 '<a href="mailto:yurc...@ukr.net">yurc...@ukr.net</a>'
-                '<br/> [uk] Ukrainian translation', ''
+                '<br/> [uk] Ukrainian translation',
+                ''
             )
             + QCoreApplication.translate(
                 '',
                 '<p>You-Cheng Hsieh '
                 '<a href="mailto:yochenhs...@gmail.com">'
                 'yochenhs...@gmail.com</a>'
-                '<br/> [zh_TW] Chinese (Taiwan) translation', ''
+                '<br/> [zh_TW] Chinese (Taiwan) translation',
+                ''
+            )
+            + QCoreApplication.translate(
+                '',
+                '<p>pmav99<br/> Project',
+                ''
             )
-            + QCoreApplication.translate('', '<p>pmav99<br/> Project', ''))
+        )
         return contributors
--- meteo-qt-1.0.0.orig/meteo_qt/citylistdlg.py
+++ meteo-qt-1.0.0/meteo_qt/citylistdlg.py
@@ -127,7 +127,7 @@ class CityListDlg(QDialog):
                 QCoreApplication.translate(
                     'Message when trying to remove the'
                     'last and unique city in the list',
-                    'This is the default city !',
+                    'This is the default city!',
                     'Cities list dialogue'
                 )
             )
--- meteo-qt-1.0.0.orig/meteo_qt/meteo_qt.py
+++ meteo-qt-1.0.0/meteo_qt/meteo_qt.py
@@ -17,6 +17,9 @@ from lxml import etree
 import json
 import time
 import datetime
+import traceback
+from io import StringIO
+import gc
 
 from PyQt5.QtCore import (
     PYQT_VERSION_STR, QT_VERSION_STR, QCoreApplication, QByteArray,
@@ -143,17 +146,6 @@ class SystemTrayIcon(QMainWindow):
         # The traycolor has to be initialized here for the case when we cannot
         # reach the tray method (case: set the color at first time usage)
         self.traycolor = ''
-        self.refresh()
-
-    def overviewcity(self):
-        temp_trend = ''
-        if self.temp_trend == " ↗":
-            temp_trend = " "
-        elif self.temp_trend == " ↘":
-            temp_trend = ""
-
-        self.overviewcitydlg = QDialog()
-        self.setCentralWidget(self.overviewcitydlg)
         self.days_dico = {'0': self.tr('Mon'),
                           '1': self.tr('Tue'),
                           '2': self.tr('Wed'),
@@ -169,14 +161,21 @@ class SystemTrayIcon(QMainWindow):
         self.hpa_indications = self.cond.pressure
         self.uv_risk = self.cond.uv_risk
         self.uv_recommend = self.cond.uv_recommend
+
+        self.refresh()
+
+    def overviewcity(self):
+        self.overviewcitydlg = QDialog()
+        self.setCentralWidget(self.overviewcitydlg)
         self.forecast_weather_list = []
         self.dayforecast_weather_list = []
         self.icon_list = []
         self.dayforecast_icon_list = []
         self.unit_temp = self.units_dico[self.unit]
-        self.total_layout = QVBoxLayout()
+        total_layout = QVBoxLayout()
+
         # ----First part overview day -----
-        self.over_layout = QVBoxLayout()
+        over_layout = QVBoxLayout()
         self.dayforecast_layout = QHBoxLayout()
         self.dayforecast_temp_layout = QHBoxLayout()
         # Check for city translation
@@ -197,27 +196,28 @@ class SystemTrayIcon(QMainWindow):
         self.city_label = QLabel(
             '<font size="4"><b>' + city_label + '<\b><\font>'
         )
-        self.over_layout.addWidget(self.city_label)
-        self.icontemp_layout = QHBoxLayout()
-        self.icon_label = QLabel()
-        self.icon_label.setPixmap(self.wIcon)
-        self.icontemp_layout.addWidget(self.icon_label)
-        self.temp_label = QLabel(
+        over_layout.addWidget(self.city_label)
+        icontemp_layout = QHBoxLayout()
+        icon_label = QLabel()
+        icon_label.setPixmap(self.wIcon)
+        icontemp_layout.addWidget(icon_label)
+        temp_label = QLabel(
             '<font size="5"><b>' + '{0:.1f}'
             .format(float(self.weatherDataDico['Temp'][:-1])) + ' '
-            + self.unit_temp + temp_trend + '<\b><\font>'
+            + self.unit_temp + self.temp_trend + '<\b><\font>'
         )
-        self.icontemp_layout.addWidget(self.temp_label)
-        self.over_layout.addLayout(self.icontemp_layout)
-        self.weather = QLabel(
+        icontemp_layout.addWidget(temp_label)
+        over_layout.addLayout(icontemp_layout)
+        weather = QLabel(
             '<font size="4"><b>'
             + self.weatherDataDico['Meteo']
             + '<\b><\font>'
         )
-        self.icontemp_layout.addWidget(self.weather)
-        self.icontemp_layout.addStretch()
-        self.over_layout.addLayout(self.dayforecast_layout)
-        self.over_layout.addLayout(self.dayforecast_temp_layout)
+        weather.setWordWrap(True)
+        icontemp_layout.addWidget(weather)
+        icontemp_layout.addStretch()
+        over_layout.addLayout(self.dayforecast_layout)
+        over_layout.addLayout(self.dayforecast_temp_layout)
         # ------Second part overview day---------
         self.over_grid = QGridLayout()
         # Wind
@@ -233,20 +233,23 @@ class SystemTrayIcon(QMainWindow):
         if wind_unit == 'imperial':
             self.unit_system = ' mph '
             self.unit_system_wind = ' mph '
-        self.windLabelDescr = QLabel('None')
+        windLabelDescr = QLabel('None')
         wind_speed = '{0:.1f}'.format(float(self.weatherDataDico['Wind'][0]))
         windTobeaufort = str(self.convertToBeaufort(wind_speed))
         if self.bft_bool is True:
             wind_speed = windTobeaufort
-            self.unit_system_wind = ' Bft. '
+            unit_system_wind = ' Bft. '
+        else:
+            unit_system_wind = self.unit_system_wind
+
         try:
-            self.windLabelDescr = QLabel(
+            windLabelDescr = QLabel(
                 '<font color=>' + self.weatherDataDico['Wind'][4]
                 + ' ' + self.weatherDataDico['Wind'][2] + '° ' + '<br/>'
-                + wind_speed + self.unit_system_wind
+                + wind_speed + unit_system_wind
                 + self.weatherDataDico['Wind'][1] + '<\font>'
             )
-            self.windLabelDescr.setToolTip(
+            windLabelDescr.setToolTip(
                 self.beaufort_sea_land[windTobeaufort]
             )
         except:
@@ -262,7 +265,7 @@ class SystemTrayIcon(QMainWindow):
         self.clouds_label = QLabel(
             '<font size="3" color=><b>' + self.tr('Cloudiness') + '<\b><\font>'
         )
-        self.clouds_name = QLabel(
+        clouds_name = QLabel(
             '<font color=>' + self.weatherDataDico['Clouds'] + '<\font>'
         )
         # Pressure
@@ -270,26 +273,26 @@ class SystemTrayIcon(QMainWindow):
             '<font size="3" color=><b>' + self.tr('Pressure') + '<\b><\font>'
         )
         if self.hPaTrend == 0:
-            hpa = ""
+            hpa = "→"
         elif self.hPaTrend < 0:
-            hpa = ""
+            hpa = "↘"
         elif self.hPaTrend > 0:
-            hpa = ""
-        self.pressure_value = QLabel(
+            hpa = "↗"
+        pressure_value = QLabel(
             '<font color=>' + str(float(self.weatherDataDico['Pressure'][0]))
             + ' ' + self.weatherDataDico['Pressure'][1] + " " + hpa + '<\font>'
         )
-        self.pressure_value.setToolTip(self.hpa_indications['hpa'])
+        pressure_value.setToolTip(self.hpa_indications['hpa'])
         # Humidity
         self.humidity_label = QLabel(
             '<font size="3" color=><b>' + self.tr('Humidity') + '<\b><\font>'
         )
-        self.humidity_value = QLabel(
+        humidity_value = QLabel(
             '<font color=>' + self.weatherDataDico['Humidity'][0] + ' '
             + self.weatherDataDico['Humidity'][1] + '<\font>'
         )
         # Precipitation
-        self.precipitation_label = QLabel(
+        precipitation_label = QLabel(
             '<font size="3" color=><b>'
             + QCoreApplication.translate(
                 'Precipitation type (no/rain/snow)',
@@ -311,24 +314,24 @@ class SystemTrayIcon(QMainWindow):
                 rain_value = "{0:.4f}".format(float(rain_value))
             else:
                 rain_value = "{0:.2f}".format(float(rain_value))
-        self.precipitation_value = QLabel(
+        precipitation_value = QLabel(
             '<font color=>' + rain_mode + ' ' + rain_value
             + ' ' + rain_unit + '</font>'
         )
         # Sunrise Sunset Daylight
-        self.sunrise_label = QLabel(
+        sunrise_label = QLabel(
             '<font color=><b>' + self.tr('Sunrise') + '</b></font>'
         )
-        self.sunset_label = QLabel(
+        sunset_label = QLabel(
             '<font color=><b>' + self.tr('Sunset') + '</b></font>'
         )
         rise_str = self.utc('Sunrise', 'weatherdata')
         set_str = self.utc('Sunset', 'weatherdata')
-        self.sunrise_value = QLabel(
+        sunrise_value = QLabel(
             '<font color=>' + rise_str[:-3] + '</font>'
         )
-        self.sunset_value = QLabel('<font color=>' + set_str[:-3] + '</font>')
-        self.daylight_label = QLabel(
+        sunset_value = QLabel('<font color=>' + set_str[:-3] + '</font>')
+        daylight_label = QLabel(
             '<font color=><b>'
             + QCoreApplication.translate(
                 'Daylight duration', 'Daylight',
@@ -337,7 +340,7 @@ class SystemTrayIcon(QMainWindow):
             + '</b></font>'
         )
         daylight_value = self.daylight_delta(rise_str[:-3], set_str[:-3])
-        self.daylight_value_label = QLabel(
+        daylight_value_label = QLabel(
             '<font color=>' + daylight_value + '</font>'
         )
         # --UV---
@@ -374,32 +377,34 @@ class SystemTrayIcon(QMainWindow):
         self.ozone_value_label = QLabel()
         self.ozone_value_label.setText(fetching_text)
         self.over_grid.addWidget(self.wind_label, 0, 0)
-        self.over_grid.addWidget(self.windLabelDescr, 0, 1)
+        self.over_grid.addWidget(windLabelDescr, 0, 1)
         self.over_grid.addWidget(self.wind_icon_label, 0, 2)
         self.over_grid.addWidget(self.clouds_label, 1, 0)
-        self.over_grid.addWidget(self.clouds_name, 1, 1)
+        self.over_grid.addWidget(clouds_name, 1, 1)
         self.over_grid.addWidget(self.pressure_label, 2, 0)
-        self.over_grid.addWidget(self.pressure_value, 2, 1)
+        self.over_grid.addWidget(pressure_value, 2, 1)
         self.over_grid.addWidget(self.humidity_label, 3, 0)
-        self.over_grid.addWidget(self.humidity_value, 3, 1, 1, 3)  # align left
-        self.over_grid.addWidget(self.precipitation_label, 4, 0)
-        self.over_grid.addWidget(self.precipitation_value, 4, 1)
-        self.over_grid.addWidget(self.sunrise_label, 5, 0)
-        self.over_grid.addWidget(self.sunrise_value, 5, 1)
-        self.over_grid.addWidget(self.sunset_label, 6, 0)
-        self.over_grid.addWidget(self.sunset_value, 6, 1)
-        self.over_grid.addWidget(self.daylight_label, 7, 0)
-        self.over_grid.addWidget(self.daylight_value_label, 7, 1)
+        self.over_grid.addWidget(humidity_value, 3, 1, 1, 3)  # align left
+        self.over_grid.addWidget(precipitation_label, 4, 0)
+        self.over_grid.addWidget(precipitation_value, 4, 1)
+        self.over_grid.addWidget(sunrise_label, 5, 0)
+        self.over_grid.addWidget(sunrise_value, 5, 1)
+        self.over_grid.addWidget(sunset_label, 6, 0)
+        self.over_grid.addWidget(sunset_value, 6, 1)
+        self.over_grid.addWidget(daylight_label, 7, 0)
+        self.over_grid.addWidget(daylight_value_label, 7, 1)
+        self.over_grid.addWidget(self.uv_label, 8, 0)
+        self.over_grid.addWidget(self.uv_value_label, 8, 1)
         # -------------Forecast-------------
         self.forecast_days_layout = QHBoxLayout()
         self.forecast_icons_layout = QHBoxLayout()
         self.forecast_minmax_layout = QHBoxLayout()
         # ----------------------------------
-        self.total_layout.addLayout(self.over_layout)
-        self.total_layout.addLayout(self.over_grid)
-        self.total_layout.addLayout(self.forecast_icons_layout)
-        self.total_layout.addLayout(self.forecast_days_layout)
-        self.total_layout.addLayout(self.forecast_minmax_layout)
+        total_layout.addLayout(over_layout)
+        total_layout.addLayout(self.over_grid)
+        total_layout.addLayout(self.forecast_icons_layout)
+        total_layout.addLayout(self.forecast_days_layout)
+        total_layout.addLayout(self.forecast_minmax_layout)
 
         if self.forcast6daysBool:
             self.forecast6data()
@@ -416,10 +421,16 @@ class SystemTrayIcon(QMainWindow):
         self.ozone_fetch()
         logging.debug('Fetched ozone data')
 
-        self.overviewcitydlg.setLayout(self.total_layout)
+        self.overviewcitydlg.setLayout(total_layout)
         self.setWindowTitle(self.tr('Weather status'))
         self.restoreGeometry(self.settings.value("MainWindow/Geometry",
                                                  QByteArray()))
+        ##  Option to start with the panel closed, true by defaut
+        #   starting with the panel open can be useful for users who don't have plasma
+        #   installed (to set keyboard shortcuts or other default window behaviours)
+        start_minimized = self.settings.value('StartMinimized') or 'True'
+        if start_minimized == 'False':
+            self.showpanel()
 
     def daylight_delta(self, s1, s2):
         FMT = '%H:%M'
@@ -520,8 +531,15 @@ class SystemTrayIcon(QMainWindow):
                 return 12
 
     def wind_icon_direction(self):
-        transf = QTransform()
         angle = self.weatherDataDico['Wind'][2]
+        if angle == '':
+            if self.wind_icon_label.isVisible is True:
+                self.wind_icon_label.hide()
+            return
+        else:
+            if self.wind_icon_label.isVisible is False:
+                self.wind_icon_label.show()
+        transf = QTransform()
         logging.debug('Wind degrees direction: ' + angle)
         transf.rotate(int(float(angle)))
         rotated = self.wind_icon.transformed(
@@ -568,13 +586,13 @@ class SystemTrayIcon(QMainWindow):
             uv = float(uv)
         except:
             return ('grey', 'None')
-        if uv <= 2.9:
+        if uv <= 2.99:
             return ('green', 'Low')
-        elif uv <= 5.9:
+        elif uv <= 5.99:
             return ('yellow', 'Moderate')
-        elif uv <= 7.9:
+        elif uv <= 7.99:
             return ('orange', 'High')
-        elif uv <= 10.9:
+        elif uv <= 10.99:
             return ('red', 'Very high')
         elif uv >= 11:
             return ('purple', 'Extreme')
@@ -633,106 +651,143 @@ class SystemTrayIcon(QMainWindow):
         fetched_file_periods = (len(self.forecast6_data.xpath('//time')))
         if fetched_file_periods < periods:
             periods = fetched_file_periods
-            logging.warn('Reduce forecast for the next 6 days to {0}'.format(
+            logging.warning('Reduce forecast for the next 6 days to {0}'.format(
                 periods - 1))
-        for d in range(1, periods):
-            date_list = self.forecast6_data[4][d].get('day').split('-')
-            day_of_week = str(datetime.date(
-                int(date_list[0]), int(date_list[1]),
-                int(date_list[2])).weekday())
-            label = QLabel('' + self.days_dico[day_of_week] + '')
-            label.setToolTip(self.forecast6_data[4][d].get('day'))
-            label.setAlignment(Qt.AlignHCenter)
-            self.forecast_days_layout.addWidget(label)
-            mlabel = QLabel(
-                '<font color=>' + '{0:.0f}'
-                .format(float(self.forecast6_data[4][d][4].get('min')))
-                + '°<br/>' + '{0:.0f}'
-                .format(float(self.forecast6_data[4][d][4].get('max')))
-                + '°</font>'
-            )
-            mlabel.setAlignment(Qt.AlignHCenter)
-            mlabel.setToolTip(self.tr('Min Max Temperature of the day'))
-            self.forecast_minmax_layout.addWidget(mlabel)
-            # icon
-            self.icon_list.append(self.forecast6_data[4][d][0].get('var'))
-            weather_cond = self.forecast6_data[4][d][0].get('name')
-            try:
-                weather_cond = (
-                    self.conditions[self.forecast6_data[4][d][0].get('number')]
-                )
-            except:
-                logging.warn(
-                    'Cannot find localisation string for :'
-                    + weather_cond
-                )
-                pass
-            try:
-                # Take the label translated text and remove the html tags
-                doc.setHtml(self.precipitation_label.text())
-                precipitation_label = doc.toPlainText() + ': '
-                precipitation_type = self.forecast6_data[4][d][1].get('type')
-                precipitation_type = (
-                    self.precipitation[precipitation_type] + ' '
-                )
-                precipitation_value = self.forecast6_data[4][d][1].get('value')
-                rain_unit = ' mm'
-                if self.unit_system == ' mph ':
-                    rain_unit = ' inch'
-                    precipitation_value = (
-                        str(float(precipitation_value) / 25.4) + ' '
+        counter_day = 0
+        forecast_data = False
+
+        for element in self.forecast6_data.iter():
+
+            if element.tag == 'time':
+                forecast_data = True
+            if forecast_data is False:
+                continue
+
+            if element.tag == 'time':
+                counter_day += 1
+                if counter_day == periods:
+                    break
+
+                weather_end = False
+                date_list = element.get('day').split('-')
+                day_of_week = str(datetime.date(
+                    int(date_list[0]), int(date_list[1]),
+                    int(date_list[2])).weekday()
+                )
+                label = QLabel('' + self.days_dico[day_of_week] + '')
+                label.setToolTip(element.get('day'))
+                label.setAlignment(Qt.AlignHCenter)
+                self.forecast_days_layout.addWidget(label)
+
+            if element.tag == 'temperature':
+                mlabel = QLabel(
+                    '<font color=>' + '{0:.0f}'
+                    .format(float(element.get('min')))
+                    + '°<br/>' + '{0:.0f}'
+                    .format(float(element.get('max')))
+                    + '°</font>'
+                )
+                mlabel.setAlignment(Qt.AlignHCenter)
+                mlabel.setToolTip(self.tr('Min Max Temperature of the day'))
+                self.forecast_minmax_layout.addWidget(mlabel)
+
+            if element.tag == 'symbol':
+                # icon
+                self.icon_list.append(element.get('var'))
+                weather_cond = element.get('name')
+                try:
+                    weather_cond = (
+                        self.conditions[element.get('number')]
                     )
-                    precipitation_value = (
-                        "{0:.2f}".format(float(precipitation_value))
+                except KeyError:
+                    logging.warning(
+                        'Cannot find localisation string for: '
+                        + weather_cond
                     )
-                else:
-                    precipitation_value = (
-                        "{0:.1f}".format(float(precipitation_value))
+                    pass
+
+            if element.tag == 'precipitation':
+
+                try:
+                    # Take the label translated text and remove the html tags
+                    doc.setHtml(self.precipitation_label.text())
+                    precipitation_label = doc.toPlainText() + ': '
+                    precipitation_type = element.get('type')
+                    precipitation_type = (
+                        self.precipitation[precipitation_type] + ' '
                     )
-                weather_cond += (
-                    '\n' + precipitation_label + precipitation_type
-                    + precipitation_value + rain_unit
-                )
-            except:
-                pass
-            doc.setHtml(self.wind_label.text())
-            wind = doc.toPlainText() + ': '
-            try:
-                wind_direction = (
-                    self.wind_direction[
-                        self.forecast6_data[4][d][2].get('code')
-                    ]
+                    precipitation_value = element.get('value')
+                    rain_unit = ' mm'
+                    if self.unit_system == ' mph ':
+                        rain_unit = ' inch'
+                        precipitation_value = (
+                            str(float(precipitation_value) / 25.4) + ' '
+                        )
+                        precipitation_value = (
+                            "{0:.2f}".format(float(precipitation_value))
+                        )
+                    else:
+                        precipitation_value = (
+                            "{0:.1f}".format(float(precipitation_value))
+                        )
+                    weather_cond += (
+                        '\n' + precipitation_label + precipitation_type
+                        + precipitation_value + rain_unit
+                    )
+                except:
+                    pass
+
+            if element.tag == 'windDirection':
+                doc.setHtml(self.wind_label.text())
+                wind = doc.toPlainText() + ': '
+                try:
+                    wind_direction = (
+                        self.wind_direction[element.get('code')]
+                    )
+                except KeyError:
+                    wind_direction = ''
+
+            if element.tag == 'windSpeed':
+                wind_speed = (
+                    '{0:.1f}'.format(float(element.get('mps')))
                 )
-            except:
-                wind_direction = ''
-            wind_speed = (
-                '{0:.1f}'.format(
-                    float(self.forecast6_data[4][d][3].get('mps'))
+                if self.bft_bool:
+                    wind_speed = str(self.convertToBeaufort(wind_speed))
+                weather_cond += (
+                    '\n'
+                    + wind
+                    + wind_speed
+                    + self.unit_system_wind
+                    + wind_direction
                 )
-            )
-            if self.bft_bool:
-                wind_speed = str(self.convertToBeaufort(wind_speed))
-            weather_cond += (
-                '\n' + wind + wind_speed + self.unit_system_wind
-                + wind_direction
-            )
-            doc.setHtml(self.pressure_label.text())
-            pressure_label = doc.toPlainText() + ': '
-            pressure = (
-                '{0:.1f}'.format(
-                    float(self.forecast6_data[4][d][5].get('value'))
+
+            if element.tag == 'pressure':
+
+                doc.setHtml(self.pressure_label.text())
+                pressure_label = doc.toPlainText() + ': '
+                pressure = (
+                    '{0:.1f}'.format(
+                        float(element.get('value'))
+                    )
                 )
-            )
-            weather_cond += '\n' + pressure_label + pressure + ' hPa'
-            humidity = self.forecast6_data[4][d][6].get('value')
-            doc.setHtml(self.humidity_label.text())
-            humidity_label = doc.toPlainText() + ': '
-            weather_cond += '\n' + humidity_label + humidity + ' %'
-            clouds = self.forecast6_data[4][d][7].get('all')
-            doc.setHtml(self.clouds_label.text())
-            clouds_label = doc.toPlainText() + ': '
-            weather_cond += '\n' + clouds_label + clouds + ' %'
-            self.forecast_weather_list.append(weather_cond)
+                weather_cond += '\n' + pressure_label + pressure + ' hPa'
+
+            if element.tag == 'humidity':
+                humidity = element.get('value')
+                doc.setHtml(self.humidity_label.text())
+                humidity_label = doc.toPlainText() + ': '
+                weather_cond += '\n' + humidity_label + humidity + ' %'
+
+            if element.tag == 'clouds':
+                clouds = element.get('all')
+                doc.setHtml(self.clouds_label.text())
+                clouds_label = doc.toPlainText() + ': '
+                weather_cond += '\n' + clouds_label + clouds + ' %'
+                weather_end = True
+
+            if weather_end is True:
+                self.forecast_weather_list.append(weather_cond)
+                weather_end = False
 
     def forecastdata(self):
         '''Forecast for the next 4 days'''
@@ -777,8 +832,8 @@ class SystemTrayIcon(QMainWindow):
                     ]
                 )
             except:
-                logging.warn(
-                    'Cannot find localisation string for :'
+                logging.warning(
+                    'Cannot find localisation string for: '
                     + weather_cond
                 )
                 pass
@@ -886,7 +941,7 @@ class SystemTrayIcon(QMainWindow):
             if fetched_file_periods < periods:
                 # Some times server sends less data
                 periods = fetched_file_periods
-                logging.warn(
+                logging.warning(
                     'Reduce forecast of the day to {0}'.format(periods - 1)
                 )
         for d in range(start, periods):
@@ -919,7 +974,7 @@ class SystemTrayIcon(QMainWindow):
                     )
                     wind += wind_name_translated
                 except KeyError:
-                    logging.warn('Cannot find wind name :' + str(wind_name))
+                    logging.warning('Cannot find wind name: ' + str(wind_name))
                     logging.info('Set wind name to None')
                     wind = ''
                 finally:
@@ -1002,7 +1057,7 @@ class SystemTrayIcon(QMainWindow):
             if winddircode != '':
                 wind = self.wind_direction[winddircode] + ' '
             else:
-                logging.warn(
+                logging.warning(
                     'Wind direction code is missing: '
                     + str(winddircode)
                 )
@@ -1013,12 +1068,12 @@ class SystemTrayIcon(QMainWindow):
                         self.conditions[self.clouds_name_dic[clouds.lower()]]
                     )
                 except KeyError:
-                    logging.warn(
+                    logging.warning(
                         'The clouding description in json is not relevant'
                     )
                     clouds_translated = ''
             else:
-                logging.warn('Clouding name is missing: ' + str(clouds))
+                logging.warning('Clouding name is missing: ' + str(clouds))
             clouds_cond = clouds_translated + ' ' + str(cloudspercent) + '%'
             ttip = ttip + wind + clouds_cond
             daytime.setToolTip(ttip)
@@ -1094,9 +1149,12 @@ class SystemTrayIcon(QMainWindow):
             self.uv_value_label.setText('<font color=>' + uv_gauge + '</font>')
         logging.debug('UV gauge ◼: ' + uv_gauge)
         self.uv_value_label.setToolTip(self.uv_recommend[uv_color[1]])
-        if uv_gauge != '-':
-            self.over_grid.addWidget(self.uv_label, 8, 0)
-            self.over_grid.addWidget(self.uv_value_label, 8, 1)
+        if uv_gauge == '-':
+            self.uv_label.hide()
+            self.uv_value_label.hide()
+        else:
+            self.uv_label.show()
+            self.uv_value_label.show()
 
     def dayiconfetch(self):
         '''Icons for the forecast of the day'''
@@ -1164,7 +1222,7 @@ class SystemTrayIcon(QMainWindow):
             or self.download_thread.isRunning()
         ):
             logging.debug(
-                'WheelEvent : Downloading icons - remaining thread...'
+                'WheelEvent: Downloading icons - remaining thread...'
             )
             return
         self.icon_city_loading()
@@ -1217,8 +1275,8 @@ class SystemTrayIcon(QMainWindow):
             )
         except:
             logging.debug(
-                'Cities menu : firsttime run,'
-                'if clic cancel in settings without any city configured'
+                'Cities menu: firsttime run,'
+                'if clicked cancel in settings without any city configured'
             )
             pass
         # Prevent duplicate entries
@@ -1300,7 +1358,7 @@ class SystemTrayIcon(QMainWindow):
             self.icon_city_loading()
         self.inerror = False
         self.systray.setIcon(QIcon(':/noicon'))
-        self.systray.setToolTip(self.tr('Fetching weather data ...'))
+        self.systray.setToolTip(self.tr('Fetching weather data...'))
         self.city = self.settings.value('City') or ''
         self.id_ = self.settings.value('ID') or None
         if self.id_ is None:
@@ -1373,7 +1431,7 @@ class SystemTrayIcon(QMainWindow):
             self.inerror = False
         elif done == 1:
             self.inerror = True
-            logging.debug('Trying to retrieve data ...')
+            logging.debug('Trying to retrieve data...')
             self.timer.singleShot(10000, self.try_again)
             return
         if hasattr(self, 'updateicon'):
@@ -1414,62 +1472,107 @@ class SystemTrayIcon(QMainWindow):
     def weatherdata(self, tree):
         if self.inerror:
             return
-        self.tempFloat = tree[1].get('value')
-        self.temp = ' ' + str(round(float(self.tempFloat))) + '°'
-        self.temp_decimal = '{0:.1f}'.format(float(self.tempFloat)) + '°'
-        self.meteo = tree[8].get('value')
-        meteo_condition = tree[8].get('number')
-        try:
-            self.meteo = self.conditions[meteo_condition]
-        except:
-            logging.debug('Cannot find localisation string for'
-                          'meteo_condition:' + str(meteo_condition))
-            pass
-        clouds = tree[5].get('name')
-        clouds_percent = tree[5].get('value') + '%'
-        try:
-            clouds = self.clouds[clouds]
-            clouds = self.conditions[clouds]
-        except:
-            logging.debug(
-                'Cannot find localisation string for clouds:'
-                + str(clouds)
-            )
-            pass
-        wind = tree[4][0].get('name').lower()
-        try:
-            wind = self.wind[wind]
-            wind = self.conditions[wind]
-        except:
-            logging.debug(
-                'Cannot find localisation string for wind:'
-                + str(wind)
-            )
-            pass
-        try:
-            wind_codes = tree[4][2].get('code')
-            wind_dir_value = tree[4][2].get('value')
-            wind_dir = tree[4][2].get('name')
-        except:
-            wind_codes = tree[4][1].get('code')
-            wind_dir_value = tree[4][1].get('value')
-            wind_dir = tree[4][1].get('name')
-        try:
-            wind_codes = self.wind_codes[wind_codes]
-        except:
-            logging.debug(
-                'Cannot find localisation string for wind_codes:'
-                + str(wind_codes)
-            )
-            pass
-        try:
-            wind_dir = self.wind_dir[tree[4][2].get('code')]
-        except:
-            logging.debug(
-                'Cannot find localisation string for wind_dir:'
-                + str(wind_dir)
-            )
-            pass
+
+        for element in tree.iter():
+
+            if element.tag == 'sun':
+                self.weatherDataDico['Sunrise'] = element.get('rise')
+                self.weatherDataDico['Sunset'] = element.get('set')
+
+            if element.tag == 'temperature':
+                self.tempFloat = element.get('value')
+                self.temp = ' ' + str(round(float(self.tempFloat))) + '°'
+                self.temp_decimal = '{0:.1f}'.format(float(self.tempFloat)) + '°'
+
+            if element.tag == 'weather':
+                self.meteo = element.get('value')
+                meteo_condition = element.get('number')
+                try:
+                    self.meteo = self.conditions[meteo_condition]
+                except KeyError:
+                    logging.debug(
+                        'Cannot find localisation string for'
+                        ' meteo_condition:'
+                        + str(meteo_condition)
+                    )
+                    pass
+
+            if element.tag == 'clouds':
+                clouds = element.get('name')
+                clouds_percent = element.get('value') + '%'
+                try:
+                    clouds = self.clouds[clouds]
+                    clouds = self.conditions[clouds]
+                except KeyError:
+                    logging.debug(
+                        'Cannot find localisation string for clouds:'
+                        + str(clouds)
+                    )
+                    pass
+
+            if element.tag == 'speed':
+                wind_value = element.get('value')
+                wind = element.get('name').lower()
+                try:
+                    wind = self.wind[wind]
+                    wind = self.conditions[wind]
+                except KeyError:
+                    logging.debug(
+                        'Cannot find localisation string for wind:'
+                        + str(wind)
+                    )
+                    pass
+            if element.tag == 'direction':
+                wind_codes_english = element.get('code')
+                wind_dir_value = element.get('value')
+                wind_dir = element.get('name')
+
+                try:
+                    wind_dir_value = str(int(float(wind_dir_value)))
+                except TypeError:
+                    wind_dir_value = ''
+
+                try:
+                    wind_codes = self.wind_codes[wind_codes_english]
+                except (KeyError, UnboundLocalError):
+                    logging.debug(
+                        'Cannot find localisation string for wind_codes:'
+                        + str(wind_codes_english)
+                    )
+                    wind_codes = wind_codes_english
+
+                if wind_codes is None:
+                    wind_codes = ''
+
+                try:
+                    wind_dir = self.wind_dir[wind_codes_english]
+                except KeyError:
+                    logging.debug(
+                        'Cannot find localisation string for wind_dir:'
+                        + str(wind_dir)
+                    )
+                    if wind_dir is None:
+                        wind_dir = ''
+
+            if element.tag == 'humidity':
+                self.weatherDataDico['Humidity'] = (
+                    element.get('value'), element.get('unit')
+                )
+
+            if element.tag == 'pressure':
+                self.weatherDataDico['Pressure'] = (
+                    element.get('value'), element.get('unit')
+                )
+
+            if element.tag == 'precipitation':
+                rain_mode = element.get('mode')
+                rain_value = element.get('value')
+                if rain_value is None:
+                    rain_value = ''
+                self.weatherDataDico['Precipitation'] = (
+                    rain_mode, rain_value
+                )
+
         self.city_weather_info = (
             self.city + ' ' + self.country + ' '
             + self.temp_decimal + ' ' + self.meteo
@@ -1481,24 +1584,16 @@ class SystemTrayIcon(QMainWindow):
         self.weatherDataDico['Country'] = self.country
         self.weatherDataDico['Temp'] = self.tempFloat + '°'
         self.weatherDataDico['Meteo'] = self.meteo
-        self.weatherDataDico['Humidity'] = (tree[2].get('value'),
-                                            tree[2].get('unit'))
+
         self.weatherDataDico['Wind'] = (
-            tree[4][0].get('value'), wind, str(int(float(wind_dir_value))),
-            wind_codes, wind_dir)
-        self.weatherDataDico['Clouds'] = (clouds_percent + ' ' + clouds)
-        self.weatherDataDico['Pressure'] = (tree[3].get('value'),
-                                            tree[3].get('unit'))
-        self.weatherDataDico['Humidity'] = (tree[2].get('value'),
-                                            tree[2].get('unit'))
-        self.weatherDataDico['Sunrise'] = tree[0][2].get('rise')
-        self.weatherDataDico['Sunset'] = tree[0][2].get('set')
-        rain_value = tree[7].get('value')
-        if rain_value is None:
-            rain_value = ''
-        self.weatherDataDico['Precipitation'] = (
-            tree[7].get('mode'), rain_value
+            wind_value,
+            wind,
+            wind_dir_value,
+            wind_codes,
+            wind_dir
         )
+        self.weatherDataDico['Clouds'] = (clouds_percent + ' ' + clouds)
+
         if self.id_ not in self.trendCities_dic:
             # dict {'id': 'hPa', , '',  'T°', 'temp_trend', 'weather changedBool'}
             self.trendCities_dic[self.id_] = [''] * 5
@@ -1655,10 +1750,14 @@ class SystemTrayIcon(QMainWindow):
         self.activate(3)
 
     def activate(self, reason):
+        ##  Option to start with the panel closed, true by defaut
+        #   starting with the panel open can be useful for users who don't have plasma
+        #   installed (to set keyboard shortcuts or other default window behaviours)
+        start_minimized = self.settings.value('StartMinimized') or 'True'
         if reason == 3:
             if self.inerror or self.id_ is None or self.id_ == '':
                 return
-            if self.isVisible():
+            if self.isVisible() and start_minimized == 'True':
                 self.hide()
             else:
                 self.show()
@@ -1840,22 +1939,33 @@ class Download(QThread):
         done = 0
 
         logging.debug(
-            'Fetching url for 6 days :' + self.forecast6_url
+            'Fetching url for 6 days: ' + self.forecast6_url
             + self.id_ + self.suffix + '&cnt=7'
         )
+        reqforecast6 = (
+            self.forecast6_url + self.id_
+            + self.suffix + '&cnt=7'
+        )
         try:
             reqforecast6 = urllib.request.urlopen(
                 self.forecast6_url + self.id_
                 + self.suffix + '&cnt=7', timeout=5
             )
             pageforecast6 = reqforecast6.read()
+            if str(pageforecast6).count('ClientError') > 0:
+                raise TypeError
             treeforecast6 = etree.fromstring(pageforecast6)
             forcast6days = True
         except (
-            urllib.error.HTTPError, urllib.error.URLError, etree.XMLSyntaxError
+                timeout,
+                urllib.error.HTTPError,
+                urllib.error.URLError,
+                etree.XMLSyntaxError,
+                TypeError
         ) as e:
             forcast6days = False
-            logging.error('6 days forcast not available : ' + str(e))
+            logging.error('Url of 6 days forcast not available: ' + str(reqforecast6))
+            logging.error('6 days forcast not available: ' + str(e))
 
         try:
             logging.debug(
@@ -1877,7 +1987,7 @@ class Download(QThread):
             elif self.html404(pagedayforecast, 'day_forecast'):
                 # Try with json
                 logging.debug(
-                    'Fetching json url for forecast of the day :'
+                    'Fetching json url for forecast of the day: '
                     + self.day_forecast_url + self.id_
                     + self.suffix.replace('xml', 'json')
                 )
@@ -1914,13 +2024,16 @@ class Download(QThread):
             self.day_forecast_rawpage['PyQt_PyObject'].emit(treedayforecast)
             self.done.emit(int(done))
         except (
-            urllib.error.HTTPError, urllib.error.URLError, TypeError
+                ConnectionResetError,
+                urllib.error.HTTPError,
+                urllib.error.URLError,
+                TypeError
         ) as error:
             if self.tentatives >= 10:
                 done = 1
                 try:
                     m_error = (
-                        self.tr('Error :\n') + str(error.code)
+                        self.tr('Error:\n') + str(error.code)
                         + ' ' + str(error.reason)
                     )
                 except:
@@ -1931,7 +2044,7 @@ class Download(QThread):
                 return
             else:
                 self.tentatives += 1
-                logging.warn('Error: ' + str(error))
+                logging.warning('Error: ' + str(error))
                 logging.info('Try again...' + str(self.tentatives))
                 self.run()
         except timeout:
@@ -1942,7 +2055,7 @@ class Download(QThread):
                 return
             else:
                 self.tentatives += 1
-                logging.warn(
+                logging.warning(
                     '5 secondes timeout, new tentative: '
                     + str(self.tentatives)
                 )
@@ -2225,7 +2338,7 @@ def main():
     loggerStream = logging.getLogger()
     handlerStream = logging.StreamHandler()
     loggerStreamFormatter = logging.Formatter(
-        '%(levelname)s: %(message)s - %(lineno)s :%(module)s'
+        '%(levelname)s: %(message)s - %(lineno)s: %(module)s'
     )
     handlerStream.setFormatter(loggerStreamFormatter)
     loggerStream.addHandler(handlerStream)
@@ -2234,5 +2347,42 @@ def main():
     app.exec_()
 
 
+def excepthook(exc_type, exc_value, tracebackobj):
+    """
+    Global function to catch unhandled exceptions.
+
+    Parameters
+    ----------
+    exc_type : str
+        exception type
+    exc_value : int
+        exception value
+    tracebackobj : traceback
+        traceback object
+    """
+    separator = '-' * 80
+
+    now = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") + ' CRASH:'
+
+    info = StringIO()
+    traceback.print_tb(tracebackobj, None, info)
+    info.seek(0)
+    info = info.read()
+
+    errmsg = '{}\t \n{}'.format(exc_type, exc_value)
+    sections = [now, separator, errmsg, separator, info]
+    msg = '\n'.join(sections)
+
+    print(msg)
+
+    settings = QSettings()
+    logPath = os.path.dirname(settings.fileName())
+    logFile = logPath + '/meteo-qt.log'
+    with open(logFile, 'a') as logfile:
+        logfile.write(msg)
+
+
+sys.excepthook = excepthook
+
 if __name__ == '__main__':
     main()
--- meteo-qt-1.0.0.orig/meteo_qt/searchcity.py
+++ meteo-qt-1.0.0/meteo_qt/searchcity.py
@@ -327,7 +327,7 @@ class WorkThread(QThread):
                 + self.suffix
             )
             logging.debug(
-                'City before utf8 encode :' + self.accurate_url
+                'City before utf8 encode: ' + self.accurate_url
                 + self.city + self.suffix
             )
             req = urllib.request.urlopen(
--- meteo-qt-1.0.0.orig/meteo_qt/settings.py
+++ meteo-qt-1.0.0/meteo_qt/settings.py
@@ -290,6 +290,21 @@ class MeteoSettings(QDialog):
         self.owmkey_text = QLineEdit()
         self.owmkey_text.setText(apikey)
         self.owmkey_text.textChanged.connect(self.apikey_changed)
+
+        self.start_minimized_label = QLabel(
+            QCoreApplication.translate(
+                'Checkable option to show or not the window at startup',
+                'Start minimized',
+                'Settings dialogue'
+            )
+        )
+        self.start_minimized_chbx = QCheckBox()
+        start_minimized_bool = self.settings.value('StartMinimized') or 'True'
+        self.start_minimized_bool = eval(start_minimized_bool)
+        self.start_minimized_chbx.setChecked(self.start_minimized_bool)
+        self.start_minimized_chbx.stateChanged.connect(self.start_minimized)
+        self.start_minimized_changed = False
+
         # ----------
         self.panel = QGridLayout()
         self.panel.addWidget(self.city_title, 0, 0)
@@ -323,6 +338,8 @@ class MeteoSettings(QDialog):
         self.panel.addWidget(self.owmkey_label, 11, 0)
         self.panel.addWidget(self.owmkey_text, 11, 1)
         self.panel.addWidget(self.owmkey_create, 11, 2)
+        self.panel.addWidget(self.start_minimized_label, 12, 0)
+        self.panel.addWidget(self.start_minimized_chbx, 12, 1)
 
         self.layout.addLayout(self.panel)
         self.layout.addLayout(self.buttonLayout)
@@ -513,6 +530,18 @@ class MeteoSettings(QDialog):
             bold = 'False'
         self.settings.setValue('Bold', str(bold))
 
+    def start_minimized(self, state):
+        self.start_minimized_state = state
+        self.start_minimized_changed = True
+        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
+
+    def start_minimized_apply(self):
+        if self.start_minimized_state == 2:
+            start_minimized = 'True'
+        else:
+            start_minimized = 'False'
+        self.settings.setValue('StartMinimized', start_minimized)
+
     def beaufort(self, state):
         self.bft_state = state
         self.bft_changed = True
@@ -630,6 +659,8 @@ class MeteoSettings(QDialog):
             self.bold_apply()
         if self.bft_changed:
             self.beaufort_apply()
+        if self.start_minimized_changed:
+            self.start_minimized_apply()
         proxy_url = self.settings.value('Proxy_url') or ''
         if proxy_url == '':
             self.proxy_bool = False
--- meteo-qt-1.0.0.orig/share/meteo-qt.desktop
+++ meteo-qt-1.0.0/share/meteo-qt.desktop
@@ -1,23 +1,29 @@
 [Desktop Entry]
 Type=Application
 Name=Meteo-qt
+Name[cs]=Meteo-qt
 Name[el]=Meteo-qt
 Name[pl]=Meteo-qt
 Name[ru]=Meteo-qt
+Name[sk]=Meteo-qt
 Name[uk]=Meteo-qt
 Name[es]=Meteo-qt
 GenericName=Weather status information
+GenericName[cs]=Informace o počasí
 GenericName[de]=Informationen zur Wetterlage
 GenericName[el]=Μετεωρολογικές πληροφορίες
 GenericName[pl]=Informacje pogodowe
 GenericName[ru]=Сведения о погоде
+GenericName[sk]=Informácie o počasí
 GenericName[uk]=Дані щодо погоди
 GenericName[es]=Información meteorológica
 Comment=A Qt system tray application for weather information
+Comment[cs]=Qt aplikace, která zobrazuje informace o počasí v systémové liště
 Comment[de]=Qt Anwendung für die Benachrichtungsfläche von Taskleisten, die Informationen zur Wetterlage anzeigt
 Comment[el]=Μια Qt εφαρμογή πλαισίου συστήματος για τις καιρικές συνθήκες
 Comment[pl]=Aplikacja Qt z informacjami pogodowymi zasobniku systemowym
 Comment[ru]=Отображает сведения о погоде в системном лотке
+Comment[sk]=Qt aplikácia, ktorá zobrazuje informácie o počasí v systémovej lište
 Comment[uk]=Програма на Qt, що показує дані щодо погоди у системному лотку
 Comment[es]=Una aplicación de icono de bandeja para información meteorológica
 Exec=meteo-qt

Reply via email to