diff --git a/addons/aldryn-django/addon.json b/addons/aldryn-django/addon.json
index 74280fe..e5e0abe 100644
--- a/addons/aldryn-django/addon.json
+++ b/addons/aldryn-django/addon.json
@@ -1,3 +1,4 @@
{
+ "installed-apps": [],
"package-name": "aldryn-django"
-}
+}
\ No newline at end of file
diff --git a/addons/aldryn-django/aldryn_config.py b/addons/aldryn-django/aldryn_config.py
index 1a7fb8e..6304cc4 100644
--- a/addons/aldryn-django/aldryn_config.py
+++ b/addons/aldryn-django/aldryn_config.py
@@ -1,17 +1,98 @@
# -*- coding: utf-8 -*-
import json
+import os
import sys
from aldryn_client import forms
+SYSTEM_FIELD_WARNING = 'WARNING: this field is auto-written. Please do not change it here.'
+
+
+class CachedLoader(list):
+ """
+ A list subclass to be used for the template loaders option
+
+ This subclass exposes the same interface as a list and allows subsequent
+ code to alter the list of template loaders without knowing if it has been
+ wrapped by the `django.template.loaders.cached.Loader` loader.
+
+ `uncached_*` methods are available to allow cached-loader-aware code to
+ alter the main template loaders.
+ """
+ loader = 'django.template.loaders.cached.Loader'
+
+ def __init__(self, loaders):
+ self._cached_loaders = list(loaders)
+ super(CachedLoader, self).__init__([
+ (self.loader, self._cached_loaders),
+ ])
+
+ methods = ('append', 'extend', 'insert', 'remove',
+ 'pop', 'index', 'count')
+ for method in methods:
+ self.overwrite_method(method)
+
+ def overwrite_method(self, method):
+ uncached_method = 'uncached_{}'.format(method)
+ setattr(self, uncached_method, getattr(self, method))
+ setattr(self, method, getattr(self._cached_loaders, method))
+
class Form(forms.BaseForm):
- languages = forms.CharField('Languages', required=True, initial='["en", "de"]')
+ languages = forms.CharField(
+ 'Languages',
+ required=True,
+ initial='["en", "de"]',
+ help_text=SYSTEM_FIELD_WARNING,
+ )
+ use_manifeststaticfilesstorage = forms.CheckboxField(
+ 'Hash static file names',
+ required=False,
+ initial=False,
+ help_text=(
+ 'Use ManifestStaticFilesStorage to manage static files and set '
+ 'far-expiry headers. Enabling this option disables autosync for '
+ 'static files, and can cause deployment and/or 500 errors if a '
+ 'referenced file is missing. Please ensure that your test server '
+ 'works with this option enabled before deploying it to the live '
+ 'site.'
+ )
+ )
+ enable_gis = forms.CheckboxField(
+ 'Enable django.contrib.gis',
+ required=False,
+ initial=False,
+ help_text=(
+ 'Enable Geodjango (django.contrib.gis) related functionality.\n'
+ 'WARNING: Requires postgis (contact support to enable it for your '
+ 'project). For local development change "postgres:9.4" to '
+ '"mdillon/postgis:9.4" in docker-compose.yml and run '
+ '"aldryn project up" to re-create the db container.'
+ )
+ )
+ disable_default_language_prefix = forms.CheckboxField(
+ 'Remove URL language prefix for default language',
+ required=False,
+ initial=False,
+ help_text=(
+ 'For example, http://example.com/ rather than '
+ 'http://example.com/en/ if en (English) is the default language. '
+ 'If multiple languages are configured, this option will be ignored '
+ 'for Django versions prior to 1.10.'
+ )
+ )
+ session_timeout = forms.NumberField(
+ 'Timeout for users session, in seconds.',
+ required=False,
+ initial=(60 * 60 * 24 * 7 * 2),
+ help_text=(
+ 'By default it\'s two weeks (Django default).'
+ ),
+ )
def to_settings(self, data, settings):
- import os
+ import django_cache_url
import dj_database_url
import warnings
- import yurl
from functools import partial
from aldryn_addons.utils import boolean_ish, djsenv
env = partial(djsenv, settings=settings)
@@ -21,14 +102,21 @@ class Form(forms.BaseForm):
settings['DATA_ROOT'] = env('DATA_ROOT', os.path.join(settings['BASE_DIR'], 'data'))
settings['SECRET_KEY'] = env('SECRET_KEY', 'this-is-not-very-random')
settings['DEBUG'] = boolean_ish(env('DEBUG', False))
- settings['TEMPLATE_DEBUG'] = boolean_ish(env('TEMPLATE_DEBUG', settings['DEBUG']))
+ settings['ENABLE_SYNCING'] = boolean_ish(
+ env('ENABLE_SYNCING', settings['DEBUG']))
+ settings['DISABLE_TEMPLATE_CACHE'] = boolean_ish(
+ env('DISABLE_TEMPLATE_CACHE', settings['DEBUG']))
settings['DATABASE_URL'] = env('DATABASE_URL')
- if settings['DATABASE_URL']:
- pass
- elif env('DJANGO_MODE') == 'build':
+ settings['CACHE_URL'] = env('CACHE_URL')
+ if env('DJANGO_MODE') == 'build':
+ # In build mode we don't have any connected services like db or
+ # cache available. So we need to configure those things in a way
+ # they can run without real backends.
settings['DATABASE_URL'] = 'sqlite://:memory:'
- else:
+ settings['CACHE_URL'] = 'locmem://'
+
+ if not settings['DATABASE_URL']:
settings['DATABASE_URL'] = 'sqlite:///{}'.format(
os.path.join(settings['DATA_ROOT'], 'db.sqlite3')
)
@@ -40,27 +128,22 @@ class Form(forms.BaseForm):
)
settings['DATABASES']['default'] = dj_database_url.parse(settings['DATABASE_URL'])
+ if not settings['CACHE_URL']:
+ settings['CACHE_URL'] = 'locmem://'
+ warnings.warn(
+ 'no cache configured. Falling back to CACHE_URL={0}'.format(
+ settings['CACHE_URL']
+ ),
+ RuntimeWarning,
+ )
+ settings['CACHES']['default'] = django_cache_url.parse(settings['CACHE_URL'])
+
settings['ROOT_URLCONF'] = env('ROOT_URLCONF', 'urls')
settings['ADDON_URLS'].append('aldryn_django.urls')
settings['ADDON_URLS_I18N'].append('aldryn_django.i18n_urls')
settings['WSGI_APPLICATION'] = 'wsgi.application'
- settings['STATIC_URL'] = env('STATIC_URL', '/static/')
- settings['STATIC_URL_IS_ON_OTHER_DOMAIN'] = bool(yurl.URL(settings['STATIC_URL']).host)
- settings['STATIC_ROOT'] = env(
- 'STATIC_ROOT',
- os.path.join(settings['BASE_DIR'], 'static_collected'),
- )
- settings['STATICFILES_DIRS'] = env(
- 'STATICFILES_DIRS',
- [os.path.join(settings['BASE_DIR'], 'static'),]
- )
-
- settings['MEDIA_URL'] = env('MEDIA_URL', '/media/')
- settings['MEDIA_URL_IS_ON_OTHER_DOMAIN'] = bool(yurl.URL(settings['MEDIA_URL']).host)
- settings['MEDIA_ROOT'] = env('MEDIA_ROOT', os.path.join(settings['DATA_ROOT'], 'media'))
-
settings['INSTALLED_APPS'].extend([
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -71,80 +154,204 @@ class Form(forms.BaseForm):
'django.contrib.staticfiles',
'aldryn_django',
])
- if 'sqlite3' not in settings['DATABASES']['default']['ENGINE']:
- settings['INSTALLED_APPS'].append('south')
- settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([
- 'django.core.context_processors.request',
- 'aldryn_django.context_processors.debug',
- ])
- settings['MIDDLEWARE_CLASSES'].extend([
+ if settings['ENABLE_SYNCING'] or settings['DISABLE_TEMPLATE_CACHE']:
+ loader_list_class = list
+ else:
+ loader_list_class = CachedLoader
+
+ settings['TEMPLATES'] = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': env('TEMPLATE_DIRS', [os.path.join(settings['BASE_DIR'], 'templates')], ),
+ 'OPTIONS': {
+ 'debug': boolean_ish(env('TEMPLATE_DEBUG', settings['DEBUG'])),
+ 'context_processors': [
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ 'django.core.context_processors.i18n',
+ 'django.core.context_processors.debug',
+ 'django.core.context_processors.request',
+ 'django.core.context_processors.media',
+ 'django.core.context_processors.csrf',
+ 'django.core.context_processors.tz',
+ 'django.core.context_processors.static',
+ 'aldryn_django.context_processors.debug',
+ ],
+ 'loaders': loader_list_class([
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+ 'django.template.loaders.eggs.Loader',
+ ]),
+ },
+ },
+ ]
+
+ settings['MIDDLEWARE_CLASSES'] = [
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ # 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.locale.LocaleMiddleware',
- 'aldryn_django.middleware.CurrentSiteMiddleware',
- ])
+ 'django.contrib.sites.middleware.CurrentSiteMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ # 'django.middleware.security.SecurityMiddleware',
+ ]
+
+ if not env('DISABLE_GZIP'):
+ settings['MIDDLEWARE_CLASSES'].insert(
+ 0, 'django.middleware.gzip.GZipMiddleware')
- settings['TEMPLATE_DIRS'] = env(
- 'TEMPLATE_DIRS',
- [os.path.join(settings['BASE_DIR'], 'templates')],
- )
settings['SITE_ID'] = env('SITE_ID', 1)
+ settings['ADDON_URLS_I18N_LAST'] = 'aldryn_django.urls_redirect'
+
self.domain_settings(data, settings, env=env)
+ self.security_settings(data, settings, env=env)
self.server_settings(settings, env=env)
self.logging_settings(settings, env=env)
- self.cache_settings(settings, env=env)
- self.storage_settings(settings, env=env)
+ # Order matters, sentry settings rely on logging being configured.
+ self.sentry_settings(settings, env=env)
+ self.storage_settings_for_media(settings, env=env)
+ self.storage_settings_for_static(data, settings, env=env)
+ self.email_settings(data, settings, env=env)
self.i18n_settings(data, settings, env=env)
self.migration_settings(settings, env=env)
+ settings['ALDRYN_DJANGO_ENABLE_GIS'] = data['enable_gis']
+ if settings['ALDRYN_DJANGO_ENABLE_GIS']:
+ self.gis_settings(settings, env=env)
return settings
def domain_settings(self, data, settings, env):
+ from aldryn_addons.utils import boolean_ish
+
settings['ALLOWED_HOSTS'] = env('ALLOWED_HOSTS', ['localhost', '*'])
# will take a full config dict from ALDRYN_SITES_DOMAINS if available,
# otherwise fall back to constructing the dict from DOMAIN,
# DOMAIN_ALIASES and DOMAIN_REDIRECTS
- domains = env('ALDRYN_SITES_DOMAINS', {})
domain = env('DOMAIN')
if domain:
settings['DOMAIN'] = domain
- domain_aliases = env('DOMAIN_ALIASES', '')
- domain_redirects = env('DOMAIN_REDIRECTS', '')
+
+ domains = env('ALDRYN_SITES_DOMAINS', {})
+ permanent_redirect = boolean_ish(env('ALDRYN_SITES_REDIRECT_PERMANENT', False))
+
if not domains and domain:
+ domain_aliases = [
+ d.strip()
+ for d in env('DOMAIN_ALIASES', '').split(',')
+ if d.strip()
+ ]
+ domain_redirects = [
+ d.strip()
+ for d in env('DOMAIN_REDIRECTS', '').split(',')
+ if d.strip()
+ ]
domains = {
1: {
+ 'name': env('SITE_NAME', ''),
'domain': domain,
- 'aliases': [d.strip() for d in domain_aliases.split(',') if d.strip()],
- 'redirects': [d.strip() for d in domain_redirects.split(',') if d.strip()]
- }
+ 'aliases': domain_aliases,
+ 'redirects': domain_redirects,
+ },
}
settings['ALDRYN_SITES_DOMAINS'] = domains
- if domains and settings['SITE_ID'] in domains:
- settings['ALLOWED_HOSTS'].extend([
- domain for domain in domains[settings['SITE_ID']]['aliases']
- ] + [
- domain for domain in domains[settings['SITE_ID']]['redirects']
- ])
+ settings['ALDRYN_SITES_REDIRECT_PERMANENT'] = permanent_redirect
+ # This is ensured again by aldryn-sites, but we already do it here
+ # as we need the full list of domains later when configuring
+ # media/static serving, before aldryn-sites had a chance to run.
+ site_domains = domains.get(settings['SITE_ID'])
+ if site_domains:
+ settings['ALLOWED_HOSTS'].append(site_domains['domain'])
+ settings['ALLOWED_HOSTS'].extend(site_domains['aliases'])
+ settings['ALLOWED_HOSTS'].extend(site_domains['redirects'])
settings['INSTALLED_APPS'].append('aldryn_sites')
+
settings['MIDDLEWARE_CLASSES'].insert(
settings['MIDDLEWARE_CLASSES'].index('django.middleware.common.CommonMiddleware'),
'aldryn_sites.middleware.SiteMiddleware',
)
+ def security_settings(self, data, settings, env):
+ s = settings
+ s['SECURE_SSL_REDIRECT'] = env('SECURE_SSL_REDIRECT', None)
+ s['SECURE_REDIRECT_EXEMPT'] = env('SECURE_REDIRECT_EXEMPT', [])
+ s['SECURE_HSTS_SECONDS'] = env('SECURE_HSTS_SECONDS', 0)
+ # SESSION_COOKIE_SECURE is handled by
+ # django.contrib.sessions.middleware.SessionMiddleware
+ s['SESSION_COOKIE_SECURE'] = env('SESSION_COOKIE_SECURE', False)
+ s['SECURE_PROXY_SSL_HEADER'] = env(
+ 'SECURE_PROXY_SSL_HEADER',
+ ('HTTP_X_FORWARDED_PROTO', 'https')
+ )
+ s['SESSION_COOKIE_AGE'] = env('SESSION_COOKIE_AGE', data.get('session_timeout') or 60 * 60 * 24 * 7 * 2)
+
+ # SESSION_COOKIE_HTTPONLY and SECURE_FRAME_DENY must be False for CMS
+ # SESSION_COOKIE_HTTPONLY is handled by
+ # django.contrib.sessions.middleware.SessionMiddleware
+ s['SESSION_COOKIE_HTTPONLY'] = env('SESSION_COOKIE_HTTPONLY', False)
+
+ s['SECURE_CONTENT_TYPE_NOSNIFF'] = env('SECURE_CONTENT_TYPE_NOSNIFF', False)
+ s['SECURE_BROWSER_XSS_FILTER'] = env('SECURE_BROWSER_XSS_FILTER', False)
+
+ s['MIDDLEWARE_CLASSES'].insert(
+ s['MIDDLEWARE_CLASSES'].index('aldryn_sites.middleware.SiteMiddleware') + 1,
+ 'django.middleware.security.SecurityMiddleware',
+ )
+
+ # Add the debreach middlewares to counter CRIME/BREACH attacks.
+ # We always add it even if the GZipMiddleware is not enabled because
+ # we cannot assume that every upstream proxy implements a
+ # countermeasure itself.
+ s['RANDOM_COMMENT_EXCLUDED_VIEWS'] = set([])
+ if 'django.middleware.gzip.GZipMiddleware' in s['MIDDLEWARE_CLASSES']:
+ index = s['MIDDLEWARE_CLASSES'].index('django.middleware.gzip.GZipMiddleware') + 1
+ else:
+ index = 0
+ s['MIDDLEWARE_CLASSES'].insert(index, 'aldryn_django.middleware.RandomCommentExclusionMiddleware')
+ s['MIDDLEWARE_CLASSES'].insert(index, 'debreach.middleware.RandomCommentMiddleware')
+ if 'django.middleware.csrf.CsrfViewMiddleware' in s['MIDDLEWARE_CLASSES']:
+ s['MIDDLEWARE_CLASSES'].insert(
+ s['MIDDLEWARE_CLASSES'].index('django.middleware.csrf.CsrfViewMiddleware'),
+ 'debreach.middleware.CSRFCryptMiddleware',
+ )
+
def server_settings(self, settings, env):
settings['PORT'] = env('PORT', 80)
settings['BACKEND_PORT'] = env('BACKEND_PORT', 8000)
settings['ENABLE_NGINX'] = env('ENABLE_NGINX', False)
- settings['ENABLE_PAGESPEED'] = env('ENABLE_PAGESPEED', False)
- settings['ENABLE_BROWSERCACHE'] = env('ENABLE_BROWSERCACHE', False)
- settings['BROWSERCACHE_MAX_AGE'] = env('BROWSERCACHE_MAX_AGE', 300)
+ settings['ENABLE_PAGESPEED'] = env(
+ 'ENABLE_PAGESPEED',
+ env('PAGESPEED', False),
+ )
+ settings['STATICFILES_DEFAULT_MAX_AGE'] = env(
+ 'STATICFILES_DEFAULT_MAX_AGE',
+ # Keep BROWSERCACHE_MAX_AGE for backwards compatibility
+ env('BROWSERCACHE_MAX_AGE', 300),
+ )
settings['NGINX_CONF_PATH'] = env('NGINX_CONF_PATH')
settings['NGINX_PROCFILE_PATH'] = env('NGINX_PROCFILE_PATH')
+ settings['PAGESPEED_ADMIN_HTPASSWD_PATH'] = env(
+ 'PAGESPEED_ADMIN_HTPASSWD_PATH',
+ os.path.join(
+ os.path.dirname(settings['NGINX_CONF_PATH']),
+ 'pagespeed_admin.htpasswd',
+ )
+ )
+ settings['PAGESPEED_ADMIN_USER'] = env('PAGESPEED_ADMIN_USER')
+ settings['PAGESPEED_ADMIN_PASSWORD'] = env('PAGESPEED_ADMIN_PASSWORD')
settings['DJANGO_WEB_WORKERS'] = env('DJANGO_WEB_WORKERS', 3)
settings['DJANGO_WEB_MAX_REQUESTS'] = env('DJANGO_WEB_MAX_REQUESTS', 500)
settings['DJANGO_WEB_TIMEOUT'] = env('DJANGO_WEB_TIMEOUT', 120)
+ # https://docs.djangoproject.com/en/1.8/ref/settings/#use-x-forwarded-host
+ settings['USE_X_FORWARDED_HOST'] = env('USE_X_FORWARDED_HOST', False)
+
def logging_settings(self, settings, env):
settings['LOGGING'] = {
'version': 1,
@@ -191,40 +398,180 @@ class Form(forms.BaseForm):
}
}
- def cache_settings(self, settings, env):
- import django_cache_url
- cache_url = env('CACHE_URL')
- if cache_url:
- settings['CACHES']['default'] = django_cache_url.parse(cache_url)
+ def sentry_settings(self, settings, env):
+ sentry_dsn = env('SENTRY_DSN')
- def storage_settings(self, settings, env):
+ if sentry_dsn:
+ settings['INSTALLED_APPS'].append('raven.contrib.django')
+ settings['RAVEN_CONFIG'] = {'dsn': sentry_dsn}
+ settings['LOGGING']['handlers']['sentry'] = {
+ 'level': 'ERROR',
+ 'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
+ }
+
+ def storage_settings_for_media(self, settings, env):
+ import yurl
from aldryn_django.storage import parse_storage_url
if env('DEFAULT_STORAGE_DSN'):
settings['DEFAULT_STORAGE_DSN'] = env('DEFAULT_STORAGE_DSN')
-
+ settings['MEDIA_URL'] = env('MEDIA_URL', '/media/')
if 'DEFAULT_STORAGE_DSN' in settings:
settings.update(parse_storage_url(settings['DEFAULT_STORAGE_DSN']))
+ media_host = yurl.URL(settings['MEDIA_URL']).host
+ settings['MEDIA_URL_IS_ON_OTHER_DOMAIN'] = (
+ media_host and media_host not in settings['ALLOWED_HOSTS']
+ )
+ settings['MEDIA_ROOT'] = env('MEDIA_ROOT', os.path.join(settings['DATA_ROOT'], 'media'))
+ settings['MEDIA_HEADERS'] = []
+
+ cmds = {}
+ if os.path.exists('/usr/bin/pngout'):
+ cmds['png'] = '/usr/bin/pngout {filename} {filename}.png -s0 -y -force && mv {filename}.png {filename}'
+ if os.path.exists('/usr/bin/jpegoptim'):
+ cmds['jpeg'] = '/usr/bin/jpegoptim --max=90 --overwrite --strip-all --all-progressive {filename}'
+ if os.path.exists('/usr/bin/gifsicle'):
+ cmds['gif'] = '/usr/bin/gifsicle --batch --optimize=2 {filename}'
+ settings['THUMBNAIL_OPTIMIZE_COMMAND'] = cmds
+
+ def storage_settings_for_static(self, data, settings, env):
+ import yurl
+ use_gzip = not env('DISABLE_GZIP')
+ use_manifest = data['use_manifeststaticfilesstorage']
+ if use_gzip:
+ if use_manifest:
+ storage = 'aldryn_django.storage.ManifestGZippedStaticFilesStorage'
+ else:
+ storage = 'aldryn_django.storage.GZippedStaticFilesStorage'
+ else:
+ if use_manifest:
+ storage = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
+ else:
+ storage = 'django.contrib.staticfiles.storage.StaticFilesStorage'
+ settings['STATICFILES_STORAGE'] = storage
+
+ settings['STATIC_URL'] = env('STATIC_URL', '/static/')
+ static_host = yurl.URL(settings['STATIC_URL']).host
+ settings['STATIC_URL_IS_ON_OTHER_DOMAIN'] = (
+ static_host and static_host not in settings['ALLOWED_HOSTS']
+ )
+ settings['STATIC_ROOT'] = env(
+ 'STATIC_ROOT',
+ os.path.join(settings['BASE_DIR'], 'static_collected'),
+ )
+ settings['STATIC_HEADERS'] = [
+ # Set far-future expiration headers for static files with hashed
+ # filenames. Also set cors headers to * for fonts.
+ (r'.*\.[0-9a-f]{10,16}\.(eot|ttf|otf|woff)', {
+ 'Access-Control-Allow-Origin': '*',
+ 'Cache-Control': 'public, max-age={}'.format(3600 * 24 * 365),
+ }),
+ (r'.*\.[0-9a-f]{10,16}\.[a-z]+', {
+ 'Cache-Control': 'public, max-age={}'.format(3600 * 24 * 365),
+ }),
+ # Set default expiration headers for all remaining static files.
+ # *Has to be last* as processing stops at the first matching
+ # pattern it finds. Also set cors headers to * for fonts.
+ (r'.*\.(eot|ttf|otf|woff)', {
+ 'Access-Control-Allow-Origin': '*',
+ 'Cache-Control': 'public, max-age={}'.format(
+ settings['STATICFILES_DEFAULT_MAX_AGE'],
+ ),
+ }),
+ ('.*', {
+ 'Cache-Control': 'public, max-age={}'.format(
+ settings['STATICFILES_DEFAULT_MAX_AGE'],
+ ),
+ }),
+ ]
+ settings['STATICFILES_DIRS'] = env(
+ 'STATICFILES_DIRS',
+ [os.path.join(settings['BASE_DIR'], 'static')]
+ )
+
+ def email_settings(self, data, settings, env):
+ import dj_email_url
+
+ email_url = env('EMAIL_URL', '')
+ if email_url:
+ settings['EMAIL_URL'] = email_url
+ settings.update(dj_email_url.parse(email_url))
+
+ from_email = env('DEFAULT_FROM_EMAIL', '')
+ if from_email:
+ settings['DEFAULT_FROM_EMAIL'] = from_email
+
+ server_email = env('SERVER_EMAIL', '')
+ if server_email:
+ settings['SERVER_EMAIL'] = server_email
def i18n_settings(self, data, settings, env):
- settings['ALL_LANGUAGES'] = list(settings['LANGUAGES'])
+ from django.utils.translation import ugettext_lazy
+
+ settings['ALL_LANGUAGES'] = [
+ (code, ugettext_lazy(name))
+ for code, name in settings['LANGUAGES']
+ ]
settings['ALL_LANGUAGES_DICT'] = dict(settings['ALL_LANGUAGES'])
- languages = json.loads(data['languages'])
- settings['LANGUAGE_CODE'] = languages[0]
+
settings['USE_L10N'] = True
settings['USE_I18N'] = True
- settings['LANGUAGES'] = [
- (code, settings['ALL_LANGUAGES_DICT'][code])
- for code in languages
+
+ def language_codes_to_tuple(codes):
+ return [
+ (code, settings['ALL_LANGUAGES_DICT'][code])
+ for code in codes
+ ]
+ langs_from_env = env('LANGUAGES', None)
+ lang_codes_from_env = env('LANGUAGE_CODES', None)
+ langs_from_form = json.loads(data['languages'])
+
+ if langs_from_env:
+ settings['LANGUAGES'] = langs_from_env
+ elif lang_codes_from_env:
+ settings['LANGUAGES'] = language_codes_to_tuple(lang_codes_from_env)
+ else:
+ settings['LANGUAGES'] = language_codes_to_tuple(langs_from_form)
+
+ lang_code_from_env = env('LANGUAGE_CODE', None)
+ if lang_code_from_env:
+ settings['LANGUAGE_CODE'] = lang_code_from_env
+ else:
+ settings['LANGUAGE_CODE'] = settings['LANGUAGES'][0][0]
+
+ settings['LOCALE_PATHS'] = [
+ os.path.join(settings['BASE_DIR'], 'locale'),
]
+ if len(settings['LANGUAGES']) <= 1:
+ settings['PREFIX_DEFAULT_LANGUAGE'] = not data['disable_default_language_prefix']
+ else:
+ # this is not supported for django versions < 1.10
+ settings['PREFIX_DEFAULT_LANGUAGE'] = True
+
+ if not settings['PREFIX_DEFAULT_LANGUAGE']:
+ settings['MIDDLEWARE_CLASSES'].insert(
+ settings['MIDDLEWARE_CLASSES'].index('django.middleware.locale.LocaleMiddleware'),
+ 'aldryn_django.middleware.LanguagePrefixFallbackMiddleware',
+ )
+
def time_settings(self, settings, env):
if env('TIME_ZONE'):
settings['TIME_ZONE'] = env('TIME_ZONE')
def migration_settings(self, settings, env):
+ from aldryn_django import storage
+ from aldryn_addons.utils import boolean_ish
+
settings.setdefault('MIGRATION_COMMANDS', [])
mcmds = settings['MIGRATION_COMMANDS']
- mcmds.append('python manage.py createcachetable django_dbcache; exit 0')
- mcmds.append('python manage.py syncdb --noinput')
- mcmds.append('python manage.py migrate --list --noinput && python manage.py migrate --noinput && python manage.py migrate --list --noinput')
+ mcmds.append('CACHE_URL="locmem://" python manage.py createcachetable django_dbcache; exit 0')
+ mcmds.append('python manage.py migrate --noinput')
+
+ if not boolean_ish(env('DISABLE_S3_MEDIA_HEADERS_UPDATE')):
+ if settings['DEFAULT_FILE_STORAGE'] == storage.SCHEMES['s3']:
+ mcmds.append('python manage.py aldryn_update_s3_media_headers')
+
+ def gis_settings(self, settings, env):
+ settings['DATABASES']['default']['ENGINE'] = 'django.contrib.gis.db.backends.postgis'
+ settings['INSTALLED_APPS'].append('django.contrib.gis')
diff --git a/addons/aldryn-django/settings.json b/addons/aldryn-django/settings.json
index 5dae0aa..2b71198 100644
--- a/addons/aldryn-django/settings.json
+++ b/addons/aldryn-django/settings.json
@@ -1,3 +1,7 @@
{
- "languages": "[\"en\"]"
-}
+ "disable_default_language_prefix": false,
+ "enable_gis": false,
+ "languages": "[\"en\"]",
+ "session_timeout": 1209600,
+ "use_manifeststaticfilesstorage": false
+}
\ No newline at end of file
diff --git a/requirements.in b/requirements.in
index 7e0cbd6..ec4077b 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,3 +1,4 @@
# # Warning: text inside the INSTALLED_ADDONS tags is auto-generated. Manual changes will be overwritten.
+https://control.divio.com/api/v1/apps/serve/aldryn-django/1.8.19.1/5dfa4420-e075-4377-a4b7-9feeaa3f5efb/aldryn-django-1.8.19.1.tar.gz#egg=aldryn-django==1.8.19.1
https://control.divio.com/api/v1/apps/serve/aldryn-sso/1.1.16/dbe0c45a-c981-4beb-8624-b0d2c4196aa0/aldryn-sso-1.1.16.tar.gz#egg=aldryn-sso==1.1.16
#
diff --git a/settings.py b/settings.py
index cfe36f4..fc7ff32 100644
--- a/settings.py
+++ b/settings.py
@@ -2,6 +2,7 @@
INSTALLED_ADDONS = [
# # Warning: text inside the INSTALLED_ADDONS tags is auto-generated. Manual changes will be overwritten.
+ 'aldryn-django',
'aldryn-sso',
#
]