From a87269dd0944a5a5e4ddd99748f58e1bb435c83c Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 15 Oct 2014 15:32:07 +0200 Subject: Fix support for multi-word city names (Weather module) Also, add support for setting a wmo_id directly in your config file. This fixes jasperproject/jasper-client#42 --- client/modules/Weather.py | 74 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 10 deletions(-) (limited to 'client') diff --git a/client/modules/Weather.py b/client/modules/Weather.py index 7076f50..b57991b 100644 --- a/client/modules/Weather.py +++ b/client/modules/Weather.py @@ -1,7 +1,11 @@ # -*- coding: utf-8-*- import re import datetime +import struct +import urllib import feedparser +import requests +import bs4 from app_utils import getTimezone from semantic.dates import DateService @@ -34,9 +38,57 @@ def replaceAcronyms(text): return text -def getForecast(profile): - return feedparser.parse("http://rss.wunderground.com/auto/rss_full/" - + str(profile['location']))['entries'] +def get_locations(): + r = requests.get('http://www.wunderground.com/about/faq/' + + 'international_cities.asp') + soup = bs4.BeautifulSoup(r.text) + data = soup.find(id="inner-content").find('pre').string + # Data Stucture: + # 00 25 location + # 01 1 + # 02 2 region + # 03 1 + # 04 2 country + # 05 2 + # 06 4 ID + # 07 5 + # 08 7 latitude + # 09 1 + # 10 7 logitude + # 11 1 + # 12 5 elevation + # 13 5 wmo_id + s = struct.Struct("25s1s2s1s2s2s4s5s7s1s7s1s5s5s") + for line in data.splitlines()[3:]: + row = s.unpack_from(line) + info = {'name': row[0].strip(), + 'region': row[2].strip(), + 'country': row[4].strip(), + 'latitude': float(row[8].strip()), + 'logitude': float(row[10].strip()), + 'elevation': int(row[12].strip()), + 'id': row[6].strip(), + 'wmo_id': row[13].strip()} + yield info + + +def get_forecast_by_name(location_name): + entries = feedparser.parse("http://rss.wunderground.com/auto/rss_full/%s" + % urllib.quote(location_name))['entries'] + if entries: + # We found weather data the easy way + return entries + else: + # We try to get weather data via the list of stations + for location in get_locations(): + if location['name'] == location_name: + return get_forecast_by_wmo_id(location['wmo_id']) + + +def get_forecast_by_wmo_id(wmo_id): + return feedparser.parse("http://rss.wunderground.com/auto/" + + "rss_full/global/stations/%s.xml" + % wmo_id)['entries'] def handle(text, mic, profile): @@ -51,11 +103,15 @@ def handle(text, mic, profile): profile -- contains information related to the user (e.g., phone number) """ - - if not profile['location']: - mic.say( - "I'm sorry, I can't seem to access that information. Please make" + - "sure that you've set your location on the dashboard.") + forecast = None + if 'wmo_id' in profile: + forecast = get_forecast_by_wmo_id(str(profile['wmo_id'])) + elif 'location' in profile: + forecast = get_forecast_by_name(str(profile['location'])) + + if not forecast: + mic.say("I'm sorry, I can't seem to access that information. Please " + + "make sure that you've set your location on the dashboard.") return tz = getTimezone(profile) @@ -74,8 +130,6 @@ def handle(text, mic, profile): else: date_keyword = "On " + weekday - forecast = getForecast(profile) - output = None for entry in forecast: -- cgit v1.3.1 From 7dd554da0bc5fecdb911241d10908c2cde7601e8 Mon Sep 17 00:00:00 2001 From: schneefux Date: Wed, 15 Oct 2014 16:11:47 +0200 Subject: Fix Weather testcase The only change here is that the test profile location has been changed from "08544" (US zipcode of Princeton, NJ) to "Cape Town" (this was chosen because of high code coverage). It looks like it was broken anyway and just passed because the weather module did not fail if the city was not found. If I type http://rss.wunderground.com/auto/rss_full/08544 into my webbrowser, it says "City not found". If you now have an invalid location name in your profile, the user will be informed that something is fishy. --- client/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client') diff --git a/client/test.py b/client/test.py index 0a414f4..d72e76b 100644 --- a/client/test.py +++ b/client/test.py @@ -21,7 +21,7 @@ from stt import TranscriptionMode DEFAULT_PROFILE = { 'prefers_email': False, - 'location': '08544', + 'location': 'Cape Town', 'timezone': 'US/Eastern', 'phone_number': '012344321' } -- cgit v1.3.1