Hugo Lopes Tavares avatar Hugo Lopes Tavares committed bb67d96

uses wsgi_intercept to intercept calls to python.python.org, so all pypi packages are got locally

Comments (0)

Files changed (2)

tests/pypi_server.py

+import os
+import re
+import wsgi_intercept
+from wsgi_intercept.urllib2_intercept import install_opener
+
+
+PYPI_DEFAULT_STATIC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "pypiserver")
+
+
+def get_similar_pages(url):
+    """
+    >>> get_similar_pages('http://pypi.python.org/simple/initools')
+    'http://pypi.python.org/simple/INITools'
+    >>> get_similar_pages('http://pypi.python.org/simple/initools/0.2')
+    'http://pypi.python.org/simple/INITools/0.2'
+    >>> get_similar_pages('http://pypi.python.org/simple/setuptools_git')
+    'http://pypi.python.org/simple/setuptools-git'
+    >>> get_similar_pages('http://pypi.python.org/simple/setuptools_git/setuptools_git-0.3.4.tar.gz')
+    'http://pypi.python.org/simple/setuptools-git/setuptools_git-0.3.4.tar.gz'
+    """
+    r = re.search(r'/simple/([^/]+)', url)
+    here = os.path.dirname(os.path.abspath(__file__))
+    all_packages = os.listdir(os.path.join(here, 'pypiserver', 'simple'))
+    if r:
+        package_name = r.group(1)
+        for package in all_packages:
+            if re.match(package_name, package, re.IGNORECASE):
+                return re.sub(package_name, package, url, 1)
+            if re.match(package_name.replace('_', '-'), package):
+                return re.sub(package_name, package, url, 1)
+    return url
+
+def pypi_app():
+    def wsgi_app(environ, start_response):
+        headers = [('Content-type', 'text/html')]
+        path_tree = environ['PATH_INFO'].split('/')
+        url = os.path.join(PYPI_DEFAULT_STATIC_PATH, *path_tree)
+        filepath = url
+        if environ['PATH_INFO'].endswith('.gz'):
+            headers = [('Content-type', 'application/x-gtar')]
+        else:
+            filepath = os.path.join(url, 'index.html')
+        filepath = get_similar_pages(filepath)
+        start_response('200 OK', headers)
+        if not os.path.exists(filepath):
+                return ''
+        return [open(filepath).read()]
+    return wsgi_app
+
+
+def use_fake_pypi():
+    # allow wsgi_intercept to work with urllib2 fakes
+    install_opener()
+    wsgi_intercept.add_wsgi_intercept('pypi.python.org', 80, pypi_app)

tests/test_pip.py

 import atexit
 import textwrap
 import urllib
+import tarfile
 from scripttest import TestFileEnvironment
 from path import Path, curdir
 
 
         # Install this version instead
         self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True)
+        self._use_fake_pypi_server()
 
     def run(self, *args, **kw):
         if self.verbose:
     def __del__(self):
         shutil.rmtree(self.root_path, ignore_errors=True)
 
+    def _copy_wsgi_intercept_files(self):
+        download_and_extract_bz2_file_to_here(
+                'http://bitbucket.org/hltbra/'
+                'pip-fake-pypi-server/raw/0859b02feb0f/'
+                'wsgi_intercept_clean.tar.bz2')
+    
+    def _copy_pypiserver_fake_files(self):
+        download_and_extract_bz2_file_to_here(
+                'http://bitbucket.org/hltbra/'
+                'pip-fake-pypi-server/raw/10ef24c13180/'
+                'pypiserver.tar.bz2')
+
+    def _use_fake_pypi_server(self):
+        if not os.path.exists(here/'pypiserver'):
+            self._copy_pypiserver_fake_files()
+        if not os.path.exists(here/'wsgi_intercept'):
+            self._copy_wsgi_intercept_files()
+        site_packages = self.root_path / self.site_packages
+        pth = open(os.path.join(site_packages, 'wsgi_intercept_pypi.pth'), 'w')
+        pth.write('import sys; sys.path.insert(0, "%s"); '
+                  'import pypi_server; '
+                  'pypi_server.use_fake_pypi(); '
+                  'sys.path.pop(0)' % here.abspath)
+        pth.close()
+
+
+def download_and_extract_bz2_file_to_here(file_url):
+    filepath, _ = urllib.urlretrieve(file_url)
+    wsgi_intercept = tarfile.open(filepath)
+    for filepath in wsgi_intercept:
+        wsgi_intercept.extract(filepath, here)
+    wsgi_intercept.close()
+
 
 def run_pip(*args, **kw):
     return env.run('pip', *args, **kw)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.