We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove feedparser dependency
The weather module needlessly uses `feedparser` for some things, which adds a needless (python3-incompatible) dependency. It should be done with straight XML processing, instead.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sopel/modules/weather.py`
Content:
```
1 # coding=utf8
2 """
3 weather.py - Sopel Yahoo! Weather Module
4 Copyright 2008, Sean B. Palmer, inamidst.com
5 Copyright 2012, Edward Powell, embolalia.net
6 Licensed under the Eiffel Forum License 2.
7 
8 http://sopel.chat
9 """
10 from __future__ import unicode_literals
11 
12 from sopel import web
13 from sopel.module import commands, example, NOLIMIT
14 
15 import feedparser
16 import xmltodict
17 
18 
19 def woeid_search(query):
20     """
21     Find the first Where On Earth ID for the given query. Result is the etree
22     node for the result, so that location data can still be retrieved. Returns
23     None if there is no result, or the woeid field is empty.
24     """
25     query = 'q=select * from geo.placefinder where text="%s"' % query
26     body = web.get('http://query.yahooapis.com/v1/public/yql?' + query,
27                    dont_decode=True)
28     parsed = xmltodict.parse(body).get('query')
29     results = parsed.get('results')
30     if results is None or results.get('Result') is None:
31         return None
32     if type(results.get('Result')) is list:
33         return results.get('Result')[0]
34     return results.get('Result')
35 
36 
37 def get_cover(parsed):
38     try:
39         condition = parsed.entries[0]['yweather_condition']
40     except KeyError:
41         return 'unknown'
42     text = condition['text']
43     # code = int(condition['code'])
44     # TODO parse code to get those little icon thingies.
45     return text
46 
47 
48 def get_temp(parsed):
49     try:
50         condition = parsed.entries[0]['yweather_condition']
51         temp = int(condition['temp'])
52     except (KeyError, ValueError):
53         return 'unknown'
54     f = round((temp * 1.8) + 32, 2)
55     return (u'%d\u00B0C (%d\u00B0F)' % (temp, f))
56 
57 
58 def get_humidity(parsed):
59     try:
60         humidity = parsed['feed']['yweather_atmosphere']['humidity']
61     except (KeyError, ValueError):
62         return 'unknown'
63     return "Humidity: %s%%" % humidity
64 
65 
66 def get_wind(parsed):
67     try:
68         wind_data = parsed['feed']['yweather_wind']
69         kph = float(wind_data['speed'])
70         m_s = float(round(kph / 3.6, 1))
71         speed = int(round(kph / 1.852, 0))
72         degrees = int(wind_data['direction'])
73     except (KeyError, ValueError):
74         return 'unknown'
75 
76     if speed < 1:
77         description = 'Calm'
78     elif speed < 4:
79         description = 'Light air'
80     elif speed < 7:
81         description = 'Light breeze'
82     elif speed < 11:
83         description = 'Gentle breeze'
84     elif speed < 16:
85         description = 'Moderate breeze'
86     elif speed < 22:
87         description = 'Fresh breeze'
88     elif speed < 28:
89         description = 'Strong breeze'
90     elif speed < 34:
91         description = 'Near gale'
92     elif speed < 41:
93         description = 'Gale'
94     elif speed < 48:
95         description = 'Strong gale'
96     elif speed < 56:
97         description = 'Storm'
98     elif speed < 64:
99         description = 'Violent storm'
100     else:
101         description = 'Hurricane'
102 
103     if (degrees <= 22.5) or (degrees > 337.5):
104         degrees = u'\u2193'
105     elif (degrees > 22.5) and (degrees <= 67.5):
106         degrees = u'\u2199'
107     elif (degrees > 67.5) and (degrees <= 112.5):
108         degrees = u'\u2190'
109     elif (degrees > 112.5) and (degrees <= 157.5):
110         degrees = u'\u2196'
111     elif (degrees > 157.5) and (degrees <= 202.5):
112         degrees = u'\u2191'
113     elif (degrees > 202.5) and (degrees <= 247.5):
114         degrees = u'\u2197'
115     elif (degrees > 247.5) and (degrees <= 292.5):
116         degrees = u'\u2192'
117     elif (degrees > 292.5) and (degrees <= 337.5):
118         degrees = u'\u2198'
119 
120     return description + ' ' + str(m_s) + 'm/s (' + degrees + ')'
121 
122 
123 @commands('weather', 'wea')
124 @example('.weather London')
125 def weather(bot, trigger):
126     """.weather location - Show the weather at the given location."""
127 
128     location = trigger.group(2)
129     woeid = ''
130     if not location:
131         woeid = bot.db.get_nick_value(trigger.nick, 'woeid')
132         if not woeid:
133             return bot.msg(trigger.sender, "I don't know where you live. " +
134                            'Give me a location, like .weather London, or tell me where you live by saying .setlocation London, for example.')
135     else:
136         location = location.strip()
137         woeid = bot.db.get_nick_value(location, 'woeid')
138         if woeid is None:
139             first_result = woeid_search(location)
140             if first_result is not None:
141                 woeid = first_result.get('woeid')
142 
143     if not woeid:
144         return bot.reply("I don't know where that is.")
145 
146     query = web.urlencode({'w': woeid, 'u': 'c'})
147     url = 'http://weather.yahooapis.com/forecastrss?' + query
148     parsed = feedparser.parse(url)
149     location = parsed['feed']['title']
150 
151     cover = get_cover(parsed)
152     temp = get_temp(parsed)
153     humidity = get_humidity(parsed)
154     wind = get_wind(parsed)
155     bot.say(u'%s: %s, %s, %s, %s' % (location, cover, temp, humidity, wind))
156 
157 
158 @commands('setlocation', 'setwoeid')
159 @example('.setlocation Columbus, OH')
160 def update_woeid(bot, trigger):
161     """Set your default weather location."""
162     if not trigger.group(2):
163         bot.reply('Give me a location, like "Washington, DC" or "London".')
164         return NOLIMIT
165 
166     first_result = woeid_search(trigger.group(2))
167     if first_result is None:
168         return bot.reply("I don't know where that is.")
169 
170     woeid = first_result.get('woeid')
171 
172     bot.db.set_nick_value(trigger.nick, 'woeid', woeid)
173 
174     neighborhood = first_result.get('neighborhood').text or ''
175     if neighborhood:
176         neighborhood += ','
177     city = first_result.get('city') or ''
178     state = first_result.get('state') or ''
179     country = first_result.get('country') or ''
180     uzip = first_result.get('uzip') or ''
181     bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' %
182               (woeid, neighborhood, city, state, country, uzip))
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sopel/modules/weather.py b/sopel/modules/weather.py
--- 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
 
 
@@ -36,10 +35,10 @@
 
 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_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_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_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'
 
