Skip to content

Commit 191df32

Browse files
committed
Merge branch 'gonzobot' into gonzobot+clean-up-func-launches
2 parents 72ab45b + 75330cf commit 191df32

48 files changed

Lines changed: 767 additions & 401 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ python:
44
- "3.5"
55
- "3.6"
66
- "3.7-dev"
7+
- "nightly"
8+
- "pypy3"
9+
10+
cache: pip
711

812
install:
913
- "sudo apt-get update -q"
@@ -18,3 +22,9 @@ after_success:
1822

1923
env:
2024
- PYTHONPATH=.
25+
- PYTHONPATH=. PYTHONASYNCIODEBUG=1
26+
27+
matrix:
28+
allow_failures:
29+
- python: "3.7-dev"
30+
- python: "nightly"

cloudbot/bot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ def add_hook(hook, _event, _run_before=False):
314314
add_hook(command_hook, command_event)
315315
else:
316316
event.notice("Possible matches: {}".format(
317-
formatting.get_text_list([command for command, plugin in potential_matches])))
317+
formatting.get_text_list(sorted([command for command, plugin in potential_matches]))))
318318

319319
if event.type in (EventType.message, EventType.action):
320320
# Regex hooks

cloudbot/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def try_connect(self):
7979
try:
8080
yield from self.connect(timeout)
8181
except Exception:
82-
logger.exception("[%s] Error occurred while connecting.")
82+
logger.exception("[%s] Error occurred while connecting.", self.name)
8383
else:
8484
break
8585

cloudbot/clients/irc.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,13 @@ def connect(self, timeout=None):
126126
return
127127

128128
if self._connected:
129+
self._connected = False
129130
logger.info("[{}] Reconnecting".format(self.name))
130-
self._transport.close()
131+
if self._transport:
132+
self._transport.close()
131133
else:
132-
self._connected = True
133134
logger.info("[{}] Connecting".format(self.name))
135+
134136
optional_params = {}
135137
if self.local_bind:
136138
optional_params["local_addr"] = self.local_bind
@@ -144,6 +146,8 @@ def connect(self, timeout=None):
144146

145147
self._transport, self._protocol = yield from coro
146148

