diff options
Diffstat (limited to 'client/modules/Weather.py')
| -rw-r--r-- | client/modules/Weather.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/client/modules/Weather.py b/client/modules/Weather.py new file mode 100644 index 0000000..85a8f1d --- /dev/null +++ b/client/modules/Weather.py @@ -0,0 +1,104 @@ +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.parseDay(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() + + weather_desc = entry['summary'].split('-')[1] + + 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)) |
