From 51e6dbfee7cb4a0189940edf0f36e76211c0059a Mon Sep 17 00:00:00 2001 From: Max Gurela Date: Mon, 2 Nov 2015 11:10:26 -0800 Subject: [PATCH 1/5] Resolve #926 Also cleaned up dict value retrieval a little, the .get() calls were a bit unnecessary. --- sopel/modules/weather.py | 47 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/sopel/modules/weather.py b/sopel/modules/weather.py index c0b603ca19..f4ae9e38a0 100644 --- a/sopel/modules/weather.py +++ b/sopel/modules/weather.py @@ -12,7 +12,6 @@ from sopel import web from sopel.module import commands, example, NOLIMIT -import feedparser import xmltodict @@ -25,21 +24,21 @@ def woeid_search(query): query = 'q=select * from geo.placefinder where text="%s"' % query body = web.get('http://query.yahooapis.com/v1/public/yql?' + query, dont_decode=True) - parsed = xmltodict.parse(body).get('query') - results = parsed.get('results') - if results is None or results.get('Result') is None: + parsed = xmltodict.parse(body)['query'] + results = parsed['results'] + if results is None or results['Result'] is None: return None - if type(results.get('Result')) is list: - return results.get('Result')[0] - return results.get('Result') + if type(results['Result']) is list: + return results['Result'][0] + return results['Result'] def get_cover(parsed): try: - condition = parsed.entries[0]['yweather_condition'] + condition = parsed['channel']['item']['yweather:condition'] except KeyError: return 'unknown' - text = condition['text'] + text = condition['@text'] # code = int(condition['code']) # TODO parse code to get those little icon thingies. return text @@ -47,8 +46,8 @@ def get_cover(parsed): def get_temp(parsed): try: - condition = parsed.entries[0]['yweather_condition'] - temp = int(condition['temp']) + condition = parsed['channel']['item']['yweather:condition'] + temp = int(condition['@temp']) except (KeyError, ValueError): return 'unknown' f = round((temp * 1.8) + 32, 2) @@ -57,7 +56,7 @@ def get_temp(parsed): def get_humidity(parsed): try: - humidity = parsed['feed']['yweather_atmosphere']['humidity'] + humidity = parsed['channel']['yweather:atmosphere']['@humidity'] except (KeyError, ValueError): return 'unknown' return "Humidity: %s%%" % humidity @@ -65,11 +64,11 @@ def get_humidity(parsed): def get_wind(parsed): try: - wind_data = parsed['feed']['yweather_wind'] - kph = float(wind_data['speed']) + wind_data = parsed['channel']['yweather:wind'] + kph = float(wind_data['@speed']) m_s = float(round(kph / 3.6, 1)) speed = int(round(kph / 1.852, 0)) - degrees = int(wind_data['direction']) + degrees = int(wind_data['@direction']) except (KeyError, ValueError): return 'unknown' @@ -138,15 +137,15 @@ def weather(bot, trigger): if woeid is None: first_result = woeid_search(location) if first_result is not None: - woeid = first_result.get('woeid') + woeid = first_result['woeid'] if not woeid: return bot.reply("I don't know where that is.") query = web.urlencode({'w': woeid, 'u': 'c'}) url = 'http://weather.yahooapis.com/forecastrss?' + query - parsed = feedparser.parse(url) - location = parsed['feed']['title'] + parsed = xmltodict.parse(url)['rss'] + location = parsed['channel']['title'] cover = get_cover(parsed) temp = get_temp(parsed) @@ -167,16 +166,16 @@ def update_woeid(bot, trigger): if first_result is None: return bot.reply("I don't know where that is.") - woeid = first_result.get('woeid') + woeid = first_result['woeid'] bot.db.set_nick_value(trigger.nick, 'woeid', woeid) - neighborhood = first_result.get('neighborhood').text or '' + neighborhood = first_result['neighborhood'] or '' if neighborhood: neighborhood += ',' - city = first_result.get('city') or '' - state = first_result.get('state') or '' - country = first_result.get('country') or '' - uzip = first_result.get('uzip') or '' + city = first_result['city'] or '' + state = first_result['state'] or '' + country = first_result['country'] or '' + uzip = first_result['uzip'] or '' bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' % (woeid, neighborhood, city, state, country, uzip)) From 2be5591c61e191d561b19b9580b9a85bf612a5c9 Mon Sep 17 00:00:00 2001 From: Max Gurela Date: Mon, 2 Nov 2015 11:12:06 -0800 Subject: [PATCH 2/5] Remove feedparser dep from requirements --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7501e7e17f..b3856aba06 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -feedparser xmltodict pytz praw From 6ed918fae5fd1a0651ffdb597879a5e70312cfec Mon Sep 17 00:00:00 2001 From: Max Gurela Date: Mon, 2 Nov 2015 11:12:33 -0800 Subject: [PATCH 3/5] Remove feedparser from RPM spec --- contrib/rpm/willie.spec.in | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/rpm/willie.spec.in b/contrib/rpm/willie.spec.in index d1c7a3cf52..5a4d5dcbd6 100644 --- a/contrib/rpm/willie.spec.in +++ b/contrib/rpm/willie.spec.in @@ -17,7 +17,6 @@ BuildRequires: dos2unix BuildRequires: systemd Requires: pytz -Requires: python-feedparser Requires: python-enchant Requires: pyOpenSSL Requires: python-praw From d0170b53c10f096d07eb6420eeae5fe67860af76 Mon Sep 17 00:00:00 2001 From: Max Gurela Date: Sat, 14 Nov 2015 10:09:55 -0800 Subject: [PATCH 4/5] Switch back to get() calls There's some places where there were already try catch blocks for KeyError, so I left those ones. --- sopel/modules/weather.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sopel/modules/weather.py b/sopel/modules/weather.py index f4ae9e38a0..fb4e5269d9 100644 --- a/sopel/modules/weather.py +++ b/sopel/modules/weather.py @@ -24,13 +24,13 @@ def woeid_search(query): query = 'q=select * from geo.placefinder where text="%s"' % query body = web.get('http://query.yahooapis.com/v1/public/yql?' + query, dont_decode=True) - parsed = xmltodict.parse(body)['query'] - results = parsed['results'] - if results is None or results['Result'] is None: + parsed = xmltodict.parse(body).get('query') + results = parsed.get('results') + if results is None or results.get('Result') is None: return None - if type(results['Result']) is list: - return results['Result'][0] - return results['Result'] + if type(results.get('Result')) is list: + return results.get('Result')[0] + return results.get('Result') def get_cover(parsed): @@ -137,15 +137,15 @@ def weather(bot, trigger): if woeid is None: first_result = woeid_search(location) if first_result is not None: - woeid = first_result['woeid'] + woeid = first_result.get('woeid') if not woeid: return bot.reply("I don't know where that is.") query = web.urlencode({'w': woeid, 'u': 'c'}) url = 'http://weather.yahooapis.com/forecastrss?' + query - parsed = xmltodict.parse(url)['rss'] - location = parsed['channel']['title'] + parsed = xmltodict.parse(url).get('rss') + location = parsed.get('channel').get('title') cover = get_cover(parsed) temp = get_temp(parsed) @@ -166,16 +166,16 @@ def update_woeid(bot, trigger): if first_result is None: return bot.reply("I don't know where that is.") - woeid = first_result['woeid'] + woeid = first_result.get('woeid') bot.db.set_nick_value(trigger.nick, 'woeid', woeid) - neighborhood = first_result['neighborhood'] or '' + neighborhood = first_result.get('neighborhood') or '' if neighborhood: neighborhood += ',' - city = first_result['city'] or '' - state = first_result['state'] or '' - country = first_result['country'] or '' - uzip = first_result['uzip'] or '' + city = first_result.get('city') or '' + state = first_result.get('state') or '' + country = first_result.get('country') or '' + uzip = first_result.get('uzip') or '' bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' % (woeid, neighborhood, city, state, country, uzip)) From 9b0e4c792aa939f0d67e17e32d998c38af30d4c1 Mon Sep 17 00:00:00 2001 From: Max Gurela Date: Sat, 14 Nov 2015 18:00:07 -0800 Subject: [PATCH 5/5] Properly fetch the xml before passing it to xmltodict I'm a moron. --- sopel/modules/weather.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sopel/modules/weather.py b/sopel/modules/weather.py index fb4e5269d9..944546fe1a 100644 --- a/sopel/modules/weather.py +++ b/sopel/modules/weather.py @@ -143,8 +143,9 @@ def weather(bot, trigger): return bot.reply("I don't know where that is.") query = web.urlencode({'w': woeid, 'u': 'c'}) - url = 'http://weather.yahooapis.com/forecastrss?' + query - parsed = xmltodict.parse(url).get('rss') + raw = web.get('http://weather.yahooapis.com/forecastrss?' + query, + dont_decode=True) + parsed = xmltodict.parse(raw).get('rss') location = parsed.get('channel').get('title') cover = get_cover(parsed)