Ticket #596: django_as_egg_2.patch

File django_as_egg_2.patch, 8.9 KB (added by sil@…, 10 years ago)

Better patch: ignore previous one

  • django/utils/autoreload.py

     
    3737    mtimes = {}
    3838    while RUN_RELOADER:
    3939        for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())) + reloadFiles:
     40            if not os.path.exists(filename): continue # file might be in an egg, so it can't be reloaded
    4041            if filename.endswith(".pyc"):
    4142                filename = filename[:-1]
    4243            mtime = os.stat(filename).st_mtime
  • django/conf/global_settings.py

     
    6060# Extension on all templates.
    6161TEMPLATE_FILE_EXTENSION = '.html'
    6262
     63# Callables which know how to import template sources from various
     64# sources; the expected interface is callable(name, [dirs]), where dirs
     65# is a list of directories to search instead of TEMPLATE_DIRS.
     66TEMPLATE_SOURCE_LOADERS = (
     67    'django.core.template_file.load_template_source',
     68    'django.core.template_eggs.load_template_source',
     69)
     70
     71
    6372# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
    6473# trailing slash.
    6574# Examples: "http://foo.com/media/", "/media/".
  • django/core/template_loader.py

     
    11"Wrapper for loading templates from storage of some sort (e.g. files or db)"
    22import template
    3 from template_file import load_template_source
    43
     4from django.conf.settings import TEMPLATE_SOURCE_LOADERS
     5from django.core import exceptions
     6
     7template_source_loaders = []
     8for path in TEMPLATE_SOURCE_LOADERS:
     9    i = path.rfind('.')
     10    module, attr = path[:i], path[i+1:]
     11    try:
     12        mod = __import__(module, globals(), locals(), [attr])
     13    except ImportError, e:
     14        raise exceptions.ImproperlyConfigured, 'Error importing template_source_loader %s: "%s"' % (module, e)
     15    try:
     16        template_source_loaders.append(getattr(mod, attr))
     17    except AttributeError:
     18        raise exceptions.ImproperlyConfigured, 'Module "%s" does not define a "%s" callable template_source_loader' % (module, attr)
     19
     20def load_template_source(name, dirs=None):
     21    for loader in template_source_loaders:
     22        try:
     23            return loader(name, dirs)
     24        except template.TemplateDoesNotExist:
     25            pass
     26    raise template.TemplateDoesNotExist, name
     27
     28
    529class ExtendsError(Exception):
    630    pass
    731
     
    2448    Loads the given template_name and renders it with the given dictionary as
    2549    context. The template_name may be a string to load a single template using
    2650    get_template, or it may be a tuple to use select_template to find one of
    27     the templates in the list.  Returns a string. 
     51    the templates in the list.  Returns a string.
    2852    """
    2953    dictionary = dictionary or {}
    3054    if isinstance(template_name, (list, tuple)):
  • django/core/servers/basehttp.py

     
    616616
    617617        # Find the admin file and serve it up, if it exists and is readable.
    618618        relative_url = environ['PATH_INFO'][len(self.media_url):]
    619         file_path = os.path.join(self.media_dir, relative_url)
    620         if not os.path.exists(file_path):
     619
     620        # Nasty hack to see if we're running in an egg
     621        # We can't just use resource_* as we do when setting up, because
     622        # the user might have set the media_dir to be something outside
     623        # the egg, and so resource_* won't find it. So, check for .egg in media_dir,
     624        # and if it's there then use resource_* to get the resources.
     625        if self.media_dir.find('.egg') == -1:
     626          MEDIA_PATH_IS_REAL = True
     627          file_path = os.path.join(self.media_dir, relative_url)
     628          path_exists = os.path.exists(file_path)
     629        else:
     630          from pkg_resources import resource_exists, resource_stream
     631          import django
     632          MEDIA_PATH_IS_REAL = False
     633          file_path = self.media_dir[len(django.__path__[0]):] + '/' + relative_url
     634          path_exists = resource_exists('django',file_path)
     635
     636        if not path_exists:
    621637            status = '404 NOT FOUND'
    622638            headers = {'Content-type': 'text/plain'}
    623639            output = ['Page not found: %s' % file_path]
    624640        else:
    625641            try:
    626                 fp = open(file_path, 'rb')
     642                if MEDIA_PATH_IS_REAL:
     643                  fp = open(file_path, 'rb')
     644                else:
     645                  fp = resource_stream('django',file_path)
    627646            except IOError:
    628647                status = '401 UNAUTHORIZED'
    629648                headers = {'Content-type': 'text/plain'}
  • django/core/management.py

     
    33
    44import django
    55import os, re, sys
     6try:
     7  from pkg_resources import resource_listdir, resource_isdir, resource_stream
     8  OK_IN_EGG = True
     9except:
     10  OK_IN_EGG = False
    611
    712MODULE_TEMPLATE = '''    {%% if perms.%(app)s.%(addperm)s or perms.%(app)s.%(changeperm)s %%}
    813    <tr>
     
    353358    except OSError, e:
    354359        sys.stderr.write("Error: %s\n" % e)
    355360        sys.exit(1)
    356     template_dir = PROJECT_TEMPLATE_DIR % app_or_project
    357     for d, subdirs, files in os.walk(template_dir):
     361    if OK_IN_EGG:
     362      # Use setuptools.resource_* to get the resources, which should work whether
     363      # django is installed as a directory or as an egg
     364      template_dir = (PROJECT_TEMPLATE_DIR % app_or_project)[len(django.__path__[0])+1:]
     365      print template_dir
     366      walklist = _walk_pkgresources_helper(template_dir)
     367    else:
     368      # Use django.__path__, which is the installation directory
     369      template_dir = PROJECT_TEMPLATE_DIR % app_or_project
     370      walklist = os.walk(template_dir)
     371    for d, subdirs, files in walklist:
    358372        relative_dir = d[len(template_dir)+1:].replace('%s_name' % app_or_project, name)
    359373        if relative_dir:
    360374            os.mkdir(os.path.join(top_dir, relative_dir))
     
    364378        for f in files:
    365379            if f.endswith('.pyc'):
    366380                continue
    367             fp_old = open(os.path.join(d, f), 'r')
     381            if OK_IN_EGG:
     382              fp_old = resource_stream('django',d + '/' + f)
     383            else:
     384              fp_old = open(os.path.join(d, f), 'r')
    368385            fp_new = open(os.path.join(top_dir, relative_dir, f.replace('%s_name' % app_or_project, name)), 'w')
    369386            fp_new.write(fp_old.read().replace('{{ %s_name }}' % app_or_project, name).replace('{{ %s_name }}' % other, other_name))
    370387            fp_old.close()
    371388            fp_new.close()
    372389
     390def _walk_pkgresources_helper(top, topdown=True, onerror=None):
     391    """An equivalent to os.walk but using the setuptools resource_* APIs, in order
     392       to allow walking over directories inside egg files."""
     393    try:
     394        names = resource_listdir('django',top)
     395    except:
     396        # Should handle an error callback here, but we don't.
     397        return
     398    dirs, nondirs = [], []
     399    for name in names:
     400        if resource_isdir('django',top + '/' + name): # note, / separate, not os.path.join
     401            dirs.append(name)
     402        else:
     403            nondirs.append(name)
     404
     405    if topdown:
     406        yield top, dirs, nondirs
     407    for name in dirs:
     408        path = top + '/' + name
     409        for x in _walk_pkgresources_helper(path, topdown, onerror):
     410            yield x
     411    if not topdown:
     412        yield top, dirs, nondirs
     413
    373414def startproject(project_name, directory):
    374415    "Creates a Django project for the given project_name in the given directory."
    375416    from random import choice
     
    379420    admin_settings_file = os.path.join(directory, project_name, 'settings/admin.py')
    380421    settings_contents = open(admin_settings_file, 'r').read()
    381422    fp = open(admin_settings_file, 'w')
     423    # Nasty hack to see if we're running in an egg
     424    # If we're running as an egg, then the admin template path must be
     425    # a path that's *relative* to the Django install dir. If we're not,
     426    # then it must be an *absolute* path. So if .egg is in django.__path__[0],
     427    # make the path relative.
     428    admin_template_dir_to_use = ADMIN_TEMPLATE_DIR
     429    if admin_template_dir_to_use.find('.egg') == -1:
     430        admin_template_dir_to_use = admin_template_dir_to_use[len(django.__path__[0]):]
    382431    settings_contents = re.sub(r'(?s)\b(TEMPLATE_DIRS\s*=\s*\()(.*?)\)', "\\1\n    r%r,\\2)" % ADMIN_TEMPLATE_DIR, settings_contents)
    383432    fp.write(settings_contents)
    384433    fp.close()
Back to Top