Krzysztof Szukiełojć | 15b62b7 | 2017-02-15 08:58:18 +0100 | [diff] [blame] | 1 | # Copyright 2012 Canonical Ltd. This software is licensed under the |
| 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 3 | |
| 4 | """Remote API library.""" |
| 5 | |
| 6 | from __future__ import ( |
| 7 | absolute_import, |
| 8 | print_function, |
| 9 | unicode_literals, |
| 10 | ) |
| 11 | |
| 12 | str = None |
| 13 | |
| 14 | __metaclass__ = type |
| 15 | __all__ = [ |
| 16 | "ascii_url", |
| 17 | "urlencode", |
| 18 | ] |
| 19 | |
| 20 | |
| 21 | from urllib import quote_plus |
| 22 | from urlparse import urlparse |
| 23 | |
| 24 | |
| 25 | def ascii_url(url): |
| 26 | """Encode `url` as ASCII if it isn't already.""" |
| 27 | if isinstance(url, unicode): |
| 28 | urlparts = urlparse(url) |
| 29 | urlparts = urlparts._replace( |
| 30 | netloc=urlparts.netloc.encode("idna")) |
| 31 | url = urlparts.geturl() |
| 32 | return url.encode("ascii") |
| 33 | |
| 34 | |
| 35 | def urlencode(data): |
| 36 | """A version of `urllib.urlencode` that isn't insane. |
| 37 | |
| 38 | This only cares that `data` is an iterable of iterables. Each sub-iterable |
| 39 | must be of overall length 2, i.e. a name/value pair. |
| 40 | |
| 41 | Unicode strings will be encoded to UTF-8. This is what Django expects; see |
| 42 | `smart_text` in the Django documentation. |
| 43 | """ |
| 44 | enc = lambda string: quote_plus( |
| 45 | string.encode("utf-8") if isinstance(string, unicode) else string) |
| 46 | return b"&".join( |
| 47 | b"%s=%s" % (enc(name), enc(value)) |
| 48 | for name, value in data) |