From d23043cfd1221546e63ac98723ae0329edecd42d Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Sun, 10 Oct 2010 23:20:27 -0400 Subject: removed coffin, from trunk, added dependencies and updated the version --- askbot/__init__.py | 2 +- askbot/setup_templates/settings.py | 2 +- coffin/.___init__.py | Bin 187 -> 0 bytes coffin/._common.py | Bin 187 -> 0 bytes coffin/._interop.py | Bin 184 -> 0 bytes coffin/__init__.py | 44 --- coffin/common.py | 148 ---------- coffin/conf/.___init__.py | Bin 184 -> 0 bytes coffin/conf/__init__.py | 0 coffin/conf/urls/__init__.py | 0 coffin/conf/urls/defaults.py | 4 - coffin/contrib/__init__.py | 0 coffin/contrib/markup/__init__.py | 0 coffin/contrib/markup/models.py | 0 coffin/contrib/markup/templatetags/__init__.py | 0 coffin/contrib/markup/templatetags/markup.py | 15 - coffin/contrib/syndication/__init__.py | 0 coffin/contrib/syndication/feeds.py | 36 --- coffin/interop.py | 120 -------- coffin/shortcuts/.___init__.py | Bin 187 -> 0 bytes coffin/shortcuts/__init__.py | 25 -- coffin/template/.___init__.py | Bin 187 -> 0 bytes coffin/template/._defaultfilters.py | Bin 185 -> 0 bytes coffin/template/._defaulttags.py | Bin 184 -> 0 bytes coffin/template/._library.py | Bin 187 -> 0 bytes coffin/template/._loader.py | Bin 187 -> 0 bytes coffin/template/._loaders.py | Bin 184 -> 0 bytes coffin/template/__init__.py | 93 ------- coffin/template/defaultfilters.py | 99 ------- coffin/template/defaulttags.py | 364 ------------------------- coffin/template/library.py | 215 --------------- coffin/template/loader.py | 66 ----- coffin/template/loaders.py | 38 --- coffin/views/__init__.py | 0 coffin/views/defaults.py | 35 --- coffin/views/generic/._simple.py | Bin 185 -> 0 bytes coffin/views/generic/__init__.py | 1 - coffin/views/generic/simple.py | 6 - setup.py | 2 + 39 files changed, 4 insertions(+), 1311 deletions(-) delete mode 100644 coffin/.___init__.py delete mode 100644 coffin/._common.py delete mode 100644 coffin/._interop.py delete mode 100644 coffin/__init__.py delete mode 100644 coffin/common.py delete mode 100644 coffin/conf/.___init__.py delete mode 100644 coffin/conf/__init__.py delete mode 100644 coffin/conf/urls/__init__.py delete mode 100644 coffin/conf/urls/defaults.py delete mode 100644 coffin/contrib/__init__.py delete mode 100644 coffin/contrib/markup/__init__.py delete mode 100644 coffin/contrib/markup/models.py delete mode 100644 coffin/contrib/markup/templatetags/__init__.py delete mode 100644 coffin/contrib/markup/templatetags/markup.py delete mode 100644 coffin/contrib/syndication/__init__.py delete mode 100644 coffin/contrib/syndication/feeds.py delete mode 100644 coffin/interop.py delete mode 100644 coffin/shortcuts/.___init__.py delete mode 100644 coffin/shortcuts/__init__.py delete mode 100644 coffin/template/.___init__.py delete mode 100644 coffin/template/._defaultfilters.py delete mode 100644 coffin/template/._defaulttags.py delete mode 100644 coffin/template/._library.py delete mode 100644 coffin/template/._loader.py delete mode 100644 coffin/template/._loaders.py delete mode 100644 coffin/template/__init__.py delete mode 100644 coffin/template/defaultfilters.py delete mode 100644 coffin/template/defaulttags.py delete mode 100644 coffin/template/library.py delete mode 100644 coffin/template/loader.py delete mode 100644 coffin/template/loaders.py delete mode 100644 coffin/views/__init__.py delete mode 100644 coffin/views/defaults.py delete mode 100644 coffin/views/generic/._simple.py delete mode 100644 coffin/views/generic/__init__.py delete mode 100644 coffin/views/generic/simple.py diff --git a/askbot/__init__.py b/askbot/__init__.py index 8e5e3242..026a8a85 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -22,7 +22,7 @@ def get_version(): """returns version of the askbot app this version is meaningful for pypi only """ - return '0.6.14' + return '0.6.15' #todo: maybe send_mail functions belong to models #or the future API diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py index c9075c2b..abb2ac6d 100644 --- a/askbot/setup_templates/settings.py +++ b/askbot/setup_templates/settings.py @@ -168,7 +168,7 @@ AUTHENTICATION_BACKENDS = ( LOG_FILENAME = 'askbot.log' logging.basicConfig( filename=os.path.join(os.path.dirname(__file__), 'log', LOG_FILENAME), - level=logging.DEBUG, + level=logging.CRITICAL, format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s', ) diff --git a/coffin/.___init__.py b/coffin/.___init__.py deleted file mode 100644 index b44b5fae..00000000 Binary files a/coffin/.___init__.py and /dev/null differ diff --git a/coffin/._common.py b/coffin/._common.py deleted file mode 100644 index c83780af..00000000 Binary files a/coffin/._common.py and /dev/null differ diff --git a/coffin/._interop.py b/coffin/._interop.py deleted file mode 100644 index 94121d1f..00000000 Binary files a/coffin/._interop.py and /dev/null differ diff --git a/coffin/__init__.py b/coffin/__init__.py deleted file mode 100644 index df89bdd6..00000000 --- a/coffin/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Coffin -~~~~~~ - -`Coffin ` is a package that resolves the -impedance mismatch between `Django ` and `Jinja2 -` through various adapters. The aim is to use Coffin -as a drop-in replacement for Django's template system to whatever extent is -reasonable. - -:copyright: 2008 by Christopher D. Leary -:license: BSD, see LICENSE for more details. -""" - - -__all__ = ('__version__', '__build__', '__docformat__', 'get_revision') -__version__ = (0, 3) -__docformat__ = 'restructuredtext en' - -import os - -def _get_git_revision(path): - revision_file = os.path.join(path, 'refs', 'heads', 'master') - if not os.path.exists(revision_file): - return None - fh = open(revision_file, 'r') - try: - return fh.read() - finally: - fh.close() - -def get_revision(): - """ - :returns: Revision number of this branch/checkout, if available. None if - no revision number can be determined. - """ - package_dir = os.path.dirname(__file__) - checkout_dir = os.path.normpath(os.path.join(package_dir, '..')) - path = os.path.join(checkout_dir, '.git') - if os.path.exists(path): - return _get_git_revision(path) - return None - -__build__ = get_revision() diff --git a/coffin/common.py b/coffin/common.py deleted file mode 100644 index 2e381ff3..00000000 --- a/coffin/common.py +++ /dev/null @@ -1,148 +0,0 @@ -import os -import warnings - -from django import dispatch -from jinja2 import Environment, loaders - -__all__ = ('env', 'need_env') - -env = None - -_JINJA_I18N_EXTENSION_NAME = 'jinja2.ext.i18n' - -# TODO: This should be documented (as even I'm not sure where it's use-case is) -need_env = dispatch.Signal(providing_args=['arguments', 'loaders', - 'filters', 'extensions', - 'globals', 'tests']) - -class CoffinEnvironment(Environment): - def __init__(self, filters={}, globals={}, tests={}, loader=None, extensions=[], **kwargs): - if not loader: - loader = loaders.ChoiceLoader(self._get_loaders()) - all_ext = self._get_all_extensions() - - extensions.extend(all_ext['extensions']) - super(CoffinEnvironment, self).__init__(extensions=extensions, loader=loader, **kwargs) - self.filters.update(filters) - self.filters.update(all_ext['filters']) - self.globals.update(globals) - self.globals.update(all_ext['globals']) - self.tests.update(tests) - self.tests.update(all_ext['tests']) - - from coffin.template import Template as CoffinTemplate - self.template_class = CoffinTemplate - - def _get_loaders(self): - """Tries to translate each template loader given in the Django settings - (:mod:`django.settings`) to a similarly-behaving Jinja loader. - Warns if a similar loader cannot be found. - Allows for Jinja2 loader instances to be placed in the template loader - settings. - """ - loaders = [] - - from coffin.template.loaders import jinja_loader_from_django_loader - - from django.conf import settings - for loader in settings.TEMPLATE_LOADERS: - if isinstance(loader, basestring): - loader_obj = jinja_loader_from_django_loader(loader) - if loader_obj: - loaders.append(loader_obj) - else: - warnings.warn('Cannot translate loader: %s' % loader) - else: # It's assumed to be a Jinja2 loader instance. - loaders.append(loader) - return loaders - - - def _get_templatelibs(self): - """Return an iterable of template ``Library`` instances. - - Since we cannot support the {% load %} tag in Jinja, we have to - register all libraries globally. - """ - from django.conf import settings - from django.template import get_library, InvalidTemplateLibrary - - libs = [] - for a in settings.INSTALLED_APPS: - try: - path = __import__(a + '.templatetags', {}, {}, ['__file__']).__file__ - path = os.path.dirname(path) # we now have the templatetags/ directory - except ImportError: - pass - else: - for f in os.listdir(path): - if f == '__init__.py': - continue - if f.endswith('.py'): - try: - # TODO: will need updating when #6587 lands - libs.append(get_library( - "django.templatetags.%s" % os.path.splitext(f)[0])) - except InvalidTemplateLibrary: - pass - return libs - - def _get_all_extensions(self): - from django.conf import settings - from coffin.template import builtins - from django.core.urlresolvers import get_callable - - extensions, filters, globals, tests = [], {}, {}, {} - - # start with our builtins - for lib in builtins: - extensions.extend(getattr(lib, 'jinja2_extensions', [])) - filters.update(getattr(lib, 'jinja2_filters', {})) - globals.update(getattr(lib, 'jinja2_globals', {})) - tests.update(getattr(lib, 'jinja2_tests', {})) - - if settings.USE_I18N: - extensions.append(_JINJA_I18N_EXTENSION_NAME) - - # add the globally defined extension list - extensions.extend(list(getattr(settings, 'JINJA2_EXTENSIONS', []))) - - def from_setting(setting): - retval = {} - setting = getattr(settings, setting, {}) - if isinstance(setting, dict): - for key, value in setting.iteritems(): - retval[user] = callable(value) and value or get_callable(value) - else: - for value in setting: - value = callable(value) and value or get_callable(value) - retval[value.__name__] = value - return retval - - filters.update(from_setting('JINJA2_FILTERS')) - globals.update(from_setting('JINJA2_GLOBALS')) - tests.update(from_setting('JINJA2_TESTS')) - - # add extensions defined in application's templatetag libraries - for lib in self._get_templatelibs(): - extensions.extend(getattr(lib, 'jinja2_extensions', [])) - filters.update(getattr(lib, 'jinja2_filters', {})) - globals.update(getattr(lib, 'jinja2_globals', {})) - tests.update(getattr(lib, 'jinja2_tests', {})) - - return dict( - extensions=extensions, - filters=filters, - globals=globals, - tests=tests, - ) - -def get_env(): - """ - :return: A Jinja2 environment singleton. - """ - # need_env.send(sender=Environment, arguments=arguments, - # loaders=loaders_, extensions=extensions, - # filters=filters, tests=tests, globals=globals) - return CoffinEnvironment(autoescape=True) - -env = get_env() diff --git a/coffin/conf/.___init__.py b/coffin/conf/.___init__.py deleted file mode 100644 index c6b47018..00000000 Binary files a/coffin/conf/.___init__.py and /dev/null differ diff --git a/coffin/conf/__init__.py b/coffin/conf/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/conf/urls/__init__.py b/coffin/conf/urls/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/conf/urls/defaults.py b/coffin/conf/urls/defaults.py deleted file mode 100644 index 3049e2b9..00000000 --- a/coffin/conf/urls/defaults.py +++ /dev/null @@ -1,4 +0,0 @@ -from django.conf.urls.defaults import * - -handler404 = 'coffin.views.defaults.page_not_found' -handler500 = 'coffin.views.defaults.server_error' \ No newline at end of file diff --git a/coffin/contrib/__init__.py b/coffin/contrib/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/contrib/markup/__init__.py b/coffin/contrib/markup/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/contrib/markup/models.py b/coffin/contrib/markup/models.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/contrib/markup/templatetags/__init__.py b/coffin/contrib/markup/templatetags/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/contrib/markup/templatetags/markup.py b/coffin/contrib/markup/templatetags/markup.py deleted file mode 100644 index 0d6b92f9..00000000 --- a/coffin/contrib/markup/templatetags/markup.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Makes the template filters from the ``django.contrib.markup`` app -available to both the Jinja2 and Django engines. - -In other words, adding ``coffin.contrib.markup`` to your INSTALLED_APPS -setting will enable the markup filters not only through Coffin, but -also through the default Django template system. -""" - -from coffin.template import Library as CoffinLibrary -from django.contrib.markup.templatetags.markup import register - - -# Convert Django's Library into a Coffin Library object, which will -# make sure the filters are correctly ported to Jinja2. -register = CoffinLibrary.from_django(register) \ No newline at end of file diff --git a/coffin/contrib/syndication/__init__.py b/coffin/contrib/syndication/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/contrib/syndication/feeds.py b/coffin/contrib/syndication/feeds.py deleted file mode 100644 index f8f0701f..00000000 --- a/coffin/contrib/syndication/feeds.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.contrib.syndication.feeds import * # merge modules - -import sys -from django.contrib.syndication.feeds import Feed as DjangoFeed -from coffin.template import loader as coffin_loader - - -class Feed(DjangoFeed): - """A ``Feed`` implementation that renders it's title and - description templates using Jinja2. - - Unfortunately, Django's base ``Feed`` class is not very extensible - in this respect at all. For a real solution, we'd have to essentially - have to duplicate the whole class. So for now, we use this terrible - non-thread safe hack. - - Another, somewhat crazy option would be: - * Render the templates ourselves through Jinja2 (possible - introduce new attributes to avoid having to rewrite the - existing ones). - * Make the rendered result available to Django/the superclass by - using a custom template loader using a prefix, say - "feed:". The loader would simply - return the Jinja-rendered template (escaped), the Django template - mechanism would find no nodes and just pass the output through. - Possible even worse than this though. - """ - - def get_feed(self, *args, **kwargs): - parent_module = sys.modules[DjangoFeed.__module__] - old_loader = parent_module.loader - parent_module.loader = coffin_loader - try: - return super(Feed, self).get_feed(*args, **kwargs) - finally: - parent_module.loader = old_loader \ No newline at end of file diff --git a/coffin/interop.py b/coffin/interop.py deleted file mode 100644 index 54120004..00000000 --- a/coffin/interop.py +++ /dev/null @@ -1,120 +0,0 @@ -"""Compatibility functions between Jinja2 and Django. - -General notes: - - - The Django ``stringfilter`` decorator is supported, but should not be - used when writing filters specifically for Jinja: It will lose the - attributes attached to the filter function by Jinja's - ``environmentfilter`` and ``contextfilter`` decorators, when used - in the wrong order. - - Maybe coffin should provide a custom version of stringfilter. - - - While transparently converting filters between Django and Jinja works - for the most part, there is an issue with Django's - ``mark_for_escaping``, as Jinja does not support a similar mechanism. - Instead, for Jinja, we escape such strings immediately (whereas Django - defers it to the template engine). -""" - -import inspect -from django.utils.safestring import SafeUnicode, SafeData, EscapeData -from jinja2 import Markup, environmentfilter - - -__all__ = ( - 'DJANGO', 'JINJA2', - 'django_filter_to_jinja2', - 'jinja2_filter_to_django', - 'guess_filter_type',) - - -DJANGO = 'django' -JINJA2 = 'jinja2' - - -def django_filter_to_jinja2(filter_func): - """ - Note: Due to the way this function is used by - ``coffin.template.Library``, it needs to be able to handle native - Jinja2 filters and pass them through unmodified. This necessity - stems from the fact that it is not always possible to determine - the type of a filter. - - TODO: Django's "func.is_safe" is not yet handled - """ - def _convert(v): - if isinstance(v, SafeData): - return Markup(v) - if isinstance(v, EscapeData): - return Markup.escape(v) # not 100% equivalent, see mod docs - return v - def conversion_wrapper(*args, **kwargs): - result = filter_func(*args, **kwargs) - return _convert(result) - # Jinja2 supports a similar machanism to Django's - # ``needs_autoescape`` filters: environment filters. We can - # thus support Django filters that use it in Jinja2 with just - # a little bit of argument rewriting. - if hasattr(filter_func, 'needs_autoescape'): - @environmentfilter - def autoescape_wrapper(environment, *args, **kwargs): - kwargs['autoescape'] = environment.autoescape - return conversion_wrapper(*args, **kwargs) - return autoescape_wrapper - else: - return conversion_wrapper - - -def jinja2_filter_to_django(filter_func): - """ - Note: Due to the way this function is used by - ``coffin.template.Library``, it needs to be able to handle native - Django filters and pass them through unmodified. This necessity - stems from the fact that it is not always possible to determine - the type of a filter. - """ - if guess_filter_type(filter_func)[0] == DJANGO: - return filter_func - def _convert(v): - # TODO: for now, this is not even necessary: Markup strings have - # a custom replace() method that is immume to Django's escape() - # attempts. - #if isinstance(v, Markup): - # return SafeUnicode(v) # jinja is always unicode - # ... Jinja does not have a EscapeData equivalent - return v - def wrapped(value, *args, **kwargs): - result = filter_func(value, *args, **kwargs) - return _convert(result) - return wrapped - - -def guess_filter_type(filter_func): - """Returns a 2-tuple of (type, can_be_ported). - - ``type`` is one of DJANGO, JINJA2, or ``False`` if the type can - not be determined. - - ``can_be_ported`` is ``True`` if we believe the filter could be - ported to the other engine, respectively, or ``False`` if we know - it can't. - - TODO: May not yet use all possible clues, e.g. decorators like - ``stringfilter``. - TOOD: Needs tests. - """ - if hasattr(filter_func, 'contextfilter') or \ - hasattr(filter_func, 'environmentfilter'): - return JINJA2, False - - args = inspect.getargspec(filter_func) - if len(args[0]) - (len(args[3]) if args[3] else 0) > 2: - return JINJA2, False - - if hasattr(filter_func, 'needs_autoescape'): - return DJANGO, True - - # Looks like your run of the mill Python function, which are - # easily convertible in either direction. - return False, True \ No newline at end of file diff --git a/coffin/shortcuts/.___init__.py b/coffin/shortcuts/.___init__.py deleted file mode 100644 index c21832ed..00000000 Binary files a/coffin/shortcuts/.___init__.py and /dev/null differ diff --git a/coffin/shortcuts/__init__.py b/coffin/shortcuts/__init__.py deleted file mode 100644 index c882dfcd..00000000 --- a/coffin/shortcuts/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.http import HttpResponse - -# Merge with original namespace so user -# doesn't have to import twice. -from django.shortcuts import * - - -__all__ = ('render_to_string', 'render_to_response',) - - -# Is within ``template.loader`` as per Django specification - -# but I think it fits very well here. -from coffin.template.loader import render_to_string - - -def render_to_response(template_name, dictionary=None, context_instance=None, - mimetype=None): - """ - :param template_name: Filename of the template to get or a sequence of - filenames to try, in order. - :param dictionary: Rendering context for the template. - :returns: A response object with the evaluated template as a payload. - """ - rendered = render_to_string(template_name, dictionary, context_instance) - return HttpResponse(rendered, mimetype=mimetype) diff --git a/coffin/template/.___init__.py b/coffin/template/.___init__.py deleted file mode 100644 index 87947898..00000000 Binary files a/coffin/template/.___init__.py and /dev/null differ diff --git a/coffin/template/._defaultfilters.py b/coffin/template/._defaultfilters.py deleted file mode 100644 index 8fd7d746..00000000 Binary files a/coffin/template/._defaultfilters.py and /dev/null differ diff --git a/coffin/template/._defaulttags.py b/coffin/template/._defaulttags.py deleted file mode 100644 index db9dcec7..00000000 Binary files a/coffin/template/._defaulttags.py and /dev/null differ diff --git a/coffin/template/._library.py b/coffin/template/._library.py deleted file mode 100644 index 18fe8260..00000000 Binary files a/coffin/template/._library.py and /dev/null differ diff --git a/coffin/template/._loader.py b/coffin/template/._loader.py deleted file mode 100644 index 3b699201..00000000 Binary files a/coffin/template/._loader.py and /dev/null differ diff --git a/coffin/template/._loaders.py b/coffin/template/._loaders.py deleted file mode 100644 index e17a06d5..00000000 Binary files a/coffin/template/._loaders.py and /dev/null differ diff --git a/coffin/template/__init__.py b/coffin/template/__init__.py deleted file mode 100644 index b487c8f5..00000000 --- a/coffin/template/__init__.py +++ /dev/null @@ -1,93 +0,0 @@ -from django.template import ( - Context as DjangoContext, - add_to_builtins as django_add_to_builtins, - get_library) -from jinja2 import Template as _Jinja2Template - -# Merge with ``django.template``. -from django.template import __all__ -from django.template import * - -# Override default library class with ours -from library import * - - -class Template(_Jinja2Template): - """Fixes the incompabilites between Jinja2's template class and - Django's. - - The end result should be a class that renders Jinja2 templates but - is compatible with the interface specfied by Django. - - This includes flattening a ``Context`` instance passed to render - and making sure that this class will automatically use the global - coffin environment. - """ - - def __new__(cls, template_string, origin=None, name=None): - # We accept the "origin" and "name" arguments, but discard them - # right away - Jinja's Template class (apparently) stores no - # equivalent information. - from coffin.common import env - - return env.from_string(template_string, template_class=cls) - - def __iter__(self): - # TODO: Django allows iterating over the templates nodes. Should - # be parse ourself and iterate over the AST? - raise NotImplementedError() - - def render(self, context=None): - """Differs from Django's own render() slightly in that makes the - ``context`` parameter optional. We try to strike a middle ground - here between implementing Django's interface while still supporting - Jinja's own call syntax as well. - """ - if context is None: - context = {} - else: - context = dict_from_django_context(context) - assert isinstance(context, dict) # Required for **-operator. - return super(Template, self).render(**context) - - -def dict_from_django_context(context): - """Flattens a Django :class:`django.template.context.Context` object. - """ - if not isinstance(context, DjangoContext): - return context - else: - dict_ = {} - # Newest dicts are up front, so update from oldest to newest. - for subcontext in reversed(list(context)): - dict_.update(dict_from_django_context(subcontext)) - return dict_ - - -# libraries to load by default for a new environment -builtins = [] - - -def add_to_builtins(module_name): - """Add the given module to both Coffin's list of default template - libraries as well as Django's. This makes sense, since Coffin - libs are compatible with Django libraries. - - You can still use Django's own ``add_to_builtins`` to register - directly with Django and bypass Coffin. - - TODO: Allow passing path to (or reference of) extensions and - filters directly. This would make it easier to use this function - with 3rd party Jinja extensions that do not know about Coffin and - thus will not provide a Library object. - - XXX/TODO: Why do we need our own custom list of builtins? Our - Library object is compatible, remember!? We can just add them - directly to Django's own list of builtins. - """ - builtins.append(get_library(module_name)) - django_add_to_builtins(module_name) - - -add_to_builtins('coffin.template.defaulttags') -add_to_builtins('coffin.template.defaultfilters') \ No newline at end of file diff --git a/coffin/template/defaultfilters.py b/coffin/template/defaultfilters.py deleted file mode 100644 index c566a7d2..00000000 --- a/coffin/template/defaultfilters.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Jinja2-ports of many of Django's default filters. - -TODO: Most of the filters in here need to be updated for autoescaping. -""" - -from coffin.template import Library -from jinja2.runtime import Undefined -# from jinja2 import Markup - -register = Library() - -@register.filter(jinja2_only=True) -def url(view_name, *args, **kwargs): - from coffin.template.defaulttags import url - return url._reverse(view_name, args, kwargs) - -@register.filter(jinja2_only=True) -def timesince(value, arg=None): - if value is None or isinstance(value, Undefined): - return u'' - from django.utils.timesince import timesince - if arg: - return timesince(value, arg) - return timesince(value) - -@register.filter(jinja2_only=True) -def timeuntil(value, arg=None): - if value is None or isinstance(value, Undefined): - return u'' - from django.utils.timesince import timeuntil - return timeuntil(date, arg) - -@register.filter(jinja2_only=True) -def date(value, arg=None): - if value is None or isinstance(value, Undefined): - return u'' - from django.conf import settings - from django.utils.dateformat import format - if arg is None: - arg = settings.DATE_FORMAT - return format(value, arg) - -@register.filter(jinja2_only=True) -def time(value, arg=None): - if value is None or isinstance(value, Undefined): - return u'' - from django.conf import settings - from django.utils.dateformat import time_format - if arg is None: - arg = settings.TIME_FORMAT - return time_format(value, arg) - -@register.filter(jinja2_only=True) -def truncatewords(value, length): - # Jinja2 has it's own ``truncate`` filter that supports word - # boundaries and more stuff, but cannot deal with HTML. - from django.utils.text import truncate_words - return truncate_words(value, int(length)) - -@register.filter(jinja2_only=True) -def truncatewords_html(value, length): - from django.utils.text import truncate_html_words - return truncate_html_words(value, int(length)) - -@register.filter(jinja2_only=True) -def pluralize(value, s1='s', s2=None): - """Like Django's pluralize-filter, but instead of using an optional - comma to separate singular and plural suffixes, it uses two distinct - parameters. - - It also is less forgiving if applied to values that do not allow - making a decision between singular and plural. - """ - if s2 is not None: - singular_suffix, plural_suffix = s1, s2 - else: - plural_suffix = s1 - singular_suffix = '' - - try: - if int(value) != 1: - return plural_suffix - except TypeError: # not a string or a number; maybe it's a list? - if len(value) != 1: - return plural_suffix - return singular_suffix - -@register.filter(jinja2_only=True) -def floatformat(value, arg=-1): - """Builds on top of Django's own version, but adds strict error - checking, staying with the philosophy. - """ - from django.template.defaultfilters import floatformat - from coffin.interop import django_filter_to_jinja2 - arg = int(arg) # raise exception - result = django_filter_to_jinja2(floatformat)(value, arg) - if result == '': # django couldn't handle the value - raise ValueError(value) - return result \ No newline at end of file diff --git a/coffin/template/defaulttags.py b/coffin/template/defaulttags.py deleted file mode 100644 index b9994257..00000000 --- a/coffin/template/defaulttags.py +++ /dev/null @@ -1,364 +0,0 @@ -from jinja2 import nodes -from jinja2.ext import Extension -from jinja2.exceptions import TemplateSyntaxError -from django.conf import settings -from coffin.template import Library - - -class LoadExtension(Extension): - """The load-tag is a no-op in Coffin. Instead, all template libraries - are always loaded. - - Note: Supporting a functioning load-tag in Jinja is tough, though - theoretically possible. The trouble is activating new extensions while - parsing is ongoing. The ``Parser.extensions`` dict of the current - parser instance needs to be modified, but apparently the only way to - get access would be by hacking the stack. - """ - - tags = set(['load']) - - def parse(self, parser): - while not parser.stream.current.type == 'block_end': - parser.stream.next() - return [] - - -"""class AutoescapeExtension(Extension): - ""#" - Template to output works in three phases in Jinja2: parsing, - generation (compilation, AST-traversal), and rendering (execution). - - Unfortunatly, the environment ``autoescape`` option comes into effect - during traversal, the part where we happen to have basically no control - over as an extension. It determines whether output is wrapped in - ``escape()`` calls. - - Solutions that could possibly work: - - * This extension could preprocess it's childnodes and wrap - everything output related inside the appropriate - ``Markup()`` or escape() call. - - * We could use the ``preprocess`` hook to insert the - appropriate ``|safe`` and ``|escape`` filters on a - string-basis. This is very unlikely to work well. - - There's also the issue of inheritance and just generally the nesting - of autoescape-tags to consider. - - Other things of note: - - * We can access ``parser.environment``, but that would only - affect the **parsing** of our child nodes. - - * In the commented-out code below we are trying to affect the - autoescape setting during rendering. As noted, this could be - necessary for rare border cases where custom extension use - the autoescape attribute. - - Both the above things would break Environment thread-safety though! - - Overall, it's not looking to good for this extension. - ""#" - - tags = ['autoescape'] - - def parse(self, parser): - lineno = parser.stream.next().lineno - - old_autoescape = parser.environment.autoescape - parser.environment.autoescape = True - try: - body = parser.parse_statements( - ['name:endautoescape'], drop_needle=True) - finally: - parser.environment.autoescape = old_autoescape - - # Not sure yet if the code below is necessary - it changes - # environment.autoescape during template rendering. If for example - # a CallBlock function accesses ``environment.autoescape``, it - # presumably is. - # This also should use try-finally though, which Jinja's API - # doesn't support either. We could fake that as well by using - # InternalNames that output the necessary indentation and keywords, - # but at this point it starts to get really messy. - # - # TODO: Actually, there's ``nodes.EnvironmentAttribute``. - #ae_setting = object.__new__(nodes.InternalName) - #nodes.Node.__init__(ae_setting, 'environment.autoescape', lineno=lineno) - #temp = parser.free_identifier() - #body.insert(0, nodes.Assign(temp, ae_setting)) - #body.insert(1, nodes.Assign(ae_setting, nodes.Const(True))) - #body.insert(len(body), nodes.Assign(ae_setting, temp)) - return body -""" - - -class URLExtension(Extension): - """Returns an absolute URL matching given view with its parameters. - - This is a way to define links that aren't tied to a particular URL - configuration:: - - {% url path.to.some_view arg1,arg2,name1=value1 %} - - Known differences to Django's url-Tag: - - - In Django, the view name may contain any non-space character. - Since Jinja's lexer does not identify whitespace to us, only - characters that make up valid identifers, plus dots and hyphens - are allowed. Note that identifers in Jinja 2 may not contain - non-ascii characters. - - As an alternative, you may specifify the view as a string, - which bypasses all these restrictions. It further allows you - to apply filters: - - {% url "меткаda.some-view"|afilter %} - """ - - tags = set(['url']) - - def parse(self, parser): - stream = parser.stream - - tag = stream.next() - - # get view name - if stream.current.test('string'): - viewname = parser.parse_primary() - else: - # parse valid tokens and manually build a string from them - bits = [] - name_allowed = True - while True: - if stream.current.test_any('dot', 'sub'): - bits.append(stream.next()) - name_allowed = True - elif stream.current.test('name') and name_allowed: - bits.append(stream.next()) - name_allowed = False - else: - break - viewname = nodes.Const("".join([b.value for b in bits])) - if not bits: - raise TemplateSyntaxError("'%s' requires path to view" % - tag.value, tag.lineno) - - # get arguments - args = [] - kwargs = [] - while not stream.current.test_any('block_end', 'name:as'): - if args or kwargs: - stream.expect('comma') - if stream.current.test('name') and stream.look().test('assign'): - key = nodes.Const(stream.next().value) - stream.skip() - value = parser.parse_expression() - kwargs.append(nodes.Pair(key, value, lineno=key.lineno)) - else: - args.append(parser.parse_expression()) - - make_call_node = lambda *kw: \ - self.call_method('_reverse', - args=[viewname, nodes.List(args), nodes.Dict(kwargs)], - kwargs=kw) - - # if an as-clause is specified, write the result to context... - if stream.next_if('name:as'): - var = nodes.Name(stream.expect('name').value, 'store') - call_node = make_call_node(nodes.Keyword('fail', nodes.Const(False))) - return nodes.Assign(var, call_node) - # ...otherwise print it out. - else: - return nodes.Output([make_call_node()]).set_lineno(tag.lineno) - - @classmethod - def _reverse(self, viewname, args, kwargs, fail=True): - from django.core.urlresolvers import reverse, NoReverseMatch - - # Try to look up the URL twice: once given the view name, - # and again relative to what we guess is the "main" app. - url = '' - try: - url = reverse(viewname, args=args, kwargs=kwargs) - except NoReverseMatch: - projectname = settings.SETTINGS_MODULE.split('.')[0] - try: - url = reverse(projectname + '.' + viewname, - args=args, kwargs=kwargs) - except NoReverseMatch: - if fail: - raise - else: - return '' - - return url - - -class WithExtension(Extension): - """Adds a value to the context (inside this block) for caching and - easy access, just like the Django-version does. - - For example:: - - {% with person.some_sql_method as total %} - {{ total }} object{{ total|pluralize }} - {% endwith %} - - TODO: The new Scope node introduced in Jinja2 6334c1eade73 (the 2.2 - dev version) would help here, but we don't want to rely on that yet. - See also: - http://dev.pocoo.org/projects/jinja/browser/tests/test_ext.py - http://dev.pocoo.org/projects/jinja/ticket/331 - http://dev.pocoo.org/projects/jinja/ticket/329 - """ - - tags = set(['with']) - - def parse(self, parser): - lineno = parser.stream.next().lineno - - value = parser.parse_expression() - parser.stream.expect('name:as') - name = parser.stream.expect('name') - - body = parser.parse_statements(['name:endwith'], drop_needle=True) - return nodes.CallBlock( - self.call_method('_render_block', args=[value]), - [nodes.Name(name.value, 'store')], [], body).\ - set_lineno(lineno) - - def _render_block(self, value, caller=None): - return caller(value) - - -class CacheExtension(Extension): - """Exactly like Django's own tag, but supports full Jinja2 - expressiveness for all arguments. - - {% cache gettimeout()*2 "foo"+options.cachename %} - ... - {% endcache %} - - This actually means that there is a considerable incompatibility - to Django: In Django, the second argument is simply a name, but - interpreted as a literal string. This tag, with Jinja2 stronger - emphasis on consistent syntax, requires you to actually specify the - quotes around the name to make it a string. Otherwise, allowing - Jinja2 expressions would be very hard to impossible (one could use - a lookahead to see if the name is followed by an operator, and - evaluate it as an expression if so, or read it as a string if not. - TODO: This may not be the right choice. Supporting expressions - here is probably not very important, so compatibility should maybe - prevail. Unfortunately, it is actually pretty hard to be compatibly - in all cases, simply because Django's per-character parser will - just eat everything until the next whitespace and consider it part - of the fragment name, while we have to work token-based: ``x*2`` - would actually be considered ``"x*2"`` in Django, while Jinja2 - would give us three tokens: ``x``, ``*``, ``2``. - - General Syntax: - - {% cache [expire_time] [fragment_name] [var1] [var2] .. %} - .. some expensive processing .. - {% endcache %} - - Available by default (does not need to be loaded). - - Partly based on the ``FragmentCacheExtension`` from the Jinja2 docs. - - TODO: Should there be scoping issues with the internal dummy macro - limited access to certain outer variables in some cases, there is a - different way to write this. Generated code would look like this: - - internal_name = environment.extensions['..']._get_cache_value(): - if internal_name is not None: - yield internal_name - else: - internal_name = "" # or maybe use [] and append() for performance - internalname += "..." - internalname += "..." - internalname += "..." - environment.extensions['..']._set_cache_value(internalname): - yield internalname - - In other words, instead of using a CallBlock which uses a local - function and calls into python, we have to separate calls into - python, but put the if-else logic itself into the compiled template. - """ - - tags = set(['cache']) - - def parse(self, parser): - lineno = parser.stream.next().lineno - - expire_time = parser.parse_expression() - fragment_name = parser.parse_expression() - vary_on = [] - while not parser.stream.current.test('block_end'): - vary_on.append(parser.parse_expression()) - - body = parser.parse_statements(['name:endcache'], drop_needle=True) - - return nodes.CallBlock( - self.call_method('_cache_support', - [expire_time, fragment_name, - nodes.List(vary_on), nodes.Const(lineno)]), - [], [], body).set_lineno(lineno) - - def _cache_support(self, expire_time, fragm_name, vary_on, lineno, caller): - from django.core.cache import cache # delay depending in settings - from django.utils.http import urlquote - - try: - expire_time = int(expire_time) - except (ValueError, TypeError): - raise TemplateSyntaxError('"%s" tag got a non-integer ' - 'timeout value: %r' % (list(self.tags)[0], expire_time), lineno) - - cache_key = u':'.join([fragm_name] + [urlquote(v) for v in vary_on]) - value = cache.get(cache_key) - if value is None: - value = caller() - cache.set(cache_key, value, expire_time) - return value - - -class SpacelessExtension(Extension): - """Removes whitespace between HTML tags, including tab and - newline characters. - - Works exactly like Django's own tag. - """ - - tags = ['spaceless'] - - def parse(self, parser): - lineno = parser.stream.next().lineno - body = parser.parse_statements(['name:endspaceless'], drop_needle=True) - return nodes.CallBlock( - self.call_method('_strip_spaces', [], [], None, None), - [], [], body - ).set_lineno(lineno) - - def _strip_spaces(self, caller=None): - from django.utils.html import strip_spaces_between_tags - return strip_spaces_between_tags(caller().strip()) - - -# nicer import names -load = LoadExtension -url = URLExtension -with_ = WithExtension -cache = CacheExtension -spaceless = SpacelessExtension - - -register = Library() -register.tag(load) -register.tag(url) -register.tag(with_) -register.tag(cache) -register.tag(spaceless) \ No newline at end of file diff --git a/coffin/template/library.py b/coffin/template/library.py deleted file mode 100644 index 8e80edc5..00000000 --- a/coffin/template/library.py +++ /dev/null @@ -1,215 +0,0 @@ -from django.template import Library as DjangoLibrary, InvalidTemplateLibrary -from jinja2.ext import Extension as Jinja2Extension -from coffin.interop import ( - DJANGO, JINJA2, - guess_filter_type, jinja2_filter_to_django, django_filter_to_jinja2) - - -__all__ = ['Library'] - - -class Library(DjangoLibrary): - """Version of the Django ``Library`` class that can handle both - Django template engine tags and filters, as well as Jinja2 - extensions and filters. - - Tries to present a common registration interface to the extension - author, but provides both template engines with only those - components they can support. - - Since custom Django tags and Jinja2 extensions are two completely - different beasts, they are handled completely separately. You can - register custom Django tags as usual, for example: - - register.tag('current_time', do_current_time) - - Or register a Jinja2 extension like this: - - register.tag(CurrentTimeNode) - - Filters, on the other hand, work similarily in both engines, and - for the most one can't tell whether a filter function was written - for Django or Jinja2. A compatibility layer is used to make to - make the filters you register usuable with both engines: - - register.filter('cut', cut) - - However, some of the more powerful filters just won't work in - Django, for example if more than one argument is required, or if - context- or environmentfilters are used. If ``cut`` in the above - example where such an extended filter, it would only be registered - with Jinja. - - See also the module documentation for ``coffin.interop`` for - information on some of the limitations of this conversion. - - TODO: Jinja versions of the ``simple_tag`` and ``inclusion_tag`` - helpers would be nice, though since custom tags are not needed as - often in Jinja, this is not urgent. - """ - - def __init__(self): - super(Library, self).__init__() - self.jinja2_filters = {} - self.jinja2_extensions = [] - self.jinja2_globals = {} - self.jinja2_tests = {} - - @classmethod - def from_django(cls, django_library): - """Create a Coffin library object from a Django library. - - Specifically, this ensures that filters already registered - with the Django library are also made available to Jinja, - where applicable. - """ - from copy import copy - result = cls() - result.filters = copy(django_library.filters) - result.tags = copy(django_library.tags) - for name, func in result.filters.iteritems(): - result._register_filter(name, func, jinja2_only=True) - return result - - def test(self, name=None, func=None): - def inner(f): - name = getattr(f, "_decorated_function", f).__name__ - self.jinja2_tests[name] = f - return f - if name == None and func == None: - # @register.test() - return inner - elif func == None: - if (callable(name)): - # register.test() - return inner(name) - else: - # @register.test('somename') or @register.test(name='somename') - def dec(func): - return self.test(name, func) - return dec - elif name != None and func != None: - # register.filter('somename', somefunc) - self.jinja2_tests[name] = func - return func - else: - raise InvalidTemplateLibrary("Unsupported arguments to " - "Library.test: (%r, %r)", (name, func)) - - def object(self, name=None, func=None): - def inner(f): - name = getattr(f, "_decorated_function", f).__name__ - self.jinja2_globals[name] = f - return f - if name == None and func == None: - # @register.object() - return inner - elif func == None: - if (callable(name)): - # register.object() - return inner(name) - else: - # @register.object('somename') or @register.object(name='somename') - def dec(func): - return self.object(name, func) - return dec - elif name != None and func != None: - # register.object('somename', somefunc) - self.jinja2_globals[name] = func - return func - else: - raise InvalidTemplateLibrary("Unsupported arguments to " - "Library.object: (%r, %r)", (name, func)) - - def tag(self, name_or_node=None, compile_function=None): - """Register a Django template tag (1) or Jinja 2 extension (2). - - For (1), supports the same invocation syntax as the original - Django version, including use as a decorator. - - For (2), since Jinja 2 extensions are classes (which can't be - decorated), and have the tag name effectively built in, only the - following syntax is supported: - - register.tag(MyJinjaExtensionNode) - """ - if isinstance(name_or_node, Jinja2Extension): - if compile_function: - raise InvalidTemplateLibrary('"compile_function" argument not supported for Jinja2 extensions') - self.jinja2_extensions.append(name_or_node) - return name_or_node - else: - return super(Library, self).tag(name_or_node, compile_function) - - def tag_function(self, func_or_node): - if issubclass(func_or_node, Jinja2Extension): - self.jinja2_extensions.append(func_or_node) - return func_or_node - else: - return super(Library, self).tag_function(func_or_node) - - def filter(self, name=None, filter_func=None, jinja2_only=False): - """Register a filter with both the Django and Jinja2 template - engines, if possible - or only Jinja2, if ``jinja2_only`` is - specified. ``jinja2_only`` does not affect conversion of the - filter if neccessary. - - Implements a compatibility layer to handle the different - auto-escaping approaches transparently. Extended Jinja2 filter - features like environment- and contextfilters are however not - supported in Django. Such filters will only be registered with - Jinja. - - Supports the same invocation syntax as the original Django - version, including use as a decorator. - - If the function is supposed to return the registered filter - (by example of the superclass implementation), but has - registered multiple filters, a tuple of all filters is - returned. - """ - def filter_function(f): - return self._register_filter( - getattr(f, "_decorated_function", f).__name__, - f, jinja2_only=jinja2_only) - if name == None and filter_func == None: - # @register.filter() - return filter_function - elif filter_func == None: - if (callable(name)): - # @register.filter - return filter_function(name) - else: - # @register.filter('somename') or @register.filter(name='somename') - def dec(func): - return self.filter(name, func, jinja2_only=jinja2_only) - return dec - elif name != None and filter_func != None: - # register.filter('somename', somefunc) - return self._register_filter(name, filter_func, - jinja2_only=jinja2_only) - else: - raise InvalidTemplateLibrary("Unsupported arguments to " - "Library.filter: (%r, %r)", (name, filter_func)) - - def _register_filter(self, name, func, jinja2_only=None): - filter_type, can_be_ported = guess_filter_type(func) - if filter_type == JINJA2 and not can_be_ported: - self.jinja2_filters[name] = func - return func - elif filter_type == DJANGO and not can_be_ported: - if jinja2_only: - raise ValueError('This filter cannot be ported to Jinja2.') - self.filters[name] = func - return func - elif jinja2_only: - func = django_filter_to_jinja2(func) - self.jinja2_filters[name] = func - return func - else: - # register the filter with both engines - django_func = jinja2_filter_to_django(func) - jinja2_func = django_filter_to_jinja2(func) - self.filters[name] = django_func - self.jinja2_filters[name] = jinja2_func - return (django_func, jinja2_func) diff --git a/coffin/template/loader.py b/coffin/template/loader.py deleted file mode 100644 index 1f2bbb1f..00000000 --- a/coffin/template/loader.py +++ /dev/null @@ -1,66 +0,0 @@ -"""Replacement for ``django.template.loader`` that uses Jinja 2. - -The module provides a generic way to load templates from an arbitrary -backend storage (e.g. filesystem, database). -""" - -from coffin.template import Template as CoffinTemplate -from jinja2 import TemplateNotFound - - -def find_template_source(name, dirs=None): - # This is Django's most basic loading function through which - # all template retrievals go. Not sure if Jinja 2 publishes - # an equivalent, but no matter, it mostly for internal use - # anyway - developers will want to start with - # ``get_template()`` or ``get_template_from_string`` anyway. - raise NotImplementedError() - - -def get_template(template_name): - # Jinja will handle this for us, and env also initializes - # the loader backends the first time it is called. - from coffin.common import env - return env.get_template(template_name) - - -def get_template_from_string(source): - """ - Does not support then ``name`` and ``origin`` parameters from - the Django version. - """ - from coffin.common import env - return env.from_string(source) - - -def render_to_string(template_name, dictionary=None, context_instance=None): - """Loads the given ``template_name`` and renders it with the given - dictionary as context. The ``template_name`` may be a string to load - a single template using ``get_template``, or it may be a tuple to use - ``select_template`` to find one of the templates in the list. - - ``dictionary`` may also be Django ``Context`` object. - - Returns a string. - """ - dictionary = dictionary or {} - if isinstance(template_name, (list, tuple)): - template = select_template(template_name) - else: - template = get_template(template_name) - if context_instance: - context_instance.update(dictionary) - else: - context_instance = dictionary - return template.render(context_instance) - - -def select_template(template_name_list): - "Given a list of template names, returns the first that can be loaded." - for template_name in template_name_list: - try: - return get_template(template_name) - except TemplateNotFound: - continue - # If we get here, none of the templates could be loaded - raise TemplateNotFound(', '.join(template_name_list)) diff --git a/coffin/template/loaders.py b/coffin/template/loaders.py deleted file mode 100644 index cb42fd5d..00000000 --- a/coffin/template/loaders.py +++ /dev/null @@ -1,38 +0,0 @@ -from jinja2 import loaders - - -def jinja_loader_from_django_loader(django_loader): - """Attempts to make a conversion from the given Django loader to an - similarly-behaving Jinja loader. - - :param django_loader: Django loader module string. - :return: The similarly-behaving Jinja loader, or None if a similar loader - could not be found. - """ - for substr, func in _JINJA_LOADER_BY_DJANGO_SUBSTR.iteritems(): - if substr in django_loader: - return func() - return None - - -def _make_jinja_app_loader(): - """Makes an 'app loader' for Jinja which acts like - :mod:`django.template.loaders.app_directories`. - """ - from django.template.loaders.app_directories import app_template_dirs - return loaders.FileSystemLoader(app_template_dirs) - - -def _make_jinja_filesystem_loader(): - """Makes a 'filesystem loader' for Jinja which acts like - :mod:`django.template.loaders.filesystem`. - """ - from django.conf import settings - return loaders.FileSystemLoader(settings.TEMPLATE_DIRS) - - -# Determine loaders from Django's conf. -_JINJA_LOADER_BY_DJANGO_SUBSTR = { # {substr: callable, ...} - 'app_directories': _make_jinja_app_loader, - 'filesystem': _make_jinja_filesystem_loader, -} diff --git a/coffin/views/__init__.py b/coffin/views/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/coffin/views/defaults.py b/coffin/views/defaults.py deleted file mode 100644 index 4386a49b..00000000 --- a/coffin/views/defaults.py +++ /dev/null @@ -1,35 +0,0 @@ -from django import http -from django.template import Context, RequestContext -from coffin.template.loader import render_to_string - - -__all__ = ('page_not_found', 'server_error', 'shortcut') - - -# no Jinja version for this needed -from django.views.defaults import shortcut - - -def page_not_found(request, template_name='404.html'): - """ - Default 404 handler. - - Templates: `404.html` - Context: - request_path - The path of the requested URL (e.g., '/app/pages/bad_page/') - """ - content = render_to_string(template_name, - RequestContext(request, {'request_path': request.path})) - return http.HttpResponseNotFound(content) - - -def server_error(request, template_name='500.html'): - """ - 500 error handler. - - Templates: `500.html` - Context: None - """ - content = render_to_string(template_name, Context({})) - return http.HttpResponseServerError(content) diff --git a/coffin/views/generic/._simple.py b/coffin/views/generic/._simple.py deleted file mode 100644 index a1bb18de..00000000 Binary files a/coffin/views/generic/._simple.py and /dev/null differ diff --git a/coffin/views/generic/__init__.py b/coffin/views/generic/__init__.py deleted file mode 100644 index 7ea80e4c..00000000 --- a/coffin/views/generic/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from django.views.generic import * diff --git a/coffin/views/generic/simple.py b/coffin/views/generic/simple.py deleted file mode 100644 index ff7678b2..00000000 --- a/coffin/views/generic/simple.py +++ /dev/null @@ -1,6 +0,0 @@ -import inspect - -from django.views.generic.simple import * -from coffin.template import loader, RequestContext - -exec inspect.getsource(direct_to_template) diff --git a/setup.py b/setup.py index 50c72ddb..f1ab7da0 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,8 @@ import sys install_requires = [ 'django==1.1.2', + 'Jinja2', + 'Coffin==0.3.0', 'South>=0.7.1', 'oauth2', 'recaptcha-client', -- cgit v1.2.3-1-g7c22