@@ -144,9 +143,10 @@
         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']
+    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)
     temp = get_temp(parsed)
@@ -171,7 +171,7 @@
 
     bot.db.set_nick_value(trigger.nick, 'woeid', woeid)
 
-    neighborhood = first_result.get('neighborhood').text or ''
+    neighborhood = first_result.get('neighborhood') or ''
     if neighborhood:
         neighborhood += ','
     city = first_result.get('city') or ''

{"golden_diff": "diff --git a/sopel/modules/weather.py b/sopel/modules/weather.py\n--- a/sopel/modules/weather.py\n+++ b/sopel/modules/weather.py\n@@ -12,7 +12,6 @@\n from sopel import web\n from sopel.module import commands, example, NOLIMIT\n \n-import feedparser\n import xmltodict\n \n \n@@ -36,10 +35,10 @@\n \n def get_cover(parsed):\n     try:\n-        condition = parsed.entries[0]['yweather_condition']\n+        condition = parsed['channel']['item']['yweather:condition']\n     except KeyError:\n         return 'unknown'\n-    text = condition['text']\n+    text = condition['@text']\n     # code = int(condition['code'])\n     # TODO parse code to get those little icon thingies.\n     return text\n@@ -47,8 +46,8 @@\n \n def get_temp(parsed):\n     try:\n-        condition = parsed.entries[0]['yweather_condition']\n-        temp = int(condition['temp'])\n+        condition = parsed['channel']['item']['yweather:condition']\n+        temp = int(condition['@temp'])\n     except (KeyError, ValueError):\n         return 'unknown'\n     f = round((temp * 1.8) + 32, 2)\n@@ -57,7 +56,7 @@\n \n def get_humidity(parsed):\n     try:\n-        humidity = parsed['feed']['yweather_atmosphere']['humidity']\n+        humidity = parsed['channel']['yweather:atmosphere']['@humidity']\n     except (KeyError, ValueError):\n         return 'unknown'\n     return \"Humidity: %s%%\" % humidity\n@@ -65,11 +64,11 @@\n \n def get_wind(parsed):\n     try:\n-        wind_data = parsed['feed']['yweather_wind']\n-        kph = float(wind_data['speed'])\n+        wind_data = parsed['channel']['yweather:wind']\n+        kph = float(wind_data['@speed'])\n         m_s = float(round(kph / 3.6, 1))\n         speed = int(round(kph / 1.852, 0))\n-        degrees = int(wind_data['direction'])\n+        degrees = int(wind_data['@direction'])\n     except (KeyError, ValueError):\n         return 'unknown'\n \n@@ -144,9 +143,10 @@\n         return bot.reply(\"I don't know where that is.\")\n \n     query = web.urlencode({'w': woeid, 'u': 'c'})\n-    url = 'http://weather.yahooapis.com/forecastrss?' + query\n-    parsed = feedparser.parse(url)\n-    location = parsed['feed']['title']\n+    raw = web.get('http://weather.yahooapis.com/forecastrss?' + query, \n+                  dont_decode=True)\n+    parsed = xmltodict.parse(raw).get('rss')\n+    location = parsed.get('channel').get('title')\n \n     cover = get_cover(parsed)\n     temp = get_temp(parsed)\n@@ -171,7 +171,7 @@\n \n     bot.db.set_nick_value(trigger.nick, 'woeid', woeid)\n \n-    neighborhood = first_result.get('neighborhood').text or ''\n+    neighborhood = first_result.get('neighborhood') or ''\n     if neighborhood:\n         neighborhood += ','\n     city = first_result.get('city') or ''\n", "issue": "Remove feedparser dependency\nThe weather module needlessly uses `feedparser` for some things, which adds a needless (python3-incompatible) dependency. It should be done with straight XML processing, instead.\n\n", "before_files": [{"content": "# coding=utf8\n\"\"\"\nweather.py - Sopel Yahoo! Weather Module\nCopyright 2008, Sean B. Palmer, inamidst.com\nCopyright 2012, Edward Powell, embolalia.net\nLicensed under the Eiffel Forum License 2.\n\nhttp://sopel.chat\n\"\"\"\nfrom __future__ import unicode_literals\n\nfrom sopel import web\nfrom sopel.module import commands, example, NOLIMIT\n\nimport feedparser\nimport xmltodict\n\n\ndef woeid_search(query):\n    \"\"\"\n    Find the first Where On Earth ID for the given query. Result is the etree\n    node for the result, so that location data can still be retrieved. Returns\n    None if there is no result, or the woeid field is empty.\n    \"\"\"\n    query = 'q=select * from geo.placefinder where text=\"%s\"' % query\n    body = web.get('http://query.yahooapis.com/v1/public/yql?' + query,\n                   dont_decode=True)\n    parsed = xmltodict.parse(body).get('query')\n    results = parsed.get('results')\n    if results is None or results.get('Result') is None:\n        return None\n    if type(results.get('Result')) is list:\n        return results.get('Result')[0]\n    return results.get('Result')\n\n\ndef get_cover(parsed):\n    try:\n        condition = parsed.entries[0]['yweather_condition']\n    except KeyError:\n        return 'unknown'\n    text = condition['text']\n    # code = int(condition['code'])\n    # TODO parse code to get those little icon thingies.\n    return text\n\n\ndef get_temp(parsed):\n    try:\n        condition = parsed.entries[0]['yweather_condition']\n        temp = int(condition['temp'])\n    except (KeyError, ValueError):\n        return 'unknown'\n    f = round((temp * 1.8) + 32, 2)\n    return (u'%d\\u00B0C (%d\\u00B0F)' % (temp, f))\n\n\ndef get_humidity(parsed):\n    try:\n        humidity = parsed['feed']['yweather_atmosphere']['humidity']\n    except (KeyError, ValueError):\n        return 'unknown'\n    return \"Humidity: %s%%\" % humidity\n\n\ndef get_wind(parsed):\n    try:\n        wind_data = parsed['feed']['yweather_wind']\n        kph = float(wind_data['speed'])\n        m_s = float(round(kph / 3.6, 1))\n        speed = int(round(kph / 1.852, 0))\n        degrees = int(wind_data['direction'])\n    except (KeyError, ValueError):\n        return 'unknown'\n\n    if speed < 1:\n        description = 'Calm'\n    elif speed < 4:\n        description = 'Light air'\n    elif speed < 7:\n        description = 'Light breeze'\n    elif speed < 11:\n        description = 'Gentle breeze'\n    elif speed < 16:\n        description = 'Moderate breeze'\n    elif speed < 22:\n        description = 'Fresh breeze'\n    elif speed < 28:\n        description = 'Strong breeze'\n    elif speed < 34:\n        description = 'Near gale'\n    elif speed < 41:\n        description = 'Gale'\n    elif speed < 48:\n        description = 'Strong gale'\n    elif speed < 56:\n        description = 'Storm'\n    elif speed < 64:\n        description = 'Violent storm'\n    else:\n        description = 'Hurricane'\n\n    if (degrees <= 22.5) or (degrees > 337.5):\n        degrees = u'\\u2193'\n    elif (degrees > 22.5) and (degrees <= 67.5):\n        degrees = u'\\u2199'\n    elif (degrees > 67.5) and (degrees <= 112.5):\n        degrees = u'\\u2190'\n    elif (degrees > 112.5) and (degrees <= 157.5):\n        degrees = u'\\u2196'\n    elif (degrees > 157.5) and (degrees <= 202.5):\n        degrees = u'\\u2191'\n    elif (degrees > 202.5) and (degrees <= 247.5):\n        degrees = u'\\u2197'\n    elif (degrees > 247.5) and (degrees <= 292.5):\n        degrees = u'\\u2192'\n    elif (degrees > 292.5) and (degrees <= 337.5):\n        degrees = u'\\u2198'\n\n    return description + ' ' + str(m_s) + 'm/s (' + degrees + ')'\n\n\n@commands('weather', 'wea')\n@example('.weather London')\ndef weather(bot, trigger):\n    \"\"\".weather location - Show the weather at the given location.\"\"\"\n\n    location = trigger.group(2)\n    woeid = ''\n    if not location:\n        woeid = bot.db.get_nick_value(trigger.nick, 'woeid')\n        if not woeid:\n            return bot.msg(trigger.sender, \"I don't know where you live. \" +\n                           'Give me a location, like .weather London, or tell me where you live by saying .setlocation London, for example.')\n    else:\n        location = location.strip()\n        woeid = bot.db.get_nick_value(location, 'woeid')\n        if woeid is None:\n            first_result = woeid_search(location)\n            if first_result is not None:\n                woeid = first_result.get('woeid')\n\n    if not woeid:\n        return bot.reply(\"I don't know where that is.\")\n\n    query = web.urlencode({'w': woeid, 'u': 'c'})\n    url = 'http://weather.yahooapis.com/forecastrss?' + query\n    parsed = feedparser.parse(url)\n    location = parsed['feed']['title']\n\n    cover = get_cover(parsed)\n    temp = get_temp(parsed)\n    humidity = get_humidity(parsed)\n    wind = get_wind(parsed)\n    bot.say(u'%s: %s, %s, %s, %s' % (location, cover, temp, humidity, wind))\n\n\n@commands('setlocation', 'setwoeid')\n@example('.setlocation Columbus, OH')\ndef update_woeid(bot, trigger):\n    \"\"\"Set your default weather location.\"\"\"\n    if not trigger.group(2):\n        bot.reply('Give me a location, like \"Washington, DC\" or \"London\".')\n        return NOLIMIT\n\n    first_result = woeid_search(trigger.group(2))\n    if first_result is None:\n        return bot.reply(\"I don't know where that is.\")\n\n    woeid = first_result.get('woeid')\n\n    bot.db.set_nick_value(trigger.nick, 'woeid', woeid)\n\n    neighborhood = first_result.get('neighborhood').text or ''\n    if neighborhood:\n        neighborhood += ','\n    city = first_result.get('city') or ''\n    state = first_result.get('state') or ''\n    country = first_result.get('country') or ''\n    uzip = first_result.get('uzip') or ''\n    bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' %\n              (woeid, neighborhood, city, state, country, uzip))\n", "path": "sopel/modules/weather.py"}], "after_files": [{"content": "# coding=utf8\n\"\"\"\nweather.py - Sopel Yahoo! Weather Module\nCopyright 2008, Sean B. Palmer, inamidst.com\nCopyright 2012, Edward Powell, embolalia.net\nLicensed under the Eiffel Forum License 2.\n\nhttp://sopel.chat\n\"\"\"\nfrom __future__ import unicode_literals\n\nfrom sopel import web\nfrom sopel.module import commands, example, NOLIMIT\n\nimport xmltodict\n\n\ndef woeid_search(query):\n    \"\"\"\n    Find the first Where On Earth ID for the given query. Result is the etree\n    node for the result, so that location data can still be retrieved. Returns\n    None if there is no result, or the woeid field is empty.\n    \"\"\"\n    query = 'q=select * from geo.placefinder where text=\"%s\"' % query\n    body = web.get('http://query.yahooapis.com/v1/public/yql?' + query,\n                   dont_decode=True)\n    parsed = xmltodict.parse(body).get('query')\n    results = parsed.get('results')\n    if results is None or results.get('Result') is None:\n        return None\n    if type(results.get('Result')) is list:\n        return results.get('Result')[0]\n    return results.get('Result')\n\n\ndef get_cover(parsed):\n    try:\n        condition = parsed['channel']['item']['yweather:condition']\n    except KeyError:\n        return 'unknown'\n    text = condition['@text']\n    # code = int(condition['code'])\n    # TODO parse code to get those little icon thingies.\n    return text\n\n\ndef get_temp(parsed):\n    try:\n        condition = parsed['channel']['item']['yweather:condition']\n        temp = int(condition['@temp'])\n    except (KeyError, ValueError):\n        return 'unknown'\n    f = round((temp * 1.8) + 32, 2)\n    return (u'%d\\u00B0C (%d\\u00B0F)' % (temp, f))\n\n\ndef get_humidity(parsed):\n    try:\n        humidity = parsed['channel']['yweather:atmosphere']['@humidity']\n    except (KeyError, ValueError):\n        return 'unknown'\n    return \"Humidity: %s%%\" % humidity\n\n\ndef get_wind(parsed):\n    try:\n        wind_data = parsed['channel']['yweather:wind']\n        kph = float(wind_data['@speed'])\n        m_s = float(round(kph / 3.6, 1))\n        speed = int(round(kph / 1.852, 0))\n        degrees = int(wind_data['@direction'])\n    except (KeyError, ValueError):\n        return 'unknown'\n\n    if speed < 1:\n        description = 'Calm'\n    elif speed < 4:\n        description = 'Light air'\n    elif speed < 7:\n        description = 'Light breeze'\n    elif speed < 11:\n        description = 'Gentle breeze'\n    elif speed < 16:\n        description = 'Moderate breeze'\n    elif speed < 22:\n        description = 'Fresh breeze'\n    elif speed < 28:\n        description = 'Strong breeze'\n    elif speed < 34:\n        description = 'Near gale'\n    elif speed < 41:\n        description = 'Gale'\n    elif speed < 48:\n        description = 'Strong gale'\n    elif speed < 56:\n        description = 'Storm'\n    elif speed < 64:\n        description = 'Violent storm'\n    else:\n        description = 'Hurricane'\n\n    if (degrees <= 22.5) or (degrees > 337.5):\n        degrees = u'\\u2193'\n    elif (degrees > 22.5) and (degrees <= 67.5):\n        degrees = u'\\u2199'\n    elif (degrees > 67.5) and (degrees <= 112.5):\n        degrees = u'\\u2190'\n    elif (degrees > 112.5) and (degrees <= 157.5):\n        degrees = u'\\u2196'\n    elif (degrees > 157.5) and (degrees <= 202.5):\n        degrees = u'\\u2191'\n    elif (degrees > 202.5) and (degrees <= 247.5):\n        degrees = u'\\u2197'\n    elif (degrees > 247.5) and (degrees <= 292.5):\n        degrees = u'\\u2192'\n    elif (degrees > 292.5) and (degrees <= 337.5):\n        degrees = u'\\u2198'\n\n    return description + ' ' + str(m_s) + 'm/s (' + degrees + ')'\n\n\n@commands('weather', 'wea')\n@example('.weather London')\ndef weather(bot, trigger):\n    \"\"\".weather location - Show the weather at the given location.\"\"\"\n\n    location = trigger.group(2)\n    woeid = ''\n    if not location:\n        woeid = bot.db.get_nick_value(trigger.nick, 'woeid')\n        if not woeid:\n            return bot.msg(trigger.sender, \"I don't know where you live. \" +\n                           'Give me a location, like .weather London, or tell me where you live by saying .setlocation London, for example.')\n    else:\n        location = location.strip()\n        woeid = bot.db.get_nick_value(location, 'woeid')\n        if woeid is None:\n            first_result = woeid_search(location)\n            if first_result is not None:\n                woeid = first_result.get('woeid')\n\n    if not woeid:\n        return bot.reply(\"I don't know where that is.\")\n\n    query = web.urlencode({'w': woeid, 'u': 'c'})\n    raw = web.get('http://weather.yahooapis.com/forecastrss?' + query, \n                  dont_decode=True)\n    parsed = xmltodict.parse(raw).get('rss')\n    location = parsed.get('channel').get('title')\n\n    cover = get_cover(parsed)\n    temp = get_temp(parsed)\n    humidity = get_humidity(parsed)\n    wind = get_wind(parsed)\n    bot.say(u'%s: %s, %s, %s, %s' % (location, cover, temp, humidity, wind))\n\n\n@commands('setlocation', 'setwoeid')\n@example('.setlocation Columbus, OH')\ndef update_woeid(bot, trigger):\n    \"\"\"Set your default weather location.\"\"\"\n    if not trigger.group(2):\n        bot.reply('Give me a location, like \"Washington, DC\" or \"London\".')\n        return NOLIMIT\n\n    first_result = woeid_search(trigger.group(2))\n    if first_result is None:\n        return bot.reply(\"I don't know where that is.\")\n\n    woeid = first_result.get('woeid')\n\n    bot.db.set_nick_value(trigger.nick, 'woeid', woeid)\n\n    neighborhood = first_result.get('neighborhood') or ''\n    if neighborhood:\n        neighborhood += ','\n    city = first_result.get('city') or ''\n    state = first_result.get('state') or ''\n    country = first_result.get('country') or ''\n    uzip = first_result.get('uzip') or ''\n    bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' %\n              (woeid, neighborhood, city, state, country, uzip))\n", "path": "sopel/modules/weather.py"}]}