149+
self._connected = True
150+
147151
tasks = [
148152
self.bot.plugin_manager.launch(hook, Event(bot=self.bot, conn=self, hook=hook))
149153
for hook in self.bot.plugin_manager.connect_hooks
@@ -303,14 +307,14 @@ def connection_lost(self, exc):
303307
# we've been closed intentionally, so don't reconnect
304308
return
305309
logger.error("[{}] Connection lost: {}".format(self.conn.name, exc))
306-
async_util.wrap_future(self.conn.connect(), loop=self.loop)
310+
async_util.wrap_future(self.conn.try_connect(), loop=self.loop)
307311

308312
def eof_received(self):
309313
self._connected = False
310314
# create a new connected_future for when we are connected.
311315
self._connected_future = async_util.create_future(self.loop)
312316
logger.info("[{}] EOF received.".format(self.conn.name))
313-
async_util.wrap_future(self.conn.connect(), loop=self.loop)
317+
async_util.wrap_future(self.conn.try_connect(), loop=self.loop)
314318
return True
315319

316320
@asyncio.coroutine

cloudbot/util/formatting.py

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import copy
4848
import html.entities
4949
import re
50+
import warnings
5051
from html.parser import HTMLParser
5152

5253
from cloudbot.util.colors import strip_irc
@@ -247,11 +248,65 @@ def pluralize(num=0, text=''):
247248
Takes a number and a string, and pluralizes that string using the number and combines the results.
248249
:rtype: str
249250
"""
250-
return "{:,} {}{}".format(num, text, "s"[num == 1:])
251+
warnings.warn(
252+
"formatting.pluralize() is deprecated, please use one of the other formatting.pluralize_*() functions",
253+
DeprecationWarning
254+
)
255+
return pluralize_suffix(num, text)
251256

252257

253-
# alternate form
254-
pluralise = pluralize
258+
def pluralise(num=0, text=''):
259+
"""
260+
Takes a number and a string, and pluralizes that string using the number and combines the results.
261+
:rtype: str
262+
"""
263+
warnings.warn(
264+
"formatting.pluralise() is deprecated, please use one of the other formatting.pluralise_*() functions",
265+
DeprecationWarning
266+
)
267+
return pluralise_suffix(num, text)
268+
269+
270+
def pluralize_suffix(num=0, text='', suffix='s'):
271+
"""
272+
Takes a number and a string, and pluralizes that string using the number and combines the results.
273+
:rtype: str
274+
"""
275+
return pluralize_select(num, text, text + suffix)
276+
277+
278+
pluralise_suffix = pluralize_suffix
279+
280+
281+
def pluralize_select(count, single, plural):
282+
return "{:,} {}".format(count, single if count == 1 else plural)
283+
284+
285+
pluralise_select = pluralize_select
286+
287+
288+
def pluralize_auto(count, thing):
289+
if thing.endswith(('s', 'ss', 'sh', 'ch', 'x', 'z')):
290+
return pluralize_suffix(count, thing, 'es')
291+
elif thing.endswith(('f', 'fe')):
292+
return pluralize_select(count, thing, thing.rsplit('f', 1)[0] + 'ves')
293+
elif thing.endswith('y') and thing[-2:-1].lower() not in "aeiou":
294+
return pluralize_select(count, thing, thing[:-1] + 'ies')
295+
elif thing.endswith('y') and thing[-2:-1].lower() in "aeiou":
296+
return pluralize_suffix(count, thing)
297+
elif thing.endswith('o'):
298+
return pluralize_suffix(count, thing, 'es')
299+
elif thing.endswith('us'):
300+
return pluralize_select(count, thing, thing[:-2] + 'i')
301+
elif thing.endswith('is'):
302+
return pluralize_select(count, thing, thing[:-2] + 'es')
303+
elif thing.endswith('on'):
304+
return pluralize_select(count, thing, thing[:-2] + 'a')
305+
else:
306+
return pluralize_suffix(count, thing)
307+
308+
309+
pluralise_auto = pluralize_auto
255310

256311

257312
def dict_format(args, formats):

cloudbot/util/test/test_formatting.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from cloudbot.util.formatting import munge, dict_format, pluralize, strip_colors, truncate, truncate_str, \
2-
strip_html, multi_replace, multiword_replace, truncate_words, smart_split, get_text_list, ireplace, chunk_str
1+
from cloudbot.util.formatting import munge, dict_format, strip_colors, truncate, truncate_str, \
2+
strip_html, multi_replace, multiword_replace, truncate_words, smart_split, get_text_list, ireplace, chunk_str, \
3+
pluralize_suffix
34

45
test_munge_input = "The quick brown fox jumps over the lazy dog"
56
test_munge_count = 3
@@ -55,8 +56,8 @@ def test_dict_format():
5556

5657

5758
def test_pluralize():
58-
assert pluralize(test_pluralize_num_a, test_pluralize_text) == test_pluralize_result_a
59-
assert pluralize(test_pluralize_num_b, test_pluralize_text) == test_pluralize_result_b
59+
assert pluralize_suffix(test_pluralize_num_a, test_pluralize_text) == test_pluralize_result_a
60+
assert pluralize_suffix(test_pluralize_num_b, test_pluralize_text) == test_pluralize_result_b
6061

6162

6263
def test_strip_colors():

cloudbot/util/web.py

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ def try_shorten(self, url, custom=None, key=None):
8787
return url
8888

8989
def expand(self, url):
90-
r = requests.get(url, allow_redirects=False)
90+
try:
91+
r = requests.get(url, allow_redirects=False)
92+
r.raise_for_status()
93+
except RequestException as e:
94+
r = e.response
95+
raise ServiceError(r.status_code, r)
9196

9297
if 'location' in r.headers:
9398
return r.headers['location']
@@ -127,7 +132,13 @@ def _decorate(impl):
127132
class Isgd(Shortener):
128133
def shorten(self, url, custom=None, key=None):
129134
p = {'url': url, 'shorturl': custom, 'format': 'json'}
130-
r = requests.get('http://is.gd/create.php', params=p)
135+
try:
136+
r = requests.get('http://is.gd/create.php', params=p)
137+
r.raise_for_status()
138+
except RequestException as e:
139+
r = e.response
140+
raise ServiceError(r.status_code, r)
141+
131142
j = r.json()
132143

133144
if 'shorturl' in j:
@@ -137,7 +148,13 @@ def shorten(self, url, custom=None, key=None):
137148

138149
def expand(self, url):
139150
p = {'shorturl': url, 'format': 'json'}
140-
r = requests.get('http://is.gd/forward.php', params=p)
151+
try:
152+
r = requests.get('http://is.gd/forward.php', params=p)
153+
r.raise_for_status()
154+
except RequestException as e:
155+
r = e.response
156+
raise ServiceError(r.status_code, r)
157+
141158
j = r.json()
142159

143160
if 'url' in j:
@@ -152,7 +169,13 @@ def shorten(self, url, custom=None, key=None):
152169
h = {'content-type': 'application/json'}
153170
k = {'key': key}
154171
p = {'longUrl': url}
155-
r = requests.post('https://www.googleapis.com/urlshortener/v1/url', params=k, data=json.dumps(p), headers=h)
172+
try:
173+
r = requests.post('https://www.googleapis.com/urlshortener/v1/url', params=k, data=json.dumps(p), headers=h)
174+
r.raise_for_status()
175+
except RequestException as e:
176+
r = e.response
177+
raise ServiceError(r.status_code, r)
178+
156179
j = r.json()
157180

158181
if 'error' not in j:
@@ -162,7 +185,13 @@ def shorten(self, url, custom=None, key=None):
162185

163186
def expand(self, url):
164187
p = {'shortUrl': url}
165-
r = requests.get('https://www.googleapis.com/urlshortener/v1/url', params=p)
188+
try:
189+
r = requests.get('https://www.googleapis.com/urlshortener/v1/url', params=p)
190+
r.raise_for_status()
191+
except RequestException as e:
192+
r = e.response
193+
raise ServiceError(r.status_code, r)
194+
166195
j = r.json()
167196

168197
if 'error' not in j:
@@ -175,7 +204,12 @@ def expand(self, url):
175204
class Gitio(Shortener):
176205
def shorten(self, url, custom=None, key=None):
177206
p = {'url': url, 'code': custom}
178-
r = requests.post('http://git.io', data=p)
207+
try:
208+
r = requests.post('http://git.io', data=p)
209+
r.raise_for_status()
210+
except RequestException as e:
211+
r = e.response
212+
raise ServiceError(r.status_code, r)
179213

180214
if r.status_code == requests.codes.created:
181215
s = r.headers['location']
@@ -190,13 +224,19 @@ def shorten(self, url, custom=None, key=None):
190224
@_pastebin('hastebin')
191225
class Hastebin(Pastebin):
192226
def paste(self, data, ext):
193-
r = requests.post(HASTEBIN_SERVER + '/documents', data=data)
194-
j = r.json()
195-
196-
if r.status_code is requests.codes.ok:
197-
return '{}/{}.{}'.format(HASTEBIN_SERVER, j['key'], ext)
227+
try:
228+
r = requests.post(HASTEBIN_SERVER + '/documents', data=data)
229+
r.raise_for_status()
230+
except RequestException as e:
231+
r = e.response
232+
raise ServiceError(r.status_code, r)
198233
else:
199-
raise ServiceError(j['message'], r)
234+
j = r.json()
235+
236+
if r.status_code is requests.codes.ok:
237+
return '{}/{}.{}'.format(HASTEBIN_SERVER, j['key'], ext)
238+
else:
239+
raise ServiceError(j['message'], r)
200240

201241

202242
@_pastebin('snoonet')
@@ -207,10 +247,10 @@ def paste(self, data, ext):
207247
'expire': '1d'
208248
}
209249
try:
210-
r = requests.post(SNOONET_PASTE + '/paste/new', params=params)
250+
r = requests.post(SNOONET_PASTE + '/paste/new', data=params)
211251
r.raise_for_status()
212252
except RequestException as e:
213253
r = e.response
214-
return ServiceError(r.status_code, r)
254+
raise ServiceError(r.status_code, r)
215255
else:
216256
return '{}'.format(r.url)

0 commit comments

Comments
 (0)