Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions weather.ozweather/addon.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="weather.ozweather" name="Oz Weather" version="2.1.5" provider-name="Bossanova808">
<addon id="weather.ozweather" name="Oz Weather" version="2.1.6" provider-name="Bossanova808">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.requests" version="2.22.0+matrix.1"/>
<import addon="script.module.beautifulsoup4" version="4.8.2+matrix.1"/>
<import addon="script.module.pytz" version="3.0+matrix.2"/>
<import addon="script.module.bossanova808" version="1.0.0"/>
<import addon="script.module.bossanova808" version="1.0.2"/>
</requires>
<extension point="xbmc.python.weather" library="default.py"/>
<extension point="xbmc.addon.metadata">
Expand All @@ -23,8 +23,9 @@
<icon>icon.png</icon>
<fanart>fanart.jpg</fanart>
</assets>
<news>v2.1.5 Minor fixes
- Fix feels like calculation when data not returned by BOM, and Current.Wind
<news>v2.1.6 Performance improvements, prep for Piers
- Improve performance when used with multiple Kodi Profiles by using a shared cache (stored under special://temp/ozweather)
- A bunch of code improvements and defensive programming to cope with scenarios where things are not at times available
</news>
</extension>
</addon>
5 changes: 5 additions & 0 deletions weather.ozweather/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v2.1.6 Performance improvements, prep for Piers
- Improve performance when used with multiple Kodi Profiles by using a shared cache (stored under special://temp/ozweather)
- A bunch of code improvements and defensive programming to cope with scenarios where things are not at times available


v2.1.5 Minor fixes
- Fix feels like calculation when data not returned by BOM, and Current.Wind

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,20 @@ msgstr ""

msgctxt "#32208"
msgid "Enter postcode, suburb or area."
msgstr "
msgstr ""

msgctxt "#32209"
msgid "Radar backgrounds not showing? Try forcing a refresh"
msgstr "
msgstr ""

msgctxt "#32210"
msgid "Refresh all radar backgrounds on next weather fetch?"
msgstr "
msgstr ""

msgctxt "#32211"
msgid "Closest Radar "
msgstr "
msgstr ""

msgctxt "#32212"
msgid "If entered, these radar codes overrule the closest found."
msgstr "
msgstr ""
21 changes: 15 additions & 6 deletions weather.ozweather/resources/lib/abc/abc_video.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# -*- coding: utf-8 -*-
import requests
import sys
import xbmc
import xbmcgui
import json
from bs4 import BeautifulSoup

# Allow for unit testing this file
# Allow for unit testing this file (remember to install kodistubs!)
# This brings this addon's resources, and bossanova808 module stuff into scope
# (when running this module outside Kodi)
if not xbmc.getUserAgent():
sys.path.insert(0, '../../..')
sys.path.insert(0, '../../../../script.module.bossanova808/resources/lib')

from resources.lib.store import Store
from bossanova808.utilities import *
from bossanova808.constants import CWD
from bossanova808.logger import Logger


def scrape_and_play_abc_weather_video():
Expand All @@ -21,8 +23,11 @@ def scrape_and_play_abc_weather_video():
"""
url = get_abc_weather_video_link()
# Construct an offscreen list item with metadata...
if not url:
xbmcgui.Dialog().notification("OzWeather", "Couldn't retrieve ABC weather video - sorry!", xbmcgui.NOTIFICATION_ERROR, 4000)
return
item = xbmcgui.ListItem(path=url)
item.setProperty('mimetype', 'video/mpeg')
item.setProperty('mimetype', 'video/mp4')
item.setInfo('Video', {'title': 'ABC Weather In 90 Seconds'})
item.setArt({'thumb': f'{CWD}/resources/weather-in-90-seconds.png'})
# ...and then play it, fullscreen
Expand All @@ -33,9 +38,13 @@ def scrape_and_play_abc_weather_video():
# See bottom of this file for notes on matching the video links (& Store.py for the regex)
def get_abc_weather_video_link():
try:
r = requests.get(Store.ABC_URL)
r = requests.get(Store.ABC_URL, timeout=15)
bs = BeautifulSoup(r.text, "html.parser")
json_string = bs.find("script", {'type': 'application/json', "id": "__NEXT_DATA__"})
if not json_string or not json_string.string:
error_msg = "ABC __NEXT_DATA__ script not found on page, couldn't extract ABC weather video link"
Logger.error(error_msg)
raise ValueError(error_msg)
json_object = json.loads(json_string.string)
# Logger.debug(json_object)
# Put the json blob into: https://jsonhero.io/j/JU0I9LB4AlLU
Expand All @@ -48,7 +57,7 @@ def get_abc_weather_video_link():
return sorted(urls, key=lambda x: x['bitrate'], reverse=True)[0]['file']

except Exception as inst:
Logger.error("Couldn't get ABC video URL from scraped page: " + str(inst))
Logger.error(f"Couldn't get ABC video URL from scraped page: {inst}")
return ""


Expand Down
25 changes: 10 additions & 15 deletions weather.ozweather/resources/lib/bom/bom_forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
import math
import xbmc

# Allow for unit testing this file
# Allow for unit testing this file e (remember to install kodistubs!)
# This brings this addon's resources, and bossanova808 module stuff into scope
# (when running this module outside Kodi)
if not xbmc.getUserAgent():
sys.path.insert(0, '../../..')
sys.path.insert(0, '../../../../script.module.bossanova808/resources/lib')

from resources.lib.store import Store
from bossanova808.utilities import *
from bossanova808.logger import Logger

"""
Expand Down Expand Up @@ -48,11 +47,7 @@ def set_key(weather_data, index, key, value):

if index == 0:
weather_data['Current.' + key] = value.strip()
weather_data['Current.' + key] = value.strip()

weather_data['Day' + str(index) + '.' + key] = value.strip()
weather_data['Day' + str(index) + '.' + key] = value.strip()
weather_data['Daily.' + str(index + 1) + '.' + key] = value.strip()
weather_data['Daily.' + str(index + 1) + '.' + key] = value.strip()


Expand Down Expand Up @@ -121,9 +116,9 @@ def bom_forecast(geohash):

bom_api_current_observations_url = f'{bom_api_url_areahash}/observations'
bom_api_forecast_seven_days_url = f'{bom_api_url_areahash}/forecasts/daily'
# FUTURE? - these API end points exist, but are not yet used by OzWeather
# bom_api_forecast_three_hourly_url = f'{bom_api_url_areahash}/forecasts/3-hourly'
# bom_api_forecast_rain = f'{bom_api_url_areahash}/forecast/rain'
# FUTURE? - these API end points exist, but are not yet actually used by OzWeather
# bom_api_forecast_three_hourly_url = f"{bom_api_url_areahash}/forecasts/3-hourly"
# bom_api_forecast_rain = f"{bom_api_url_areahash}/forecast/rain"

# Holders for the BOM JSON API results...
area_information = None
Expand All @@ -139,7 +134,7 @@ def bom_forecast(geohash):
now = datetime.datetime.now()

try:
r = requests.get(bom_api_area_information_url)
r = requests.get(bom_api_area_information_url, timeout=15)
area_information = r.json()["data"]
Logger.debug(area_information)
if area_information:
Expand All @@ -153,7 +148,7 @@ def bom_forecast(geohash):

# Get CURRENT OBSERVATIONS
try:
r = requests.get(bom_api_current_observations_url)
r = requests.get(bom_api_current_observations_url, timeout=15)
current_observations = r.json()["data"]
weather_data['ObservationsUpdated'] = utc_str_to_local_str(r.json()["metadata"]["issue_time"], time_zone=location_timezone)
weather_data['ObservationsStation'] = r.json()["data"]['station']['name']
Expand All @@ -173,7 +168,7 @@ def bom_forecast(geohash):

# Get 7-DAY FORECAST
try:
r = requests.get(bom_api_forecast_seven_days_url)
r = requests.get(bom_api_forecast_seven_days_url, timeout=15)
forecast_seven_days = r.json()["data"]
weather_data['ForecastUpdated'] = utc_str_to_local_str(r.json()["metadata"]["issue_time"], time_zone=location_timezone)
weather_data['ForecastRegion'] = r.json()["metadata"]["forecast_region"].title()
Expand All @@ -187,7 +182,7 @@ def bom_forecast(geohash):
# FUTURE?
# # Get 3 HOURLY FORECAST
# try:
# r = requests.get(bom_api_forecast_three_hourly_url)
# r = requests.get(bom_api_forecast_three_hourly_url, timeout=15)
# forecast_three_hourly = r.json()["data"]
# log(forecast_three_hourly)
#
Expand All @@ -197,7 +192,7 @@ def bom_forecast(geohash):
#
# # Get RAIN FORECAST
# try:
# r = requests.get(bom_api_forecast_rain)
# r = requests.get(bom_api_forecast_rain, timeout=15)
# forecast_rain = r.json()["data"]
# log(forecast_rain)
#
Expand Down Expand Up @@ -285,7 +280,7 @@ def bom_forecast(geohash):

weather_data['Current.WarningsText'] = warnings_text

# 7 DAY FORECAST
# 7-DAY FORECAST
if forecast_seven_days:
weather_data['Current.Condition'] = forecast_seven_days[0]['short_text']
weather_data['Current.ConditionLong'] = forecast_seven_days[0]['extended_text']
Expand Down
18 changes: 10 additions & 8 deletions weather.ozweather/resources/lib/bom/bom_location.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import requests
import sys
import xbmc
import xbmcgui

# Allow for unit testing this file
# Allow for unit testing this file (remember to install kodistubs!)
# This brings this addon's resources, and bossanova808 module stuff into scope
# (when running this module outside Kodi)
# (only when running this module *outside* of Kodi)
if not xbmc.getUserAgent():
sys.path.insert(0, '../../..')
sys.path.insert(0, '../../../../script.module.bossanova808/resources/lib')

from resources.lib.bom.bom_radar import *
from bossanova808.utilities import *
from resources.lib.store import Store
from resources.lib.bom.bom_radar import closest_radar_to_lat_lon
from bossanova808.constants import ADDON, ADDON_NAME, TRANSLATE
from bossanova808.logger import Logger


Expand All @@ -23,7 +25,7 @@ def get_bom_locations_for(text):
location_geohashes = []

try:
r = requests.get(Store.BOM_API_LOCATIONS_URL, params={'search': text})
r = requests.get(Store.BOM_API_LOCATIONS_URL, params={'search': text}, timeout=15)
for result in r.json()['data']:
Logger.debug(result)
locations.append(f'{result["name"]}, {result["state"]} {result["postcode"]} ({result["geohash"]})')
Expand All @@ -45,7 +47,7 @@ def find_bom_location():
What we need is actually a geohash we can then use with the BOM API
Save the chosen result, e.g. Ascot Vale, VIC 3032 and geohash r1r11df
"""
keyboard = xbmc.Keyboard('', LANGUAGE(32195), False)
keyboard = xbmc.Keyboard('', TRANSLATE(32195), False)
keyboard.doModal()

if keyboard.isConfirmed() and keyboard.getText() != '':
Expand All @@ -68,10 +70,10 @@ def find_bom_location():
# Don't save the settings is this goes wrong
location_info_url = f'https://api.weather.bom.gov.au/v1/locations/{location_geohashes[selected]}'
try:
location_info = requests.get(location_info_url).json()['data']
location_info = requests.get(location_info_url, timeout=15).json()['data']
Logger.debug(location_info)
except:
Logger.debug("Error retrieving location info for geohash {location_geohashes[selected]}")
Logger.debug(f"Error retrieving location info for geohash {location_geohashes[selected]}")
raise

# Save the geohash and latitude and longitude of the location
Expand Down
Loading