blob: a646acff3cdd91999bf5413108df337969f264f8 [file] [log] [blame]
Tarek Ziade1231a4e2011-05-19 13:07:25 +02001"""Utilities related to the mirror infrastructure defined in PEP 381."""
2
3from string import ascii_lowercase
4import socket
5
6DEFAULT_MIRROR_URL = "last.pypi.python.org"
7
8
9def 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
33def 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
46def 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)