summaryrefslogtreecommitdiff
path: root/easy_install.py
diff options
context:
space:
mode:
authorPJ Eby <distutils-sig@python.org>2005-05-30 03:37:50 +0000
committerPJ Eby <distutils-sig@python.org>2005-05-30 03:37:50 +0000
commit454420e3e2f2e76653a0f419f200900cebf7e66f (patch)
treef6f9aeb26e54ed8b918cee2bb5cd74360fcf9525 /easy_install.py
parent749999c228548a9f317a45b07a3b137de859ea73 (diff)
downloadpython-setuptools-bitbucket-454420e3e2f2e76653a0f419f200900cebf7e66f.tar.gz
Add SourceForge download support, graciously contributed by Ian Bicking.
Also, move some more imports to the top.
Diffstat (limited to 'easy_install.py')
-rwxr-xr-xeasy_install.py71
1 files changed, 56 insertions, 15 deletions
diff --git a/easy_install.py b/easy_install.py
index 960cfe75..8b03ce82 100755
--- a/easy_install.py
+++ b/easy_install.py
@@ -154,6 +154,7 @@ Options
"""
import sys, os.path, pkg_resources, re, zipimport, zipfile, tarfile, shutil
+import urlparse, urllib, tempfile
from distutils.sysconfig import get_python_lib
from shutil import rmtree # must have, because it can be called from __del__
from pkg_resources import *
@@ -161,7 +162,6 @@ from pkg_resources import *
-
class Installer:
"""Manage a download/build/install process"""
@@ -170,8 +170,7 @@ class Installer:
def __init__(self, instdir=None, zip_ok=False, multi=None, tmpdir=None):
if tmpdir is None:
- from tempfile import mkdtemp
- tmpdir = mkdtemp(prefix="easy_install-")
+ tmpdir = tempfile.mkdtemp(prefix="easy_install-")
self.tmpdir = tmpdir
@@ -203,6 +202,7 @@ class Installer:
+
def samefile(self,p1,p2):
if hasattr(os.path,'samefile') and (
os.path.exists(p1) and os.path.exists(p2)
@@ -286,9 +286,7 @@ class Installer:
def _extract_zip(self,zipname,extract_dir):
- import zipfile
z = zipfile.ZipFile(zipname)
-
try:
for info in z.infolist():
name = info.filename
@@ -326,6 +324,8 @@ class Installer:
finally:
tarobj.close()
+
+
def _run_setup(self, setup_script):
from setuptools.command import bdist_egg
sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
@@ -368,7 +368,7 @@ class Installer:
def install_egg(self, egg_path, zip_ok):
- import shutil
+
destination = os.path.join(self.instdir, os.path.basename(egg_path))
ensure_directory(destination)
@@ -409,9 +409,9 @@ class Installer:
self.pth_file.save()
def _download_url(self, scheme, url):
+
# Determine download filename
- from urlparse import urlparse
- name = filter(None,urlparse(url)[2].split('/'))[-1]
+ name = filter(None,urlparse.urlparse(url)[2].split('/'))[-1]
while '..' in name:
name = name.replace('..','.').replace('\\','_')
@@ -422,10 +422,8 @@ class Installer:
return self._download_svn(url, filename)
# Download the file
- from urllib import FancyURLopener, URLopener
-
- class _opener(FancyURLopener):
- http_error_default = URLopener.http_error_default
+ class _opener(urllib.FancyURLopener):
+ http_error_default = urllib.URLopener.http_error_default
try:
filename,headers = _opener().retrieve(
@@ -449,6 +447,8 @@ class Installer:
+
+
def _extract_file(self, dist_filename):
if zipfile.is_zipfile(dist_filename):
self._extract_zip(dist_filename, self.tmpdir)
@@ -464,16 +464,28 @@ class Installer:
def _download_html(self, url, headers, filename):
- # Check if it is a subversion index page:
+ # Check for a sourceforge URL
+ sf_url = url.startswith('http://prdownloads.')
file = open(filename)
for line in file:
if line.strip():
+ # Check for a subversion index page
if re.search(r'<title>Revision \d+:', line):
+ # it's a subversion index page:
file.close()
os.unlink(filename)
return self._download_svn(url, filename)
- else:
- break # not an index page
+ # Check for a SourceForge header
+ elif sf_url:
+ if re.search(r'^<HTML><HEAD>', line, re.I):
+ continue # skip first line
+ elif re.search(r'<TITLE>Select a Mirror for File:',line):
+ # Sourceforge mirror page
+ page = file.read()
+ file.close()
+ os.unlink(filename)
+ return self._download_sourceforge(url, page)
+ break # not an index page
file.close()
raise RuntimeError("Unexpected HTML page found at "+url)
@@ -482,6 +494,35 @@ class Installer:
os.system("svn checkout -q %s %s" % (url, filename))
return filename
+ def _download_sourceforge(self, source_url, sf_page):
+ """Download package from randomly-selected SourceForge mirror"""
+
+ mirror_regex = re.compile(r'HREF=(/.*?\?use_mirror=[^>]*)')
+ urls = [m.group(1) for m in mirror_regex.finditer(sf_page)]
+ if not urls:
+ raise RuntimeError(
+ "URL looks like a Sourceforge mirror page, but no URLs found"
+ )
+
+ import random
+ url = urlparse.urljoin(source_url, random.choice(urls))
+ f = urllib.urlopen(url)
+ match = re.search(
+ r'<META HTTP-EQUIV="refresh" content=".*?URL=(.*?)"',
+ f.read()
+ )
+ f.close()
+
+ if match:
+ download_url = match.group(1)
+ scheme = URL_SCHEME(download_url)
+ return self._download_url(scheme.group(1), download_url)
+ else:
+ raise RuntimeError(
+ 'No META HTTP-EQUIV="refresh" found in Sourceforge page at %s'
+ % url
+ )
+