# HG changeset patch # User cavaliet # Date 1302273181 -7200 # Node ID 125fc6df230d752dcda392fb8cb093098cc8c9cc # Parent 2e2989c3072c88a1df669c1b5aa5140d91d3ac30# Parent 0556c56ef5ebf7cafd290c95d473814ec09b0143 fusionner diff -r 2e2989c3072c -r 125fc6df230d .hgignore --- a/.hgignore Wed Mar 23 17:34:36 2011 +0100 +++ b/.hgignore Fri Apr 08 16:33:01 2011 +0200 @@ -32,4 +32,10 @@ syntax: regexp ^src/ldt/build$ syntax: regexp -^src/ldt/ldt\.egg-info$ \ No newline at end of file +^src/ldt/ldt\.egg-info$ +syntax: regexp +^src/ldt/distribute-0\.6\.14\.tar\.gz$ +syntax: regexp +^src/ldt/distribute-0\.6\.14-py2\.6\.egg$ +syntax: regexp +^src/ldt/MANIFEST\.in$ \ No newline at end of file diff -r 2e2989c3072c -r 125fc6df230d .pydevproject --- a/.pydevproject Wed Mar 23 17:34:36 2011 +0100 +++ b/.pydevproject Fri Apr 08 16:33:01 2011 +0200 @@ -1,11 +1,11 @@ - - - - -python_platform -python 2.6 - -/platform/src/ldt -/platform/web - - + + + + +python_live +python 2.6 + +/platform/src/ldt +/platform/web + + diff -r 2e2989c3072c -r 125fc6df230d src/ldt/distribute_setup.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/distribute_setup.py Fri Apr 08 16:33:01 2011 +0200 @@ -0,0 +1,485 @@ +#!python +"""Bootstrap distribute installation + +If you want to use setuptools in your package's setup.py, just include this +file in the same directory with it, and add this to the top of your setup.py:: + + from distribute_setup import use_setuptools + use_setuptools() + +If you want to require a specific version of setuptools, set a download +mirror, or use an alternate download directory, you can do so by supplying +the appropriate options to ``use_setuptools()``. + +This file can also be run as a script to install or upgrade setuptools. +""" +import os +import sys +import time +import fnmatch +import tempfile +import tarfile +from distutils import log + +try: + from site import USER_SITE +except ImportError: + USER_SITE = None + +try: + import subprocess + + def _python_cmd(*args): + args = (sys.executable,) + args + return subprocess.call(args) == 0 + +except ImportError: + # will be used for python 2.3 + def _python_cmd(*args): + args = (sys.executable,) + args + # quoting arguments if windows + if sys.platform == 'win32': + def quote(arg): + if ' ' in arg: + return '"%s"' % arg + return arg + args = [quote(arg) for arg in args] + return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 + +DEFAULT_VERSION = "0.6.14" +DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" +SETUPTOOLS_FAKED_VERSION = "0.6c11" + +SETUPTOOLS_PKG_INFO = """\ +Metadata-Version: 1.0 +Name: setuptools +Version: %s +Summary: xxxx +Home-page: xxx +Author: xxx +Author-email: xxx +License: xxx +Description: xxx +""" % SETUPTOOLS_FAKED_VERSION + + +def _install(tarball): + # extracting the tarball + tmpdir = tempfile.mkdtemp() + log.warn('Extracting in %s', tmpdir) + old_wd = os.getcwd() + try: + os.chdir(tmpdir) + tar = tarfile.open(tarball) + _extractall(tar) + tar.close() + + # going in the directory + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) + os.chdir(subdir) + log.warn('Now working in %s', subdir) + + # installing + log.warn('Installing Distribute') + if not _python_cmd('setup.py', 'install'): + log.warn('Something went wrong during the installation.') + log.warn('See the error message above.') + finally: + os.chdir(old_wd) + + +def _build_egg(egg, tarball, to_dir): + # extracting the tarball + tmpdir = tempfile.mkdtemp() + log.warn('Extracting in %s', tmpdir) + old_wd = os.getcwd() + try: + os.chdir(tmpdir) + tar = tarfile.open(tarball) + _extractall(tar) + tar.close() + + # going in the directory + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) + os.chdir(subdir) + log.warn('Now working in %s', subdir) + + # building an egg + log.warn('Building a Distribute egg in %s', to_dir) + _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) + + finally: + os.chdir(old_wd) + # returning the result + log.warn(egg) + if not os.path.exists(egg): + raise IOError('Could not build the egg.') + + +def _do_download(version, download_base, to_dir, download_delay): + egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' + % (version, sys.version_info[0], sys.version_info[1])) + if not os.path.exists(egg): + tarball = download_setuptools(version, download_base, + to_dir, download_delay) + _build_egg(egg, tarball, to_dir) + sys.path.insert(0, egg) + import setuptools + setuptools.bootstrap_install_from = egg + + +def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, + to_dir=os.curdir, download_delay=15, no_fake=True): + # making sure we use the absolute path + to_dir = os.path.abspath(to_dir) + was_imported = 'pkg_resources' in sys.modules or \ + 'setuptools' in sys.modules + try: + try: + import pkg_resources + if not hasattr(pkg_resources, '_distribute'): + if not no_fake: + _fake_setuptools() + raise ImportError + except ImportError: + return _do_download(version, download_base, to_dir, download_delay) + try: + pkg_resources.require("distribute>="+version) + return + except pkg_resources.VersionConflict: + e = sys.exc_info()[1] + if was_imported: + sys.stderr.write( + "The required version of distribute (>=%s) is not available,\n" + "and can't be installed while this script is running. Please\n" + "install a more recent version first, using\n" + "'easy_install -U distribute'." + "\n\n(Currently using %r)\n" % (version, e.args[0])) + sys.exit(2) + else: + del pkg_resources, sys.modules['pkg_resources'] # reload ok + return _do_download(version, download_base, to_dir, + download_delay) + except pkg_resources.DistributionNotFound: + return _do_download(version, download_base, to_dir, + download_delay) + finally: + if not no_fake: + _create_fake_setuptools_pkg_info(to_dir) + +def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, + to_dir=os.curdir, delay=15): + """Download distribute from a specified location and return its filename + + `version` should be a valid distribute version number that is available + as an egg for download under the `download_base` URL (which should end + with a '/'). `to_dir` is the directory where the egg will be downloaded. + `delay` is the number of seconds to pause before an actual download + attempt. + """ + # making sure we use the absolute path + to_dir = os.path.abspath(to_dir) + try: + from urllib.request import urlopen + except ImportError: + from urllib2 import urlopen + tgz_name = "distribute-%s.tar.gz" % version + url = download_base + tgz_name + saveto = os.path.join(to_dir, tgz_name) + src = dst = None + if not os.path.exists(saveto): # Avoid repeated downloads + try: + log.warn("Downloading %s", url) + src = urlopen(url) + # Read/write all in one block, so we don't create a corrupt file + # if the download is interrupted. + data = src.read() + dst = open(saveto, "wb") + dst.write(data) + finally: + if src: + src.close() + if dst: + dst.close() + return os.path.realpath(saveto) + +def _no_sandbox(function): + def __no_sandbox(*args, **kw): + try: + from setuptools.sandbox import DirectorySandbox + if not hasattr(DirectorySandbox, '_old'): + def violation(*args): + pass + DirectorySandbox._old = DirectorySandbox._violation + DirectorySandbox._violation = violation + patched = True + else: + patched = False + except ImportError: + patched = False + + try: + return function(*args, **kw) + finally: + if patched: + DirectorySandbox._violation = DirectorySandbox._old + del DirectorySandbox._old + + return __no_sandbox + +def _patch_file(path, content): + """Will backup the file then patch it""" + existing_content = open(path).read() + if existing_content == content: + # already patched + log.warn('Already patched.') + return False + log.warn('Patching...') + _rename_path(path) + f = open(path, 'w') + try: + f.write(content) + finally: + f.close() + return True + +_patch_file = _no_sandbox(_patch_file) + +def _same_content(path, content): + return open(path).read() == content + +def _rename_path(path): + new_name = path + '.OLD.%s' % time.time() + log.warn('Renaming %s into %s', path, new_name) + os.rename(path, new_name) + return new_name + +def _remove_flat_installation(placeholder): + if not os.path.isdir(placeholder): + log.warn('Unkown installation at %s', placeholder) + return False + found = False + for file in os.listdir(placeholder): + if fnmatch.fnmatch(file, 'setuptools*.egg-info'): + found = True + break + if not found: + log.warn('Could not locate setuptools*.egg-info') + return + + log.warn('Removing elements out of the way...') + pkg_info = os.path.join(placeholder, file) + if os.path.isdir(pkg_info): + patched = _patch_egg_dir(pkg_info) + else: + patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) + + if not patched: + log.warn('%s already patched.', pkg_info) + return False + # now let's move the files out of the way + for element in ('setuptools', 'pkg_resources.py', 'site.py'): + element = os.path.join(placeholder, element) + if os.path.exists(element): + _rename_path(element) + else: + log.warn('Could not find the %s element of the ' + 'Setuptools distribution', element) + return True + +_remove_flat_installation = _no_sandbox(_remove_flat_installation) + +def _after_install(dist): + log.warn('After install bootstrap.') + placeholder = dist.get_command_obj('install').install_purelib + _create_fake_setuptools_pkg_info(placeholder) + +def _create_fake_setuptools_pkg_info(placeholder): + if not placeholder or not os.path.exists(placeholder): + log.warn('Could not find the install location') + return + pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) + setuptools_file = 'setuptools-%s-py%s.egg-info' % \ + (SETUPTOOLS_FAKED_VERSION, pyver) + pkg_info = os.path.join(placeholder, setuptools_file) + if os.path.exists(pkg_info): + log.warn('%s already exists', pkg_info) + return + + log.warn('Creating %s', pkg_info) + f = open(pkg_info, 'w') + try: + f.write(SETUPTOOLS_PKG_INFO) + finally: + f.close() + + pth_file = os.path.join(placeholder, 'setuptools.pth') + log.warn('Creating %s', pth_file) + f = open(pth_file, 'w') + try: + f.write(os.path.join(os.curdir, setuptools_file)) + finally: + f.close() + +_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info) + +def _patch_egg_dir(path): + # let's check if it's already patched + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') + if os.path.exists(pkg_info): + if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): + log.warn('%s already patched.', pkg_info) + return False + _rename_path(path) + os.mkdir(path) + os.mkdir(os.path.join(path, 'EGG-INFO')) + pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') + f = open(pkg_info, 'w') + try: + f.write(SETUPTOOLS_PKG_INFO) + finally: + f.close() + return True + +_patch_egg_dir = _no_sandbox(_patch_egg_dir) + +def _before_install(): + log.warn('Before install bootstrap.') + _fake_setuptools() + + +def _under_prefix(location): + if 'install' not in sys.argv: + return True + args = sys.argv[sys.argv.index('install')+1:] + for index, arg in enumerate(args): + for option in ('--root', '--prefix'): + if arg.startswith('%s=' % option): + top_dir = arg.split('root=')[-1] + return location.startswith(top_dir) + elif arg == option: + if len(args) > index: + top_dir = args[index+1] + return location.startswith(top_dir) + if arg == '--user' and USER_SITE is not None: + return location.startswith(USER_SITE) + return True + + +def _fake_setuptools(): + log.warn('Scanning installed packages') + try: + import pkg_resources + except ImportError: + # we're cool + log.warn('Setuptools or Distribute does not seem to be installed.') + return + ws = pkg_resources.working_set + try: + setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools', + replacement=False)) + except TypeError: + # old distribute API + setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools')) + + if setuptools_dist is None: + log.warn('No setuptools distribution found') + return + # detecting if it was already faked + setuptools_location = setuptools_dist.location + log.warn('Setuptools installation detected at %s', setuptools_location) + + # if --root or --preix was provided, and if + # setuptools is not located in them, we don't patch it + if not _under_prefix(setuptools_location): + log.warn('Not patching, --root or --prefix is installing Distribute' + ' in another location') + return + + # let's see if its an egg + if not setuptools_location.endswith('.egg'): + log.warn('Non-egg installation') + res = _remove_flat_installation(setuptools_location) + if not res: + return + else: + log.warn('Egg installation') + pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') + if (os.path.exists(pkg_info) and + _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): + log.warn('Already patched.') + return + log.warn('Patching...') + # let's create a fake egg replacing setuptools one + res = _patch_egg_dir(setuptools_location) + if not res: + return + log.warn('Patched done.') + _relaunch() + + +def _relaunch(): + log.warn('Relaunching...') + # we have to relaunch the process + # pip marker to avoid a relaunch bug + if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']: + sys.argv[0] = 'setup.py' + args = [sys.executable] + sys.argv + sys.exit(subprocess.call(args)) + + +def _extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + import copy + import operator + from tarfile import ExtractError + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 448 # decimal for oct 0700 + self.extract(tarinfo, path) + + # Reverse sort directories. + if sys.version_info < (2, 4): + def sorter(dir1, dir2): + return cmp(dir1.name, dir2.name) + directories.sort(sorter) + directories.reverse() + else: + directories.sort(key=operator.attrgetter('name'), reverse=True) + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError: + e = sys.exc_info()[1] + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + +def main(argv, version=DEFAULT_VERSION): + """Install or upgrade setuptools and EasyInstall""" + tarball = download_setuptools() + _install(tarball) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff -r 2e2989c3072c -r 125fc6df230d src/ldt/ldt/ldt_utils/projectserializer.py --- a/src/ldt/ldt/ldt_utils/projectserializer.py Wed Mar 23 17:34:36 2011 +0100 +++ b/src/ldt/ldt/ldt_utils/projectserializer.py Fri Apr 08 16:33:01 2011 +0200 @@ -147,6 +147,7 @@ element_duration = element_node.attrib[u"dur"] element_media = content.iri_id element_color = element_node.attrib[u"color"] + element_ldt_src = element_node.attrib.get(u"src", "") element_title = reduce_text_node(element_node, "title/text()") element_description = reduce_text_node(element_node, "abstract/text()") @@ -211,11 +212,15 @@ "end": int(element_begin) + int(element_duration), "id": element_id, "media": element_media, + "color": element_color, "content": { "mimetype": "application/x-ldt-structured", "title": element_title, "description": element_description, "color": element_color, + "img": { + "src": element_ldt_src, + }, "audio": { "src" : element_audio_src, "mimetype": "audio/mp3", diff -r 2e2989c3072c -r 125fc6df230d src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html --- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html Wed Mar 23 17:34:36 2011 +0100 +++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/projectslist.html Fri Apr 08 16:33:01 2011 +0200 @@ -18,9 +18,9 @@
{% trans 'link json by id' %}
{% ifequal project.state 2 %} - {% trans 'Project published, click to unpublish' %} + {% trans 'Project published, click to unpublish' %} {% else %} - {% trans 'Project not published, click to publish' %} + {% trans 'Project not published, click to publish' %} {% endifequal %} diff -r 2e2989c3072c -r 125fc6df230d src/ldt/ldt/media/swf/ldt/LignesDeTempsFlex.swf Binary file src/ldt/ldt/media/swf/ldt/LignesDeTempsFlex.swf has changed diff -r 2e2989c3072c -r 125fc6df230d src/ldt/ldt/settings.py --- a/src/ldt/ldt/settings.py Wed Mar 23 17:34:36 2011 +0100 +++ b/src/ldt/ldt/settings.py Fri Apr 08 16:33:01 2011 +0200 @@ -28,6 +28,7 @@ 'ldt.user', 'ldt.management', 'oauth_provider', + 'social_auth', ) MIDDLEWARE_CLASSES = ( @@ -41,18 +42,6 @@ 'jogging.middleware.LoggingMiddleware', ) -TEMPLATE_CONTEXT_PROCESSORS = ( - "django.core.context_processors.request", - "django.core.context_processors.auth", - "django.core.context_processors.debug", - "django.core.context_processors.i18n", - "django.core.context_processors.media", - "ldt.utils.context_processors.ldt", - "ldt.utils.context_processors.base", - "ldt.utils.context_processors.web", - "ldt.utils.context_processors.version", -) - WEB_URL = getattr(settings, 'WEB_URL', '') diff -r 2e2989c3072c -r 125fc6df230d src/ldt/ldt/utils/context_processors.py --- a/src/ldt/ldt/utils/context_processors.py Wed Mar 23 17:34:36 2011 +0100 +++ b/src/ldt/ldt/utils/context_processors.py Fri Apr 08 16:33:01 2011 +0200 @@ -2,15 +2,8 @@ import ldt -def ldt(request): - return {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX } - -def base(request): - return {'BASE_URL': settings.BASE_URL, 'MEDIA_URL': settings.MEDIA_URL } +def ldtcontext(request): + return {'BASE_URL': settings.BASE_URL, 'MEDIA_URL': settings.MEDIA_URL, 'TC1': 'TC1', \ + 'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'WEB_URL': settings.WEB_URL, \ + 'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX, 'VERSION': ldt.get_version() } -def web(request): - return {'WEB_URL': settings.WEB_URL } - -def version(request): - return {'VERSION': ldt.get_version() } - diff -r 2e2989c3072c -r 125fc6df230d src/ldt/setup.py --- a/src/ldt/setup.py Wed Mar 23 17:34:36 2011 +0100 +++ b/src/ldt/setup.py Fri Apr 08 16:33:01 2011 +0200 @@ -1,5 +1,9 @@ import os -from setuptools import setup, find_packages + +from distribute_setup import use_setuptools +use_setuptools() + +from setuptools import setup ROOT_DIR = os.path.dirname(__file__) SOURCE_DIR = os.path.join(ROOT_DIR, 'ldt') @@ -43,13 +47,22 @@ new_data_files.extend([os.path.join(ldirpath[len(base_path):], f) for f in lfilenames]) data_files.setdefault(key,[]).extend(new_data_files) +#write MANIFEST.in + +m = open("MANIFEST.in", "w") + +m.write("exclude MANIFEST.in\n") +for key,file_list in data_files.iteritems(): + for filename in file_list: + m.write("include %s/%s\n" % (key.replace(".","/"), filename)) +m.close() setup( name='ldt', version=version, author='Yves-Marie Haussonne (IRI)', author_email='contact@iri.centrepompidou.fr', - packages = find_packages(), + packages = packages, package_data = data_files, scripts=[], url='https://www.iri.centrepompidou.fr/dev/hg/platform', diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/lib/lib_create_env.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/virtualenv/res/lib/lib_create_env.py Fri Apr 08 16:33:01 2011 +0200 @@ -0,0 +1,292 @@ +import sys +import os +import os.path +import shutil +import tarfile +import zipfile +import urllib +import platform +import patch + +join = os.path.join +system_str = platform.system() + + +URLS = { + 'DISTRIBUTE': {'setup': 'distribute', 'url':'http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', 'local':"distribute-0.6.14.tar.gz"}, + 'DJANGO': {'setup': 'django', 'url': 'http://www.djangoproject.com/download/1.2.4/tarball/', 'local':"Django-1.2.4.tar.gz"}, + 'JOGGING': {'setup': 'jogging', 'url': 'http://github.com/zain/jogging/tarball/v0.2.2', 'local':"jogging-0.2.2.tar.gz"}, + 'DJANGO-EXTENSIONS': { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/tarball/0.6', 'local':"django-extensions-0.6.tar.gz"}, + 'DJANGO-REGISTRATION': { 'setup': 'django-registration', 'url':'http://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz', 'local':"django-registration.tar.gz"}, + 'DJANGO-TAGGING': { 'setup': 'django-tagging', 'url':'http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz', 'local':"django-tagging-0.3.1.tar.gz"}, + 'DJANGO-PISTON': { 'setup': 'django-piston', 'url':"django-piston-0.2.2-modified.tar.gz", 'local':"django-piston-0.2.2-modified.tar.gz"}, + 'OAUTH2': { 'setup': 'python-oauth2', 'url':"python-oauth2-1.2.1-modified.tar.gz", 'local':"python-oauth2-1.2.1-modified.tar.gz"}, + 'HTTPLIB2': { 'setup': 'python-oauth2', 'url':'http://httplib2.googlecode.com/files/httplib2-0.6.0.tar.gz', 'local':"httplib2-0.6.0.tar.gz"}, + 'DJANGO-OAUTH-PLUS': { 'setup': 'django-oauth-plus', 'url':'http://bitbucket.org/david/django-oauth-plus/get/f314f018e473.gz', 'local':"django-oauth-plus.tar.gz"}, + 'MYSQL': { 'setup': 'mysql-python', 'url': 'http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz/download', 'local':"MySQL-python-1.2.3.tar.gz"}, + 'SETUPTOOLS-HG': { 'setup':'mercurial_hg', 'url':'http://pypi.python.org/packages/source/s/setuptools_hg/setuptools_hg-0.2.tar.gz', 'local':"setuptools_hg-0.2.tar.gz"}, + 'MERCURIAL': {'setup':'mercurial', 'url':'http://pypi.python.org/packages/source/d/mercurial/mercurial-1.7.5.tar.gz', 'local':"mercurial-1.7.5.tar.gz"} +} + +if system_str == 'Windows': + URLS.update({ + 'PSYCOPG2': {'setup': 'psycopg2','url': 'psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip', 'local':"psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip"}, + 'JCC': {'setup': 'http://pylucene-win32-binary.googlecode.com/files/JCC-2.6-py2.6-win32.egg', 'local':"JCC-2.6-py2.6-win32.egg"}, + 'PYLUCENE': {'setup': 'http://pylucene-win32-binary.googlecode.com/files/lucene-3.0.2-py2.6-win32.egg', 'local':"lucene-3.0.2-py2.6-win32.egg"}, + 'PIL': {'setup': 'pil', 'url': 'http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.6.exe', 'local':"PIL-1.1.7.win32-py2.6.exe"}, + 'LXML': {'setup': 'lxml', 'url': 'http://pypi.python.org/packages/2.6/l/lxml/lxml-2.2.8-py2.6-win32.egg', 'local':"lxml-2.2.8-py2.6-win32.egg"} + }) +else: + URLS.update({ + 'PSYCOPG2': {'setup': 'psycopg2','url': 'http://initd.org/psycopg/tarballs/PSYCOPG-2-3/psycopg2-2.3.2.tar.gz', 'local':"psycopg2-2.3.2.tar.gz"}, + 'PYLUCENE': {'setup': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'url': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'local':"pylucene-3.0.3-1-src.tar.gz"}, + 'PIL': {'setup': 'pil', 'url': 'http://effbot.org/downloads/Imaging-1.1.7.tar.gz', 'local':"Imaging-1.1.7.tar.gz"}, + 'LXML': {'setup': 'lxml', 'url':"lxml_2.2.8.tar.gz", 'local':"lxml-2.2.8.tar.gz"} + }) + + + +class ResourcesEnv(object): + + def __init__(self, src_base, urls, normal_installs): + self.src_base = src_base + self.URLS = {} + self.__init_url(urls) + self.NORMAL_INSTALL = normal_installs + + def get_src_base_path(self, fpath): + return os.path.abspath(os.path.join(self.src_base, fpath)).replace("\\","/") + + def __add_package_def(self, key, setup, url, local): + self.URLS[key] = {'setup':setup, 'url':url, 'local':self.get_src_base_path(local)} + + def __init_url(self, urls): + for key, url_dict in urls.items(): + url = url_dict['url'] + if not url.startswith("http://"): + url = self.get_src_base_path(url) + self.__add_package_def(key, url_dict["setup"], url, url_dict["local"]) + +def ensure_dir(dir, logger): + if not os.path.exists(dir): + logger.notify('Creating directory %s' % dir) + os.makedirs(dir) + +def extend_parser(parser): + parser.add_option( + '--index-url', + metavar='INDEX_URL', + dest='index_url', + default='http://pypi.python.org/simple/', + help='base URL of Python Package Index') + parser.add_option( + '--type-install', + metavar='type_install', + dest='type_install', + default='local', + help='type install : local, url, setup') + parser.add_option( + '--ignore-packages', + metavar='ignore_packages', + dest='ignore_packages', + default=None, + help='list of comma separated keys for package to ignore') + +def adjust_options(options, args): + pass + + +def install_pylucene(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop): + + logger.notify("Get Pylucene from %s " % res_env.URLS['PYLUCENE'][res_source_key]) + pylucene_src = os.path.join(src_dir,"pylucene.tar.gz") + if res_source_key == 'local': + shutil.copy(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src) + else: + urllib.urlretrieve(res_env.URLS['PYLUCENE'][res_source_key], pylucene_src) + tf = tarfile.open(pylucene_src,'r:gz') + pylucene_base_path = os.path.join(src_dir,"pylucene") + logger.notify("Extract Pylucene to %s " % pylucene_base_path) + tf.extractall(pylucene_base_path) + tf.close() + + pylucene_src_path = os.path.join(pylucene_base_path, os.listdir(pylucene_base_path)[0]) + jcc_src_path = os.path.abspath(os.path.join(pylucene_src_path,"jcc")) + + #install jcc + + #patch for linux + if system_str == 'Linux' : + olddir = os.getcwd() + patch_dest_path = os.path.join(lib_dir,'site-packages','setuptools-0.6c11-py'+'%s.%s' % (sys.version_info[0], sys.version_info[1])+'.egg') + if os.path.isfile(patch_dest_path): + # must unzip egg + # rename file and etract all + shutil.move(patch_dest_path, patch_dest_path + ".zip") + zf = zipfile.ZipFile(patch_dest_path + ".zip",'r') + zf.extractall(patch_dest_path) + os.remove(patch_dest_path + ".zip") + logger.notify("Patch jcc : %s " % (patch_dest_path)) + os.chdir(patch_dest_path) + p = patch.fromfile(os.path.join(jcc_src_path,"jcc","patches","patch.43.0.6c11")) + p.apply() + os.chdir(olddir) + + logger.notify("Install jcc") + call_subprocess([os.path.abspath(os.path.join(home_dir, 'bin', 'python')), 'setup.py', 'install'], + cwd=jcc_src_path, + filter_stdout=filter_python_develop, + show_stdout=True) + #install pylucene + + logger.notify("Install pylucene") + #modify makefile + makefile_path = os.path.join(pylucene_src_path,"Makefile") + logger.notify("Modify makefile %s " % makefile_path) + shutil.move( makefile_path, makefile_path+"~" ) + + destination= open( makefile_path, "w" ) + source= open( makefile_path+"~", "r" ) + destination.write("PREFIX_PYTHON="+os.path.abspath(home_dir)+"\n") + destination.write("ANT=ant\n") + destination.write("PYTHON=$(PREFIX_PYTHON)/bin/python\n") + + if system_str == "Darwin": + if sys.version_info >= (2,6): + destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n") + else: + destination.write("JCC=$(PYTHON) -m jcc --shared --arch x86_64 --arch i386\n") + destination.write("NUM_FILES=2\n") + elif system_str == "Windows": + destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\n") + destination.write("NUM_FILES=2\n") + else: + if sys.version_info >= (2,6) and sys.version_info <= (2,7): + destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared\n") + else: + destination.write("JCC=$(PYTHON) -m jcc --shared\n") + destination.write("NUM_FILES=2\n") + for line in source: + destination.write( line ) + source.close() + destination.close() + os.remove(makefile_path+"~" ) + + logger.notify("pylucene make") + call_subprocess(['make'], + cwd=os.path.abspath(pylucene_src_path), + filter_stdout=filter_python_develop, + show_stdout=True) + + logger.notify("pylucene make install") + call_subprocess(['make', 'install'], + cwd=os.path.abspath(pylucene_src_path), + filter_stdout=filter_python_develop, + show_stdout=True) + + +def install_psycopg2(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop): + psycopg2_src = os.path.join(src_dir,"psycopg2.zip") + shutil.copy(res_env.URLS['PSYCOPG2'][res_source_key], psycopg2_src) + #extract psycopg2 + zf = zipfile.ZipFile(psycopg2_src) + psycopg2_base_path = os.path.join(src_dir,"psycopg2") + zf.extractall(psycopg2_base_path) + zf.close() + + psycopg2_src_path = os.path.join(psycopg2_base_path, os.listdir(psycopg2_base_path)[0]) + shutil.copytree(os.path.join(psycopg2_src_path, 'psycopg2'), os.path.abspath(os.path.join(home_dir, 'Lib', 'psycopg2'))) + shutil.copy(os.path.join(psycopg2_src_path, 'psycopg2-2.0.10-py2.6.egg-info'), os.path.abspath(os.path.join(home_dir, 'Lib', 'site-packages'))) + + + +def lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, normal_installs, urls=None): + + all_urls = URLS.copy() + if urls is not None: + all_urls.update(urls) + + res_env = ResourcesEnv(src_base, all_urls, normal_installs) + + def filter_python_develop(line): + if not line.strip(): + return Logger.DEBUG + for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ', + 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ', + 'creating ', 'Copying ']: + if line.startswith(prefix): + return Logger.DEBUG + return Logger.NOTIFY + + + def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir, res_env, logger, call_subprocess): + logger.notify("Install %s from %s with %s" % (key,res_env.URLS[key][res_source_key],method)) + if method == 'pip': + if sys.platform == 'win32': + args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]] + else: + args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), res_env.URLS[key][res_source_key]] + if option_str : + args.insert(4,option_str) + call_subprocess(args, + cwd=os.path.abspath(tmp_dir), + filter_stdout=filter_python_develop, + show_stdout=True, + extra_env=extra_env) + else: + if sys.platform == 'win32': + args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), res_env.URLS[key][res_source_key]] + else: + args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), res_env.URLS[key][res_source_key]] + if option_str : + args.insert(1,option_str) + call_subprocess(args, + cwd=os.path.abspath(tmp_dir), + filter_stdout=filter_python_develop, + show_stdout=True, + extra_env=extra_env) + + + def after_install(options, home_dir): + + global logger + + verbosity = options.verbose - options.quiet + logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)]) + + + home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) + base_dir = os.path.dirname(home_dir) + src_dir = os.path.join(home_dir, 'src') + tmp_dir = os.path.join(home_dir, 'tmp') + ensure_dir(src_dir, logger) + ensure_dir(tmp_dir, logger) + system_str = platform.system() + + res_source_key = options.type_install + + ignore_packages = [] + + if options.ignore_packages : + ignore_packages = options.ignore_packages.split(",") + + logger.indent += 2 + try: + for key, method, option_str, extra_env in res_env.NORMAL_INSTALL: + if key not in ignore_packages: + if callable(method): + method(option_str, extra_env, res_source_key, home_dir, tmp_dir, src_dir, res_env, logger, call_subprocess, filter_python_develop) + else: + normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir, res_env, logger, call_subprocess) + + logger.notify("Clear source dir") + shutil.rmtree(src_dir) + + finally: + logger.indent -= 2 + script_dir = join(base_dir, bin_dir) + logger.notify('Run "%s Package" to install new packages that provide builds' + % join(script_dir, 'easy_install')) + + + return adjust_options, extend_parser, after_install diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/lib/patch.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/virtualenv/res/lib/patch.py Fri Apr 08 16:33:01 2011 +0200 @@ -0,0 +1,589 @@ +""" Patch utility to apply unified diffs + + Brute-force line-by-line non-recursive parsing + + Copyright (c) 2008-2010 anatoly techtonik + Available under the terms of MIT license + + Project home: http://code.google.com/p/python-patch/ + + + $Id: patch.py 76 2010-04-08 19:10:21Z techtonik $ + $HeadURL: https://python-patch.googlecode.com/svn/trunk/patch.py $ +""" + +__author__ = "techtonik.rainforce.org" +__version__ = "10.04" + +import copy +import logging +import re +# cStringIO doesn't support unicode in 2.5 +from StringIO import StringIO +from logging import debug, info, warning + +from os.path import exists, isfile, abspath +from os import unlink + + +#------------------------------------------------ +# Logging is controlled by "python_patch" logger + +debugmode = False + +logger = logging.getLogger("python_patch") +loghandler = logging.StreamHandler() +logger.addHandler(loghandler) + +debug = logger.debug +info = logger.info +warning = logger.warning + +#: disable library logging by default +logger.setLevel(logging.CRITICAL) + +#------------------------------------------------ + + +def fromfile(filename): + """ Parse patch file and return Patch() object + """ + + info("reading patch from file %s" % filename) + fp = open(filename, "rb") + patch = Patch(fp) + fp.close() + return patch + + +def fromstring(s): + """ Parse text string and return Patch() object + """ + + return Patch( + StringIO.StringIO(s) + ) + + + +class HunkInfo(object): + """ Parsed hunk data container (hunk starts with @@ -R +R @@) """ + + def __init__(self): + self.startsrc=None #: line count starts with 1 + self.linessrc=None + self.starttgt=None + self.linestgt=None + self.invalid=False + self.text=[] + + def copy(self): + return copy.copy(self) + +# def apply(self, estream): +# """ write hunk data into enumerable stream +# return strings one by one until hunk is +# over +# +# enumerable stream are tuples (lineno, line) +# where lineno starts with 0 +# """ +# pass + + + +class Patch(object): + + def __init__(self, stream=None): + + # define Patch data members + # table with a row for every source file + + #: list of source filenames + self.source=None + self.target=None + #: list of lists of hunks + self.hunks=None + #: file endings statistics for every hunk + self.hunkends=None + + if stream: + self.parse(stream) + + def copy(self): + return copy.copy(self) + + def parse(self, stream): + """ parse unified diff """ + self.source = [] + self.target = [] + self.hunks = [] + self.hunkends = [] + + # define possible file regions that will direct the parser flow + header = False # comments before the patch body + filenames = False # lines starting with --- and +++ + + hunkhead = False # @@ -R +R @@ sequence + hunkbody = False # + hunkskip = False # skipping invalid hunk mode + + header = True + lineends = dict(lf=0, crlf=0, cr=0) + nextfileno = 0 + nexthunkno = 0 #: even if index starts with 0 user messages number hunks from 1 + + # hunkinfo holds parsed values, hunkactual - calculated + hunkinfo = HunkInfo() + hunkactual = dict(linessrc=None, linestgt=None) + + fe = enumerate(stream) + for lineno, line in fe: + + # analyze state + if header and line.startswith("--- "): + header = False + # switch to filenames state + filenames = True + #: skip hunkskip and hunkbody code until you read definition of hunkhead + if hunkbody: + # process line first + if re.match(r"^[- \+\\]", line): + # gather stats about line endings + if line.endswith("\r\n"): + self.hunkends[nextfileno-1]["crlf"] += 1 + elif line.endswith("\n"): + self.hunkends[nextfileno-1]["lf"] += 1 + elif line.endswith("\r"): + self.hunkends[nextfileno-1]["cr"] += 1 + + if line.startswith("-"): + hunkactual["linessrc"] += 1 + elif line.startswith("+"): + hunkactual["linestgt"] += 1 + elif not line.startswith("\\"): + hunkactual["linessrc"] += 1 + hunkactual["linestgt"] += 1 + hunkinfo.text.append(line) + # todo: handle \ No newline cases + else: + warning("invalid hunk no.%d at %d for target file %s" % (nexthunkno, lineno+1, self.target[nextfileno-1])) + # add hunk status node + self.hunks[nextfileno-1].append(hunkinfo.copy()) + self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True + # switch to hunkskip state + hunkbody = False + hunkskip = True + + # check exit conditions + if hunkactual["linessrc"] > hunkinfo.linessrc or hunkactual["linestgt"] > hunkinfo.linestgt: + warning("extra hunk no.%d lines at %d for target %s" % (nexthunkno, lineno+1, self.target[nextfileno-1])) + # add hunk status node + self.hunks[nextfileno-1].append(hunkinfo.copy()) + self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True + # switch to hunkskip state + hunkbody = False + hunkskip = True + elif hunkinfo.linessrc == hunkactual["linessrc"] and hunkinfo.linestgt == hunkactual["linestgt"]: + self.hunks[nextfileno-1].append(hunkinfo.copy()) + # switch to hunkskip state + hunkbody = False + hunkskip = True + + # detect mixed window/unix line ends + ends = self.hunkends[nextfileno-1] + if ((ends["cr"]!=0) + (ends["crlf"]!=0) + (ends["lf"]!=0)) > 1: + warning("inconsistent line ends in patch hunks for %s" % self.source[nextfileno-1]) + if debugmode: + debuglines = dict(ends) + debuglines.update(file=self.target[nextfileno-1], hunk=nexthunkno) + debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines) + + if hunkskip: + match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line) + if match: + # switch to hunkhead state + hunkskip = False + hunkhead = True + elif line.startswith("--- "): + # switch to filenames state + hunkskip = False + filenames = True + if debugmode and len(self.source) > 0: + debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1])) + + if filenames: + if line.startswith("--- "): + if nextfileno in self.source: + warning("skipping invalid patch for %s" % self.source[nextfileno]) + del self.source[nextfileno] + # double source filename line is encountered + # attempt to restart from this second line + re_filename = "^--- ([^\t]+)" + match = re.match(re_filename, line) + # todo: support spaces in filenames + if match: + self.source.append(match.group(1).strip()) + else: + warning("skipping invalid filename at line %d" % lineno) + # switch back to header state + filenames = False + header = True + elif not line.startswith("+++ "): + if nextfileno in self.source: + warning("skipping invalid patch with no target for %s" % self.source[nextfileno]) + del self.source[nextfileno] + else: + # this should be unreachable + warning("skipping invalid target patch") + filenames = False + header = True + else: + if nextfileno in self.target: + warning("skipping invalid patch - double target at line %d" % lineno) + del self.source[nextfileno] + del self.target[nextfileno] + nextfileno -= 1 + # double target filename line is encountered + # switch back to header state + filenames = False + header = True + else: + re_filename = "^\+\+\+ ([^\t]+)" + match = re.match(re_filename, line) + if not match: + warning("skipping invalid patch - no target filename at line %d" % lineno) + # switch back to header state + filenames = False + header = True + else: + self.target.append(match.group(1).strip()) + nextfileno += 1 + # switch to hunkhead state + filenames = False + hunkhead = True + nexthunkno = 0 + self.hunks.append([]) + self.hunkends.append(lineends.copy()) + continue + + if hunkhead: + match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line) + if not match: + if nextfileno-1 not in self.hunks: + warning("skipping invalid patch with no hunks for file %s" % self.target[nextfileno-1]) + # switch to header state + hunkhead = False + header = True + continue + else: + # switch to header state + hunkhead = False + header = True + else: + hunkinfo.startsrc = int(match.group(1)) + hunkinfo.linessrc = 1 + if match.group(3): hunkinfo.linessrc = int(match.group(3)) + hunkinfo.starttgt = int(match.group(4)) + hunkinfo.linestgt = 1 + if match.group(6): hunkinfo.linestgt = int(match.group(6)) + hunkinfo.invalid = False + hunkinfo.text = [] + + hunkactual["linessrc"] = hunkactual["linestgt"] = 0 + + # switch to hunkbody state + hunkhead = False + hunkbody = True + nexthunkno += 1 + continue + else: + if not hunkskip: + warning("patch file incomplete - %s" % filename) + # sys.exit(?) + else: + # duplicated message when an eof is reached + if debugmode and len(self.source) > 0: + debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1])) + + info("total files: %d total hunks: %d" % (len(self.source), sum(len(hset) for hset in self.hunks))) + + + def apply(self): + """ apply parsed patch """ + + total = len(self.source) + for fileno, filename in enumerate(self.source): + + f2patch = filename + if not exists(f2patch): + f2patch = self.target[fileno] + if not exists(f2patch): + warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, f2patch)) + continue + if not isfile(f2patch): + warning("not a file - %s" % f2patch) + continue + filename = f2patch + + info("processing %d/%d:\t %s" % (fileno+1, total, filename)) + + # validate before patching + f2fp = open(filename) + hunkno = 0 + hunk = self.hunks[fileno][hunkno] + hunkfind = [] + hunkreplace = [] + validhunks = 0 + canpatch = False + for lineno, line in enumerate(f2fp): + if lineno+1 < hunk.startsrc: + continue + elif lineno+1 == hunk.startsrc: + hunkfind = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " -"] + hunkreplace = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " +"] + #pprint(hunkreplace) + hunklineno = 0 + + # todo \ No newline at end of file + + # check hunks in source file + if lineno+1 < hunk.startsrc+len(hunkfind)-1: + if line.rstrip("\r\n") == hunkfind[hunklineno]: + hunklineno+=1 + else: + debug("hunk no.%d doesn't match source file %s" % (hunkno+1, filename)) + # file may be already patched, but we will check other hunks anyway + hunkno += 1 + if hunkno < len(self.hunks[fileno]): + hunk = self.hunks[fileno][hunkno] + continue + else: + break + + # check if processed line is the last line + if lineno+1 == hunk.startsrc+len(hunkfind)-1: + debug("file %s hunk no.%d -- is ready to be patched" % (filename, hunkno+1)) + hunkno+=1 + validhunks+=1 + if hunkno < len(self.hunks[fileno]): + hunk = self.hunks[fileno][hunkno] + else: + if validhunks == len(self.hunks[fileno]): + # patch file + canpatch = True + break + else: + if hunkno < len(self.hunks[fileno]): + warning("premature end of source file %s at hunk %d" % (filename, hunkno+1)) + + f2fp.close() + + if validhunks < len(self.hunks[fileno]): + if self._match_file_hunks(filename, self.hunks[fileno]): + warning("already patched %s" % filename) + else: + warning("source file is different - %s" % filename) + if canpatch: + backupname = filename+".orig" + if exists(backupname): + warning("can't backup original file to %s - aborting" % backupname) + else: + import shutil + shutil.move(filename, backupname) + if self.write_hunks(backupname, filename, self.hunks[fileno]): + warning("successfully patched %s" % filename) + unlink(backupname) + else: + warning("error patching file %s" % filename) + shutil.copy(filename, filename+".invalid") + warning("invalid version is saved to %s" % filename+".invalid") + # todo: proper rejects + shutil.move(backupname, filename) + + # todo: check for premature eof + + + def can_patch(self, filename): + """ Check if specified filename can be patched. Returns None if file can + not be found among source filenames. False if patch can not be applied + clearly. True otherwise. + + :returns: True, False or None + """ + idx = self._get_file_idx(filename, source=True) + if idx == None: + return None + return self._match_file_hunks(filename, self.hunks[idx]) + + + def _match_file_hunks(self, filepath, hunks): + matched = True + fp = open(abspath(filepath)) + + class NoMatch(Exception): + pass + + lineno = 1 + line = fp.readline() + hno = None + try: + for hno, h in enumerate(hunks): + # skip to first line of the hunk + while lineno < h.starttgt: + if not len(line): # eof + debug("check failed - premature eof before hunk: %d" % (hno+1)) + raise NoMatch + line = fp.readline() + lineno += 1 + for hline in h.text: + if hline.startswith("-"): + continue + if not len(line): + debug("check failed - premature eof on hunk: %d" % (hno+1)) + # todo: \ No newline at the end of file + raise NoMatch + if line.rstrip("\r\n") != hline[1:].rstrip("\r\n"): + debug("file is not patched - failed hunk: %d" % (hno+1)) + raise NoMatch + line = fp.readline() + lineno += 1 + + except NoMatch: + matched = False + # todo: display failed hunk, i.e. expected/found + + fp.close() + return matched + + + def patch_stream(self, instream, hunks): + """ Generator that yields stream patched with hunks iterable + + Converts lineends in hunk lines to the best suitable format + autodetected from input + """ + + # todo: At the moment substituted lineends may not be the same + # at the start and at the end of patching. Also issue a + # warning/throw about mixed lineends (is it really needed?) + + hunks = iter(hunks) + + srclineno = 1 + + lineends = {'\n':0, '\r\n':0, '\r':0} + def get_line(): + """ + local utility function - return line from source stream + collecting line end statistics on the way + """ + line = instream.readline() + # 'U' mode works only with text files + if line.endswith("\r\n"): + lineends["\r\n"] += 1 + elif line.endswith("\n"): + lineends["\n"] += 1 + elif line.endswith("\r"): + lineends["\r"] += 1 + return line + + for hno, h in enumerate(hunks): + debug("hunk %d" % (hno+1)) + # skip to line just before hunk starts + while srclineno < h.startsrc: + yield get_line() + srclineno += 1 + + for hline in h.text: + # todo: check \ No newline at the end of file + if hline.startswith("-") or hline.startswith("\\"): + get_line() + srclineno += 1 + continue + else: + if not hline.startswith("+"): + get_line() + srclineno += 1 + line2write = hline[1:] + # detect if line ends are consistent in source file + if sum([bool(lineends[x]) for x in lineends]) == 1: + newline = [x for x in lineends if lineends[x] != 0][0] + yield line2write.rstrip("\r\n")+newline + else: # newlines are mixed + yield line2write + + for line in instream: + yield line + + + def write_hunks(self, srcname, tgtname, hunks): + src = open(srcname, "rb") + tgt = open(tgtname, "wb") + + debug("processing target file %s" % tgtname) + + tgt.writelines(self.patch_stream(src, hunks)) + + tgt.close() + src.close() + return True + + + def _get_file_idx(self, filename, source=None): + """ Detect index of given filename within patch. + + :param filename: + :param source: search filename among sources (True), + targets (False), or both (None) + :returns: int or None + """ + filename = abspath(filename) + if source == True or source == None: + for i,fnm in enumerate(self.source): + if filename == abspath(fnm): + return i + if source == False or source == None: + for i,fnm in enumerate(self.target): + if filename == abspath(fnm): + return i + + + + +from optparse import OptionParser +from os.path import exists +import sys + +if __name__ == "__main__": + opt = OptionParser(usage="%prog [options] unipatch-file", version="python-patch %s" % __version__) + opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode") + (options, args) = opt.parse_args() + + if not args: + opt.print_version() + opt.print_help() + sys.exit() + debugmode = options.debugmode + patchfile = args[0] + if not exists(patchfile) or not isfile(patchfile): + sys.exit("patch file does not exist - %s" % patchfile) + + + if debugmode: + loglevel = logging.DEBUG + logformat = "%(levelname)8s %(message)s" + else: + loglevel = logging.INFO + logformat = "%(message)s" + logger.setLevel(loglevel) + loghandler.setFormatter(logging.Formatter(logformat)) + + + + patch = fromfile(patchfile) + #pprint(patch) + patch.apply() + + # todo: document and test line ends handling logic - patch.py detects proper line-endings + # for inserted hunks and issues a warning if patched file has incosistent line ends diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/Django-1.2.4.tar.gz Binary file virtualenv/res/src/Django-1.2.4.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/Imaging-1.1.7.tar.gz Binary file virtualenv/res/src/Imaging-1.1.7.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/JCC-2.6-py2.6-win32.egg Binary file virtualenv/res/src/JCC-2.6-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/MySQL-python-1.2.3.tar.gz Binary file virtualenv/res/src/MySQL-python-1.2.3.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/PIL-1.1.7.win32-py2.6.exe Binary file virtualenv/res/src/PIL-1.1.7.win32-py2.6.exe has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/distribute-0.6.14.tar.gz Binary file virtualenv/res/src/distribute-0.6.14.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/django-extensions-0.6.tar.gz Binary file virtualenv/res/src/django-extensions-0.6.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/django-oauth-plus.tar.gz Binary file virtualenv/res/src/django-oauth-plus.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/django-piston-0.2.2-modified.tar.gz Binary file virtualenv/res/src/django-piston-0.2.2-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/django-registration.tar.gz Binary file virtualenv/res/src/django-registration.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/django-tagging-0.3.1.tar.gz Binary file virtualenv/res/src/django-tagging-0.3.1.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/facebook-python-sdk-322930c.tar.gz Binary file virtualenv/res/src/facebook-python-sdk-322930c.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/httplib2-0.6.0.tar.gz Binary file virtualenv/res/src/httplib2-0.6.0.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/jogging-0.2.2.tar.gz Binary file virtualenv/res/src/jogging-0.2.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/lucene-3.0.2-py2.6-win32.egg Binary file virtualenv/res/src/lucene-3.0.2-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/lxml-2.2.8-py2.6-win32.egg Binary file virtualenv/res/src/lxml-2.2.8-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/lxml-2.2.8.tar.gz Binary file virtualenv/res/src/lxml-2.2.8.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/mercurial-1.7.5.tar.gz Binary file virtualenv/res/src/mercurial-1.7.5.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/oauth-1.0.1.tar.gz Binary file virtualenv/res/src/oauth-1.0.1.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip Binary file virtualenv/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/psycopg2-2.3.2.tar.gz Binary file virtualenv/res/src/psycopg2-2.3.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/pylinkedin-0.3.tar.bz2 Binary file virtualenv/res/src/pylinkedin-0.3.tar.bz2 has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/pylucene-3.0.3-1-src.tar.gz Binary file virtualenv/res/src/pylucene-3.0.3-1-src.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/python-oauth2-1.2.1-modified.tar.gz Binary file virtualenv/res/src/python-oauth2-1.2.1-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/python-openid-2.2.5.tar.gz Binary file virtualenv/res/src/python-openid-2.2.5.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/setuptools_hg-0.2.tar.gz Binary file virtualenv/res/src/setuptools_hg-0.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/res/src/uswaretech-Django-Socialauth-1e22872-modified.tar.gz Binary file virtualenv/res/src/uswaretech-Django-Socialauth-1e22872-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/setup/create_python_env.py --- a/virtualenv/setup/create_python_env.py Wed Mar 23 17:34:36 2011 +0100 +++ b/virtualenv/setup/create_python_env.py Fri Apr 08 16:33:01 2011 +0200 @@ -29,137 +29,17 @@ # - 4Suite-xml - easy_install ftp://ftp.4suite.org/pub/4Suite/4Suite-XML-1.0.2.tar.bz2 # - pylucene - script -src_base = os.path.join(here,"res","src").replace("\\","/") -lib_path = os.path.abspath(os.path.join(here,"res","lib")).replace("\\","/") - -EXTRA_TEXT = "URLS = { \n" - -EXTRA_TEXT += " 'DISTRIBUTE' : { 'setup': 'distribute', 'url': 'http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"distribute-0.6.14.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'MERCURIAL' : { 'setup': 'distribute', 'url': 'http://pypi.python.org/packages/source/d/mercurial/mercurial-1.7.5.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"mercurial-1.7.5.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += "}\n" - -EXTRA_TEXT += "import sys\n" -EXTRA_TEXT += "sys.path.append('"+lib_path+"')\n" - -EXTRA_TEXT += """ - -import shutil -import tarfile -import zipfile -import urllib -import platform - - -INDEX_URL = 'http://pypi.python.org/simple/' - - -def extend_parser(parser): - parser.add_option( - '--index-url', - metavar='INDEX_URL', - dest='index_url', - default='', - help='base URL of Python Package Index') - parser.add_option( - '--type-install', - metavar='type_install', - dest='type_install', - default='local', - help='type install : local, url, setup') - parser.add_option( - '--ignore-packages', - metavar='ignore_packages', - dest='ignore_packages', - default=None, - help='list of comma separated keys for package to ignore') - - - -def adjust_options(options, args): - pass +src_base = os.path.abspath(os.path.join(here,"..","res","src")).replace("\\","/") +lib_path = os.path.abspath(os.path.join(here,"..","res","lib")).replace("\\","/") +patch_path = os.path.abspath(os.path.join(here,"res","patch")).replace("\\","/") -def after_install(options, home_dir): - home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) - base_dir = os.path.dirname(home_dir) - src_dir = join(home_dir, 'src') - tmp_dir = join(home_dir, 'tmp') - ensure_dir(src_dir) - ensure_dir(tmp_dir) - system_str = platform.system() - - res_source_key = options.type_install - - ignore_packages = [] - - if options.ignore_packages : - ignore_packages = options.ignore_packages.split(",") - - logger.indent += 2 - try: - NORMAL_INSTALL = [ #(key,method, option_str, extra_env) - ('DISTRIBUTE', 'pip', None, None), - ('MERCURIAL', 'pip', None, None), - ] - - - for key, method, option_str, extra_env in NORMAL_INSTALL: - if key not in ignore_packages: - normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir) - - logger.notify("Clear source dir") - shutil.rmtree(src_dir) - - finally: - logger.indent -= 2 - script_dir = join(base_dir, bin_dir) - logger.notify('Run "%s Package" to install new packages that provide builds' - % join(script_dir, 'easy_install')) - +EXTRA_TEXT = "import sys\n" +EXTRA_TEXT += "sys.path.append('%s')\n" % (lib_path) +EXTRA_TEXT += "sys.path.append('%s')\n" % (os.path.abspath(os.path.join(here,"res")).replace("\\","/")) +EXTRA_TEXT += "from res_create_env import generate_install_methods\n" +EXTRA_TEXT += "adjust_options, extend_parser, after_install = generate_install_methods(path_locations, '%s', Logger, call_subprocess)\n" % (src_base) -def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir): - logger.notify("Install %s from %s with %s" % (key,URLS[key][res_source_key],method)) - if method == 'pip': - if sys.platform == 'win32': - args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), URLS[key][res_source_key]] - else: - args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), URLS[key][res_source_key]] - if option_str : - args.insert(4,option_str) - call_subprocess(args, - cwd=os.path.abspath(tmp_dir), - filter_stdout=filter_python_develop, - show_stdout=True, - extra_env=extra_env) - else: - if sys.platform == 'win32': - args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), URLS[key][res_source_key]] - else: - args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), URLS[key][res_source_key]] - if option_str : - args.insert(1,option_str) - call_subprocess(args, - cwd=os.path.abspath(tmp_dir), - filter_stdout=filter_python_develop, - show_stdout=True, - extra_env=extra_env) - - -def ensure_dir(dir): - if not os.path.exists(dir): - logger.notify('Creating directory %s' % dir) - os.makedirs(dir) - -def filter_python_develop(line): - if not line.strip(): - return Logger.DEBUG - for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ', - 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ', - 'creating ', 'Copying ']: - if line.startswith(prefix): - return Logger.DEBUG - return Logger.NOTIFY -""" def main(): python_version = ".".join(map(str,sys.version_info[0:2])) diff -r 2e2989c3072c -r 125fc6df230d virtualenv/setup/res/res_create_env.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/virtualenv/setup/res/res_create_env.py Fri Apr 08 16:33:01 2011 +0200 @@ -0,0 +1,15 @@ +import platform + +from lib_create_env import lib_generate_install_methods, install_pylucene, install_psycopg2 + +system_str = platform.system() + + +INSTALLS = [#(key,method, option_str, dict_extra_env) + ('DISTRIBUTE', 'pip', None, None), + ('MERCURIAL', 'pip', None, None), + ('SETUPTOOLS-HG', 'pip', None, None), +] + +def generate_install_methods(path_locations, src_base, Logger, call_subprocess): + return lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, INSTALLS) diff -r 2e2989c3072c -r 125fc6df230d virtualenv/setup/res/src/distribute-0.6.14.tar.gz Binary file virtualenv/setup/res/src/distribute-0.6.14.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/setup/res/src/mercurial-1.7.5.tar.gz Binary file virtualenv/setup/res/src/mercurial-1.7.5.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/create_python_env.py --- a/virtualenv/web/create_python_env.py Wed Mar 23 17:34:36 2011 +0100 +++ b/virtualenv/web/create_python_env.py Fri Apr 08 16:33:01 2011 +0200 @@ -8,7 +8,8 @@ - distribute - psycopg2 requires the PostgreSQL libpq libraries and the pg_config utility -- python project-boot.py --distribute --no-site-packages --index-url=http://pypi.websushi.org/ --clear --type-install=local +- python project-boot.py --distribute --no-site-packages --index-url=http://pypi.websushi.org/ --clear --type-install=local --ignore-packages=MYSQL +- python project-boot.py --no-site-packages --clear --ignore-packages=MYSQL --type-install=local - For Linux : python project-boot.py --unzip-setuptools --no-site-packages --index-url=http://pypi.websushi.org/ --clear --type-install=local @@ -33,293 +34,23 @@ # - 4Suite-xml - easy_install ftp://ftp.4suite.org/pub/4Suite/4Suite-XML-1.0.2.tar.bz2 # - pylucene - script -src_base = os.path.join(here,"res","src").replace("\\","/") -lib_path = os.path.abspath(os.path.join(here,"res","lib")).replace("\\","/") +src_base = os.path.abspath(os.path.join(here,"..","res","src")).replace("\\","/") +lib_path = os.path.abspath(os.path.join(here,"..","res","lib")).replace("\\","/") patch_path = os.path.abspath(os.path.join(here,"res","patch")).replace("\\","/") -EXTRA_TEXT = "URLS = { \n" -EXTRA_TEXT += " 'DISTRIBUTE' : { 'setup': 'distribute', 'url': 'http://pypi.python.org/packages/source/d/distribute/distribute-0.6.14.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"distribute-0.6.14.tar.gz")).replace("\\","/")+"'},\n" -if sys.platform == 'win32': - EXTRA_TEXT += " 'PSYCOPG2' : { 'setup': 'psycopg2','url': 'D:/wakimd/dev/hg/platform/virtualenv/web/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip', 'local': '"+ os.path.abspath(os.path.join(src_base,"psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip")).replace("\\","/")+"'},\n" -else: - EXTRA_TEXT += " 'PSYCOPG2' : { 'setup': 'psycopg2','url': 'http://initd.org/psycopg/tarballs/PSYCOPG-2-3/psycopg2-2.3.2.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"psycopg2-2.3.2.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'MYSQL' : { 'setup': 'mysql-python', 'url': 'http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/MySQL-python-1.2.3.tar.gz/download', 'local' : '"+ os.path.abspath(os.path.join(src_base,"MySQL-python-1.2.3.tar.gz")).replace("\\","/")+"'},\n" -if sys.platform == 'win32': - EXTRA_TEXT += " 'PYLUCENE' : { 'setup': 'http://pylucene-win32-binary.googlecode.com/files/lucene-3.0.2-py2.6-win32.egg', 'local': '"+ os.path.abspath(os.path.join(src_base,"lucene-3.0.2-py2.6-win32.egg")).replace("\\","/")+"'},\n" - EXTRA_TEXT += " 'JCC' : { 'setup': 'http://pylucene-win32-binary.googlecode.com/files/JCC-2.6-py2.6-win32.egg', 'local': '"+ os.path.abspath(os.path.join(src_base,"JCC-2.6-py2.6-win32.egg")).replace("\\","/")+"'},\n" -else: - EXTRA_TEXT += " 'PYLUCENE' : { 'setup': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'url': 'http://apache.crihan.fr/dist/lucene/pylucene/pylucene-3.0.3-1-src.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"pylucene-3.0.3-1-src.tar.gz")).replace("\\","/")+"'},\n" -if sys.platform == 'win32': - EXTRA_TEXT += " 'PIL' : { 'setup': 'pil', 'url': 'http://effbot.org/media/downloads/PIL-1.1.7.win32-py2.6.exe', 'local': '"+ os.path.abspath(os.path.join(src_base,"PIL-1.1.7.win32-py2.6.exe")).replace("\\","/")+"'},\n" -else: - EXTRA_TEXT += " 'PIL' : { 'setup': 'pil', 'url': 'http://effbot.org/downloads/Imaging-1.1.7.tar.gz', 'local': '"+ os.path.abspath(os.path.join(src_base,"Imaging-1.1.7.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'DJANGO' : { 'setup': 'django', 'url': 'http://www.djangoproject.com/download/1.2.4/tarball/', 'local': '"+ os.path.abspath(os.path.join(src_base,"Django-1.2.4.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'JOGGING' : { 'setup': 'jogging', 'url': 'http://github.com/zain/jogging/tarball/v0.2.2', 'local': '"+ os.path.abspath(os.path.join(src_base,"jogging-0.2.2.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'DJANGO-EXTENSIONS' : { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/tarball/0.6', 'local':'"+ os.path.abspath(os.path.join(src_base,"django-extensions-0.6.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'DJANGO-REGISTRATION' : { 'setup': 'django-registration', 'url':'http://bitbucket.org/ubernostrum/django-registration/get/tip.tar.gz', 'local':'"+ os.path.abspath(os.path.join(src_base,"django-registration.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'DJANGO-TAGGING' : { 'setup': 'django-tagging', 'url':'http://django-tagging.googlecode.com/files/django-tagging-0.3.1.tar.gz', 'local':'"+ os.path.abspath(os.path.join(src_base,"django-tagging-0.3.1.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'DJANGO-PISTON' : { 'setup': 'django-piston', 'url':'"+ os.path.abspath(os.path.join(src_base,"django-piston-0.2.2-modified.tar.gz")).replace("\\","/")+"', 'local':'"+ os.path.abspath(os.path.join(src_base,"django-piston-0.2.2-modified.tar.gz")).replace("\\","/")+"' },\n" -if sys.platform == 'win32': - EXTRA_TEXT += " 'LXML' : { 'setup': 'lxml', 'url': 'http://pypi.python.org/packages/2.6/l/lxml/lxml-2.2.8-py2.6-win32.egg', 'local': '"+ os.path.abspath(os.path.join(src_base,"lxml-2.2.8-py2.6-win32.egg")).replace("\\","/")+"'},\n" -else: - EXTRA_TEXT += " 'LXML' : { 'setup': 'lxml', 'url': '"+ os.path.abspath(os.path.join(src_base,"lxml_2.2.8.tar.gz"))+"', 'local': '"+ os.path.abspath(os.path.join(src_base,"lxml-2.2.8.tar.gz")).replace("\\","/")+"'},\n" -EXTRA_TEXT += " 'SETUPTOOLS-HG' : { 'setup': 'setuptools-hg', 'url':'http://bitbucket.org/jezdez/setuptools_hg/downloads/setuptools_hg-0.2.tar.gz', 'local':'"+ os.path.abspath(os.path.join(src_base,"setuptools_hg-0.2.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'OAUTH2' : { 'setup': 'python-oauth2', 'url':'"+ os.path.abspath(os.path.join(src_base,"python-oauth2-1.2.1-modified.tar.gz")).replace("\\","/")+"', 'local':'"+ os.path.abspath(os.path.join(src_base,"python-oauth2-1.2.1-modified.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'HTTPLIB2' : { 'setup': 'python-oauth2', 'url':'http://httplib2.googlecode.com/files/httplib2-0.6.0.tar.gz', 'local':'"+ os.path.abspath(os.path.join(src_base,"httplib2-0.6.0.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += " 'DJANGO-OAUTH-PLUS' : { 'setup': 'django-oauth-plus', 'url':'http://bitbucket.org/david/django-oauth-plus/get/f314f018e473.gz', 'local':'"+ os.path.abspath(os.path.join(src_base,"django-oauth-plus.tar.gz")).replace("\\","/")+"' },\n" -EXTRA_TEXT += "}\n" - -EXTRA_TEXT += "import sys\n" -EXTRA_TEXT += "sys.path.append('"+lib_path+"')\n" - -EXTRA_TEXT += """ - -import shutil -import tarfile -import zipfile -import urllib -import platform -import patch - - -INDEX_URL = 'http://pypi.python.org/simple/' - - -def extend_parser(parser): - parser.add_option( - '--index-url', - metavar='INDEX_URL', - dest='index_url', - default='', - help='base URL of Python Package Index') - parser.add_option( - '--type-install', - metavar='type_install', - dest='type_install', - default='local', - help='type install : local, url, setup') - parser.add_option( - '--ignore-packages', - metavar='ignore_packages', - dest='ignore_packages', - default=None, - help='list of comma separated keys for package to ignore') +EXTRA_TEXT = "import sys\n" +EXTRA_TEXT += "sys.path.append('%s')\n" % (lib_path) +EXTRA_TEXT += "sys.path.append('%s')\n" % (os.path.abspath(os.path.join(here,"res")).replace("\\","/")) +EXTRA_TEXT += "from res_create_env import generate_install_methods\n" +EXTRA_TEXT += "adjust_options, extend_parser, after_install = generate_install_methods(path_locations, '%s', Logger, call_subprocess)\n" % (src_base) -def adjust_options(options, args): - pass - - -def after_install(options, home_dir): - home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) - base_dir = os.path.dirname(home_dir) - src_dir = join(home_dir, 'src') - tmp_dir = join(home_dir, 'tmp') - ensure_dir(src_dir) - ensure_dir(tmp_dir) - system_str = platform.system() - - res_source_key = options.type_install - - ignore_packages = [] - - if options.ignore_packages : - ignore_packages = options.ignore_packages.split(",") - - logger.indent += 2 - try: - - if 'PYLUCENE' not in ignore_packages and system_str != "Windows": - #get pylucene - logger.notify("Get Pylucene from %s " % URLS['PYLUCENE'][res_source_key]) - pylucene_src = os.path.join(src_dir,"pylucene.tar.gz") - if res_source_key == 'local': - shutil.copy(URLS['PYLUCENE'][res_source_key], pylucene_src) - else: - urllib.urlretrieve(URLS['PYLUCENE'][res_source_key], pylucene_src) - tf = tarfile.open(pylucene_src,'r:gz') - pylucene_base_path = os.path.join(src_dir,"pylucene") - logger.notify("Extract Pylucene to %s " % pylucene_base_path) - tf.extractall(pylucene_base_path) - tf.close() - - pylucene_src_path = os.path.join(pylucene_base_path, os.listdir(pylucene_base_path)[0]) - jcc_src_path = os.path.abspath(os.path.join(pylucene_src_path,"jcc")) - - #install jcc - - #patch for linux - if system_str == 'Linux' : - olddir = os.getcwd() - patch_dest_path = os.path.join(lib_dir,'site-packages','setuptools-0.6c11-py'+'%s.%s' % (sys.version_info[0], sys.version_info[1])+'.egg') - if os.path.isfile(patch_dest_path): - # must unzip egg - # rename file and etract all - shutil.move(patch_dest_path, patch_dest_path + ".zip") - zf = zipfile.ZipFile(patch_dest_path + ".zip",'r') - zf.extractall(patch_dest_path) - os.remove(patch_dest_path + ".zip") - logger.notify("Patch jcc : %s " % (patch_dest_path)) - os.chdir(patch_dest_path) - p = patch.fromfile(os.path.join(jcc_src_path,"jcc","patches","patch.43.0.6c11")) - p.apply() - os.chdir(olddir) - - logger.notify("Install jcc") - call_subprocess([os.path.abspath(os.path.join(home_dir, 'bin', 'python')), 'setup.py', 'install'], - cwd=jcc_src_path, - filter_stdout=filter_python_develop, - show_stdout=True) - #install pylucene - - logger.notify("Install pylucene") - #modify makefile - makefile_path = os.path.join(pylucene_src_path,"Makefile") - logger.notify("Modify makefile %s " % makefile_path) - shutil.move( makefile_path, makefile_path+"~" ) - - destination= open( makefile_path, "w" ) - source= open( makefile_path+"~", "r" ) - destination.write("PREFIX_PYTHON="+os.path.abspath(home_dir)+"\\n") - destination.write("ANT=ant\\n") - destination.write("PYTHON=$(PREFIX_PYTHON)/bin/python\\n") - - if system_str == "Darwin": - if sys.version_info >= (2,6): - destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\\n") - else: - destination.write("JCC=$(PYTHON) -m jcc --shared --arch x86_64 --arch i386\\n") - destination.write("NUM_FILES=2\\n") - elif system_str == "Windows": - destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared --arch x86_64 --arch i386\\n") - destination.write("NUM_FILES=2\\n") - else: - if sys.version_info >= (2,6) and sys.version_info < (2,7): - destination.write("JCC=$(PYTHON) -m jcc.__main__ --shared\\n") - else: - destination.write("JCC=$(PYTHON) -m jcc --shared\\n") - destination.write("NUM_FILES=2\\n") - for line in source: - destination.write( line ) - source.close() - destination.close() - os.remove(makefile_path+"~" ) - - logger.notify("pylucene make") - call_subprocess(['make'], - cwd=os.path.abspath(pylucene_src_path), - filter_stdout=filter_python_develop, - show_stdout=True) - - logger.notify("pylucene make install") - call_subprocess(['make', 'install'], - cwd=os.path.abspath(pylucene_src_path), - filter_stdout=filter_python_develop, - show_stdout=True) - - if system_str == 'Linux' and 'DISTRIBUTE' not in ignore_packages: - normal_install('DISTRIBUTE', 'pip', None, None, res_source_key, home_dir, tmp_dir) - - NORMAL_INSTALL = [ #(key,method, option_str, extra_env) - ('MYSQL', 'pip', None, None), - ('PIL', 'easy_install', None, None), - ('DJANGO','pip', None, None), - ('JOGGING','pip', None, None), - ('DJANGO-EXTENSIONS', 'pip', None, None), - ('DJANGO-REGISTRATION', 'easy_install', '-Z', None), - ('DJANGO-TAGGING', 'pip', None, None), - ('DJANGO-PISTON', 'pip', None, None), - ('SETUPTOOLS-HG', 'pip', None, None), - ('HTTPLIB2', 'pip', None, None), - ('OAUTH2', 'pip', None, None), - ('DJANGO-OAUTH-PLUS', 'pip', None, None), - ] - - if 'PYLUCENE' not in ignore_packages and system_str == "Windows": - NORMAL_INSTALL.append(('JCC','easy_install',None,None)) - NORMAL_INSTALL.append(('PYLUCENE','easy_install',None,None)) - - if system_str == "Darwin": - NORMAL_INSTALL.append(('LXML', 'easy_install', None, {'STATIC_DEPS': 'true'})) - else: - NORMAL_INSTALL.append(('LXML', 'easy_install', None, None)) - - if system_str == "Windows": - #get psycopg2 - psycopg2_src = os.path.join(src_dir,"psycopg2.zip") - shutil.copy(URLS['PSYCOPG2'][res_source_key], psycopg2_src) - #extract psycopg2 - zf = zipfile.ZipFile(psycopg2_src) - psycopg2_base_path = os.path.join(src_dir,"psycopg2") - zf.extractall(psycopg2_base_path) - zf.close() - - psycopg2_src_path = os.path.join(psycopg2_base_path, os.listdir(psycopg2_base_path)[0]) - shutil.copytree(os.path.join(psycopg2_src_path, 'psycopg2'), os.path.abspath(os.path.join(home_dir, 'Lib', 'psycopg2'))) - shutil.copy(os.path.join(psycopg2_src_path, 'psycopg2-2.0.10-py2.6.egg-info'), os.path.abspath(os.path.join(home_dir, 'Lib', 'site-packages'))) - else: - NORMAL_INSTALL.append(('PSYCOPG2', 'pip', None, None)) - - - for key, method, option_str, extra_env in NORMAL_INSTALL: - if key not in ignore_packages: - normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir) - - logger.notify("Clear source dir") - shutil.rmtree(src_dir) - - finally: - logger.indent -= 2 - script_dir = join(base_dir, bin_dir) - logger.notify('Run "%s Package" to install new packages that provide builds' - % join(script_dir, 'easy_install')) - - -def normal_install(key, method, option_str, extra_env, res_source_key, home_dir, tmp_dir): - logger.notify("Install %s from %s with %s" % (key,URLS[key][res_source_key],method)) - if method == 'pip': - if sys.platform == 'win32': - args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'pip')), 'install', '-E', os.path.abspath(home_dir), URLS[key][res_source_key]] - else: - args = [os.path.abspath(os.path.join(home_dir, 'bin', 'pip')), 'install', '-E', os.path.abspath(home_dir), URLS[key][res_source_key]] - if option_str : - args.insert(4,option_str) - call_subprocess(args, - cwd=os.path.abspath(tmp_dir), - filter_stdout=filter_python_develop, - show_stdout=True, - extra_env=extra_env) - else: - if sys.platform == 'win32': - args = [os.path.abspath(os.path.join(home_dir, 'Scripts', 'easy_install')), URLS[key][res_source_key]] - else: - args = [os.path.abspath(os.path.join(home_dir, 'bin', 'easy_install')), URLS[key][res_source_key]] - if option_str : - args.insert(1,option_str) - call_subprocess(args, - cwd=os.path.abspath(tmp_dir), - filter_stdout=filter_python_develop, - show_stdout=True, - extra_env=extra_env) - - -def ensure_dir(dir): - if not os.path.exists(dir): - logger.notify('Creating directory %s' % dir) - os.makedirs(dir) - -def filter_python_develop(line): - if not line.strip(): - return Logger.DEBUG - for prefix in ['Searching for', 'Reading ', 'Best match: ', 'Processing ', - 'Moving ', 'Adding ', 'running ', 'writing ', 'Creating ', - 'creating ', 'Copying ']: - if line.startswith(prefix): - return Logger.DEBUG - return Logger.NOTIFY -""" +#f = open(os.path.join(os.path. os.path.join(os.path.dirname(os.path.abspath(__file__)),"res"),'res_create_env.py'), 'r') +#EXTRA_TEXT += f.read() +#EXTRA_TEXT += "\n" +#EXTRA_TEXT += "RES_ENV = ResourcesEnv('%s')\n" % (src_base) def main(): python_version = ".".join(map(str,sys.version_info[0:2])) diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/lib/patch.py --- a/virtualenv/web/res/lib/patch.py Wed Mar 23 17:34:36 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,589 +0,0 @@ -""" Patch utility to apply unified diffs - - Brute-force line-by-line non-recursive parsing - - Copyright (c) 2008-2010 anatoly techtonik - Available under the terms of MIT license - - Project home: http://code.google.com/p/python-patch/ - - - $Id: patch.py 76 2010-04-08 19:10:21Z techtonik $ - $HeadURL: https://python-patch.googlecode.com/svn/trunk/patch.py $ -""" - -__author__ = "techtonik.rainforce.org" -__version__ = "10.04" - -import copy -import logging -import re -# cStringIO doesn't support unicode in 2.5 -from StringIO import StringIO -from logging import debug, info, warning - -from os.path import exists, isfile, abspath -from os import unlink - - -#------------------------------------------------ -# Logging is controlled by "python_patch" logger - -debugmode = False - -logger = logging.getLogger("python_patch") -loghandler = logging.StreamHandler() -logger.addHandler(loghandler) - -debug = logger.debug -info = logger.info -warning = logger.warning - -#: disable library logging by default -logger.setLevel(logging.CRITICAL) - -#------------------------------------------------ - - -def fromfile(filename): - """ Parse patch file and return Patch() object - """ - - info("reading patch from file %s" % filename) - fp = open(filename, "rb") - patch = Patch(fp) - fp.close() - return patch - - -def fromstring(s): - """ Parse text string and return Patch() object - """ - - return Patch( - StringIO.StringIO(s) - ) - - - -class HunkInfo(object): - """ Parsed hunk data container (hunk starts with @@ -R +R @@) """ - - def __init__(self): - self.startsrc=None #: line count starts with 1 - self.linessrc=None - self.starttgt=None - self.linestgt=None - self.invalid=False - self.text=[] - - def copy(self): - return copy.copy(self) - -# def apply(self, estream): -# """ write hunk data into enumerable stream -# return strings one by one until hunk is -# over -# -# enumerable stream are tuples (lineno, line) -# where lineno starts with 0 -# """ -# pass - - - -class Patch(object): - - def __init__(self, stream=None): - - # define Patch data members - # table with a row for every source file - - #: list of source filenames - self.source=None - self.target=None - #: list of lists of hunks - self.hunks=None - #: file endings statistics for every hunk - self.hunkends=None - - if stream: - self.parse(stream) - - def copy(self): - return copy.copy(self) - - def parse(self, stream): - """ parse unified diff """ - self.source = [] - self.target = [] - self.hunks = [] - self.hunkends = [] - - # define possible file regions that will direct the parser flow - header = False # comments before the patch body - filenames = False # lines starting with --- and +++ - - hunkhead = False # @@ -R +R @@ sequence - hunkbody = False # - hunkskip = False # skipping invalid hunk mode - - header = True - lineends = dict(lf=0, crlf=0, cr=0) - nextfileno = 0 - nexthunkno = 0 #: even if index starts with 0 user messages number hunks from 1 - - # hunkinfo holds parsed values, hunkactual - calculated - hunkinfo = HunkInfo() - hunkactual = dict(linessrc=None, linestgt=None) - - fe = enumerate(stream) - for lineno, line in fe: - - # analyze state - if header and line.startswith("--- "): - header = False - # switch to filenames state - filenames = True - #: skip hunkskip and hunkbody code until you read definition of hunkhead - if hunkbody: - # process line first - if re.match(r"^[- \+\\]", line): - # gather stats about line endings - if line.endswith("\r\n"): - self.hunkends[nextfileno-1]["crlf"] += 1 - elif line.endswith("\n"): - self.hunkends[nextfileno-1]["lf"] += 1 - elif line.endswith("\r"): - self.hunkends[nextfileno-1]["cr"] += 1 - - if line.startswith("-"): - hunkactual["linessrc"] += 1 - elif line.startswith("+"): - hunkactual["linestgt"] += 1 - elif not line.startswith("\\"): - hunkactual["linessrc"] += 1 - hunkactual["linestgt"] += 1 - hunkinfo.text.append(line) - # todo: handle \ No newline cases - else: - warning("invalid hunk no.%d at %d for target file %s" % (nexthunkno, lineno+1, self.target[nextfileno-1])) - # add hunk status node - self.hunks[nextfileno-1].append(hunkinfo.copy()) - self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True - # switch to hunkskip state - hunkbody = False - hunkskip = True - - # check exit conditions - if hunkactual["linessrc"] > hunkinfo.linessrc or hunkactual["linestgt"] > hunkinfo.linestgt: - warning("extra hunk no.%d lines at %d for target %s" % (nexthunkno, lineno+1, self.target[nextfileno-1])) - # add hunk status node - self.hunks[nextfileno-1].append(hunkinfo.copy()) - self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True - # switch to hunkskip state - hunkbody = False - hunkskip = True - elif hunkinfo.linessrc == hunkactual["linessrc"] and hunkinfo.linestgt == hunkactual["linestgt"]: - self.hunks[nextfileno-1].append(hunkinfo.copy()) - # switch to hunkskip state - hunkbody = False - hunkskip = True - - # detect mixed window/unix line ends - ends = self.hunkends[nextfileno-1] - if ((ends["cr"]!=0) + (ends["crlf"]!=0) + (ends["lf"]!=0)) > 1: - warning("inconsistent line ends in patch hunks for %s" % self.source[nextfileno-1]) - if debugmode: - debuglines = dict(ends) - debuglines.update(file=self.target[nextfileno-1], hunk=nexthunkno) - debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines) - - if hunkskip: - match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line) - if match: - # switch to hunkhead state - hunkskip = False - hunkhead = True - elif line.startswith("--- "): - # switch to filenames state - hunkskip = False - filenames = True - if debugmode and len(self.source) > 0: - debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1])) - - if filenames: - if line.startswith("--- "): - if nextfileno in self.source: - warning("skipping invalid patch for %s" % self.source[nextfileno]) - del self.source[nextfileno] - # double source filename line is encountered - # attempt to restart from this second line - re_filename = "^--- ([^\t]+)" - match = re.match(re_filename, line) - # todo: support spaces in filenames - if match: - self.source.append(match.group(1).strip()) - else: - warning("skipping invalid filename at line %d" % lineno) - # switch back to header state - filenames = False - header = True - elif not line.startswith("+++ "): - if nextfileno in self.source: - warning("skipping invalid patch with no target for %s" % self.source[nextfileno]) - del self.source[nextfileno] - else: - # this should be unreachable - warning("skipping invalid target patch") - filenames = False - header = True - else: - if nextfileno in self.target: - warning("skipping invalid patch - double target at line %d" % lineno) - del self.source[nextfileno] - del self.target[nextfileno] - nextfileno -= 1 - # double target filename line is encountered - # switch back to header state - filenames = False - header = True - else: - re_filename = "^\+\+\+ ([^\t]+)" - match = re.match(re_filename, line) - if not match: - warning("skipping invalid patch - no target filename at line %d" % lineno) - # switch back to header state - filenames = False - header = True - else: - self.target.append(match.group(1).strip()) - nextfileno += 1 - # switch to hunkhead state - filenames = False - hunkhead = True - nexthunkno = 0 - self.hunks.append([]) - self.hunkends.append(lineends.copy()) - continue - - if hunkhead: - match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line) - if not match: - if nextfileno-1 not in self.hunks: - warning("skipping invalid patch with no hunks for file %s" % self.target[nextfileno-1]) - # switch to header state - hunkhead = False - header = True - continue - else: - # switch to header state - hunkhead = False - header = True - else: - hunkinfo.startsrc = int(match.group(1)) - hunkinfo.linessrc = 1 - if match.group(3): hunkinfo.linessrc = int(match.group(3)) - hunkinfo.starttgt = int(match.group(4)) - hunkinfo.linestgt = 1 - if match.group(6): hunkinfo.linestgt = int(match.group(6)) - hunkinfo.invalid = False - hunkinfo.text = [] - - hunkactual["linessrc"] = hunkactual["linestgt"] = 0 - - # switch to hunkbody state - hunkhead = False - hunkbody = True - nexthunkno += 1 - continue - else: - if not hunkskip: - warning("patch file incomplete - %s" % filename) - # sys.exit(?) - else: - # duplicated message when an eof is reached - if debugmode and len(self.source) > 0: - debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1])) - - info("total files: %d total hunks: %d" % (len(self.source), sum(len(hset) for hset in self.hunks))) - - - def apply(self): - """ apply parsed patch """ - - total = len(self.source) - for fileno, filename in enumerate(self.source): - - f2patch = filename - if not exists(f2patch): - f2patch = self.target[fileno] - if not exists(f2patch): - warning("source/target file does not exist\n--- %s\n+++ %s" % (filename, f2patch)) - continue - if not isfile(f2patch): - warning("not a file - %s" % f2patch) - continue - filename = f2patch - - info("processing %d/%d:\t %s" % (fileno+1, total, filename)) - - # validate before patching - f2fp = open(filename) - hunkno = 0 - hunk = self.hunks[fileno][hunkno] - hunkfind = [] - hunkreplace = [] - validhunks = 0 - canpatch = False - for lineno, line in enumerate(f2fp): - if lineno+1 < hunk.startsrc: - continue - elif lineno+1 == hunk.startsrc: - hunkfind = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " -"] - hunkreplace = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " +"] - #pprint(hunkreplace) - hunklineno = 0 - - # todo \ No newline at end of file - - # check hunks in source file - if lineno+1 < hunk.startsrc+len(hunkfind)-1: - if line.rstrip("\r\n") == hunkfind[hunklineno]: - hunklineno+=1 - else: - debug("hunk no.%d doesn't match source file %s" % (hunkno+1, filename)) - # file may be already patched, but we will check other hunks anyway - hunkno += 1 - if hunkno < len(self.hunks[fileno]): - hunk = self.hunks[fileno][hunkno] - continue - else: - break - - # check if processed line is the last line - if lineno+1 == hunk.startsrc+len(hunkfind)-1: - debug("file %s hunk no.%d -- is ready to be patched" % (filename, hunkno+1)) - hunkno+=1 - validhunks+=1 - if hunkno < len(self.hunks[fileno]): - hunk = self.hunks[fileno][hunkno] - else: - if validhunks == len(self.hunks[fileno]): - # patch file - canpatch = True - break - else: - if hunkno < len(self.hunks[fileno]): - warning("premature end of source file %s at hunk %d" % (filename, hunkno+1)) - - f2fp.close() - - if validhunks < len(self.hunks[fileno]): - if self._match_file_hunks(filename, self.hunks[fileno]): - warning("already patched %s" % filename) - else: - warning("source file is different - %s" % filename) - if canpatch: - backupname = filename+".orig" - if exists(backupname): - warning("can't backup original file to %s - aborting" % backupname) - else: - import shutil - shutil.move(filename, backupname) - if self.write_hunks(backupname, filename, self.hunks[fileno]): - warning("successfully patched %s" % filename) - unlink(backupname) - else: - warning("error patching file %s" % filename) - shutil.copy(filename, filename+".invalid") - warning("invalid version is saved to %s" % filename+".invalid") - # todo: proper rejects - shutil.move(backupname, filename) - - # todo: check for premature eof - - - def can_patch(self, filename): - """ Check if specified filename can be patched. Returns None if file can - not be found among source filenames. False if patch can not be applied - clearly. True otherwise. - - :returns: True, False or None - """ - idx = self._get_file_idx(filename, source=True) - if idx == None: - return None - return self._match_file_hunks(filename, self.hunks[idx]) - - - def _match_file_hunks(self, filepath, hunks): - matched = True - fp = open(abspath(filepath)) - - class NoMatch(Exception): - pass - - lineno = 1 - line = fp.readline() - hno = None - try: - for hno, h in enumerate(hunks): - # skip to first line of the hunk - while lineno < h.starttgt: - if not len(line): # eof - debug("check failed - premature eof before hunk: %d" % (hno+1)) - raise NoMatch - line = fp.readline() - lineno += 1 - for hline in h.text: - if hline.startswith("-"): - continue - if not len(line): - debug("check failed - premature eof on hunk: %d" % (hno+1)) - # todo: \ No newline at the end of file - raise NoMatch - if line.rstrip("\r\n") != hline[1:].rstrip("\r\n"): - debug("file is not patched - failed hunk: %d" % (hno+1)) - raise NoMatch - line = fp.readline() - lineno += 1 - - except NoMatch: - matched = False - # todo: display failed hunk, i.e. expected/found - - fp.close() - return matched - - - def patch_stream(self, instream, hunks): - """ Generator that yields stream patched with hunks iterable - - Converts lineends in hunk lines to the best suitable format - autodetected from input - """ - - # todo: At the moment substituted lineends may not be the same - # at the start and at the end of patching. Also issue a - # warning/throw about mixed lineends (is it really needed?) - - hunks = iter(hunks) - - srclineno = 1 - - lineends = {'\n':0, '\r\n':0, '\r':0} - def get_line(): - """ - local utility function - return line from source stream - collecting line end statistics on the way - """ - line = instream.readline() - # 'U' mode works only with text files - if line.endswith("\r\n"): - lineends["\r\n"] += 1 - elif line.endswith("\n"): - lineends["\n"] += 1 - elif line.endswith("\r"): - lineends["\r"] += 1 - return line - - for hno, h in enumerate(hunks): - debug("hunk %d" % (hno+1)) - # skip to line just before hunk starts - while srclineno < h.startsrc: - yield get_line() - srclineno += 1 - - for hline in h.text: - # todo: check \ No newline at the end of file - if hline.startswith("-") or hline.startswith("\\"): - get_line() - srclineno += 1 - continue - else: - if not hline.startswith("+"): - get_line() - srclineno += 1 - line2write = hline[1:] - # detect if line ends are consistent in source file - if sum([bool(lineends[x]) for x in lineends]) == 1: - newline = [x for x in lineends if lineends[x] != 0][0] - yield line2write.rstrip("\r\n")+newline - else: # newlines are mixed - yield line2write - - for line in instream: - yield line - - - def write_hunks(self, srcname, tgtname, hunks): - src = open(srcname, "rb") - tgt = open(tgtname, "wb") - - debug("processing target file %s" % tgtname) - - tgt.writelines(self.patch_stream(src, hunks)) - - tgt.close() - src.close() - return True - - - def _get_file_idx(self, filename, source=None): - """ Detect index of given filename within patch. - - :param filename: - :param source: search filename among sources (True), - targets (False), or both (None) - :returns: int or None - """ - filename = abspath(filename) - if source == True or source == None: - for i,fnm in enumerate(self.source): - if filename == abspath(fnm): - return i - if source == False or source == None: - for i,fnm in enumerate(self.target): - if filename == abspath(fnm): - return i - - - - -from optparse import OptionParser -from os.path import exists -import sys - -if __name__ == "__main__": - opt = OptionParser(usage="%prog [options] unipatch-file", version="python-patch %s" % __version__) - opt.add_option("--debug", action="store_true", dest="debugmode", help="debug mode") - (options, args) = opt.parse_args() - - if not args: - opt.print_version() - opt.print_help() - sys.exit() - debugmode = options.debugmode - patchfile = args[0] - if not exists(patchfile) or not isfile(patchfile): - sys.exit("patch file does not exist - %s" % patchfile) - - - if debugmode: - loglevel = logging.DEBUG - logformat = "%(levelname)8s %(message)s" - else: - loglevel = logging.INFO - logformat = "%(message)s" - logger.setLevel(loglevel) - loghandler.setFormatter(logging.Formatter(logformat)) - - - - patch = fromfile(patchfile) - #pprint(patch) - patch.apply() - - # todo: document and test line ends handling logic - patch.py detects proper line-endings - # for inserted hunks and issues a warning if patched file has incosistent line ends diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/patch/piston.diff --- a/virtualenv/web/res/patch/piston.diff Wed Mar 23 17:34:36 2011 +0100 +++ b/virtualenv/web/res/patch/piston.diff Fri Apr 08 16:33:01 2011 +0200 @@ -3,6 +3,6 @@ timestamp = models.IntegerField() is_approved = models.BooleanField(default=False) -- user = models.ForeignKey(User, null=True, blank=True, related_name='piston_tokens') +- user = models.ForeignKey(User, null=True, blank=True, related_name='tokens') + user = models.ForeignKey(User, null=True, blank=True, related_name='piston_tokens') consumer = models.ForeignKey(Consumer) diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/res_create_env.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/virtualenv/web/res/res_create_env.py Fri Apr 08 16:33:01 2011 +0200 @@ -0,0 +1,54 @@ +import platform + +from lib_create_env import lib_generate_install_methods, install_pylucene, install_psycopg2 + +system_str = platform.system() + + +if system_str == 'Linux': + INSTALLS = [ + ('DISTRIBUTE', 'pip', None, None), + ] +else: + INSTALLS = [] + + +INSTALLS.extend([ #(key,method, option_str, dict_extra_env) + ('SETUPTOOLS-HG', 'pip', None, None), + ('MYSQL', 'pip', None, None), + ('PIL', 'easy_install', None, None), + ('DJANGO','pip', None, None), + ('JOGGING','pip', None, None), + ('DJANGO-EXTENSIONS', 'pip', None, None), + ('DJANGO-REGISTRATION', 'easy_install', '-Z', None), + ('DJANGO-TAGGING', 'pip', None, None), + ('DJANGO-PISTON', 'pip', None, None), + ('HTTPLIB2', 'pip', None, None), + ('OAUTH2', 'easy_install', None, None), + ('DJANGO-OAUTH-PLUS', 'pip', None, None), +]) + +if system_str == 'Windows': + INSTALLS.extend([ + ('JCC','easy_install',None,None), + ('PYLUCENE','easy_install',None,None), + ('PSYCOPG2',install_psycopg2,None,None), + ]) +else: + INSTALLS.extend([ + ('PYLUCENE',install_pylucene,None,None), + ('PSYCOPG2', 'pip', None, None), + ]) + +if system_str == "Darwin": + INSTALLS.extend([ + ('LXML', 'pip', None, {'STATIC_DEPS': 'true', 'LIBXML2_VERSION': '2.7.8', 'LIBXSLT_VERSION': '1.1.26'}), + ]) +else: + INSTALLS.extend([ + ('LXML', 'pip', None, None), + ]) + + +def generate_install_methods(path_locations, src_base, Logger, call_subprocess): + return lib_generate_install_methods(path_locations, src_base, Logger, call_subprocess, INSTALLS) diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/Django-1.2.4.tar.gz Binary file virtualenv/web/res/src/Django-1.2.4.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/Imaging-1.1.7.tar.gz Binary file virtualenv/web/res/src/Imaging-1.1.7.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/JCC-2.6-py2.6-win32.egg Binary file virtualenv/web/res/src/JCC-2.6-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/MySQL-python-1.2.3.tar.gz Binary file virtualenv/web/res/src/MySQL-python-1.2.3.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/PIL-1.1.7.win32-py2.6.exe Binary file virtualenv/web/res/src/PIL-1.1.7.win32-py2.6.exe has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/distribute-0.6.14.tar.gz Binary file virtualenv/web/res/src/distribute-0.6.14.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/django-extensions-0.6.tar.gz Binary file virtualenv/web/res/src/django-extensions-0.6.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/django-oauth-plus.tar.gz Binary file virtualenv/web/res/src/django-oauth-plus.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/django-piston-0.2.2-modified.tar.gz Binary file virtualenv/web/res/src/django-piston-0.2.2-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/django-registration.tar.gz Binary file virtualenv/web/res/src/django-registration.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/django-tagging-0.3.1.tar.gz Binary file virtualenv/web/res/src/django-tagging-0.3.1.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/facebook-python-sdk-322930c.tar.gz Binary file virtualenv/web/res/src/facebook-python-sdk-322930c.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/httplib2-0.6.0.tar.gz Binary file virtualenv/web/res/src/httplib2-0.6.0.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/jogging-0.2.2.tar.gz Binary file virtualenv/web/res/src/jogging-0.2.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/lucene-3.0.2-py2.6-win32.egg Binary file virtualenv/web/res/src/lucene-3.0.2-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/lxml-2.2.8-py2.6-win32.egg Binary file virtualenv/web/res/src/lxml-2.2.8-py2.6-win32.egg has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/lxml-2.2.8.tar.gz Binary file virtualenv/web/res/src/lxml-2.2.8.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/oauth-1.0.1.tar.gz Binary file virtualenv/web/res/src/oauth-1.0.1.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip Binary file virtualenv/web/res/src/psycopg2-2.0.10.win32-py2.6-pg8.3.7-release.zip has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/psycopg2-2.3.2.tar.gz Binary file virtualenv/web/res/src/psycopg2-2.3.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/pylinkedin-0.3.tar.bz2 Binary file virtualenv/web/res/src/pylinkedin-0.3.tar.bz2 has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/pylucene-3.0.3-1-src.tar.gz Binary file virtualenv/web/res/src/pylucene-3.0.3-1-src.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/python-oauth2-1.2.1-modified.tar.gz Binary file virtualenv/web/res/src/python-oauth2-1.2.1-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/python-openid-2.2.5.tar.gz Binary file virtualenv/web/res/src/python-openid-2.2.5.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/setuptools_hg-0.2.tar.gz Binary file virtualenv/web/res/src/setuptools_hg-0.2.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d virtualenv/web/res/src/uswaretech-Django-Socialauth-1e22872-modified.tar.gz Binary file virtualenv/web/res/src/uswaretech-Django-Socialauth-1e22872-modified.tar.gz has changed diff -r 2e2989c3072c -r 125fc6df230d web/ldtplatform/settings.py --- a/web/ldtplatform/settings.py Wed Mar 23 17:34:36 2011 +0100 +++ b/web/ldtplatform/settings.py Fri Apr 08 16:33:01 2011 +0200 @@ -1,5 +1,6 @@ #@PydevCodeAnalysisIgnore import os.path +from social_auth_settings import * # Django settings for project. DEBUG = True @@ -89,13 +90,15 @@ "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", - "ldt.utils.context_processors.ldt", - "ldt.utils.context_processors.base", - "ldt.utils.context_processors.web", - "ldtplatform.utils.context_processors.version", +# "ldt.utils.context_processors.ldt", +# "ldt.utils.context_processors.base", +# "ldt.utils.context_processors.web", + #"ldtplatform.utils.context_processors.version", + "ldt.utils.context_processors.ldtcontext", ) + ROOT_URLCONF = 'ldtplatform.urls' TEMPLATE_DIRS = ( @@ -130,7 +133,8 @@ 'oauth_provider', 'openid_consumer', 'piston', - 'socialauth', + #'socialauth', + 'social_auth', ) DECOUPAGE_BLACKLIST = ( @@ -141,6 +145,23 @@ "__MACOSX", ) +AUTHENTICATION_BACKENDS = ( + 'social_auth.backends.twitter.TwitterBackend', + 'social_auth.backends.facebook.FacebookBackend', +# 'social_auth.backends.google.GoogleOAuthBackend', +# 'social_auth.backends.google.GoogleOAuth2Backend', + 'social_auth.backends.google.GoogleBackend', + 'social_auth.backends.yahoo.YahooBackend', +# 'social_auth.backends.contrib.linkedin.LinkedinBackend', +# 'social_auth.backends.contrib.LiveJournalBackend', +# 'social_auth.backends.contrib.orkut.OrkutBackend', + 'social_auth.backends.OpenIDBackend', + 'django.contrib.auth.backends.ModelBackend', +) +SOCIAL_AUTH_IMPORT_BACKENDS = ( + 'myproy.social_auth_extra_services', +) + ACCOUNT_ACTIVATION_DAYS = 7 LDT_MAX_SEARCH_NUMBER = 50 @@ -152,17 +173,25 @@ OAUTH_PROVIDER_CONSUMER_KEY_SIZE = 256 OAUTH_AUTHORIZE_VIEW = 'oauth_provider.views.fake_authorize_view' OAUTH_CALLBACK_VIEW = 'oauth_provider.views.fake_callback_view' -TEST_WEBSERVER_ADDRPORT = "127.0.0.1:8000" +TEST_WEBSERVER_ADDRPORT = "127.0.0.1:8888" from config import * -from socialauthsettings import * +#from socialauthsettings import * LOGIN_URL = BASE_URL + 'accounts/login/' -LOGOUT_URL = BASE_URL + 'accounts/logout/' +LOGOUT_URL = BASE_URL + 'accounts/disconnect/' #LOGIN_REDIRECT_URL = BASE_URL + 'ldtplatform' LOGIN_REDIRECT_URL = BASE_URL + 'ldt/' LOGOUT_REDIRECT_URL = BASE_URL + 'accounts/login' -PROFILE_REDIRECT_URL = BASE_URL + 'accounts/create/profile' +PROFILE_REDIRECT_URL = BASE_URL + 'auth_accounts/create/profile' + +LOGIN_ERROR_URL = BASE_URL + 'accounts/login' + +FACEBOOK_APP_ID = '163134140411313' +FACEBOOK_API_SECRET = 'f25e0754a44f0d90d3f4d9ea961ff012' + +SOCIAL_AUTH_COMPLETE_URL_NAME = 'complete' +SOCIAL_AUTH_ASSOCIATE_URL_NAME = 'associate_complete' GLOBAL_LOG_LEVEL = LOG_LEVEL GLOBAL_LOG_HANDLERS = [{'handler':logging.FileHandler(LOG_FILE), 'format':"%(asctime)s - %(levelname)s : %(message)s"}] diff -r 2e2989c3072c -r 125fc6df230d web/ldtplatform/socialauthsettings.py --- a/web/ldtplatform/socialauthsettings.py Wed Mar 23 17:34:36 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -OPENID_REDIRECT_NEXT = '/accounts/openid/done/' - -OPENID_SREG = {"required": "nickname, email, fullname", - "optional":"postcode, country", - "policy_url": ""} - -#example should be something more like the real thing, i think -OPENID_AX = [{"type_uri": "http://axschema.org/contact/email", - "count": 1, - "required": True, - "alias": "email"}, - {"type_uri": "http://axschema.org/schema/fullname", - "count":1 , - "required": False, - "alias": "fname"}] - -OPENID_AX_PROVIDER_MAP = {'Google': {'email': 'http://axschema.org/contact/email', - 'firstname': 'http://axschema.org/namePerson/first', - 'lastname': 'http://axschema.org/namePerson/last'}, - 'Default': {'email': 'http://axschema.org/contact/email', - 'fullname': 'http://axschema.org/namePerson', - 'nickname': 'http://axschema.org/namePerson/friendly'} - } - -TWITTER_CONSUMER_KEY = 'AeTl6TefgICQCXwDf4gOA' -TWITTER_CONSUMER_SECRET = 'v7XqozHzQuzjyU9RkpJXrXZdTYpCMCpzZCjli62dOA' - -FACEBOOK_APP_ID = '168524599848954' -FACEBOOK_API_KEY = '5fbfc9bc5171449685e54a6fd33038a4' -FACEBOOK_SECRET_KEY = 'ffd9012b6d974180f2578c09bcb38d9f' - -LINKEDIN_CONSUMER_KEY = '' -LINKEDIN_CONSUMER_SECRET = '' - -## if any of this information is desired for your app -FACEBOOK_EXTENDED_PERMISSIONS = ( - #'publish_stream', - #'create_event', - #'rsvp_event', - #'sms', - #'offline_access', - #'email', - #'read_stream', - #'user_about_me', - #'user_activites', - #'user_birthday', - #'user_education_history', - #'user_events', - #'user_groups', - #'user_hometown', - #'user_interests', - #'user_likes', - #'user_location', - #'user_notes', - #'user_online_presence', - #'user_photo_video_tags', - #'user_photos', - #'user_relationships', - #'user_religion_politics', - #'user_status', - #'user_videos', - #'user_website', - #'user_work_history', - #'read_friendlists', - #'read_requests', - #'friend_about_me', - #'friend_activites', - #'friend_birthday', - #'friend_education_history', - #'friend_events', - #'friend_groups', - #'friend_hometown', - #'friend_interests', - #'friend_likes', - #'friend_location', - #'friend_notes', - #'friend_online_presence', - #'friend_photo_video_tags', - #'friend_photos', - #'friend_relationships', - #'friend_religion_politics', - #'friend_status', - #'friend_videos', - #'friend_website', - #'friend_work_history', -) - - -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'socialauth.auth_backends.OpenIdBackend', - 'socialauth.auth_backends.TwitterBackend', - 'socialauth.auth_backends.FacebookBackend', - 'socialauth.auth_backends.LinkedInBackend', -) - -TEMPLATE_CONTEXT_PROCESSORS = ( - "socialauth.context_processors.facebook_api_key", - 'django.core.context_processors.media', - "django.contrib.auth.context_processors.auth", - "django.core.context_processors.request", -) diff -r 2e2989c3072c -r 125fc6df230d web/ldtplatform/templates/registration/login.html --- a/web/ldtplatform/templates/registration/login.html Wed Mar 23 17:34:36 2011 +0100 +++ b/web/ldtplatform/templates/registration/login.html Fri Apr 08 16:33:01 2011 +0200 @@ -32,6 +32,8 @@
    {{form.as_ul}}
+

{% trans "Or login with your external account" %}

+

{{social_list|safe}}