class Form(forms.BaseForm): pagination = forms.NumberField('Work pagination', initial='5') work_list_truncwords = forms.NumberField('Work List Truncwords', initial='50') def to_settings(self, data, settings): settings["INSTALLED_APPS"].extend(["djangocms_portfolio"]) settings["INSTALLED_APPS"].extend(["taggit"]) settings["WORK_PAGINATION"] = data['pagination'] settings["WORK_LIST_TRUNCWORDS_COUNT"] = data['work_list_truncwords'] return settings
class Form(forms.BaseForm): grid_size = forms.NumberField('Maximum columns to support', required=False) enable_glyphicons = forms.CheckboxField( 'Enable Glyphicons', required=False, initial=True, help_text= 'If you disable this, remember to also update your sass config to not load the font.', ) enable_fontawesome = forms.CheckboxField( 'Enable Fontawesome', required=False, initial=True, help_text= 'If you disable this, remember to also update your sass config to not load the font.', ) carousel_styles = forms.CharField( 'List of additional carousel styles (comma separated)', required=False) def clean(self): data = super(Form, self).clean() # older versions of this addon had a bug where the values would be # saved to settings.json as a list instead of a string. if isinstance(data['carousel_styles'], list): data['carousel_styles'] = ', '.join(data['carousel_styles']) # prettify data['carousel_styles'] = ', '.join( split_and_strip(data['carousel_styles'])) return data def to_settings(self, data, settings): choices = [] if data['grid_size']: settings['ALDRYN_BOOTSTRAP3_GRID_SIZE'] = int(data['grid_size']) if data['enable_glyphicons']: choices.append(('glyphicons', 'glyphicons', 'Glyphicons')) if data['enable_fontawesome']: choices.append(('fontawesome', 'fa', 'Font Awesome')) if choices: settings['ALDRYN_BOOTSTRAP3_ICONSETS'] = choices if data['carousel_styles']: settings['ALDRYN_BOOTSTRAP3_CAROUSEL_STYLES'] = [ (item, item) for item in split_and_strip(data['carousel_styles']) ] return settings
class Form(forms.BaseForm): grid_size = forms.NumberField('Maximum columns to support, default is 12.', required=False) enable_icons = forms.CheckboxField( 'Enable icon support', required=False, initial=True, ) def to_settings(self, data, settings): if data['grid_size']: settings['DJANGOCMS_BOOTSTRAP4_GRID_SIZE'] = int(data['grid_size']) if data['enable_icons']: settings['DJANGOCMS_BOOTSTRAP4_USE_ICONS'] = int( data['enable_icons']) return settings
class Form(forms.BaseForm): people_plugin_styles = forms.CharField( 'List of additional people plugin styles (comma separated)', required=False) user_threshold = forms.NumberField( 'Once there are this many users, change drop-down to ID input field', required=False, min_value=0) def to_settings(self, data, settings): settings['PEOPLE_PLUGIN_STYLES'] = data.get('people_plugin_styles', '') try: settings['ALDRYN_PEOPLE_USER_THRESHOLD'] = int( data.get('user_threshold')) except (ValueError, TypeError): pass return settings
class Form(forms.BaseForm): name = forms.CharField( 'name of consent cookie that remembers user choice', help_text='Default: cookie_consent', required=False ) max_age = forms.NumberField( 'max-age of consent cookie', help_text='Default: 1 year', required=False ) decline = forms.CharField( 'decline value', help_text='Default: -1', required=False ) enabled = forms.CheckboxField( 'Enabled', required=False, initial=True ) opt_out = forms.CheckboxField( 'opt-out cookies', required=False, initial=False, help_text='opt-out cookies are set until declined opt-in cookies are set only if accepted' ) cache_backend = forms.CharField( 'Alias for backend to use for caching', help_text='Default: default', required=False ) def to_settings(self, data, settings): if data['name']: settings['COOKIE_CONSENT_NAME'] = data['name'] if data['max_age']: settings['COOKIE_CONSENT_MAX_AGE'] = int(data['max_age']) if data['decline']: settings['COOKIE_CONSENT_DECLINE'] = data['decline'] settings['COOKIE_CONSENT_ENABLED'] = data['enabled'] settings['COOKIE_CONSENT_OPT_OUT'] = data['opt_out'] if data['cache_backend']: settings['COOKIE_CONSENT_CACHE_BACKEND'] = data['cache_backend'] #settings['ADDON_URLS'].append('cookie_consent.urls') return settings
class Form(forms.BaseForm): 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.')) 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 django_cache_url import dj_database_url import warnings from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings['BASE_DIR'] = env('BASE_DIR', required=True) 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['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') 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:' settings['CACHE_URL'] = 'locmem://' if not settings['DATABASE_URL']: settings['DATABASE_URL'] = 'sqlite:///{}'.format( os.path.join(settings['DATA_ROOT'], 'db.sqlite3')) warnings.warn( 'no database configured. Falling back to DATABASE_URL={0}'. format(settings['DATABASE_URL']), RuntimeWarning, ) 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_I18N'].append('aldryn_django.i18n_urls') settings['WSGI_APPLICATION'] = 'wsgi.application' settings['INSTALLED_APPS'].extend([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'django.contrib.staticfiles', 'aldryn_django', ]) 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.template.context_processors.i18n', 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.template.context_processors.media', 'django.template.context_processors.csrf', 'django.template.context_processors.tz', 'django.template.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', '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['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) # 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): 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 domain = env('DOMAIN') if domain: settings['DOMAIN'] = domain domains = env('ALDRYN_SITES_DOMAINS', {}) 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': domain_aliases, 'redirects': domain_redirects, }, } settings['ALDRYN_SITES_DOMAINS'] = domains # 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', ) 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', 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, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', }, 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'stream': sys.stdout, }, 'null': { 'class': 'logging.NullHandler', }, }, 'loggers': { '': { 'handlers': ['console'], 'level': 'INFO', }, 'django': { 'handlers': ['console'], 'level': 'INFO', }, 'django.request': { 'handlers': ['console'], 'level': 'INFO', 'propagate': False, }, 'aldryn': { 'handlers': ['console'], 'level': 'INFO', }, 'py.warnings': { 'handlers': ['console'], }, } } def sentry_settings(self, settings, env): sentry_dsn = env('SENTRY_DSN') 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']) settings['ALL_LANGUAGES_DICT'] = dict(settings['ALL_LANGUAGES']) settings['USE_L10N'] = True settings['USE_I18N'] = True 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'), ] settings['PREFIX_DEFAULT_LANGUAGE'] = not data[ 'disable_default_language_prefix'] 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( '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')
class Form(forms.BaseForm): permissions_enabled = forms.CheckboxField( 'Enable permission checks', required=False, initial=True, help_text=( 'When set, provides new fields in each page\'s settings to assign ' 'levels of access to particular users.' ), ) cms_templates = forms.CharField( 'CMS Templates', required=True, initial='[["default.html", "Default"]]', help_text=( 'A list, in JSON format, of django CMS templates available to the ' 'project. Use double quotes for values. This list will be ' 'overridden if the project supplies a <a href=' '\'http://docs.django-cms.org/en/stable/reference/configuration.html#cms-templates\'' 'target=\'_blank\'>CMS_TEMPLATES setting</a>. See <a href=' '\'http://support.divio.com/project-types/django-cms/manage-templates-in-your-django-cms-project-on-the-divio-cloud\' ' # noqa 'target=\'_blank\'>Manage templates in your django CMS project</a> for more information.' ), ) cms_content_cache_duration = forms.NumberField( 'Set Cache Duration for Content', required=False, initial=60, help_text=( 'Cache expiration (in seconds) for show_placeholder, page_url, ' 'placeholder and static_placeholder template tags.' ), ) cms_menus_cache_duration = forms.NumberField( 'Set Cache Duration for Menus', required=False, initial=3600, help_text='Cache expiration (in seconds) for the menu tree.', ) def to_settings(self, data, settings): from functools import partial from django.urls import reverse_lazy from aldryn_addons.utils import djsenv env = partial(djsenv, settings=settings) # Core CMS stuff settings['INSTALLED_APPS'].extend([ 'cms', # 'aldryn_django_cms' must be after 'cms', otherwise we get # import time exceptions on other packages (e.g alryn-bootstrap3 # returns: # link_page = cms.models.fields.PageField( # AttributeError: 'module' object has no attribute 'fields' # ) 'aldryn_django_cms', 'menus', 'sekizai', 'treebeard', ]) # TODO: break out this stuff into other addons settings['INSTALLED_APPS'].extend([ 'parler', ]) settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'djangocms_admin_style', ) settings['TEMPLATES'][0]['OPTIONS']['context_processors'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) middlewares = [ 'cms.middleware.user.CurrentUserMiddleware', 'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.language.LanguageCookieMiddleware', ] if settings.get('MIDDLEWARE_CLASSES', None): settings['MIDDLEWARE_CLASSES'].extend(middlewares) settings['MIDDLEWARE_CLASSES'].insert(0, 'cms.middleware.utils.ApphookReloadMiddleware', ) else: settings['MIDDLEWARE'].extend(middlewares) settings['MIDDLEWARE'].insert(0, 'cms.middleware.utils.ApphookReloadMiddleware', ) settings['ADDON_URLS_I18N_LAST'] = 'cms.urls' settings['CMS_PERMISSION'] = data['permissions_enabled'] cache_durations = settings.setdefault('CMS_CACHE_DURATIONS', { 'content': 60, 'menus': 60 * 60, 'permissions': 60 * 60, }) if data['cms_content_cache_duration']: cache_durations['content'] = data['cms_content_cache_duration'] if data['cms_menus_cache_duration']: cache_durations['menus'] = data['cms_menus_cache_duration'] old_cms_templates_json = os.path.join(settings['BASE_DIR'], 'cms_templates.json') if os.path.exists(old_cms_templates_json): # Backwards compatibility with v2 with open(old_cms_templates_json) as fobj: templates = json.load(fobj) else: templates = settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) settings['CMS_TEMPLATES'] = templates # languages language_codes = [code for code, lang in settings['LANGUAGES']] settings['CMS_LANGUAGES'] = { 'default': { 'fallbacks': [fbcode for fbcode in language_codes], 'redirect_on_fallback': True, 'public': True, 'hide_untranslated': False, }, 1: [ { 'code': code, 'name': settings['ALL_LANGUAGES_DICT'][code], 'fallbacks': [fbcode for fbcode in language_codes if fbcode != code], 'public': True } for code in language_codes ] } settings['PARLER_LANGUAGES'] = {} for site_id, languages in settings['CMS_LANGUAGES'].items(): if isinstance(site_id, int): langs = [ { 'code': lang['code'], 'fallbacks': [fbcode for fbcode in language_codes if fbcode != lang['code']] } for lang in languages ] settings['PARLER_LANGUAGES'].update({site_id: langs}) parler_defaults = {'fallback': settings['LANGUAGE_CODE']} for k, v in settings['CMS_LANGUAGES'].get('default', {}).items(): if k in ['hide_untranslated', ]: parler_defaults.update({k: v}) settings['PARLER_LANGUAGES'].update({'default': parler_defaults}) TEMPLATE_CONTEXT_PROCESSORS = settings['TEMPLATES'][0]['OPTIONS']['context_processors'] TEMPLATE_CONTEXT_PROCESSORS.extend([ 'aldryn_snake.template_api.template_processor', ]) # django sitemap support settings['INSTALLED_APPS'].append('django.contrib.sitemaps') # django-compressor settings['INSTALLED_APPS'].append('compressor') settings['STATICFILES_FINDERS'].append('compressor.finders.CompressorFinder') # Disable django-comporessor for now. It does not work with the current # setup. The cache is shared, which holds the manifest. But the # compressed files reside in the docker container, which can go away at # any time. # Working solutions could be: # 1) use pre-compression # (https://django-compressor.readthedocs.org/en/latest/usage/#pre-compression) # at docker image build time. # 2) Use shared storage and save the manifest with the generated files. # Although that could be a problem if different versions of the same # app compete for the manifest file. # We're keeping compressor in INSTALLED_APPS for now, so that templates # in existing projects don't break. settings['COMPRESS_ENABLED'] = env('COMPRESS_ENABLED', False) if settings['COMPRESS_ENABLED']: # Set far-future expiration headers for django-compressor # generated files. settings.setdefault('STATIC_HEADERS', []).insert(0, ( r'{}/.*'.format(settings.get('COMPRESS_OUTPUT_DIR', 'CACHE')), { 'Cache-Control': 'public, max-age={}'.format(86400 * 365), }, )) # django-robots settings['INSTALLED_APPS'].append('robots') settings['MIGRATION_COMMANDS'].append( 'python manage.py cms fix-tree' ) # default plugins settings['INSTALLED_APPS'].extend([ # required by aldryn-forms 'captcha', ]) # select2 (required by djangocms_link plugin) settings['INSTALLED_APPS'].extend([ 'django_select2', ]) settings['ADDON_URLS'].append('aldryn_django_cms.urls') settings['ADDON_URLS_I18N'].append('aldryn_django_cms.urls_i18n') if 'ALDRYN_SSO_LOGIN_WHITE_LIST' in settings: # stage sso enabled # add internal endpoints that do not require authentication settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append(reverse_lazy('cms-check-uninstall')) # this is an internal django-cms url # which gets called when a user logs out from toolbar settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append(reverse_lazy('admin:cms_page_resolve')) # Prevent injecting random comments to counter BREACH/CRIME attacks # into the page tree snippets, as the javascript parsing the result # expects a single top-level element. (settings .setdefault('RANDOM_COMMENT_EXCLUDED_VIEWS', set([])) .add('cms.admin.pageadmin.get_tree')) return settings
class Form(forms.BaseForm): api_key = forms.CharField('Google Maps API key') plugin_module = forms.CharField('Plugin module name', initial='Generic') plugin_name = forms.CharField('Plugin name', initial='Map') location_plugin_name = forms.CharField('Location plugin name', initial='Location') page_only = forms.CheckboxField( 'Page placeholders only?', initial=False, required=False, help_text='Check this box to limit use of these plugins to CMSPage ' 'placholders only.') parent_classes = forms.CharField( 'Parent plugin classes', max_length=255, required=False, ) require_parent = forms.CheckboxField( 'Child only?', initial=False, required=False, help_text='Check this box to only allow these plugins to be used ' 'only as children of other plugins.') text_enabled = forms.CheckboxField( 'Text enabled?', initial=False, required=False, help_text='Check this box to allow these plugins to be used as ' 'children of TextPlugin instances.') advanced_options_enabled = forms.CheckboxField( 'Show advanced options', initial=True, required=False, help_text='Enable Advanced Options to allow the users to fully ' 'customise map controls e.g. streetViewControl') styled_maps_enabled = forms.CheckboxField( 'Enable styled maps?', initial=True, required=False, help_text='Check this box to allow the user to customize tha ' 'appearance of maps.') infowindow_enabled = forms.CheckboxField( 'Enable InfoWindow?', initial=True, required=False, help_text='Check this box to enable the InfoWindow') infowindow_maxwidth = forms.NumberField( 'Max width', initial=220, help_text='Set this to the desired maximum InfoWindow width.') custom_markers_enabled = forms.CheckboxField( 'Custom markers?', initial=True, required=False, help_text='Check this box to allow the use of custom markers.') def to_settings(self, data, settings): settings['DJANGOCMS_GMAPS_API_KEY'] = data['api_key'] settings['DJANGOCMS_GMAPS_PLUGIN_MODULE'] = data['plugin_module'] settings['DJANGOCMS_GMAPS_PLUGIN_NAME'] = data['plugin_name'] settings['DJANGOCMS_GMAPS_LOCATION_PLUGIN_NAME'] = data[ 'location_plugin_name'] settings['DJANGOCMS_GMAPS_PAGE_ONLY'] = data['page_only'] settings['DJANGOCMS_GMAPS_PARENT_CLASSES'] = data['parent_classes'] settings['DJANGOCMS_GMAPS_REQUIRE_PARENT'] = data['require_parent'] settings['DJANGOCMS_GMAPS_TEXT_ENABLED'] = data['text_enabled'] settings['DJANGOCMS_GMAPS_ADVANCED_OPTIONS_ENABLED'] = data[ 'advanced_options_enabled'] settings['DJANGOCMS_GMAPS_STYLED_MAPS_ENABLED'] = data[ 'styled_maps_enabled'] settings['DJANGOCMS_GMAPS_INFOWINDOW_ENABLED'] = data[ 'infowindow_enabled'] settings['DJANGOCMS_GMAPS_INFOWINDOW_MAXWIDTH'] = data[ 'infowindow_maxwidth'] settings['DJANGOCMS_GMAPS_CUSTOM_MARKERS_ENABLED'] = data[ 'custom_markers_enabled'] return settings
class Form(forms.BaseForm): unescaped_render_model_tags = forms.CheckboxField( 'Leave "render_model" tags unescaped? (security risk)', required=False, initial=True, help_text=( 'IMPORTANT: Please review your project templates before un-checking this box. ' # noqa 'See: http://www.django-cms.org/en/blog/2016/04/26/security-updates-django-cms-released/.' # noqa ), ) permissions_enabled = forms.CheckboxField( 'Enable permission checks', required=False, initial=True, help_text=( 'When set, provides new fields in each page\'s settings to assign ' 'levels of access to particular users.'), ) cms_templates = forms.CharField( 'CMS Templates', required=True, initial='[["default.html", "Default"]]', help_text=SYSTEM_FIELD_WARNING, ) boilerplate_name = forms.CharField( 'Boilerplate Name', required=False, initial='', help_text=SYSTEM_FIELD_WARNING, ) cms_content_cache_duration = forms.NumberField( 'Set Cache Duration for Content', required=False, initial=60, help_text=( 'Cache expiration (in seconds) for show_placeholder, page_url, ' 'placeholder and static_placeholder template tags.'), ) cms_menus_cache_duration = forms.NumberField( 'Set Cache Duration for Menus', required=False, initial=3600, help_text='Cache expiration (in seconds) for the menu tree.', ) def to_settings(self, data, settings): from functools import partial from django.core.urlresolvers import reverse_lazy from aldryn_addons.utils import boolean_ish, djsenv from aldryn_django import storage env = partial(djsenv, settings=settings) # Need to detect if these settings are for Django 1.8+ # Is there a better way? Can't import django to check version =( is_django_18_or_later = ('TEMPLATES' in settings) # Core CMS stuff settings['INSTALLED_APPS'].extend([ 'cms', # 'aldryn_django_cms' must be after 'cms', otherwise we get # import time exceptions on other packages (e.g alryn-bootstrap3 # returns: # link_page = cms.models.fields.PageField( # AttributeError: 'module' object has no attribute 'fields' # ) 'aldryn_django_cms', 'menus', 'sekizai', 'treebeard', 'reversion', ]) # TODO: break out this stuff into other addons settings['INSTALLED_APPS'].extend([ 'parler', ]) settings['INSTALLED_APPS'].insert( settings['INSTALLED_APPS'].index('django.contrib.admin'), 'djangocms_admin_style', ) if is_django_18_or_later: settings['TEMPLATES'][0]['OPTIONS']['context_processors'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) else: settings['TEMPLATE_CONTEXT_PROCESSORS'].extend([ 'sekizai.context_processors.sekizai', 'cms.context_processors.cms_settings', ]) settings['MIDDLEWARE_CLASSES'].extend([ 'cms.middleware.user.CurrentUserMiddleware', 'cms.middleware.page.CurrentPageMiddleware', 'cms.middleware.toolbar.ToolbarMiddleware', 'cms.middleware.language.LanguageCookieMiddleware', ]) settings['MIDDLEWARE_CLASSES'].insert( 0, 'cms.middleware.utils.ApphookReloadMiddleware', ) settings['ADDON_URLS_I18N_LAST'] = 'cms.urls' settings['CMS_PERMISSION'] = data['permissions_enabled'] cache_durations = settings.setdefault('CMS_CACHE_DURATIONS', { 'content': 60, 'menus': 60 * 60, 'permissions': 60 * 60, }) if data['cms_content_cache_duration']: cache_durations['content'] = data['cms_content_cache_duration'] if data['cms_menus_cache_duration']: cache_durations['menus'] = data['cms_menus_cache_duration'] old_cms_templates_json = os.path.join(settings['BASE_DIR'], 'cms_templates.json') if os.path.exists(old_cms_templates_json): # Backwards compatibility with v2 with open(old_cms_templates_json) as fobj: templates = json.load(fobj) else: templates = settings.get('CMS_TEMPLATES', json.loads(data['cms_templates'])) settings['CMS_TEMPLATES'] = templates # languages language_codes = [code for code, lang in settings['LANGUAGES']] settings['CMS_LANGUAGES'] = { 'default': { 'fallbacks': [fbcode for fbcode in language_codes], 'redirect_on_fallback': True, 'public': True, 'hide_untranslated': False, }, 1: [{ 'code': code, 'name': settings['ALL_LANGUAGES_DICT'][code], 'fallbacks': [fbcode for fbcode in language_codes if fbcode != code], 'public': True } for code in language_codes] } settings['PARLER_LANGUAGES'] = {} for site_id, languages in settings['CMS_LANGUAGES'].items(): if isinstance(site_id, int): langs = [{ 'code': lang['code'], 'fallbacks': [ fbcode for fbcode in language_codes if fbcode != lang['code'] ] } for lang in languages] settings['PARLER_LANGUAGES'].update({site_id: langs}) parler_defaults = {'fallback': settings['LANGUAGE_CODE']} for k, v in settings['CMS_LANGUAGES'].get('default', {}).items(): if k in [ 'hide_untranslated', ]: parler_defaults.update({k: v}) settings['PARLER_LANGUAGES'].update({'default': parler_defaults}) # aldryn-boilerplates and aldryn-snake # FIXME: Make ALDRYN_BOILERPLATE_NAME a configurable parameter settings['ALDRYN_BOILERPLATE_NAME'] = env( 'ALDRYN_BOILERPLATE_NAME', data.get('boilerplate_name', 'legacy'), ) settings['INSTALLED_APPS'].append('aldryn_boilerplates') if is_django_18_or_later: TEMPLATE_CONTEXT_PROCESSORS = settings['TEMPLATES'][0]['OPTIONS'][ 'context_processors'] TEMPLATE_LOADERS = settings['TEMPLATES'][0]['OPTIONS']['loaders'] else: TEMPLATE_CONTEXT_PROCESSORS = settings[ 'TEMPLATE_CONTEXT_PROCESSORS'] TEMPLATE_LOADERS = settings['TEMPLATE_LOADERS'] TEMPLATE_CONTEXT_PROCESSORS.extend([ 'aldryn_boilerplates.context_processors.boilerplate', 'aldryn_snake.template_api.template_processor', ]) TEMPLATE_LOADERS.insert( TEMPLATE_LOADERS.index( 'django.template.loaders.app_directories.Loader'), 'aldryn_boilerplates.template_loaders.AppDirectoriesLoader') settings['STATICFILES_FINDERS'].insert( settings['STATICFILES_FINDERS'].index( 'django.contrib.staticfiles.finders.AppDirectoriesFinder'), 'aldryn_boilerplates.staticfile_finders.AppDirectoriesFinder', ) # django sitemap support settings['INSTALLED_APPS'].append('django.contrib.sitemaps') # django-compressor settings['INSTALLED_APPS'].append('compressor') settings['STATICFILES_FINDERS'].append( 'compressor.finders.CompressorFinder') # Disable django-comporessor for now. It does not work with the current # setup. The cache is shared, which holds the manifest. But the # compressed files reside in the docker container, which can go away at # any time. # Working solutions could be: # 1) use pre-compression # (https://django-compressor.readthedocs.org/en/latest/usage/#pre-compression) # at docker image build time. # 2) Use shared storage and save the manifest with the generated files. # Although that could be a problem if different versions of the same # app compete for the manifest file. # We're keeping compressor in INSTALLED_APPS for now, so that templates # in existing projects don't break. settings['COMPRESS_ENABLED'] = env('COMPRESS_ENABLED', False) if settings['COMPRESS_ENABLED']: # Set far-future expiration headers for django-compressor # generated files. settings.setdefault('STATIC_HEADERS', []).insert( 0, ( r'{}/.*'.format( settings.get('COMPRESS_OUTPUT_DIR', 'CACHE')), { 'Cache-Control': 'public, max-age={}'.format( 86400 * 365), }, )) # django-robots settings['INSTALLED_APPS'].append('robots') # django-filer settings['INSTALLED_APPS'].extend([ 'filer', 'easy_thumbnails', 'mptt', 'polymorphic', ]) settings['FILER_DEBUG'] = boolean_ish( env('FILER_DEBUG', settings['DEBUG'])) settings['FILER_ENABLE_LOGGING'] = boolean_ish( env('FILER_ENABLE_LOGGING', True)) settings['FILER_IMAGE_USE_ICON'] = True settings['ADDON_URLS'].append('filer.server.urls') settings.setdefault('MEDIA_HEADERS', []).insert( 0, ( r'filer_public(?:_thumbnails)?/.*', { 'Cache-Control': 'public, max-age={}'.format(86400 * 365), }, )) # easy-thumbnails settings['INSTALLED_APPS'].extend([ 'easy_thumbnails', ]) settings['THUMBNAIL_QUALITY'] = env('THUMBNAIL_QUALITY', 90) # FIXME: enabling THUMBNAIL_HIGH_RESOLUTION causes timeouts/500! settings['THUMBNAIL_HIGH_RESOLUTION'] = False settings['THUMBNAIL_PRESERVE_EXTENSIONS'] = ['png', 'gif'] settings['THUMBNAIL_PROCESSORS'] = ( 'easy_thumbnails.processors.colorspace', 'easy_thumbnails.processors.autocrop', 'filer.thumbnail_processors.scale_and_crop_with_subject_location', 'easy_thumbnails.processors.filters', ) settings['THUMBNAIL_SOURCE_GENERATORS'] = ( 'easy_thumbnails.source_generators.pil_image', ) settings['THUMBNAIL_CACHE_DIMENSIONS'] = True # easy_thumbnails uses django's default storage backend (local file # system storage) by default, even if the DEFAULT_FILE_STORAGE setting # points to something else. # If the DEFAULT_FILE_STORAGE has been set to a value known by # aldryn-django, then use that as THUMBNAIL_DEFAULT_STORAGE as well. for storage_backend in storage.SCHEMES.values(): if storage_backend == settings['DEFAULT_FILE_STORAGE']: settings['THUMBNAIL_DEFAULT_STORAGE'] = storage_backend break settings['MIGRATION_COMMANDS'].append('python manage.py cms fix-tree') # default plugins settings['INSTALLED_APPS'].extend([ 'djangocms_text_ckeditor', 'djangocms_link', 'djangocms_snippet', 'djangocms_googlemap', # cmsplugin-filer 'cmsplugin_filer_file', 'cmsplugin_filer_image', # required by aldryn-forms 'captcha', ]) # boilerplate must provide /static/js/modules/ckeditor.wysiwyg.js and /static/css/base.css CKEDITOR_SETTINGS = { 'height': 300, 'language': '{{ language }}', 'toolbar': 'CMS', 'skin': 'moono', 'extraPlugins': 'cmsplugins', 'toolbar_HTMLField': [ ['Undo', 'Redo'], ['cmsplugins', '-', 'ShowBlocks'], ['Format', 'Styles'], ['TextColor', 'BGColor', '-', 'PasteText', 'PasteFromWord'], ['Maximize', ''], '/', [ 'Bold', 'Italic', 'Underline', '-', 'Subscript', 'Superscript', '-', 'RemoveFormat' ], ['JustifyLeft', 'JustifyCenter', 'JustifyRight'], ['HorizontalRule'], ['Link', 'Unlink'], [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Table' ], ['Source'], ['Link', 'Unlink', 'Anchor'], ], } boilerplate_name = settings['ALDRYN_BOILERPLATE_NAME'] if boilerplate_name == 'bootstrap3': CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/addons/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] else: CKEDITOR_SETTINGS[ 'stylesSet'] = 'default:/static/js/modules/ckeditor.wysiwyg.js' CKEDITOR_SETTINGS['contentsCss'] = ['/static/css/base.css'] # select2 (required by djangocms_link plugin) settings['INSTALLED_APPS'].extend([ 'django_select2', ]) settings['ADDON_URLS'].append('aldryn_django_cms.urls') settings['ADDON_URLS_I18N'].append('aldryn_django_cms.urls_i18n') if 'ALDRYN_SSO_LOGIN_WHITE_LIST' in settings: # stage sso enabled # add internal endpoints that do not require authentication settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('cms-check-uninstall')) # this is an internal django-cms url # which gets called when a user logs out from toolbar settings['ALDRYN_SSO_LOGIN_WHITE_LIST'].append( reverse_lazy('admin:cms_page_resolve')) # This may need to be removed in a future release. settings['CMS_UNESCAPED_RENDER_MODEL_TAGS'] = data[ 'unescaped_render_model_tags'] # Prevent injecting random comments to counter BREACH/CRIME attacks # into the page tree snippets, as the javascript parsing the result # expects a single top-level element. (settings.setdefault('RANDOM_COMMENT_EXCLUDED_VIEWS', set([])).add('cms.admin.pageadmin.get_tree')) return settings
class Form(forms.BaseForm): grid_size = forms.NumberField('Maximum columns to support, default is 12.', required=False) enable_icons = forms.CheckboxField( 'Enable icon support', required=False, initial=True, ) enable_jumbotron = forms.CheckboxField( 'Enable Jumbotron support', required=False, initial=True, ) enable_cta = forms.CheckboxField( 'Enable CTA support', required=False, initial=True, ) enable_boxout = forms.CheckboxField( 'Enable Boxout support', required=False, initial=True, ) available_colors = forms.CharField( 'Available colors', required=False, ) enable_row_bg_color = forms.CheckboxField( 'Enable row background color', required=False, initial=True, ) enable_row_bg_image = forms.CheckboxField( 'Enable row background image', required=False, initial=True, ) enable_row_bg_video = forms.CheckboxField( 'Enable row background Video', required=False, initial=False, ) enable_row_icon = forms.CheckboxField( 'Enable row icon', required=False, initial=False, ) enable_row_alignment = forms.CheckboxField( 'Enable row alignment controls', required=False, initial=True, ) enable_row_tag_type = forms.CheckboxField( 'Enable Row Tag type', required=False, initial=False, ) enable_row_gutter = forms.CheckboxField( 'Enable Row Gutter control', required=False, initial=False, ) enable_col_bg_color = forms.CheckboxField( 'Enable col background color', required=False, initial=True, ) enable_col_bg_image = forms.CheckboxField( 'Enable col background image', required=False, initial=True, ) show_button_context = forms.CheckboxField( 'Show Context for Links/Buttons', required=False, initial=False, ) enable_carousel_slide_title_anim = forms.CheckboxField( 'Enable Carousel Slide title animation', required=False, initial=False, ) enable_carousel_slide_video_bg = forms.CheckboxField( 'Enable Carousel Slide video background', required=False, initial=False, ) enable_carousel_slide_animate_title = forms.CheckboxField( 'Enable Carousel Animate title', required=False, initial=False, ) def to_settings(self, data, settings): if data['grid_size']: settings['DJANGOCMS_BOOTSTRAP4_GRID_SIZE'] = int(data['grid_size']) if data['enable_icons']: settings['DJANGOCMS_BOOTSTRAP4_USE_ICONS'] = int( data['enable_icons']) if data['enable_jumbotron']: settings['DJANGOCMS_BOOTSTRAP4_USE_JUMBOTRON'] = int( data['enable_jumbotron']) if data['enable_cta']: settings['DJANGOCMS_BOOTSTRAP4_USE_CTA'] = int(data['enable_cta']) if data['enable_boxout']: settings['DJANGOCMS_BOOTSTRAP4_USE_BOXOUT'] = int( data['enable_boxout']) if data['available_colors']: settings['DJANGOCMS_BOOTSTRAP4_AVAILABLE_COLORS'] = data[ 'available_colors'].split(",") if data['available_colors']: settings['DJANGOCMS_BOOTSTRAP4_USE_'] = data[ 'available_colors'].split(",") if data['enable_row_bg_color']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_COLOR'] = int( data['enable_row_bg_color']) if data['enable_row_bg_image']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_IMAGE'] = int( data['enable_row_bg_image']) if data['enable_row_bg_video']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_VIDEO'] = int( data['enable_row_bg_video']) if data['enable_row_icon']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_ICON'] = int( data['enable_row_icon']) if data['enable_row_alignment']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_ALIGNMENT'] = int( data['enable_row_alignment']) if data['enable_row_tag_type']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_TAG_TYPE'] = int( data['enable_row_tag_type']) if data['enable_row_gutter']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_GUTTER'] = int( data['enable_row_gutter']) if data['enable_col_bg_color']: settings['DJANGOCMS_BOOTSTRAP4_USE_COL_BG_COLOR'] = int( data['enable_col_bg_color']) if data['enable_col_bg_image']: settings['DJANGOCMS_BOOTSTRAP4_USE_COL_BG_IMAGE'] = int( data['enable_col_bg_image']) if data['show_button_context']: settings['DJANGOCMS_BOOTSTRAP4_SHOW_BUTTON_CONTEXT'] = int( data['show_button_context']) if data['enable_carousel_slide_title_anim']: settings['DJANGOCMS_BOOTSTRAP4_CAROUSEL_SLIDE_TITLE_ANIM'] = int( data['enable_carousel_slide_title_anim']) if data['enable_carousel_slide_video_bg']: settings['DJANGOCMS_BOOTSTRAP4_CAROUSEL_SLIDE_VIDEO_BG'] = int( data['enable_carousel_slide_video_bg']) if data['enable_carousel_slide_animate_title']: settings[ 'DJANGOCMS_BOOTSTRAP4_ENABLE_CAROUSEL_SLIDE_ANIMATE_TITLE'] = int( data['enable_carousel_slide_animate_title']) return settings
class Form(forms.BaseForm): hide_suffix = forms.CheckboxField('Hide Suffix', required=False, initial=False) summary_richtext = forms.CheckboxField( "Use rich text for Summary", required=False, initial=False, ) secondary_image = forms.CheckboxField('Show secondary image', required=False, initial=False) secondary_phone = forms.CheckboxField('Show secondary telephone number', required=False, initial=False) hide_email = forms.CheckboxField('Hide Email', required=False, initial=False) hide_mobile = forms.CheckboxField('Hide Mobile', required=False, initial=False) hide_phone = forms.CheckboxField('Hide Phone', required=False, initial=False) hide_fax = forms.CheckboxField('Hide Fax', required=False, initial=False) hide_website = forms.CheckboxField('Hide Website', required=False, initial=False) hide_facebook = forms.CheckboxField('Hide Facebook', required=False, initial=False) hide_twitter = forms.CheckboxField('Hide Twitter', required=False, initial=False) hide_linkedin = forms.CheckboxField('Hide LinkedIn', required=False, initial=False) hide_xing = forms.CheckboxField('Hide Xing', required=False, initial=False) hide_vcard = forms.CheckboxField('Hide vCard', required=False, initial=False) hide_groups = forms.CheckboxField('Hide Groups', required=False, initial=False) hide_categories = forms.CheckboxField('Hide Categoies', required=False, initial=False) hide_location = forms.CheckboxField('Hide Location', required=False, initial=False) hide_user = forms.CheckboxField('Hide user', required=False, initial=False) translate_is_published = forms.CheckboxField( 'Translate show on website field', required=False, initial=False) people_plugin_styles = forms.CharField( 'List of additional people plugin styles (comma separated)', required=False) user_threshold = forms.NumberField( 'Once there are this many users, change drop-down to ID input field', required=False, min_value=0) def to_settings(self, data, settings): settings['PEOPLE_PLUGIN_STYLES'] = data.get('people_plugin_styles', '') try: settings['ALDRYN_PEOPLE_USER_THRESHOLD'] = int( data.get('user_threshold')) except (ValueError, TypeError): pass settings['ALDRYN_PEOPLE_HIDE_EMAIL'] = int(data['hide_email']) settings['ALDRYN_PEOPLE_HIDE_PHONE'] = int(data['hide_phone']) settings['ALDRYN_PEOPLE_HIDE_MOBILE'] = int(data['hide_mobile']) settings['ALDRYN_PEOPLE_HIDE_VCARD'] = int(data['hide_vcard']) settings['ALDRYN_PEOPLE_HIDE_SUFFIX'] = int(data['hide_suffix']) settings['ALDRYN_PEOPLE_HIDE_FAX'] = int(data['hide_fax']) settings['ALDRYN_PEOPLE_HIDE_WEBSITE'] = int(data['hide_website']) settings['ALDRYN_PEOPLE_HIDE_FACEBOOK'] = int(data['hide_facebook']) settings['ALDRYN_PEOPLE_HIDE_TWITTER'] = int(data['hide_twitter']) settings['ALDRYN_PEOPLE_HIDE_LINKEDIN'] = int(data['hide_linkedin']) settings['ALDRYN_PEOPLE_HIDE_XING'] = int(data['hide_xing']) settings['ALDRYN_PEOPLE_HIDE_GROUPS'] = int(data['hide_groups']) settings['ALDRYN_PEOPLE_HIDE_LOCATION'] = int(data['hide_location']) settings['ALDRYN_PEOPLE_HIDE_USER'] = int(data['hide_user']) settings['ALDRYN_PEOPLE_HIDE_CATEGORIES'] = int( data['hide_categories']) settings['ALDRYN_PEOPLE_SHOW_SECONDARY_IMAGE'] = int( data['secondary_image']) settings['ALDRYN_PEOPLE_SHOW_SECONDARY_PHONE'] = int( data['secondary_phone']) settings['ALDRYN_PEOPLE_SUMMARY_RICHTEXT'] = int( data['summary_richtext']) settings['ALDRYN_PEOPLE_TRANSLATE_IS_PUBLISHED'] = int( data['translate_is_published']) settings['INSTALLED_APPS'].append('sortedm2m_filter_horizontal_widget') settings['INSTALLED_APPS'].append('django_filters') settings['INSTALLED_APPS'].append('crispy_forms') return settings
class Form(forms.BaseForm): grid_size = forms.NumberField('Maximum columns to support, default is 12.', required=False) enable_icons = forms.CheckboxField( 'Enable icon support', required=False, initial=True, ) enable_jumbotron = forms.CheckboxField( 'Enable Jumbotron support', required=False, initial=True, ) enable_cta = forms.CheckboxField( 'Enable CTA support', required=False, initial=True, ) enable_boxout = forms.CheckboxField( 'Enable Boxout support', required=False, initial=True, ) available_colors = forms.CharField( 'Available colors', required=False, ) enable_row_bg_color = forms.CheckboxField( 'Enable row background color', required=False, initial=True, ) enable_row_bg_image = forms.CheckboxField( 'Enable row background image', required=False, initial=True, ) enable_row_icon = forms.CheckboxField( 'Enable row icon', required=False, initial=True, ) enable_col_bg_color = forms.CheckboxField( 'Enable col background color', required=False, initial=True, ) enable_col_bg_image = forms.CheckboxField( 'Enable col background image', required=False, initial=True, ) def to_settings(self, data, settings): if data['grid_size']: settings['DJANGOCMS_BOOTSTRAP4_GRID_SIZE'] = int(data['grid_size']) if data['enable_icons']: settings['DJANGOCMS_BOOTSTRAP4_USE_ICONS'] = int( data['enable_icons']) if data['enable_jumbotron']: settings['DJANGOCMS_BOOTSTRAP4_USE_JUMBOTRON'] = int( data['enable_jumbotron']) if data['enable_cta']: settings['DJANGOCMS_BOOTSTRAP4_USE_CTA'] = int(data['enable_cta']) if data['enable_boxout']: settings['DJANGOCMS_BOOTSTRAP4_USE_BOXOUT'] = int( data['enable_boxout']) if data['available_colors']: settings['DJANGOCMS_BOOTSTRAP4_AVAILABLE_COLORS'] = data[ 'available_colors'].split(",") if data['available_colors']: settings['DJANGOCMS_BOOTSTRAP4_USE_'] = data[ 'available_colors'].split(",") if data['enable_row_bg_color']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_COLOR'] = int( data['enable_row_bg_color']) if data['enable_row_bg_image']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_IMAGE'] = int( data['enable_row_bg_image']) if data['enable_row_icon']: settings['DJANGOCMS_BOOTSTRAP4_USE_ROW_BG_ICON'] = int( data['enable_row_icon']) if data['enable_col_bg_color']: settings['DJANGOCMS_BOOTSTRAP4_USE_COL_BG_COLOR'] = int( data['enable_col_bg_color']) if data['enable_col_bg_image']: settings['DJANGOCMS_BOOTSTRAP4_USE_COL_BG_IMAGE'] = int( data['enable_col_bg_image']) return settings
class Form(forms.BaseForm): use_profile_apphooks = forms.CheckboxField( "Use profile app hooks", help_text=("Plug aldryn profile views as an app hook." "If not checked - you need to add aldryn-accounts urls" "to your project core urls manually."), required=False, initial=True, ) open_signup = forms.CheckboxField( "Signup is open", help_text=("whether any user may signup. If set to False only " "users with an invite code may sign up."), required=False, initial=True, ) notify_password_change = forms.CheckboxField( "Notify password change", help_text=("whether a confirmation email should be sent out " "whenever the password is changed"), required=False, initial=True, ) password_change_redirect_url = forms.CharField( "Password change redirect url", help_text=( "Where to redirect users after a successful changed password. " "Leave empty for default."), required=False, initial='', ) email_confirmation_email = forms.CheckboxField( "send confirmation email", help_text=( "Whether to send out a confirmation email when a user signs up"), required=False, initial=True, ) email_confirmation_expire_days = forms.NumberField( "Email confirmation expires after, days", help_text="How long a confirmation email code is valid.", min_value=1, max_value=9999, initial=3, ) restore_password_raise_validation_error = forms.CheckboxField( "Restore password raise validation error", help_text=( "Whether to raise validation error when user resotres password."), required=False, initial=True, ) user_display_fallback_to_username = forms.CheckboxField( "User display name fallback to username", help_text=("Whether to fallback to username when displaying a user."), required=False, initial=False, ) user_display_fallback_to_pk = forms.CheckboxField( "User display fallback to pk", help_text=("Whether to fallback to user id when displaying a user."), required=False, initial=False, ) login_redirect_url = forms.CharField( "Login redirect url", help_text=("Where to redirect users after a successful login. " "Warning! Should be a valid url, otherwise you will get " "404 errors."), required=True, initial='/', ) signup_redirect_url = forms.CharField( "Signup redirect url", help_text=( "Where to redirect users after a sign up, Use view name from urls. " "please make sure that this view can be reversed, " "include namespace if needed."), required=True, initial='accounts_profile', ) display_email_notifications = forms.CheckboxField( "Display not confirmed emails notification", help_text=("Whether to display not confirmed emails notification on " "the top of the page."), required=False, initial=True, ) display_password_notifications = forms.CheckboxField( "Display 'password not set' notification", help_text=("Whether to display 'password not set' notification on " "the top of the page."), required=False, initial=True, ) urls_prefix = forms.CharField( "Prefix for all URLs", help_text=("For example 'accounts' -> '/accounts/login'"), required=False, ) enable_python_social_auth = forms.CheckboxField( 'Enable social auth', required=False, initial=False, ) # https://python-social-auth.readthedocs.io/en/latest/backends/google.html#google-oauth2 psa_google_oauth2 = forms.CheckboxField( 'Social Auth via Google OAuth2', required=False, initial=False, ) psa_facebook_oauth2 = forms.CheckboxField( 'Social Auth via Facebook OAuth2', required=False, initial=False, ) def set_psa_settings(self, key_base, settings): for arg in ('KEY', 'SECRET', 'SCOPE'): key = '{}_{}'.format(key_base, arg) val = env(key) if arg == 'SCOPE': if val and val.startswith('['): val = ast.literal_eval(val) else: val = [] settings[key] = val def extend_context_processors(self, settings, context_processors): if settings.get('TEMPLATES'): settings['TEMPLATES'][0]['OPTIONS'][ 'context_processors'] += context_processors else: settings['TEMPLATE_CONTEXT_PROCESSORS'] += context_processors def to_settings(self, data, settings): settings.update({ 'ALDRYN_ACCOUNTS_USE_PROFILE_APPHOOKS': data['use_profile_apphooks'], 'ALDRYN_ACCOUNTS_OPEN_SIGNUP': data['open_signup'], 'ALDRYN_ACCOUNTS_NOTIFY_PASSWORD_CHANGE': data['notify_password_change'], 'ALDRYN_ACCOUNTS_PASSWORD_CHANGE_REDIRECT_URL': data['password_change_redirect_url'], 'ALDRYN_ACCOUNTS_EMAIL_CONFIRMATION_EMAIL': data['email_confirmation_email'], 'ALDRYN_ACCOUNTS_EMAIL_CONFIRMATION_EXPIRE_DAYS': data['email_confirmation_expire_days'], 'ALDRYN_ACCOUNTS_RESTORE_PASSWORD_RAISE_VALIDATION_ERROR': data['restore_password_raise_validation_error'], 'ALDRYN_ACCOUNTS_USER_DISPLAY_FALLBACK_TO_USERNAME': data['user_display_fallback_to_username'], 'ALDRYN_ACCOUNTS_USER_DISPLAY_FALLBACK_TO_PK': data['user_display_fallback_to_pk'], 'ALDRYN_ACCOUNTS_LOGIN_REDIRECT_URL': data['login_redirect_url'], 'ALDRYN_ACCOUNTS_SIGNUP_REDIRECT_URL': data['signup_redirect_url'], 'ALDRYN_ACCOUNTS_DISPLAY_EMAIL_NOTIFICATION': data['display_email_notifications'], 'ALDRYN_ACCOUNTS_DISPLAY_PASSWORD_NOTIFICATION': data['display_password_notifications'], 'ALDRYN_ACCOUNTS_URLS_PREFIX': data['urls_prefix'], }) # setup accounts login features and other urls # we have to specify those urls because add-on urls settings.update({ 'LOGIN_URL': '/login/', 'LOGOUT_URL': '/logout/', }) settings['INSTALLED_APPS'].append('aldryn_accounts') settings['ADDON_URLS'].append('aldryn_accounts.urls') settings['ADDON_URLS_I18N'].append('aldryn_accounts.urls_i18n') self.extend_context_processors( settings, ('aldryn_accounts.context_processors.notifications', )) # social auth enable_psa = data['enable_python_social_auth'] settings['ALDRYN_ACCOUNTS_ENABLE_PYTHON_SOCIAL_AUTH'] = enable_psa if enable_psa: settings['INSTALLED_APPS'].append('social_django') add_to_auth_backends = settings['AUTHENTICATION_BACKENDS'].append if data['psa_google_oauth2']: add_to_auth_backends( 'social_core.backends.google.GoogleOAuth2') self.set_psa_settings('SOCIAL_AUTH_GOOGLE_OAUTH2', settings) if data['psa_facebook_oauth2']: add_to_auth_backends( 'social_core.backends.facebook.FacebookOAuth2') self.set_psa_settings('SOCIAL_AUTH_FACEBOOK', settings) self.extend_context_processors(settings, ( 'social_django.context_processors.backends', 'social_django.context_processors.login_redirect', )) settings['SOCIAL_AUTH_PIPELINE'] = [ 'social_core.pipeline.social_auth.social_details', 'social_core.pipeline.social_auth.social_uid', 'social_core.pipeline.social_auth.auth_allowed', 'social_core.pipeline.social_auth.social_user', 'aldryn_accounts.social_auth_pipelines.get_username', 'aldryn_accounts.social_auth_pipelines.require_email', 'aldryn_accounts.social_auth_pipelines.link_to_existing_user_by_email_if_backend_is_trusted', 'aldryn_accounts.social_auth_pipelines.create_user', 'aldryn_accounts.social_auth_pipelines.set_profile_image', 'social_core.pipeline.social_auth.associate_user', 'social_core.pipeline.social_auth.load_extra_data', 'social_core.pipeline.user.user_details', 'aldryn_accounts.social_auth_pipelines.redirect_to_email_form', ] return settings
class Form(forms.BaseForm): languages = forms.CharField( "Languages", required=True, initial='["en", "de"]' ) 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." ), ) 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 django_cache_url import dj_database_url import warnings from functools import partial from aldryn_addons.utils import boolean_ish, djsenv env = partial(djsenv, settings=settings) # BASE_DIR should already be set by aldryn-addons settings["BASE_DIR"] = env("BASE_DIR", required=True) 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["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") 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:" settings["CACHE_URL"] = "locmem://" if not settings["DATABASE_URL"]: settings["DATABASE_URL"] = "sqlite:///{}".format( os.path.join(settings["DATA_ROOT"], "db.sqlite3") ) warnings.warn( "no database configured. Falling back to DATABASE_URL={0}".format( settings["DATABASE_URL"] ), RuntimeWarning, ) 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_I18N"].append("aldryn_django.i18n_urls") settings["WSGI_APPLICATION"] = "wsgi.application" settings["INSTALLED_APPS"].extend( [ "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", "django.contrib.admin", "django.contrib.staticfiles", "aldryn_django", ] ) 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.template.context_processors.i18n", "django.template.context_processors.debug", "django.template.context_processors.request", "django.template.context_processors.media", "django.template.context_processors.csrf", "django.template.context_processors.tz", "django.template.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", "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["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) # 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 domain = env("DOMAIN") if domain: settings["DOMAIN"] = domain 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": domain_aliases, "redirects": domain_redirects, } } settings["ALDRYN_SITES_DOMAINS"] = domains 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", ) def server_settings(self, settings, env): settings["PORT"] = env("PORT", 80) settings["BACKEND_PORT"] = env("BACKEND_PORT", 8000) settings["STATICFILES_DEFAULT_MAX_AGE"] = env( "STATICFILES_DEFAULT_MAX_AGE", 300 ) 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, "disable_existing_loggers": False, "filters": { "require_debug_false": { "()": "django.utils.log.RequireDebugFalse" }, "require_debug_true": { "()": "django.utils.log.RequireDebugTrue" }, }, "handlers": { "console": { "level": "INFO", "class": "logging.StreamHandler", "stream": sys.stdout, }, "null": {"class": "logging.NullHandler"}, }, "loggers": { "": {"handlers": ["console"], "level": "INFO"}, "django": {"handlers": ["console"], "level": "INFO"}, "django.request": { "handlers": ["console"], "level": "INFO", "propagate": False, }, "aldryn": {"handlers": ["console"], "level": "INFO"}, "py.warnings": {"handlers": ["console"]}, }, } def sentry_settings(self, settings, env): sentry_dsn = env("SENTRY_DSN") if sentry_dsn: import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration sentry_sdk.init( dsn=sentry_dsn, integrations=[DjangoIntegration()], debug=settings["DEBUG"], release=env("GIT_COMMIT", "develop"), environment=env("STAGE", "local"), ) 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"]) settings["ALL_LANGUAGES_DICT"] = dict(settings["ALL_LANGUAGES"]) settings["USE_L10N"] = True settings["USE_I18N"] = True 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") ] settings["PREFIX_DEFAULT_LANGUAGE"] = not data[ "disable_default_language_prefix" ] 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( '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")