eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py
changeset 69 c6bca38c1cbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py	Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,466 @@
+from random import choice
+import os
+import subprocess
+import urllib2
+import shutil
+import logging
+import re
+
+from zc.buildout import UserError
+import zc.recipe.egg
+import setuptools
+
+script_template = {
+    'wsgi': '''
+
+%(relative_paths_setup)s
+import sys
+sys.path[0:0] = [
+  %(path)s,
+  ]
+%(initialization)s
+import %(module_name)s
+
+application = %(module_name)s.%(attrs)s(%(arguments)s)
+''',
+    'fcgi': '''
+
+%(relative_paths_setup)s
+import sys
+sys.path[0:0] = [
+  %(path)s,
+  ]
+%(initialization)s
+import %(module_name)s
+
+%(module_name)s.%(attrs)s(%(arguments)s)
+'''
+}
+
+
+settings_template = '''
+import os
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3'    # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = '%(project)s.db'
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_PASSWORD = ''         # Not used with sqlite3.
+DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
+DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
+
+TIME_ZONE = 'America/Chicago'
+
+LANGUAGE_CODE = 'en-us'
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = %(media_root)s
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = '/media/'
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/admin_media/'
+
+# Don't share this with anybody.
+SECRET_KEY = '%(secret)s'
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+)
+
+ROOT_URLCONF = '%(urlconf)s'
+
+
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.admin',
+)
+
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.load_template_source',
+    'django.template.loaders.app_directories.load_template_source',
+)
+
+TEMPLATE_DIRS = (
+    os.path.join(os.path.dirname(__file__), "templates"),
+)
+
+
+'''
+
+production_settings = '''
+from %(project)s.settings import *
+'''
+
+development_settings = '''
+from %(project)s.settings import *
+DEBUG=True
+TEMPLATE_DEBUG=DEBUG
+'''
+
+urls_template = '''
+from django.conf.urls.defaults import patterns, include, handler500
+from django.conf import settings
+from django.contrib import admin
+admin.autodiscover()
+
+handler500 # Pyflakes
+
+urlpatterns = patterns(
+    '',
+    (r'^admin/(.*)', admin.site.root),
+    (r'^accounts/login/$', 'django.contrib.auth.views.login'),
+)
+
+if settings.DEBUG:
+    urlpatterns += patterns('',
+        (r'^media/(?P<path>.*)$', 'django.views.static.serve',
+         {'document_root': settings.MEDIA_ROOT}),
+    )
+'''
+
+class Recipe(object):
+    def __init__(self, buildout, name, options):
+        self.log = logging.getLogger(name)
+        self.egg = zc.recipe.egg.Egg(buildout, options['recipe'], options)
+
+        self.buildout, self.name, self.options = buildout, name, options
+        options['location'] = os.path.join(
+            buildout['buildout']['parts-directory'], name)
+        options['bin-directory'] = buildout['buildout']['bin-directory']
+
+        options.setdefault('project', 'project')
+        options.setdefault('settings', 'development')
+
+        options.setdefault('urlconf', options['project'] + '.urls')
+        options.setdefault(
+            'media_root',
+            "os.path.join(os.path.dirname(__file__), 'media')")
+        # Set this so the rest of the recipe can expect the values to be
+        # there. We need to make sure that both pythonpath and extra-paths are
+        # set for BBB.
+        if 'extra-paths' in options:
+            options['pythonpath'] = options['extra-paths']
+        else:
+            options.setdefault('extra-paths', options.get('pythonpath', ''))
+
+        # Usefull when using archived versions
+        buildout['buildout'].setdefault(
+            'download-cache',
+            os.path.join(buildout['buildout']['directory'],
+                         'downloads'))
+
+        # mod_wsgi support script
+        options.setdefault('wsgi', 'false')
+        options.setdefault('fcgi', 'false')
+        options.setdefault('wsgilog', '')
+        options.setdefault('logfile', '')
+
+        # only try to download stuff if we aren't asked to install from cache
+        self.install_from_cache = self.buildout['buildout'].get(
+            'install-from-cache', '').strip() == 'true'
+
+
+    def install(self):
+        location = self.options['location']
+        base_dir = self.buildout['buildout']['directory']
+
+        project_dir = os.path.join(base_dir, self.options['project'])
+
+        download_dir = self.buildout['buildout']['download-cache']
+        if not os.path.exists(download_dir):
+            os.mkdir(download_dir)
+
+        version = self.options['version']
+        # Remove a pre-existing installation if it is there
+        if os.path.exists(location):
+            shutil.rmtree(location)
+
+        if self.is_svn_url(version):
+            self.install_svn_version(version, download_dir, location,
+                                     self.install_from_cache)
+        else:
+            tarball = self.get_release(version, download_dir)
+            # Extract and put the dir in its proper place
+            self.install_release(version, download_dir, tarball, location)
+
+        self.options['setup'] = location
+        development = zc.recipe.egg.Develop(self.buildout,
+                                            self.options['recipe'],
+                                            self.options)
+        development.install()
+        del self.options['setup']
+
+        extra_paths = self.get_extra_paths()
+        requirements, ws = self.egg.working_set(['djangorecipe'])
+
+        script_paths = []
+
+        # Create the Django management script
+        script_paths.extend(self.create_manage_script(extra_paths, ws))
+
+        # Create the test runner
+        script_paths.extend(self.create_test_runner(extra_paths, ws))
+
+        # Make the wsgi and fastcgi scripts if enabled
+        script_paths.extend(self.make_scripts(extra_paths, ws))
+
+        # Create default settings if we haven't got a project
+        # egg specified, and if it doesn't already exist
+        if not self.options.get('projectegg'):
+            if not os.path.exists(project_dir):
+                self.create_project(project_dir)
+            else:
+                self.log.info(
+                    'Skipping creating of project: %(project)s since '
+                    'it exists' % self.options)
+
+        return script_paths + [location]
+
+    def install_svn_version(self, version, download_dir, location,
+                            install_from_cache):
+        svn_url = self.version_to_svn(version)
+        download_location = os.path.join(
+            download_dir, 'django-' +
+            self.version_to_download_suffix(version))
+        if not install_from_cache:
+            if os.path.exists(download_location):
+                if self.svn_update(download_location, version):
+                    raise UserError(
+                        "Failed to update Django; %s. "
+                        "Please check your internet connection." % (
+                            download_location))
+            else:
+                self.log.info("Checking out Django from svn: %s" % svn_url)
+                cmd = 'svn co %s %s' % (svn_url, download_location)
+                if not self.buildout['buildout'].get('verbosity'):
+                    cmd += ' -q'
+                if self.command(cmd):
+                    raise UserError("Failed to checkout Django. "
+                                    "Please check your internet connection.")
+        else:
+            self.log.info("Installing Django from cache: " + download_location)
+
+        shutil.copytree(download_location, location)
+
+
+    def install_release(self, version, download_dir, tarball, destination):
+        extraction_dir = os.path.join(download_dir, 'django-archive')
+        setuptools.archive_util.unpack_archive(tarball, extraction_dir)
+        # Lookup the resulting extraction dir instead of guessing it
+        # (Django releases have a tendency not to be consistend here)
+        untarred_dir = os.path.join(extraction_dir,
+                                    os.listdir(extraction_dir)[0])
+        shutil.move(untarred_dir, destination)
+        shutil.rmtree(extraction_dir)
+
+    def get_release(self, version, download_dir):
+        tarball = os.path.join(download_dir, 'django-%s.tar.gz' % version)
+
+        # Only download when we don't yet have an archive
+        if not os.path.exists(tarball):
+            download_url = 'http://www.djangoproject.com/download/%s/tarball/'
+            self.log.info("Downloading Django from: %s" % (
+                    download_url % version))
+
+            tarball_f = open(tarball, 'wb')
+            f = urllib2.urlopen(download_url % version)
+            tarball_f.write(f.read())
+            tarball_f.close()
+            f.close()
+        return tarball
+
+    def create_manage_script(self, extra_paths, ws):
+        project = self.options.get('projectegg', self.options['project'])
+        return zc.buildout.easy_install.scripts(
+            [(self.options.get('control-script', self.name),
+              'djangorecipe.manage', 'main')],
+            ws, self.options['executable'], self.options['bin-directory'],
+            extra_paths = extra_paths,
+            arguments= "'%s.%s'" % (project,
+                                    self.options['settings']))
+
+
+
+    def create_test_runner(self, extra_paths, working_set):
+        apps = self.options.get('test', '').split()
+        # Only create the testrunner if the user requests it
+        if apps:
+            return zc.buildout.easy_install.scripts(
+                [(self.options.get('testrunner', 'test'),
+                  'djangorecipe.test', 'main')],
+                working_set, self.options['executable'],
+                self.options['bin-directory'],
+                extra_paths = extra_paths,
+                arguments= "'%s.%s', %s" % (
+                    self.options['project'],
+                    self.options['settings'],
+                    ', '.join(["'%s'" % app for app in apps])))
+        else:
+            return []
+
+
+    def create_project(self, project_dir):
+        os.makedirs(project_dir)
+
+        template_vars = {'secret': self.generate_secret()}
+        template_vars.update(self.options)
+
+        self.create_file(
+            os.path.join(project_dir, 'development.py'),
+            development_settings, template_vars)
+
+        self.create_file(
+            os.path.join(project_dir, 'production.py'),
+            production_settings, template_vars)
+
+        self.create_file(
+            os.path.join(project_dir, 'urls.py'),
+            urls_template, template_vars)
+
+        self.create_file(
+            os.path.join(project_dir, 'settings.py'),
+            settings_template, template_vars)
+
+        # Create the media and templates directories for our
+        # project
+        os.mkdir(os.path.join(project_dir, 'media'))
+        os.mkdir(os.path.join(project_dir, 'templates'))
+
+        # Make the settings dir a Python package so that Django
+        # can load the settings from it. It will act like the
+        # project dir.
+        open(os.path.join(project_dir, '__init__.py'), 'w').close()
+
+    def make_scripts(self, extra_paths, ws):
+        scripts = []
+        _script_template = zc.buildout.easy_install.script_template
+        for protocol in ('wsgi', 'fcgi'):
+            zc.buildout.easy_install.script_template = \
+                zc.buildout.easy_install.script_header + \
+                    script_template[protocol]
+            if self.options.get(protocol, '').lower() == 'true':
+                project = self.options.get('projectegg',
+                                           self.options['project'])
+                scripts.extend(
+                    zc.buildout.easy_install.scripts(
+                        [('%s.%s' % (self.options.get('control-script',
+                                                      self.name),
+                                     protocol),
+                          'djangorecipe.%s' % protocol, 'main')],
+                        ws,
+                        self.options['executable'],
+                        self.options['bin-directory'],
+                        extra_paths=extra_paths,
+                        arguments= "'%s.%s', logfile='%s'" % (
+                            project, self.options['settings'],
+                            self.options.get('logfile'))))
+        zc.buildout.easy_install.script_template = _script_template
+        return scripts
+
+    def is_svn_url(self, version):
+        # Search if there is http/https/svn or svn+[a tunnel identifier] in the
+        # url or if the trunk marker is used, all indicating the use of svn
+        svn_version_search = re.compile(
+            r'^(http|https|svn|svn\+[a-zA-Z-_]+)://|^(trunk)$').search(version)
+        return svn_version_search is not None
+
+    def version_to_svn(self, version):
+        if version == 'trunk':
+            return 'http://code.djangoproject.com/svn/django/trunk/'
+        else:
+            return version
+
+    def version_to_download_suffix(self, version):
+        if version == 'trunk':
+            return 'svn'
+        return [p for p in version.split('/') if p][-1]
+
+    def svn_update(self, path, version):
+        command = 'svn up'
+        revision_search = re.compile(r'@([0-9]*)$').search(
+            self.options['version'])
+
+        if revision_search is not None:
+            command += ' -r ' + revision_search.group(1)
+        self.log.info("Updating Django from svn")
+        if not self.buildout['buildout'].get('verbosity'):
+            command += ' -q'
+        return self.command(command, cwd=path)
+
+    def get_extra_paths(self):
+        extra_paths = [self.options['location'],
+                       self.buildout['buildout']['directory']
+                       ]
+
+        # Add libraries found by a site .pth files to our extra-paths.
+        if 'pth-files' in self.options:
+            import site
+            for pth_file in self.options['pth-files'].splitlines():
+                pth_libs = site.addsitedir(pth_file, set())
+                if not pth_libs:
+                    self.log.warning(
+                        "No site *.pth libraries found for pth_file=%s" % (
+                         pth_file,))
+                else:
+                    self.log.info("Adding *.pth libraries=%s" % pth_libs)
+                    self.options['extra-paths'] += '\n' + '\n'.join(pth_libs)
+
+        pythonpath = [p.replace('/', os.path.sep) for p in
+                      self.options['extra-paths'].splitlines() if p.strip()]
+
+        extra_paths.extend(pythonpath)
+        return extra_paths
+
+    def update(self):
+        newest = self.buildout['buildout'].get('newest') != 'false'
+        if newest and not self.install_from_cache and \
+                self.is_svn_url(self.options['version']):
+            self.svn_update(self.options['location'], self.options['version'])
+
+        extra_paths = self.get_extra_paths()
+        requirements, ws = self.egg.working_set(['djangorecipe'])
+        # Create the Django management script
+        self.create_manage_script(extra_paths, ws)
+
+        # Create the test runner
+        self.create_test_runner(extra_paths, ws)
+
+        # Make the wsgi and fastcgi scripts if enabled
+        self.make_scripts(extra_paths, ws)
+
+    def command(self, cmd, **kwargs):
+        output = subprocess.PIPE
+        if self.buildout['buildout'].get('verbosity'):
+            output = None
+        command = subprocess.Popen(
+            cmd, shell=True, stdout=output, **kwargs)
+        return command.wait()
+
+    def create_file(self, file, template, options):
+        if os.path.exists(file):
+            return
+
+        f = open(file, 'w')
+        f.write(template % options)
+        f.close()
+
+    def generate_secret(self):
+        chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
+        return ''.join([choice(chars) for i in range(50)])