Weatherbit alerts API

This commit is contained in:
piotr
2022-06-21 03:29:46 +02:00
parent 996ad78f9a
commit 0588c18c9f
6 changed files with 368 additions and 37 deletions

View File

@@ -137,6 +137,7 @@ SKELETON_PANEL: dict = {
}, },
"openweather": { "openweather": {
"appid": "", "appid": "",
"weatherbit-api-key": "",
"lat": None, "lat": None,
"long": None, "long": None,
"lang": "en", "lang": "en",
@@ -914,9 +915,8 @@ class EditorWrapper(object):
if self.delete_weather_data: if self.delete_weather_data:
tmp_dir = temp_dir() tmp_dir = temp_dir()
for item in ["nwg-openweather-weather", "nwg-openweather-forecast"]: for item in ["nwg-openweather-weather", "nwg-openweather-forecast", "nwg-weatherbit-alerts"]:
f = "{}-{}".format(os.path.join(tmp_dir, item), self.panel["openweather"]["module-id"]) f = "{}-{}".format(os.path.join(tmp_dir, item), self.panel["openweather"]["module-id"])
# f = os.path.join(tmp_dir, item)
if os.path.exists(f): if os.path.exists(f):
eprint("Deleting {}".format(f)) eprint("Deleting {}".format(f))
os.remove(f) os.remove(f)
@@ -1723,6 +1723,7 @@ class EditorWrapper(object):
defaults = { defaults = {
"module-id": str(time.time()), "module-id": str(time.time()),
"appid": "", "appid": "",
"weatherbit-api-key": "",
"lat": None, "lat": None,
"long": None, "long": None,
"lang": "en", "lang": "en",
@@ -1770,6 +1771,12 @@ class EditorWrapper(object):
key_visibility_switch = builder.get_object("key-visibility-switch") key_visibility_switch = builder.get_object("key-visibility-switch")
key_visibility_switch.connect("toggled", switch_entry_visibility, self.ow_appid) key_visibility_switch.connect("toggled", switch_entry_visibility, self.ow_appid)
self.weatherbit_api_key = builder.get_object("weatherbit-api-key")
self.weatherbit_api_key.set_text(settings["weatherbit-api-key"])
key_visibility_switch1 = builder.get_object("key-visibility-switch1")
key_visibility_switch1.connect("toggled", switch_entry_visibility, self.weatherbit_api_key)
# Try to obtain geolocation if unset # Try to obtain geolocation if unset
if not settings["lat"] or not settings["long"]: if not settings["lat"] or not settings["long"]:
# Try nwg-shell settings # Try nwg-shell settings
@@ -1916,6 +1923,7 @@ class EditorWrapper(object):
settings = self.panel["openweather"] settings = self.panel["openweather"]
settings["appid"] = self.ow_appid.get_text() settings["appid"] = self.ow_appid.get_text()
settings["weatherbit-api-key"] = self.weatherbit_api_key.get_text()
settings["lat"] = round(self.ow_lat.get_value(), 4) settings["lat"] = round(self.ow_lat.get_value(), 4)
settings["long"] = round(self.ow_long.get_value(), 4) settings["long"] = round(self.ow_long.get_value(), 4)
settings["lang"] = self.ow_lang.get_text() settings["lang"] = self.ow_lang.get_text()

View File

@@ -8,7 +8,7 @@
<property name="label-xalign">0.5</property> <property name="label-xalign">0.5</property>
<property name="shadow-type">out</property> <property name="shadow-type">out</property>
<child> <child>
<!-- n-columns=3 n-rows=33 --> <!-- n-columns=3 n-rows=35 -->
<object class="GtkGrid" id="grid"> <object class="GtkGrid" id="grid">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
@@ -773,6 +773,7 @@ Creative Commons Attribution-ShareAlike 4.0</property>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">&lt;a href="https://openweathermap.org/appid"&gt;https://openweathermap.org/appid&lt;/a&gt;</property> <property name="label" translatable="yes">&lt;a href="https://openweathermap.org/appid"&gt;https://openweathermap.org/appid&lt;/a&gt;</property>
<property name="use-markup">True</property> <property name="use-markup">True</property>
</object> </object>
@@ -781,38 +782,6 @@ Creative Commons Attribution-ShareAlike 4.0</property>
<property name="top-attach">0</property> <property name="top-attach">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="module-id">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="margin-top">6</property>
<property name="label" translatable="yes">module.id</property>
<attributes>
<attribute name="style" value="oblique"/>
</attributes>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">32</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="margin-top">6</property>
<property name="label" translatable="yes">Module ID:</property>
<attributes>
<attribute name="style" value="oblique"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">32</property>
</packing>
</child>
<child> <child>
<object class="GtkCheckButton" id="show-volume"> <object class="GtkCheckButton" id="show-volume">
<property name="label" translatable="yes">Show precipitation volume</property> <property name="label" translatable="yes">Show precipitation volume</property>
@@ -827,6 +796,107 @@ Creative Commons Attribution-ShareAlike 4.0</property>
<property name="top-attach">31</property> <property name="top-attach">31</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="module-id">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="margin-top">6</property>
<property name="label" translatable="yes">module.id</property>
<attributes>
<attribute name="style" value="oblique"/>
</attributes>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">34</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="margin-top">6</property>
<property name="label" translatable="yes">Module ID:</property>
<attributes>
<attribute name="style" value="oblique"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">34</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Alerts</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">32</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">&lt;a href="https://www.weatherbit.io/account/create"&gt;https://www.weatherbit.io/account/create&lt;/a&gt;</property>
<property name="use-markup">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">32</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Weatherbit API key:</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">33</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="weatherbit-api-key">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="tooltip-text" translatable="yes">Paste your API key (appid) here.</property>
<property name="visibility">False</property>
<property name="invisible-char">●</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">33</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="key-visibility-switch1">
<property name="label" translatable="yes">show</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">33</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="6"
height="16"
viewBox="0 0 1.5874999 4.2333333"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="exclamation.svg"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="36.630209"
inkscape:cx="10.797099"
inkscape:cy="7.3300155"
inkscape:window-width="1918"
inkscape:window-height="1018"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showguides="true"><sodipodi:guide
position="1.5875,3.8866258"
orientation="-1,0"
id="guide5215"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
position="-1.6210715,4.2333331"
orientation="0,1"
id="guide2784"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /></sodipodi:namedview><defs
id="defs2" /><g
inkscape:label="Warstwa 1"
inkscape:groupmode="layer"
id="layer1"><text
xml:space="preserve"
style="font-size:3.25507px;line-height:1.25;font-family:sans-serif;fill:#444444;fill-opacity:0.811765;stroke-width:0.152581"
x="0.28444344"
y="3.4721246"
id="text1215"
transform="scale(1.1180032,0.89445183)"><tspan
sodipodi:role="line"
id="tspan1213"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#444444;fill-opacity:0.811765;stroke-width:0.152581"
x="0.28444344"
y="3.4721246">!</tspan></text><text
xml:space="preserve"
style="font-size:3.25507px;line-height:1.25;font-family:sans-serif;fill:#c86400;fill-opacity:1;stroke-width:0.152581"
x="0.23405394"
y="3.4159362"
id="text1215-2"
transform="scale(1.1180032,0.89445183)"><tspan
sodipodi:role="line"
id="tspan1213-9"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#c86400;fill-opacity:1;stroke-width:0.152581"
x="0.23405394"
y="3.4159362">!</tspan></text></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="6"
height="16"
viewBox="0 0 1.5874999 4.2333333"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="exclamation.svg"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="36.630209"
inkscape:cx="10.797099"
inkscape:cy="7.2754158"
inkscape:window-width="1918"
inkscape:window-height="1018"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showguides="true"><sodipodi:guide
position="1.5875,3.8866258"
orientation="-1,0"
id="guide5215"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
position="-1.6210715,4.2333331"
orientation="0,1"
id="guide2784"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /></sodipodi:namedview><defs
id="defs2" /><g
inkscape:label="Warstwa 1"
inkscape:groupmode="layer"
id="layer1"><text
xml:space="preserve"
style="font-size:3.25507px;line-height:1.25;font-family:sans-serif;fill:#444444;fill-opacity:0.811765;stroke-width:0.152581"
x="0.26079586"
y="3.4129782"
id="text1215"
transform="scale(1.1180032,0.89445183)"><tspan
sodipodi:role="line"
id="tspan1213"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#444444;fill-opacity:0.811765;stroke-width:0.152581"
x="0.26079586"
y="3.4129782">!</tspan></text></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="6"
height="16"
viewBox="0 0 1.5874999 4.2333333"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="exclamation.svg"
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:zoom="36.630209"
inkscape:cx="10.797099"
inkscape:cy="7.3300155"
inkscape:window-width="1918"
inkscape:window-height="1018"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showguides="true"><sodipodi:guide
position="1.5875,3.8866258"
orientation="-1,0"
id="guide5215"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
position="-1.6210715,4.2333331"
orientation="0,1"
id="guide2784"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" /></sodipodi:namedview><defs
id="defs2" /><g
inkscape:label="Warstwa 1"
inkscape:groupmode="layer"
id="layer1"><text
xml:space="preserve"
style="font-size:3.25507px;line-height:1.25;font-family:sans-serif;fill:#efefef;fill-opacity:0.81176472;stroke-width:0.152581"
x="0.26079586"
y="3.4129782"
id="text1215"
transform="scale(1.1180032,0.89445183)"><tspan
sodipodi:role="line"
id="tspan1213"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#efefef;fill-opacity:0.81176472;stroke-width:0.152581"
x="0.26079586"
y="3.4129782">!</tspan></text></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -3,8 +3,8 @@
import json import json
import os import os
import stat import stat
import sys
import subprocess import subprocess
import sys
import threading import threading
from datetime import datetime from datetime import datetime
@@ -70,6 +70,7 @@ def on_button_press(window, event):
class OpenWeather(Gtk.EventBox): class OpenWeather(Gtk.EventBox):
def __init__(self, settings, icons_path=""): def __init__(self, settings, icons_path=""):
defaults = {"appid": "", defaults = {"appid": "",
"weatherbit-api-key": "",
"lat": None, "lat": None,
"long": None, "long": None,
"lang": "en", "lang": "en",
@@ -140,11 +141,13 @@ class OpenWeather(Gtk.EventBox):
self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
self.add(self.box) self.add(self.box)
self.image = Gtk.Image() self.image = Gtk.Image()
self.alert_image = Gtk.Image()
self.label = Gtk.Label.new("No weather data") self.label = Gtk.Label.new("No weather data")
self.icon_path = None self.icon_path = None
self.weather = None self.weather = None
self.forecast = None self.forecast = None
self.alerts = None
self.connect('button-press-event', self.on_button_press) self.connect('button-press-event', self.on_button_press)
self.add_events(Gdk.EventMask.SCROLL_MASK) self.add_events(Gdk.EventMask.SCROLL_MASK)
@@ -166,8 +169,10 @@ class OpenWeather(Gtk.EventBox):
tmp_dir = temp_dir() tmp_dir = temp_dir()
self.weather_file = "{}-{}".format(os.path.join(tmp_dir, "nwg-openweather-weather"), settings["module-id"]) self.weather_file = "{}-{}".format(os.path.join(tmp_dir, "nwg-openweather-weather"), settings["module-id"])
self.forecast_file = "{}-{}".format(os.path.join(tmp_dir, "nwg-openweather-forecast"), settings["module-id"]) self.forecast_file = "{}-{}".format(os.path.join(tmp_dir, "nwg-openweather-forecast"), settings["module-id"])
self.alerts_file = "{}-{}".format(os.path.join(tmp_dir, "nwg-weatherbit-alerts"), settings["module-id"])
eprint("Weather file: {}".format(self.weather_file)) eprint("Weather file: {}".format(self.weather_file))
eprint("Forecast file: {}".format(self.forecast_file)) eprint("Forecast file: {}".format(self.forecast_file))
eprint("Alerts file: {}".format(self.alerts_file))
# Try to obtain geolocation if unset # Try to obtain geolocation if unset
if not settings["lat"] or not settings["long"]: if not settings["lat"] or not settings["long"]:
@@ -191,6 +196,12 @@ class OpenWeather(Gtk.EventBox):
self.forecast_request = "https://api.openweathermap.org/data/2.5/forecast?lat={}&lon={}&units={}&lang={}&appid={}".format( self.forecast_request = "https://api.openweathermap.org/data/2.5/forecast?lat={}&lon={}&units={}&lang={}&appid={}".format(
settings["lat"], settings["long"], settings["units"], settings["lang"], settings["appid"]) settings["lat"], settings["long"], settings["units"], settings["lang"], settings["appid"])
self.alerts_request = "https://api.weatherbit.io/v2.0/alerts?lat={}&lon={}&key={}".format(settings["lat"],
settings["long"],
settings[
"weatherbit-api-key"]) if \
settings["weatherbit-api-key"] else ""
self.build_box() self.build_box()
self.refresh() self.refresh()
@@ -202,15 +213,19 @@ class OpenWeather(Gtk.EventBox):
def build_box(self): def build_box(self):
if self.settings["icon-placement"] == "start": if self.settings["icon-placement"] == "start":
self.box.pack_start(self.alert_image, False, False, 0)
self.box.pack_start(self.image, False, False, 2) self.box.pack_start(self.image, False, False, 2)
self.box.pack_start(self.label, False, False, 2) self.box.pack_start(self.label, False, False, 2)
if self.settings["icon-placement"] != "start": if self.settings["icon-placement"] != "start":
self.box.pack_start(self.alert_image, False, False, 0)
self.box.pack_start(self.image, False, False, 2) self.box.pack_start(self.image, False, False, 2)
def get_data(self): def get_data(self):
self.get_weather() self.get_weather()
self.get_forecast() self.get_forecast()
if self.settings["weatherbit-api-key"]:
self.get_alerts()
GLib.idle_add(self.update_widget) GLib.idle_add(self.update_widget)
return True return True
@@ -270,6 +285,21 @@ class OpenWeather(Gtk.EventBox):
eprint(hms(), "Loading forecast data from file") eprint(hms(), "Loading forecast data from file")
self.forecast = load_json(self.forecast_file) self.forecast = load_json(self.forecast_file)
def get_alerts(self):
if not os.path.isfile(self.alerts_file) or int(file_age(self.alerts_file) > self.settings["interval"] - 1):
eprint(hms(), "Requesting alerts data")
try:
r = requests.get(self.alerts_request)
self.alerts = json.loads(r.text)
if "alerts" in self.alerts:
save_json(self.alerts, self.alerts_file)
except Exception as e:
self.alerts = None
eprint(e)
elif not self.alerts and os.path.isfile(self.alerts_file):
eprint(hms(), "Loading alerts data from file")
self.alerts = load_json(self.alerts_file)
def update_widget(self): def update_widget(self):
if self.weather and self.weather["cod"] and self.weather["cod"] in [200, "200"]: if self.weather and self.weather["cod"] and self.weather["cod"] in [200, "200"]:
if "icon" in self.weather["weather"][0]: if "icon" in self.weather["weather"][0]:
@@ -282,6 +312,16 @@ class OpenWeather(Gtk.EventBox):
self.icon_path = new_path self.icon_path = new_path
except: except:
print("Failed setting image from {}".format(new_path)) print("Failed setting image from {}".format(new_path))
if self.alerts and self.alerts["alerts"]:
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(os.path.join(self.weather_icons, "exclamation.svg"),
self.settings["icon-size"], self.settings["icon-size"])
self.alert_image.set_from_pixbuf(pixbuf)
print(self.alerts["alerts"][0]["title"])
else:
self.alert_image = Gtk.Image()
self.alert_image.set_size_request(0, 0)
lbl_content = "" lbl_content = ""
if "name" in self.weather: if "name" in self.weather:
desc = self.weather["name"] if not self.settings["loc-name"] else self.settings["loc-name"] desc = self.weather["name"] if not self.settings["loc-name"] else self.settings["loc-name"]
@@ -450,6 +490,19 @@ class OpenWeather(Gtk.EventBox):
hbox.pack_start(lbl, True, True, 0) hbox.pack_start(lbl, True, True, 0)
vbox.pack_start(hbox, False, False, 6) vbox.pack_start(hbox, False, False, 6)
# Alerts, if any
if self.alerts and "alerts" in self.alerts:
try:
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
lbl = Gtk.Label()
lbl.set_line_wrap(True)
lbl.set_justify(Gtk.Justification.CENTER)
lbl.set_markup('<span bgcolor="#cc0000"> {} </span>'.format(self.alerts["alerts"][0]["title"]))
hbox.pack_start(lbl, True, False, 6)
vbox.pack_start(hbox, False, False, 6)
except:
pass
# 5-DAY FORECAST # 5-DAY FORECAST
if self.forecast["cod"] in [200, "200"]: if self.forecast["cod"] in [200, "200"]:
lbl = Gtk.Label() lbl = Gtk.Label()
@@ -602,7 +655,7 @@ class OpenWeather(Gtk.EventBox):
if "snow" in data and "3h" in data["snow"]: if "snow" in data and "3h" in data["snow"]:
lbl = Gtk.Label() lbl = Gtk.Label()
lbl.set_markup('<span font_size="{}">{} mm</span>'.format(self.settings["popup-text-size"], lbl.set_markup('<span font_size="{}">{} mm</span>'.format(self.settings["popup-text-size"],
round(data["rain"]["3h"], 2))) round(data["snow"]["3h"], 2)))
box.pack_start(lbl, False, False, 0) box.pack_start(lbl, False, False, 0)
grid.attach(box, 12, i, 1, 1) grid.attach(box, 12, i, 1, 1)