1#!python
2
3# This file was obtained from:
4#   http://peak.telecommunity.com/dist/ez_setup.py
5# on 2011/1/21.
6
7"""Bootstrap setuptools installation
8
9If you want to use setuptools in your package's setup.py, just include this
10file in the same directory with it, and add this to the top of your setup.py::
11
12    from ez_setup import use_setuptools
13    use_setuptools()
14
15If you want to require a specific version of setuptools, set a download
16mirror, or use an alternate download directory, you can do so by supplying
17the appropriate options to ``use_setuptools()``.
18
19This file can also be run as a script to install or upgrade setuptools.
20"""
21import sys
22DEFAULT_VERSION = "0.6c11"
23DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
24
25md5_data = {
26    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
27    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
28    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
29    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
30    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
31    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
32    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
33    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
34    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
35    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
36    'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
37    'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
38    'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
39    'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
40    'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
41    'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
42    'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
43    'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
44    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
45    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
46    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
47    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
48    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
49    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
50    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
51    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
52    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
53    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
54    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
55    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
56    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
57    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
58    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
59    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
60    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
61    'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
62    'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
63    'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
64    'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
65    'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
66    'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
67    'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
68}
69
70import sys, os
71try: from hashlib import md5
72except ImportError: from md5 import md5
73
74def _validate_md5(egg_name, data):
75    if egg_name in md5_data:
76        digest = md5(data).hexdigest()
77        if digest != md5_data[egg_name]:
78            print >>sys.stderr, (
79                "md5 validation of %s failed!  (Possible download problem?)"
80                % egg_name
81            )
82            sys.exit(2)
83    return data
84
85def use_setuptools(
86    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
87    download_delay=15
88):
89    """Automatically find/download setuptools and make it available on sys.path
90
91    `version` should be a valid setuptools version number that is available
92    as an egg for download under the `download_base` URL (which should end with
93    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
94    it is not already available.  If `download_delay` is specified, it should
95    be the number of seconds that will be paused before initiating a download,
96    should one be required.  If an older version of setuptools is installed,
97    this routine will print a message to ``sys.stderr`` and raise SystemExit in
98    an attempt to abort the calling script.
99    """
100    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
101    def do_download():
102        egg = download_setuptools(version, download_base, to_dir, download_delay)
103        sys.path.insert(0, egg)
104        import setuptools; setuptools.bootstrap_install_from = egg
105    try:
106        import pkg_resources
107    except ImportError:
108        return do_download()
109    try:
110        return do_download()
111        pkg_resources.require("setuptools>="+version); return
112    except pkg_resources.VersionConflict, e:
113        if was_imported:
114            print >>sys.stderr, (
115            "The required version of setuptools (>=%s) is not available, and\n"
116            "can't be installed while this script is running. Please install\n"
117            " a more recent version first, using 'easy_install -U setuptools'."
118            "\n\n(Currently using %r)"
119            ) % (version, e.args[0])
120            sys.exit(2)
121    except pkg_resources.DistributionNotFound:
122        pass
123
124    del pkg_resources, sys.modules['pkg_resources']    # reload ok
125    return do_download()
126
127def download_setuptools(
128    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
129    delay = 15
130):
131    """Download setuptools from a specified location and return its filename
132
133    `version` should be a valid setuptools version number that is available
134    as an egg for download under the `download_base` URL (which should end
135    with a '/'). `to_dir` is the directory where the egg will be downloaded.
136    `delay` is the number of seconds to pause before an actual download attempt.
137    """
138    import urllib2, shutil
139    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
140    url = download_base + egg_name
141    saveto = os.path.join(to_dir, egg_name)
142    src = dst = None
143    if not os.path.exists(saveto):  # Avoid repeated downloads
144        try:
145            from distutils import log
146            if delay:
147                log.warn("""
148---------------------------------------------------------------------------
149This script requires setuptools version %s to run (even to display
150help).  I will attempt to download it for you (from
151%s), but
152you may need to enable firewall access for this script first.
153I will start the download in %d seconds.
154
155(Note: if this machine does not have network access, please obtain the file
156
157   %s
158
159and place it in this directory before rerunning this script.)
160---------------------------------------------------------------------------""",
161                    version, download_base, delay, url
162                ); from time import sleep; sleep(delay)
163            log.warn("Downloading %s", url)
164            src = urllib2.urlopen(url)
165            # Read/write all in one block, so we don't create a corrupt file
166            # if the download is interrupted.
167            data = _validate_md5(egg_name, src.read())
168            dst = open(saveto,"wb"); dst.write(data)
169        finally:
170            if src: src.close()
171            if dst: dst.close()
172    return os.path.realpath(saveto)
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209def main(argv, version=DEFAULT_VERSION):
210    """Install or upgrade setuptools and EasyInstall"""
211    try:
212        import setuptools
213    except ImportError:
214        egg = None
215        try:
216            egg = download_setuptools(version, delay=0)
217            sys.path.insert(0,egg)
218            from setuptools.command.easy_install import main
219            return main(list(argv)+[egg])   # we're done here
220        finally:
221            if egg and os.path.exists(egg):
222                os.unlink(egg)
223    else:
224        if setuptools.__version__ == '0.0.1':
225            print >>sys.stderr, (
226            "You have an obsolete version of setuptools installed.  Please\n"
227            "remove it from your system entirely before rerunning this script."
228            )
229            sys.exit(2)
230
231    req = "setuptools>="+version
232    import pkg_resources
233    try:
234        pkg_resources.require(req)
235    except pkg_resources.VersionConflict:
236        try:
237            from setuptools.command.easy_install import main
238        except ImportError:
239            from easy_install import main
240        main(list(argv)+[download_setuptools(delay=0)])
241        sys.exit(0) # try to force an exit
242    else:
243        if argv:
244            from setuptools.command.easy_install import main
245            main(argv)
246        else:
247            print "Setuptools version",version,"or greater has been installed."
248            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
249
250def update_md5(filenames):
251    """Update our built-in md5 registry"""
252
253    import re
254
255    for name in filenames:
256        base = os.path.basename(name)
257        f = open(name,'rb')
258        md5_data[base] = md5(f.read()).hexdigest()
259        f.close()
260
261    data = ["    %r: %r,\n" % it for it in md5_data.items()]
262    data.sort()
263    repl = "".join(data)
264
265    import inspect
266    srcfile = inspect.getsourcefile(sys.modules[__name__])
267    f = open(srcfile, 'rb'); src = f.read(); f.close()
268
269    match = re.search("\nmd5_data = {\n([^}]+)}", src)
270    if not match:
271        print >>sys.stderr, "Internal error!"
272        sys.exit(2)
273
274    src = src[:match.start(1)] + repl + src[match.end(1):]
275    f = open(srcfile,'w')
276    f.write(src)
277    f.close()
278
279
280if __name__=='__main__':
281    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
282        update_md5(sys.argv[2:])
283    else:
284        main(sys.argv[1:])
285