diff options
Diffstat (limited to 'eggs/djangorecipe-0.20-py2.6.egg/djangorecipe')
14 files changed, 1362 insertions, 0 deletions
diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.py diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo Binary files differnew file mode 100644 index 0000000..7898e21 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/__init__.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py new file mode 100644 index 0000000..17a793e --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.py @@ -0,0 +1,29 @@ +from django.core import management + +def main(settings_file, logfile=None): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + sys.exit(1) + + # Setup settings + management.setup_environ(mod) + + from django.conf import settings + + options = getattr(settings, 'FCGI_OPTIONS', {}) + if logfile: + options['outlog'] = logfile + options['errlog'] = logfile + + from django.core.servers.fastcgi import runfastcgi + + # Run FASTCGI handler + runfastcgi(**options) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo Binary files differnew file mode 100644 index 0000000..62633ea --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/fcgi.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py new file mode 100644 index 0000000..6a61411 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.py @@ -0,0 +1,16 @@ +from django.core import management + +def main(settings_file): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + return sys.exit(1) + + management.execute_manager(mod) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo Binary files differnew file mode 100644 index 0000000..d483aac --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/manage.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py new file mode 100644 index 0000000..2282513 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.py @@ -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)]) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo Binary files differnew file mode 100644 index 0000000..a73b499 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/recipe.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py new file mode 100644 index 0000000..8cad491 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.py @@ -0,0 +1,16 @@ +from django.core import management + +def main(settings_file, *apps): + argv = ['test', 'test'] + list(apps) + try: + settings = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + settings = getattr(settings, comp) + except ImportError, e: + import sys + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + return sys.exit(1) + + management.execute_manager(settings, argv=argv) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo Binary files differnew file mode 100644 index 0000000..2d4d58d --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/test.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py new file mode 100644 index 0000000..8d83ad7 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.py @@ -0,0 +1,790 @@ +import unittest +import tempfile +import os +import sys +import shutil + +import mock +from zc.buildout import UserError +from zc.recipe.egg.egg import Scripts as ZCRecipeEggScripts + +from djangorecipe.recipe import Recipe + +# Add the testing dir to the Python path so we can use a fake Django +# install. This needs to be done so that we can use this as a base for +# mock's with some of the tests. +sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'testing')) + +# Now that we have a fake Django on the path we can import the +# scripts. These are depenent on a Django install, hence the fake one. +from djangorecipe import test +from djangorecipe import manage + + +class TestRecipe(unittest.TestCase): + + def setUp(self): + # Create a directory for our buildout files created by the recipe + self.buildout_dir = tempfile.mkdtemp('djangorecipe') + + self.bin_dir = os.path.join(self.buildout_dir, 'bin') + self.develop_eggs_dir = os.path.join(self.buildout_dir, + 'develop-eggs') + self.eggs_dir = os.path.join(self.buildout_dir, 'eggs') + self.parts_dir = os.path.join(self.buildout_dir, 'parts') + + # We need to create the bin dir since the recipe should be able to expect it exists + os.mkdir(self.bin_dir) + + self.recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': sys.executable}}, + 'django', + {'recipe': 'djangorecipe', + 'version': 'trunk'}) + + def tearDown(self): + # Remove our test dir + shutil.rmtree(self.buildout_dir) + + def test_consistent_options(self): + # Buildout is pretty clever in detecting changing options. If + # the recipe modifies it's options during initialisation it + # will store this to determine wheter it needs to update or do + # a uninstall & install. We need to make sure that we normally + # do not trigger this. That means running the recipe with the + # same options should give us the same results. + self.assertEqual(*[ + Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': sys.executable}}, + 'django', + {'recipe': 'djangorecipe', + 'version': 'trunk'}).options.copy() for i in range(2)]) + + def test_svn_url(self): + # Make sure that only a few specific type of url's are + # considered svn url's + + # This is a plain release version so it should indicate it is + # not a svn url + self.failIf(self.recipe.is_svn_url('0.96.2')) + # The next line specifies a proper link with the trunk + self.assert_(self.recipe.is_svn_url('trunk')) + # A url looking like trunk should also fail + self.failIf(self.recipe.is_svn_url('trunka')) + # A full svn url including version should work + self.assert_(self.recipe.is_svn_url( + 'http://code.djangoproject.com/svn/django/branches/newforms-admin@7833')) + # HTTPS should work too + self.assert_(self.recipe.is_svn_url( + 'https://code.djangoproject.com/svn/django/branches/newforms-admin@7833')) + # Svn+ssh should work + self.assert_(self.recipe.is_svn_url( + 'svn+ssh://myserver/newforms-admin@7833')) + # Svn protocol through any custom tunnel defined in ~/.subversion/config should work + self.assert_(self.recipe.is_svn_url( + 'svn+MY_Custom-tunnel://myserver/newforms-admin@7833')) + # Using a non existent protocol should not be a svn url? + self.failIf(self.recipe.is_svn_url( + 'unknown://myserver/newforms-admin@7833')) + + def test_command(self): + # The command method is a wrapper for subprocess which excutes + # a command and return's it's status code. We will demonstrate + # this with a simple test of running `dir`. + self.failIf(self.recipe.command('echo')) + # Executing a non existing command should return an error code + self.assert_(self.recipe.command('spamspamspameggs')) + + @mock.patch('subprocess', 'Popen') + def test_command_verbose_mode(self, popen): + # When buildout is put into verbose mode the command methode + # should stop capturing the ouput of it's commands. + popen.return_value = mock.Mock() + self.recipe.buildout['buildout']['verbosity'] = 'verbose' + self.recipe.command('silly-command') + self.assertEqual( + popen.call_args, + (('silly-command',), {'shell': True, 'stdout': None})) + + def test_create_file(self): + # The create file helper should create a file at a certain + # location unless it already exists. We will need a + # non-existing file first. + f, name = tempfile.mkstemp() + # To show the function in action we need to delete the file + # before testing. + os.remove(name) + # The method accepts a template argument which it will use + # with the options argument for string substitution. + self.recipe.create_file(name, 'Spam %s', 'eggs') + # Let's check the contents of the file + self.assertEqual(open(name).read(), 'Spam eggs') + # If we try to write it again it will just ignore our request + self.recipe.create_file(name, 'Spam spam spam %s', 'eggs') + # The content of the file should therefore be the same + self.assertEqual(open(name).read(), 'Spam eggs') + # Now remove our temp file + os.remove(name) + + def test_generate_secret(self): + # To create a basic skeleton the recipe also generates a + # random secret for the settings file. Since it should very + # unlikely that it will generate the same key a few times in a + # row we will test it with letting it generate a few keys. + self.assert_(len(set( + [self.recipe.generate_secret() for i in xrange(10)])) > 1) + + def test_version_to_svn(self): + # Version specification that lead to a svn repository can be + # specified in different ways. Just specifying `trunk` should + # be enough to get the full url to the Django trunk. + self.assertEqual(self.recipe.version_to_svn('trunk'), + 'http://code.djangoproject.com/svn/django/trunk/') + # Any other specification should lead to the url it is given + self.assertEqual(self.recipe.version_to_svn('svn://somehost/trunk'), + 'svn://somehost/trunk') + + def test_version_to_download_suffic(self): + # To create standard names for the download directory a method + # is provided which converts a version to a dir suffix. A + # simple pointer to trunk should return svn. + self.assertEqual(self.recipe.version_to_download_suffix('trunk'), + 'svn') + # Any other url should return the last path component. This + # works out nicely for branches or version pinned url's. + self.assertEqual(self.recipe.version_to_download_suffix( + 'http://monty/branches/python'), 'python') + + def test_make_protocol_scripts(self): + # To ease deployment a WSGI script can be generated. The + # script adds any paths from the `extra_paths` option to the + # Python path. + self.recipe.options['wsgi'] = 'true' + self.recipe.options['fcgi'] = 'true' + self.recipe.make_scripts([], []) + # This should have created a script in the bin dir + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + self.assert_(os.path.exists(wsgi_script)) + # The contents should list our paths + contents = open(wsgi_script).read() + # It should also have a reference to our settings module + self.assert_('project.development' in contents) + # and a line which set's up the WSGI app + self.assert_("application = " + "djangorecipe.wsgi.main('project.development', logfile='')" + in contents) + self.assert_("class logger(object)" not in contents) + + # Another deployment options is FCGI. The recipe supports an option to + # automatically create the required script. + fcgi_script = os.path.join(self.bin_dir, 'django.fcgi') + self.assert_(os.path.exists(fcgi_script)) + # The contents should list our paths + contents = open(fcgi_script).read() + # It should also have a reference to our settings module + self.assert_('project.development' in contents) + # and a line which set's up the WSGI app + self.assert_("djangorecipe.fcgi.main('project.development', logfile='')" + in contents) + self.assert_("class logger(object)" not in contents) + + self.recipe.options['logfile'] = '/foo' + self.recipe.make_scripts([], []) + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + contents = open(wsgi_script).read() + self.assert_("logfile='/foo'" in contents) + + self.recipe.options['logfile'] = '/foo' + self.recipe.make_scripts([], []) + fcgi_script = os.path.join(self.bin_dir, 'django.fcgi') + contents = open(fcgi_script).read() + self.assert_("logfile='/foo'" in contents) + + @mock.patch('zc.buildout.easy_install', 'scripts') + def test_make_protocol_scripts_return_value(self, scripts): + # The return value of make scripts lists the generated scripts. + self.recipe.options['wsgi'] = 'true' + self.recipe.options['fcgi'] = 'true' + scripts.return_value = ['some-path'] + self.assertEqual(self.recipe.make_scripts([], []), + ['some-path', 'some-path']) + + + + def test_create_project(self): + # If a project does not exist already the recipe will create + # one. + project_dir = os.path.join(self.buildout_dir, 'project') + self.recipe.create_project(project_dir) + # This should have create a project directory + self.assert_(os.path.exists(project_dir)) + # With this directory we should have __init__.py to make it a + # package + self.assert_( + os.path.exists(os.path.join(project_dir, '__init__.py'))) + # There should also be a urls.py + self.assert_( + os.path.exists(os.path.join(project_dir, 'urls.py'))) + # To make it easier to start using this project both a media + # and a templates folder are created + self.assert_( + os.path.exists(os.path.join(project_dir, 'media'))) + self.assert_( + os.path.exists(os.path.join(project_dir, 'templates'))) + # The project is ready to go since the recipe has generated a + # base settings, development and production file + for f in ('settings.py', 'development.py', 'production.py'): + self.assert_( + os.path.exists(os.path.join(project_dir, f))) + + def test_create_test_runner(self): + # An executable script can be generated which will make it + # possible to execute the Django test runner. This options + # only works if we specify one or apps to test. + testrunner = os.path.join(self.bin_dir, 'test') + + # This first argument sets extra_paths, we will use this to + # make sure the script can find this recipe + recipe_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) + + # First we will show it does nothing by default + self.recipe.create_test_runner([recipe_dir], []) + self.failIf(os.path.exists(testrunner)) + + # When we specify an app to test it should create the the + # testrunner + self.recipe.options['test'] = 'knight' + self.recipe.create_test_runner([recipe_dir], []) + self.assert_(os.path.exists(testrunner)) + + def test_create_manage_script(self): + # This buildout recipe creates a alternative for the standard + # manage.py script. It has all the same functionality as the + # original one but it sits in the bin dir instead of within + # the project. + manage = os.path.join(self.bin_dir, 'django') + self.recipe.create_manage_script([], []) + self.assert_(os.path.exists(manage)) + + def test_create_manage_script_projectegg(self): + # When a projectegg is specified, then the egg specified + # should get used as the project file. + manage = os.path.join(self.bin_dir, 'django') + self.recipe.options['projectegg'] = 'spameggs' + self.recipe.create_manage_script([], []) + self.assert_(os.path.exists(manage)) + # Check that we have 'spameggs' as the project + self.assert_("djangorecipe.manage.main('spameggs.development')" + in open(manage).read()) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('zc.recipe.egg', 'Develop') + def test_fulfills_django_dependency(self, rmtree, path_exists, + urlretrieve, copytree, working_set, scripts, install_release, + manage, testrunner, develop): + # Test for https://bugs.launchpad.net/djangorecipe/+bug/397864 + # djangorecipe should always fulfil the 'Django' requirement. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + manage.return_value = [] + scripts.return_value = [] + testrunner.return_value = [] + develop_install = mock.Mock() + develop.return_value = develop_install + self.recipe.install() + + # We should see that Django was added as a develop egg. + options = develop.call_args[0][2] + self.assertEqual(options['location'], os.path.join(self.parts_dir, 'django')) + + # Check that the install() method for the develop egg was called with no args + first_method_name, args, kwargs = develop_install.method_calls[0] + self.assertEqual('install', first_method_name) + self.assertEqual(0, len(args)) + self.assertEqual(0, len(kwargs)) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('zc.recipe.egg', 'Develop') + def test_extra_paths(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, manage, testrunner, + develop): + # The recipe allows extra-paths to be specified. It uses these to + # extend the Python path within it's generated scripts. + self.recipe.options['version'] = '1.0' + self.recipe.options['extra-paths'] = 'somepackage\nanotherpackage' + path_exists.return_value = True + working_set.return_value = (None, []) + manage.return_value = [] + scripts.return_value = [] + testrunner.return_value = [] + develop.return_value = mock.Mock() + self.recipe.install() + self.assertEqual(manage.call_args[0][0][-2:], + ['somepackage', 'anotherpackage']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'create_manage_script') + @mock.patch(Recipe, 'create_test_runner') + @mock.patch('site', 'addsitedir') + @mock.patch('zc.recipe.egg', 'Develop') + def test_pth_files(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, manage, testrunner, addsitedir, + develop): + # When a pth-files option is set the recipe will use that to add more + # paths to extra-paths. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + scripts.return_value = [] + manage.return_value = [] + testrunner.return_value = [] + develop.return_value = mock.Mock() + + # The mock values needed to demonstrate the pth-files option. + addsitedir.return_value = ['extra', 'dirs'] + self.recipe.options['pth-files'] = 'somedir' + + self.recipe.install() + self.assertEqual(addsitedir.call_args, (('somedir', set([])), {})) + # The extra-paths option has been extended. + self.assertEqual(self.recipe.options['extra-paths'], '\nextra\ndirs') + + def test_create_wsgi_script_projectegg(self): + # When a projectegg is specified, then the egg specified + # should get used as the project in the wsgi script. + wsgi = os.path.join(self.bin_dir, 'django.wsgi') + recipe_dir = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) + self.recipe.options['projectegg'] = 'spameggs' + self.recipe.options['wsgi'] = 'true' + self.recipe.make_scripts([recipe_dir], []) + self.assert_(os.path.exists(wsgi)) + # Check that we have 'spameggs' as the project + self.assert_('spameggs.development' in open(wsgi).read()) + + def test_settings_option(self): + # The settings option can be used to specify the settings file + # for Django to use. By default it uses `development`. + self.assertEqual(self.recipe.options['settings'], 'development') + # When we change it an generate a manage script it will use + # this var. + self.recipe.options['settings'] = 'spameggs' + self.recipe.create_manage_script([], []) + manage = os.path.join(self.bin_dir, 'django') + self.assert_("djangorecipe.manage.main('project.spameggs')" + in open(manage).read()) + + @mock.patch('urllib2', 'urlopen') + def test_get_release(self, mock): + # The get_release method fecthes a release tarball and + # extracts it. We have setup a mock so that it won't actually + # download the release. Let's call the code. + class FakeFile(object): + def read(self): + return 'Django tarball' + def close(self): + self.closed = True + + tmp = tempfile.mkdtemp() + filename = os.path.join(tmp, 'django-0.96.2.tar.gz') + mock.return_value = FakeFile() + try: + self.assertEqual( + self.recipe.get_release('0.96.2', tmp), + filename) + # It tried to download the release through our mock + mock.assert_called_with( + 'http://www.djangoproject.com/download/0.96.2/tarball/') + # The file should have been filled with the contents from the + # handle it got. + self.assertEqual(open(filename).read(), 'Django tarball') + finally: + shutil.rmtree(tmp) + + @mock.patch('setuptools.archive_util', 'unpack_archive') + @mock.patch('shutil', 'move') + @mock.patch('shutil', 'rmtree') + @mock.patch('os', 'listdir') + def test_install_release(self, unpack, move, rmtree, listdir): + # To install a release the recipe uses a specific method. We + # have have mocked all the calls which interact with the + # filesystem. + listdir.return_value = ('Django-0.96-2',) + self.recipe.install_release('0.96.2', 'downloads', + 'downloads/django-0.96.2.tar.gz', + 'parts/django') + # Let's see what the mock's have been called with + self.assertEqual(listdir.call_args, + (('downloads/django-archive',), {})) + self.assertEqual(unpack.call_args, + (('downloads/django-0.96.2.tar.gz', + 'downloads/django-archive'), {})) + self.assertEqual(move.call_args, + (('downloads/django-archive/Django-0.96-2', + 'parts/django'), {})) + self.assertEqual(rmtree.call_args, + (('downloads/django-archive',), {})) + + @mock.patch('shutil', 'copytree') + @mock.patch(Recipe, 'command') + def test_install_svn_version(self, copytree, command): + # Installation from svn is handled by a method. We have mocked + # the command method to avoid actual checkouts of Django. + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', False) + # This should have tried to do a checkout of the Django trunk + self.assertEqual(command.call_args, + (('svn co http://code.djangoproject.com/svn/django/trunk/ downloads/django-svn -q',), {})) + # A copy command to the parts directory should also have been + # issued + self.assertEqual(copytree.call_args, + (('downloads/django-svn', 'parts/django'), {})) + + @mock.patch('shutil', 'copytree') + @mock.patch('os.path', 'exists') + @mock.patch(Recipe, 'command') + def test_install_and_update_svn_version(self, copytree, exists, command): + # When an checkout has been done of a svn based installation + # is already done the recipe should just update it. + exists.return_value = True + + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', False) + self.assertEqual(exists.call_args, (('downloads/django-svn',), {})) + self.assertEqual(command.call_args, + (('svn up -q',), {'cwd': 'downloads/django-svn'})) + + @mock.patch(Recipe, 'command') + def test_install_broken_svn(self, command): + # When the checkout from svn fails during a svn build the + # installation method raises an error. We will simulate this + # failure by telling our mock what to do. + command.return_value = 1 + # The line above should indicate a failure (non-zero exit + # code) + self.assertRaises(UserError, self.recipe.install_svn_version, + 'trunk', 'downloads', 'parts/django', False) + + @mock.patch('shutil', 'copytree') + @mock.patch(Recipe, 'command') + def test_svn_install_from_cache(self, copytree, command): + # If the buildout is told to install from cache it will not do + # a checkout but instead an existing checkout + self.recipe.buildout['buildout']['install-from-cache'] = 'true' + # Now we can run the installation method + self.recipe.install_svn_version('trunk', 'downloads', + 'parts/django', True) + # This should not have called the recipe's command method + self.failIf(command.called) + # A copy from the cache to the destination should have been + # made + self.assertEqual(copytree.call_args, + (('downloads/django-svn', 'parts/django'), {})) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_svn(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update and the version is + # a svn version it just does an update on the parts folder. + self.recipe.update() + self.assertEqual('svn up -q', command.call_args[0][0]) + # It changes the working directory so that the simple svn up + # command will work. + self.assertEqual(command.call_args[1].keys(), ['cwd']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('subprocess', 'call') + def test_update_with_cache(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, call_process): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update whilst in install + # from cache mode it just ignores it + self.recipe.install_from_cache = True + self.recipe.update() + self.failIf(call_process.called) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('subprocess', 'call') + def test_update_with_newest_false(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, call_process): + path_exists.return_value = True + working_set.return_value = (None, []) + # When the recipe is asked to do an update whilst in install + # from cache mode it just ignores it + self.recipe.buildout['buildout']['newest'] = 'false' + self.recipe.update() + self.assertFalse(call_process.called) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch('zc.recipe.egg', 'Develop') + def test_clear_existing_django(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, develop): + # When the recipe is executed and Django is already installed + # within parts it should remove it. We will mock the exists + # check to make it let the recipe think it has an existing + # Django install. + self.recipe.options['version'] = '1.0' + path_exists.return_value = True + working_set.return_value = (None, []) + scripts.return_value = [] + develop.return_value = mock.Mock() + self.recipe.install() + # This should have called remove tree + self.assert_(rmtree.called) + # We will assert that the last two compontents of the path + # passed to rmtree are the ones we wanted to delete. + self.assertEqual(rmtree.call_args[0][0].split('/')[-2:], + ['parts', 'django']) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_pinned_svn_url(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # Make sure that updating a pinned version is updated + # accordingly. It must not switch to updating beyond it's + # requested revision. + # The recipe does this by checking for an @ sign in the url / + # version. + self.recipe.is_svn_url = lambda version: True + + self.recipe.options['version'] = 'http://testing/trunk@2531' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -r 2531 -q',)) + + @mock.patch('shutil', 'rmtree') + @mock.patch('os.path', 'exists') + @mock.patch('urllib', 'urlretrieve') + @mock.patch('shutil', 'copytree') + @mock.patch(ZCRecipeEggScripts, 'working_set') + @mock.patch('zc.buildout.easy_install', 'scripts') + @mock.patch(Recipe, 'install_release') + @mock.patch(Recipe, 'command') + def test_update_username_in_svn_url(self, rmtree, path_exists, urlretrieve, + copytree, working_set, scripts, + install_release, command): + path_exists.return_value = True + working_set.return_value = (None, []) + # Make sure that updating a version with a username + # in the URL works + self.recipe.is_svn_url = lambda version: True + + # First test with both a revision and a username in the url + self.recipe.options['version'] = 'http://user@testing/trunk@2531' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -r 2531 -q',)) + + # Now test with only the username + self.recipe.options['version'] = 'http://user@testing/trunk' + self.recipe.update() + self.assertEqual(command.call_args[0], ('svn up -q',)) + + def test_python_option(self): + # The python option makes it possible to specify a specific Python + # executable which is to be used for the generated scripts. + recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': '/python4k'}}, + 'django', + {'recipe': 'djangorecipe', 'version': 'trunk', + 'wsgi': 'true'}) + recipe.make_scripts([], []) + # This should have created a script in the bin dir + wsgi_script = os.path.join(self.bin_dir, 'django.wsgi') + self.assertEqual(open(wsgi_script).readlines()[0], '#!/python4k\n') + # Changeing the option for only the part will change the used Python + # version. + recipe = Recipe({'buildout': {'eggs-directory': self.eggs_dir, + 'develop-eggs-directory': self.develop_eggs_dir, + 'python': 'python-version', + 'bin-directory': self.bin_dir, + 'parts-directory': self.parts_dir, + 'directory': self.buildout_dir, + }, + 'python-version': {'executable': '/python4k'}, + 'py5k': {'executable': '/python5k'}}, + 'django', + {'recipe': 'djangorecipe', 'version': 'trunk', + 'python': 'py5k', 'wsgi': 'true'}) + recipe.make_scripts([], []) + self.assertEqual(open(wsgi_script).readlines()[0], '#!/python5k\n') + +class ScriptTestCase(unittest.TestCase): + + def setUp(self): + # We will also need to fake the settings file's module + self.settings = mock.sentinel.Settings + sys.modules['cheeseshop'] = mock.sentinel.CheeseShop + sys.modules['cheeseshop.development'] = self.settings + sys.modules['cheeseshop'].development = self.settings + + def tearDown(self): + # We will clear out sys.modules again to clean up + for m in ['cheeseshop', 'cheeseshop.development']: + del sys.modules[m] + + +class TestTestScript(ScriptTestCase): + + @mock.patch('django.core.management', 'execute_manager') + def test_script(self, execute_manager): + # The test script should execute the standard Django test + # command with any apps given as its arguments. + test.main('cheeseshop.development', 'spamm', 'eggs') + # We only care about the arguments given to execute_manager + self.assertEqual(execute_manager.call_args[1], + {'argv': ['test', 'test', 'spamm', 'eggs']}) + + @mock.patch('django.core.management', 'execute_manager') + def test_deeply_nested_settings(self, execute_manager): + # Settings files can be more than two levels deep. We need to + # make sure the test script can properly import those. To + # demonstrate this we need to add another level to our + # sys.modules entries. + settings = mock.sentinel.SettingsModule + nce = mock.sentinel.NCE + nce.development = settings + sys.modules['cheeseshop'].nce = nce + sys.modules['cheeseshop.nce'] = nce + sys.modules['cheeseshop.nce.development'] = settings + + test.main('cheeseshop.nce.development', 'tilsit', 'stilton') + self.assertEqual(execute_manager.call_args[0], (settings,)) + + @mock.patch('sys', 'exit') + def test_settings_error(self, sys_exit): + # When the settings file cannot be imported the test runner + # wil exit with a message and a specific exit code. + test.main('cheeseshop.tilsit', 'stilton') + self.assertEqual(sys_exit.call_args, ((1,), {})) + +class TestManageScript(ScriptTestCase): + + @mock.patch('django.core.management', 'execute_manager') + def test_script(self, execute_manager): + # The manage script is a replacement for the default manage.py + # script. It has all the same bells and whistles since all it + # does is call the normal Django stuff. + manage.main('cheeseshop.development') + self.assertEqual(execute_manager.call_args, + ((self.settings,), {})) + + @mock.patch('sys', 'exit') + def test_settings_error(self, sys_exit): + # When the settings file cannot be imported the management + # script it wil exit with a message and a specific exit code. + manage.main('cheeseshop.tilsit') + self.assertEqual(sys_exit.call_args, ((1,), {})) + +def setUp(test): + zc.buildout.testing.buildoutSetUp(test) + + # Make a semi permanent download cache to speed up the test + tmp = tempfile.gettempdir() + cache_dir = os.path.join(tmp, 'djangorecipe-test-cache') + if not os.path.exists(cache_dir): + os.mkdir(cache_dir) + + # Create the default.cfg which sets the download cache + home = test.globs['tmpdir']('home') + test.globs['mkdir'](home, '.buildout') + test.globs['write'](home, '.buildout', 'default.cfg', + """ +[buildout] +download-cache = %(cache_dir)s + """ % dict(cache_dir=cache_dir)) + os.environ['HOME'] = home + + zc.buildout.testing.install('zc.recipe.egg', test) + zc.buildout.testing.install_develop('djangorecipe', test) + + +def test_suite(): + return unittest.TestSuite(( + unittest.makeSuite(TestRecipe), + unittest.makeSuite(TestTestScript), + unittest.makeSuite(TestManageScript), + )) diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo Binary files differnew file mode 100644 index 0000000..880b222 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/tests.pyo diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py new file mode 100644 index 0000000..9e9d054 --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.py @@ -0,0 +1,45 @@ +import sys + +from django.core import management + +def main(settings_file, logfile=None): + try: + mod = __import__(settings_file) + components = settings_file.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + + except ImportError, e: + sys.stderr.write("Error loading the settings module '%s': %s" + % (settings_file, e)) + sys.exit(1) + + # Setup settings + management.setup_environ(mod) + + if logfile: + import datetime + class logger(object): + def __init__(self, logfile): + self.logfile = logfile + + def write(self, data): + self.log(data) + + def writeline(self, data): + self.log(data) + + def log(self, msg): + line = '%s - %s\n' % ( + datetime.datetime.now().strftime('%Y%m%d %H:%M:%S'), msg) + fp = open(self.logfile, 'a') + try: + fp.write(line) + finally: + fp.close() + sys.stdout = sys.stderr = logger(logfile) + + from django.core.handlers.wsgi import WSGIHandler + + # Run WSGI handler for the application + return WSGIHandler() diff --git a/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo Binary files differnew file mode 100644 index 0000000..79288fe --- /dev/null +++ b/eggs/djangorecipe-0.20-py2.6.egg/djangorecipe/wsgi.pyo |