summaryrefslogtreecommitdiff
path: root/client/modules/Weather.py
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2014-07-26 23:31:25 +0000
committerschneefux <schneefux+commit@schneefux.xyz>2014-07-26 23:31:25 +0000
commit78389f252a021d642a7a0146b658f0465da6e264 (patch)
treeb740c6339ceba381004d3441f2459f65d38d02a6 /client/modules/Weather.py
parent2c55f4da462383ee6c7b89ea44e5c40cd5badf0c (diff)
downloadjasper-client-78389f252a021d642a7a0146b658f0465da6e264.tar.gz
jasper-client-78389f252a021d642a7a0146b658f0465da6e264.zip
Work on Google STT on RPi.
Diffstat (limited to 'client/modules/Weather.py')
-rw-r--r--client/modules/Weather.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/client/modules/Weather.py b/client/modules/Weather.py
new file mode 100644
index 0000000..ad1ac29
--- /dev/null
+++ b/client/modules/Weather.py
@@ -0,0 +1,110 @@
+import re
+import datetime
+import feedparser
+from app_utils import getTimezone
+from semantic.dates import DateService
+
+WORDS = ["WEATHER", "TODAY", "TOMORROW"]
+
+
+def replaceAcronyms(text):
+ """Replaces some commonly-used acronyms for an improved verbal weather report."""
+
+ def parseDirections(text):
+ words = {
+ 'N': 'north',
+ 'S': 'south',
+ 'E': 'east',
+ 'W': 'west',
+ }
+ output = [words[w] for w in list(text)]
+ return ' '.join(output)
+ acronyms = re.findall(r'\b([NESW]+)\b', text)
+
+ for w in acronyms:
+ text = text.replace(w, parseDirections(w))
+
+ text = re.sub(r'(\b\d+)F(\b)', '\g<1> Fahrenheit\g<2>', text)
+ text = re.sub(r'(\b)mph(\b)', '\g<1>miles per hour\g<2>', text)
+ text = re.sub(r'(\b)in\.', '\g<1>inches', text)
+
+ return text
+
+
+def getForecast(profile):
+ return feedparser.parse("http://rss.wunderground.com/auto/rss_full/"
+ + str(profile['location']))['entries']
+
+
+def handle(text, mic, profile):
+ """
+ Responds to user-input, typically speech text, with a summary of
+ the relevant weather for the requested date (typically, weather
+ information will not be available for days beyond tomorrow).
+
+ Arguments:
+ text -- user-input, typically transcribed speech
+ mic -- used to interact with the user (for both input and output)
+ 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.")
+ return
+
+ tz = getTimezone(profile)
+
+ service = DateService(tz=tz)
+ date = service.extractDay(text)
+ if not date:
+ date = datetime.datetime.now(tz=tz)
+ weekday = service.__daysOfWeek__[date.weekday()]
+
+ if date.weekday() == datetime.datetime.now(tz=tz).weekday():
+ date_keyword = "Today"
+ elif date.weekday() == (
+ datetime.datetime.now(tz=tz).weekday() + 1) % 7:
+ date_keyword = "Tomorrow"
+ else:
+ date_keyword = "On " + weekday
+
+ forecast = getForecast(profile)
+
+ output = None
+
+ for entry in forecast:
+ try:
+ date_desc = entry['title'].split()[0].strip().lower()
+ if date_desc == 'forecast': #For global forecasts
+ date_desc = entry['title'].split()[2].strip().lower()
+ weather_desc = entry['summary']
+
+ elif date_desc == 'current': #For first item of global forecasts
+ continue
+ else:
+ weather_desc = entry['summary'].split('-')[1] #US forecasts
+
+ if weekday == date_desc:
+ output = date_keyword + \
+ ", the weather will be " + weather_desc + "."
+ break
+ except:
+ continue
+
+ if output:
+ output = replaceAcronyms(output)
+ mic.say(output)
+ else:
+ mic.say(
+ "I'm sorry. I can't see that far ahead.")
+
+
+def isValid(text):
+ """
+ Returns True if the text is related to the weather.
+
+ Arguments:
+ text -- user-input, typically transcribed speech
+ """
+ return bool(re.search(r'\b(weathers?|temperature|forecast|outside|hot|cold|jacket|coat|rain)\b', text, re.IGNORECASE))