1 # Django settings for mygpo project.
3 # This file is part of my.gpodder.org.
5 # my.gpodder.org is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Affero General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or (at your
8 # option) any later version.
10 # my.gpodder.org is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
13 # License for more details.
15 # You should have received a copy of the GNU Affero General Public License
16 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
22 import dj_database_url
25 BASE_DIR
= os
.path
.dirname(os
.path
.abspath(__file__
))
28 def get_bool(name
, default
):
29 return os
.getenv(name
, str(default
)).lower() == 'true'
32 DEBUG
= get_bool('DEBUG', False)
34 ADMINS
= re
.findall(r
'\s*([^<]+) <([^>]+)>\s*', os
.getenv('ADMINS', ''))
39 'default': dj_database_url
.config(
40 default
='postgres://mygpo:mygpo@localhost/mygpo'),
44 _cache_used
= bool(os
.getenv('CACHE_BACKEND', False))
51 'django.core.cache.backends.memcached.MemcachedCache'),
52 'LOCATION': os
.getenv('CACHE_LOCATION'),
56 # Local time zone for this installation. Choices can be found here:
57 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
58 # although not all choices may be available on all operating systems.
59 # If running in a Windows environment this must be set to the same as your
63 # Language code for this installation. All choices can be found here:
64 # http://www.i18nguy.com/unicode/language-identifiers.html
65 LANGUAGE_CODE
= 'en-us'
69 # If you set this to False, Django will make some optimizations so as not
70 # to load the internationalization machinery.
73 STATIC_ROOT
= 'staticfiles'
74 STATIC_URL
= '/media/'
77 os
.path
.abspath(os
.path
.join(BASE_DIR
, '..', 'htdocs', 'media')),
82 'BACKEND': 'django.template.backends.django.DjangoTemplates',
85 'context_processors': [
86 'django.contrib.auth.context_processors.auth',
87 'django.template.context_processors.debug',
88 'django.template.context_processors.i18n',
89 'django.template.context_processors.media',
90 'django.template.context_processors.static',
91 'django.template.context_processors.tz',
92 'django.contrib.messages.context_processors.messages',
93 'mygpo.web.google.analytics',
94 'mygpo.web.google.adsense',
95 # make the debug variable available in templates
96 # https://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-debug
97 'django.core.context_processors.debug',
99 # required so that the request obj can be accessed from
100 # templates. this is used to direct users to previous
102 'django.core.context_processors.request',
105 ('django.template.loaders.cached.Loader', [
106 'django.template.loaders.app_directories.Loader',
113 MIDDLEWARE_CLASSES
= (
114 'django.middleware.common.CommonMiddleware',
115 'django.middleware.csrf.CsrfViewMiddleware',
116 'django.contrib.sessions.middleware.SessionMiddleware',
117 'django.contrib.auth.middleware.AuthenticationMiddleware',
118 'django.middleware.locale.LocaleMiddleware',
119 'django.contrib.messages.middleware.MessageMiddleware',
122 ROOT_URLCONF
= 'mygpo.urls'
125 'django.contrib.contenttypes',
126 'django.contrib.messages',
127 'django.contrib.admin',
128 'django.contrib.humanize',
129 'django.contrib.auth',
130 'django.contrib.sessions',
131 'django.contrib.staticfiles',
132 'django.contrib.sites',
142 'mygpo.subscriptions',
145 'mygpo.usersettings',
151 'mygpo.episodestates',
154 'mygpo.administration',
156 'mygpo.podcastlists',
162 INSTALLED_APPS
+= ('debug_toolbar', )
172 INSTALLED_APPS
+= ('opbeat.contrib.django', )
174 # add opbeat middleware to the beginning of the middleware classes list
175 MIDDLEWARE_CLASSES
= \
176 ('opbeat.contrib.django.middleware.OpbeatAPMMiddleware',) + \
183 ACCOUNT_ACTIVATION_DAYS
= int(os
.getenv('ACCOUNT_ACTIVATION_DAYS', 7))
185 AUTHENTICATION_BACKENDS
= (
186 'mygpo.users.backend.CaseInsensitiveModelBackend',
187 'mygpo.web.auth.EmailAuthenticationBackend',
190 SESSION_ENGINE
= "django.contrib.sessions.backends.cached_db"
192 # TODO: use (default) JSON serializer for security
193 # this would currently fail as we're (de)serializing datetime objects
194 # https://docs.djangoproject.com/en/1.5/topics/http/sessions/#session-serialization
195 SESSION_SERIALIZER
= 'django.contrib.sessions.serializers.PickleSerializer'
198 MESSAGE_STORAGE
= 'django.contrib.messages.storage.session.SessionStorage'
200 USER_CLASS
= 'mygpo.users.models.User'
202 LOGIN_URL
= '/login/'
204 CSRF_FAILURE_VIEW
= 'mygpo.web.views.csrf_failure'
207 DEFAULT_FROM_EMAIL
= os
.getenv('DEFAULT_FROM_EMAIL', '')
209 SECRET_KEY
= os
.getenv('SECRET_KEY', '')
211 if 'test' in sys
.argv
:
214 GOOGLE_ANALYTICS_PROPERTY_ID
= os
.getenv('GOOGLE_ANALYTICS_PROPERTY_ID', '')
216 DIRECTORY_EXCLUDED_TAGS
= os
.getenv('DIRECTORY_EXCLUDED_TAGS', '').split()
218 FLICKR_API_KEY
= os
.getenv('FLICKR_API_KEY', '')
220 SOUNDCLOUD_CONSUMER_KEY
= os
.getenv('SOUNDCLOUD_CONSUMER_KEY', '')
222 MAINTENANCE
= get_bool('MAINTENANCE', False)
225 ALLOWED_HOSTS
= ['*']
230 'disable_existing_loggers': False,
233 'format': '%(asctime)s %(name)s %(levelname)s %(message)s',
237 'require_debug_false': {
238 '()': 'django.utils.log.RequireDebugFalse'
243 'level': os
.getenv('LOGGING_CONSOLE_LEVEL', 'DEBUG'),
244 'class': 'logging.StreamHandler',
245 'formatter': 'verbose',
249 'filters': ['require_debug_false'],
250 'class': 'django.utils.log.AdminEmailHandler',
255 'handlers': os
.getenv('LOGGING_DJANGO_HANDLERS',
258 'level': os
.getenv('LOGGING_DJANGO_LEVEL', 'WARN'),
261 'handlers': os
.getenv('LOGGING_MYGPO_HANDLERS', 'console').split(),
262 'level': os
.getenv('LOGGING_MYGPO_LEVEL', 'INFO'),
265 'handlers': os
.getenv('LOGGING_CELERY_HANDLERS',
267 'level': os
.getenv('LOGGING_CELERY_LEVEL', 'DEBUG'),
272 _use_log_file
= bool(os
.getenv('LOGGING_FILENAME', False))
275 LOGGING
['handlers']['file'] = {
277 'class': 'logging.handlers.RotatingFileHandler',
278 'filename': os
.getenv('LOGGING_FILENAME'),
279 'maxBytes': 10000000,
281 'formatter': 'verbose',
285 # minimum number of subscribers a podcast must have to be assigned a slug
286 PODCAST_SLUG_SUBSCRIBER_LIMIT
= int(os
.getenv(
287 'PODCAST_SLUG_SUBSCRIBER_LIMIT', 10))
289 # minimum number of subscribers that a podcast needs to "push" one of its
290 # categories to the top
291 MIN_SUBSCRIBERS_CATEGORY
= int(os
.getenv('MIN_SUBSCRIBERS_CATEGORY', 10))
293 # maximum number of episode actions that the API processes immediatelly before
294 # returning the response. Larger requests will be handled in background.
295 # Handler can be set to None to disable
296 API_ACTIONS_MAX_NONBG
= int(os
.getenv('API_ACTIONS_MAX_NONBG', 100))
297 API_ACTIONS_BG_HANDLER
= 'mygpo.api.tasks.episode_actions_celery_handler'
300 ADSENSE_CLIENT
= os
.getenv('ADSENSE_CLIENT', '')
302 ADSENSE_SLOT_BOTTOM
= os
.getenv('ADSENSE_SLOT_BOTTOM', '')
304 # we're running behind a proxy that sets the X-Forwarded-Proto header correctly
305 # see https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
306 SECURE_PROXY_SSL_HEADER
= ('HTTP_X_FORWARDED_PROTO', 'https')
309 # enabled access to staff-only areas with ?staff=<STAFF_TOKEN>
310 STAFF_TOKEN
= os
.getenv('STAFF_TOKEN', None)
312 # Flattr settings -- available after you register your app
313 FLATTR_KEY
= os
.getenv('FLATTR_KEY', '')
314 FLATTR_SECRET
= os
.getenv('FLATTR_SECRET', '')
316 # Flattr thing of the webservice. Will be flattr'd when a user sets
317 # the "Auto-Flattr gpodder.net" option
318 FLATTR_MYGPO_THING
= os
.getenv(
319 'FLATTR_MYGPO_THING',
320 'https://flattr.com/submit/auto?user_id=stefankoegl&url=http://gpodder.net'
323 # The User-Agent string used for outgoing HTTP requests
324 USER_AGENT
= 'gpodder.net (+https://github.com/gpodder/mygpo)'
326 # Base URL of the website that is used if the actually used parameters is not
327 # available. Request handlers, for example, can access the requested domain.
328 # Code that runs in background can not do this, and therefore requires a
329 # default value. This should be set to something like 'http://example.com'
330 DEFAULT_BASE_URL
= os
.getenv('DEFAULT_BASE_URL', '')
335 BROKER_URL
= os
.getenv('BROKER_URL', 'redis://localhost')
336 CELERY_RESULT_BACKEND
= 'djcelery.backends.database:DatabaseBackend'
338 SERVER_EMAIL
= os
.getenv('SERVER_EMAIL', 'no-reply@example.com')
340 CELERY_TASK_RESULT_EXPIRES
= 60 * 60 # 1h expiry time in seconds
342 CELERY_ACCEPT_CONTENT
= ['pickle', 'json']
344 CELERY_SEND_TASK_ERROR_EMAILS
= get_bool('CELERY_SEND_TASK_ERROR_EMAILS',
349 GOOGLE_CLIENT_ID
= os
.getenv('GOOGLE_CLIENT_ID', '')
350 GOOGLE_CLIENT_SECRET
= os
.getenv('GOOGLE_CLIENT_SECRET', '')
352 # URL where users of the site can get support
353 SUPPORT_URL
= os
.getenv('SUPPORT_URL', '')
356 FEEDSERVICE_URL
= os
.getenv('FEEDSERVICE_URL', 'http://feeds.gpodder.net/')
358 # Elasticsearch settings
360 ELASTICSEARCH_SERVER
= os
.getenv('ELASTICSEARCH_SERVER', '127.0.0.1:9200')
361 ELASTICSEARCH_INDEX
= os
.getenv('ELASTICSEARCH_INDEX', 'mygpo')
362 ELASTICSEARCH_TIMEOUT
= float(os
.getenv('ELASTICSEARCH_TIMEOUT', '2'))
364 # time for how long an activation is valid; after that, an unactivated user
366 ACTIVATION_VALID_DAYS
= int(os
.getenv('ACTIVATION_VALID_DAYS', 10))
370 "ORGANIZATION_ID": os
.getenv('OPBEAT_ORGANIZATION_ID', ''),
371 "APP_ID": os
.getenv('OPBEAT_APP_ID', ''),
372 "SECRET_TOKEN": os
.getenv('OPBEAT_SECRET_TOKEN', ''),
376 INTERNAL_IPS
= os
.getenv('INTERNAL_IPS', '').split()
378 EMAIL_BACKEND
= os
.getenv('EMAIL_BACKEND',
379 'django.core.mail.backends.smtp.EmailBackend')