WARNING! All applications, which are not necessary (or at least making big sense to be enabled by default) moved to ADDITIONAL_APPS settings.
authorAlexander Solovyov <piranha@piranha.org.ua>
Thu Oct 16 23:34:22 2008 +0300 (8 days ago)
changeset 105499f39a118795
parent 10523552cd0d34cd
child 10559e96b58e0179
WARNING! All applications, which are not necessary (or at least making big sense to be enabled by default) moved to ADDITIONAL_APPS settings.

This is first step on introducing plugin-like applications. It is
backward compatibility breaking changeset and you should be careful
updating your blog.

Previous we've used [APP]_ENABLE settings, they are removed now (there is some
[something]_ENABLE settings, they have nothing common with enabling
applications). Now if you want to enable or disable something, you should add,
remove or comment application name in ADDITIONAL_APPS setting.

Some convenient defaults (list of all additional applications with some of them
commented out) are provided in local_settings.py.template.

There is also small object (lib.appcheck, available by "appcheck" name in
RequestContext) to simplify checking is application enabled or not.
apps/blog/models.py
apps/blog/tests.py
apps/context_processors.py
apps/lib/__init__.py
apps/livejournal/admin.py
settings.py
settings_local.py.template
templates/blog/post_detail.html
urls.py
       1 --- a/apps/blog/models.py	Thu Oct 16 22:33:49 2008 +0300
       2 +++ b/apps/blog/models.py	Thu Oct 16 23:34:22 2008 +0300
       3 @@ -7,6 +7,7 @@
       4  from django.utils.html import strip_tags
       5  from django.contrib.contenttypes import generic
       6  
       7 +from lib import appcheck
       8  from lib.helpers import reverse
       9  from render import render, RENDER_METHODS
      10  from blog.managers import PostManager, PublicPostManager, FeaturedPostManager
      11 @@ -99,19 +100,20 @@
      12      return Post.objects.filter(date__range=r).get(slug=slug)
      13  
      14  ping_details = {'post_detail': pingback_blog_handler}
      15 -
      16  xmlrpc.dispatcher.register_function(create_ping_func(**ping_details), 'pingback.ping')
      17  
      18 -if settings.ENABLE_PINGBACK:
      19 -    ping_links = ping_external_links(content_attr='html', url_attr='get_absolute_url',
      20 -                                     filtr=lambda x: not x.is_draft)
      21 +
      22 +ping_links = ping_external_links(content_attr='html', url_attr='get_absolute_url',
      23 +                                 filtr=lambda x: not x.is_draft)
      24 +ping_dirs = ping_directories(content_attr='html', url_attr='get_absolute_url',
      25 +                             filtr=lambda x: not x.is_draft)
      26 +
      27 +if appcheck.pingback:
      28      models.signals.post_save.connect(ping_links, sender=Post)
      29 -if settings.ENABLE_DIRECTORY_PING:
      30 -    ping_dirs = ping_directories(content_attr='html', url_attr='get_absolute_url',
      31 -                                 filtr=lambda x: not x.is_draft)
      32      models.signals.post_save.connect(ping_dirs, sender=Post)
      33  
      34 -if 'watchlist' in settings.INSTALLED_APPS:
      35 +
      36 +if appcheck.watchlist:
      37      from watchlist.models import Subscription
      38      def subscribe_author(instance, created, **kwargs):
      39          if not created:
     1.1 --- a/apps/blog/tests.py	Thu Oct 16 22:33:49 2008 +0300
     1.2 +++ b/apps/blog/tests.py	Thu Oct 16 23:34:22 2008 +0300
     1.3 @@ -9,6 +9,8 @@
     1.4  from blog.models import Post
     1.5  from discussion.models import CommentNode
     1.6  from lib.helpers import reverse
     1.7 +from lib import appcheck
     1.8 +
     1.9  
    1.10  class PostTestCase(test.TestCase):
    1.11  
    1.12 @@ -61,8 +63,13 @@
    1.13          response = self.client.post(self.p1.get_absolute_url(),
    1.14                                      {'body': 'completely useless', 'name': 'somethingright',
    1.15                                       'email': '[email protected]', 'subscribe': True})
    1.16 -        # Expect a registrations and notification email to be sent
    1.17 -        self.assertEquals(len(mail.outbox), 3)
    1.18 +        if not appcheck.watchlist:
    1.19 +            # Expect a registrations and notification email to be sent
    1.20 +            mailcount = 3
    1.21 +        else:
    1.22 +            # Additionally two notification for comment author
    1.23 +            mailcount = 5
    1.24 +        self.assertEquals(len(mail.outbox), mailcount)
    1.25  
    1.26      def testDeleteComments(self):
    1.27          c = CommentNode(approved=False, body="just test", user=self.user, object=self.p1)
     2.1 --- a/apps/context_processors.py	Thu Oct 16 22:33:49 2008 +0300
     2.2 +++ b/apps/context_processors.py	Thu Oct 16 23:34:22 2008 +0300
     2.3 @@ -4,11 +4,14 @@
     2.4  from django.contrib.sites.models import Site
     2.5  from blog.models import Post
     2.6  
     2.7 +from lib import appcheck
     2.8 +
     2.9  def settings_vars(request):
    2.10      return {
    2.11          'STATIC_URL': settings.STATIC_URL,
    2.12          'THEME_STATIC_URL': settings.THEME_STATIC_URL,
    2.13          'settings': settings,
    2.14 +        'appcheck': appcheck,
    2.15          }
    2.16  
    2.17  def featured_posts(request):
     3.1 --- a/apps/lib/__init__.py	Thu Oct 16 22:33:49 2008 +0300
     3.2 +++ b/apps/lib/__init__.py	Thu Oct 16 23:34:22 2008 +0300
     3.3 @@ -0,0 +1,8 @@
     3.4 +from django.conf import settings
     3.5 +
     3.6 +
     3.7 +class ApplicationChecker(object):
     3.8 +    "Checks if application is enabled"
     3.9 +    def __getattr__(self, attr):
    3.10 +        return attr in settings.INSTALLED_APPS
    3.11 +appcheck = ApplicationChecker()
     4.1 --- a/apps/livejournal/admin.py	Thu Oct 16 22:33:49 2008 +0300
     4.2 +++ b/apps/livejournal/admin.py	Thu Oct 16 23:34:22 2008 +0300
     4.3 @@ -4,7 +4,8 @@
     4.4  
     4.5  from livejournal.models import LiveJournalPost
     4.6  from livejournal.utils import lj_crosspost, lj_delete
     4.7 -
     4.8 +from blog.models import Post
     4.9 +from blog.admin import PostAdmin
    4.10  
    4.11  class LiveJournalPostAdmin(admin.ModelAdmin):
    4.12      list_display = ('post', 'need_crosspost')
    4.13 @@ -12,15 +13,14 @@
    4.14  admin.site.register(LiveJournalPost, LiveJournalPostAdmin)
    4.15  
    4.16  
    4.17 -if settings.ENABLE_LJ_CROSSPOST:
    4.18 -    from blog.models import Post
    4.19 -    from blog.admin import PostAdmin
    4.20 -    class LiveJournalPostInlineAdmin(admin.TabularInline):
    4.21 -        model = LiveJournalPost
    4.22 -        max_num = 1
    4.23 -    PostAdmin.list_display += ('lj_object', )
    4.24 -    pa = admin.site._registry[Post]
    4.25 -    pa.inline_instances.append(
    4.26 -        LiveJournalPostInlineAdmin(pa.model, pa.admin_site))
    4.27 -    models.signals.pre_save.connect(lj_crosspost, sender=LiveJournalPost)
    4.28 -    models.signals.pre_delete.connect(lj_delete, sender=LiveJournalPost)
    4.29 +class LiveJournalPostInlineAdmin(admin.TabularInline):
    4.30 +    model = LiveJournalPost
    4.31 +    max_num = 1
    4.32 +
    4.33 +PostAdmin.list_display += ('lj_object', )
    4.34 +
    4.35 +pa = admin.site._registry[Post]
    4.36 +pa.inline_instances.append(LiveJournalPostInlineAdmin(pa.model, pa.admin_site))
    4.37 +
    4.38 +models.signals.pre_save.connect(lj_crosspost, sender=LiveJournalPost)
    4.39 +models.signals.pre_delete.connect(lj_delete, sender=LiveJournalPost)
     5.1 --- a/settings.py	Thu Oct 16 22:33:49 2008 +0300
     5.2 +++ b/settings.py	Thu Oct 16 23:34:22 2008 +0300
     5.3 @@ -124,6 +124,8 @@
     5.4      os.path.join(PROJECT_ROOT, 'templates'),
     5.5  )
     5.6  
     5.7 +# Here are included application necessary for work
     5.8 +# All other should go to the ADDITIONAL_APPS
     5.9  INSTALLED_APPS = (
    5.10      'django.contrib.auth',
    5.11      'django.contrib.contenttypes',
    5.12 @@ -136,23 +138,14 @@
    5.13      'lib',
    5.14      'pytils',
    5.15      'accounts',
    5.16 +    'blog',
    5.17      'discussion',
    5.18 -    'blog',
    5.19 -    'pingback',
    5.20 -    'openidconsumer',
    5.21      'tagging',
    5.22      'typogrify',
    5.23 -    'livejournal',
    5.24      'render',
    5.25 -    'robots',
    5.26 -    'textblocks',
    5.27 -    'blogroll',
    5.28 +    'postimage',
    5.29 +    'openidconsumer',
    5.30      'openidserver',
    5.31 -    'recaptcha',
    5.32 -    'debug',
    5.33 -    'sape',
    5.34 -    'watchlist',
    5.35 -    'postimage',
    5.36  )
    5.37  
    5.38  APPEND_SLASH = False
    5.39 @@ -177,14 +170,11 @@
    5.40  OPENID_REDIRECT_NEXT = '/'
    5.41  
    5.42  # Pingback
    5.43 -ENABLE_PINGBACK = True
    5.44  PINGBACK_SERVER = {
    5.45      'post_detail': 'pingback.getters.post_get',
    5.46      }
    5.47  PINGBACK_RESPONSE_LENGTH = 200
    5.48  
    5.49 -# Blogs directory ping
    5.50 -ENABLE_DIRECTORY_PING = False
    5.51  # TODO: move this list to DB
    5.52  DIRECTORY_URLS = (
    5.53      'http://ping.blogs.yandex.ru/RPC2',
    5.54 @@ -239,14 +229,10 @@
    5.55      sys.stderr.write('Unable to read settings_local.py\n')
    5.56      sys.exit(1)
    5.57  
    5.58 -if ENABLE_IMPORT:
    5.59 -    INSTALLED_APPS += ('wpimport', )
    5.60 -
    5.61 -#if ENABLE_SAPE:
    5.62 -    #INSTALLED_APPS += ('sape', )
    5.63 -
    5.64 -if 'ADDITIONAL_APPS' in locals():
    5.65 -    INSTALLED_APPS = INSTALLED_APPS + locals()['ADDITIONAL_APPS']
    5.66 +try:
    5.67 +    INSTALLED_APPS += ADDITIONAL_APPS
    5.68 +except NameError:
    5.69 +    pass
    5.70  
    5.71  LOCALE_PATHS = (os.path.join(PROJECT_ROOT, 'locale'), )
    5.72  THEME_STATIC_URL = os.path.join(STATIC_URL, THEME + '/')
     6.1 --- a/settings_local.py.template	Thu Oct 16 22:33:49 2008 +0300
     6.2 +++ b/settings_local.py.template	Thu Oct 16 23:34:22 2008 +0300
     6.3 @@ -37,8 +37,6 @@
     6.4  RECAPTCHA_PUBLIC_KEY = ''
     6.5  RECAPTCHA_PRIVATE_KEY =''
     6.6  
     6.7 -ENABLE_SAPE = False # Set this to true to enable Sape.ru client
     6.8 -ENABLE_IMPORT = False # Set this to true to enable WordPress importer
     6.9  GA_ACC = '' # Google Analytics account
    6.10  LI_ACC = False # Set True if you want liveinternet.ru counter
    6.11  GRAVATAR_ENABLE = False # Enable gravatars?
    6.12 @@ -62,9 +60,21 @@
    6.13  ORM_DEBUG = False
    6.14  
    6.15  # Livejournal crossposting
    6.16 -ENABLE_LJ_CROSSPOST = False
    6.17  LJ_USERNAME = ''
    6.18  LJ_PASSWORD = ''
    6.19 +
    6.20 +ADDITIONAL_APPS = (
    6.21 +    'recaptcha',
    6.22 +    'pingback',
    6.23 +    'watchlist',   # comments subscription
    6.24 +    'blogroll',
    6.25 +    'robots',
    6.26 +#    'debug',       # debug sql query
    6.27 +#    'livejournal', # livejournal crossposting
    6.28 +#    'textblocks',
    6.29 +#    'wpimport',
    6.30 +#    'sape',        # sape.ru
    6.31 +    )
    6.32  
    6.33  # DEBUG must be False in production mode
    6.34  # Please read http://byteflow.su/wiki/DEBUG
     7.1 --- a/templates/blog/post_detail.html	Thu Oct 16 22:33:49 2008 +0300
     7.2 +++ b/templates/blog/post_detail.html	Thu Oct 16 23:34:22 2008 +0300
     7.3 @@ -18,7 +18,7 @@
     7.4  {% theme_js "ajaxforms" %}
     7.5  {% ifequal settings.CAPTCHA "recaptcha" %}<script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"></script>{% endifequal %}
     7.6  <link rel="alternate" type="application/rss+xml" title="{{ settings.BLOG_NAME }}: comments on {{ object.name }} feed" href="{% url feed feedurl %}" />
     7.7 -<link rel="pingback" href="http://{{ site.domain }}{% url xmlrpc %}" />
     7.8 +{% if appcheck.pingback %}<link rel="pingback" href="http://{{ site.domain }}{% url xmlrpc %}" />{% endif %}
     7.9  {% endblock %}
    7.10  
    7.11  {% block content %}
     8.1 --- a/urls.py	Thu Oct 16 22:33:49 2008 +0300
     8.2 +++ b/urls.py	Thu Oct 16 23:34:22 2008 +0300
     8.3 @@ -13,13 +13,13 @@
     8.4  from tagging.models import Tag
     8.5  import watchlist.mail
     8.6  import patches
     8.7 +from lib import appcheck
     8.8  
     8.9  def error500(request, template_name='500.html'):
    8.10      try:
    8.11          output = render_to_string(template_name, {}, RequestContext(request))
    8.12      except:
    8.13          output = "Critical error. Administrator was notified."
    8.14 -    #render_to_string(template_name, {}, Context())
    8.15      return HttpResponseServerError(output)
    8.16  
    8.17  handler500 = 'urls.error500'
    8.18 @@ -65,25 +65,16 @@
    8.19  if settings.DEBUG:
    8.20      urlpatterns += patterns(
    8.21          '',
    8.22 -        url(r'^media/(.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
    8.23 -        url(r'^static/(.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
    8.24 -        url(r'^admin-media/(.*)$', 'django.views.static.serve', {'document_root': join(dirname(admin.__file__), 'media')}),
    8.25 +        url(r'^media/(.*)$', 'django.views.static.serve',
    8.26 +            {'document_root': settings.MEDIA_ROOT}),
    8.27 +        url(r'^static/(.*)$', 'django.views.static.serve',
    8.28 +            {'document_root': settings.STATIC_ROOT}),
    8.29 +        url(r'^admin-media/(.*)$', 'django.views.static.serve',
    8.30 +            {'document_root': join(dirname(admin.__file__), 'media')}),
    8.31          )
    8.32  
    8.33 -if 'wpimport' in settings.INSTALLED_APPS:
    8.34 -    urlpatterns += patterns(
    8.35 -        '',
    8.36 -        url(r'^wpimport/', include('wpimport.urls')),
    8.37 -        )
    8.38 +if appcheck.wpimport:
    8.39 +    urlpatterns += patterns('', url(r'^wpimport/', include('wpimport.urls')),)
    8.40  
    8.41 -if 'wbimport' in settings.INSTALLED_APPS:
    8.42 -    urlpatterns += patterns(
    8.43 -        '',
    8.44 -        url(r'^wbimport/', include('wbimport.urls')),
    8.45 -        )
    8.46 -
    8.47 -if 'debug' in settings.INSTALLED_APPS:
    8.48 -    urlpatterns += patterns(
    8.49 -        '',
    8.50 -        url('', include('debug.urls')),
    8.51 -        )
    8.52 +if appcheck.debug:
    8.53 +    urlpatterns += patterns('', url('', include('debug.urls')),)