Tarek Ziade | 1231a4e | 2011-05-19 13:07:25 +0200 | [diff] [blame] | 1 | """Utilities related to the mirror infrastructure defined in PEP 381.""" |
| 2 | |
| 3 | from string import ascii_lowercase |
| 4 | import socket |
| 5 | |
| 6 | DEFAULT_MIRROR_URL = "last.pypi.python.org" |
| 7 | |
| 8 | |
| 9 | def get_mirrors(hostname=None): |
| 10 | """Return the list of mirrors from the last record found on the DNS |
| 11 | entry:: |
| 12 | |
| 13 | >>> from packaging.pypi.mirrors import get_mirrors |
| 14 | >>> get_mirrors() |
| 15 | ['a.pypi.python.org', 'b.pypi.python.org', 'c.pypi.python.org', |
| 16 | 'd.pypi.python.org'] |
| 17 | |
| 18 | """ |
| 19 | if hostname is None: |
| 20 | hostname = DEFAULT_MIRROR_URL |
| 21 | |
| 22 | # return the last mirror registered on PyPI. |
| 23 | try: |
| 24 | hostname = socket.gethostbyname_ex(hostname)[0] |
| 25 | except socket.gaierror: |
| 26 | return [] |
| 27 | end_letter = hostname.split(".", 1) |
| 28 | |
| 29 | # determine the list from the last one. |
| 30 | return ["%s.%s" % (s, end_letter[1]) for s in string_range(end_letter[0])] |
| 31 | |
| 32 | |
| 33 | def string_range(last): |
| 34 | """Compute the range of string between "a" and last. |
| 35 | |
| 36 | This works for simple "a to z" lists, but also for "a to zz" lists. |
| 37 | """ |
| 38 | for k in range(len(last)): |
| 39 | for x in product(ascii_lowercase, repeat=(k + 1)): |
| 40 | result = ''.join(x) |
| 41 | yield result |
| 42 | if result == last: |
| 43 | return |
| 44 | |
| 45 | |
| 46 | def product(*args, **kwds): |
| 47 | pools = [tuple(arg) for arg in args] * kwds.get('repeat', 1) |
| 48 | result = [[]] |
| 49 | for pool in pools: |
| 50 | result = [x + [y] for x in result for y in pool] |
| 51 | for prod in result: |
| 52 | yield tuple(prod) |