Merge branch 'master' into static-media
[mygpo.git] / mygpo / settings.py
blob2e1122fe7e48b176e72b6bcc13545f825dd09260
1 import re
2 import sys
3 import os.path
4 import dj_database_url
7 try:
8 from psycopg2cffi import compat
9 compat.register()
10 except ImportError:
11 pass
14 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
17 def get_bool(name, default):
18 return os.getenv(name, str(default)).lower() == 'true'
21 def get_intOrNone(name, default):
22 """ Parses the env variable, accepts ints and literal None"""
23 value = os.getenv(name, str(default))
24 if value.lower() == 'none':
25 return None
26 return int(value)
29 DEBUG = get_bool('DEBUG', False)
31 ADMINS = re.findall(r'\s*([^<]+) <([^>]+)>\s*', os.getenv('ADMINS', ''))
33 MANAGERS = ADMINS
35 DATABASES = {
36 'default': dj_database_url.config(
37 default='postgres://mygpo:mygpo@localhost/mygpo'),
41 _cache_used = bool(os.getenv('CACHE_BACKEND', False))
43 if _cache_used:
44 CACHES = {}
45 CACHES['default'] = {
46 'BACKEND': os.getenv(
47 'CACHE_BACKEND',
48 'django.core.cache.backends.memcached.MemcachedCache'),
49 'LOCATION': os.getenv('CACHE_LOCATION'),
53 # Local time zone for this installation. Choices can be found here:
54 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
55 # although not all choices may be available on all operating systems.
56 # If running in a Windows environment this must be set to the same as your
57 # system time zone.
58 TIME_ZONE = 'UTC'
60 # Language code for this installation. All choices can be found here:
61 # http://www.i18nguy.com/unicode/language-identifiers.html
62 LANGUAGE_CODE = 'en-us'
64 SITE_ID = 1
66 # If you set this to False, Django will make some optimizations so as not
67 # to load the internationalization machinery.
68 USE_I18N = True
71 # Static Files
73 STATIC_ROOT = 'staticfiles'
74 STATIC_URL = '/static/'
76 STATICFILES_DIRS = (
77 os.path.abspath(os.path.join(BASE_DIR, '..', 'static')),
81 # Media Files
83 MEDIA_ROOT = os.getenv('MEDIA_ROOT',
84 os.path.abspath(os.path.join(BASE_DIR, '..', 'media')))
86 MEDIA_URL = '/media/'
89 TEMPLATES = [{
90 'BACKEND': 'django.template.backends.django.DjangoTemplates',
91 'DIRS': [],
92 'OPTIONS': {
93 'debug': DEBUG,
94 'context_processors': [
95 'django.contrib.auth.context_processors.auth',
96 'django.template.context_processors.debug',
97 'django.template.context_processors.i18n',
98 'django.template.context_processors.media',
99 'django.template.context_processors.static',
100 'django.template.context_processors.tz',
101 'django.contrib.messages.context_processors.messages',
102 'mygpo.web.google.analytics',
103 'mygpo.web.google.adsense',
104 # make the debug variable available in templates
105 # https://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-debug
106 'django.template.context_processors.debug',
108 # required so that the request obj can be accessed from
109 # templates. this is used to direct users to previous
110 # page after login
111 'django.template.context_processors.request',
113 'libraries': {
114 'staticfiles' : 'django.templatetags.static',
116 'loaders': [
117 ('django.template.loaders.cached.Loader', [
118 'django.template.loaders.app_directories.Loader',
125 MIDDLEWARE = [
126 'django.middleware.common.CommonMiddleware',
127 'django.middleware.csrf.CsrfViewMiddleware',
128 'django.contrib.sessions.middleware.SessionMiddleware',
129 'django.contrib.auth.middleware.AuthenticationMiddleware',
130 'django.middleware.locale.LocaleMiddleware',
131 'django.contrib.messages.middleware.MessageMiddleware',
134 ROOT_URLCONF = 'mygpo.urls'
136 INSTALLED_APPS = [
137 'django.contrib.contenttypes',
138 'django.contrib.messages',
139 'django.contrib.admin',
140 'django.contrib.humanize',
141 'django.contrib.auth',
142 'django.contrib.sessions',
143 'django.contrib.staticfiles',
144 'django.contrib.sites',
145 'django.contrib.postgres',
146 'django_celery_results',
147 'django_celery_beat',
148 'mygpo.core',
149 'mygpo.podcasts',
150 'mygpo.chapters',
151 'mygpo.search',
152 'mygpo.users',
153 'mygpo.api',
154 'mygpo.web',
155 'mygpo.publisher',
156 'mygpo.subscriptions',
157 'mygpo.history',
158 'mygpo.favorites',
159 'mygpo.usersettings',
160 'mygpo.data',
161 'mygpo.userfeeds',
162 'mygpo.suggestions',
163 'mygpo.directory',
164 'mygpo.categories',
165 'mygpo.episodestates',
166 'mygpo.maintenance',
167 'mygpo.share',
168 'mygpo.administration',
169 'mygpo.pubsub',
170 'mygpo.podcastlists',
171 'mygpo.votes',
172 'django_nose',
175 try:
176 if DEBUG:
177 import debug_toolbar
178 INSTALLED_APPS += ['debug_toolbar']
179 MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
181 except ImportError:
182 pass
185 try:
186 if DEBUG:
187 import django_extensions
188 INSTALLED_APPS += ['django_extensions']
190 except ImportError:
191 pass
194 try:
195 import opbeat
197 if not DEBUG:
198 INSTALLED_APPS += ['opbeat.contrib.django']
200 except ImportError:
201 pass
204 ACCOUNT_ACTIVATION_DAYS = int(os.getenv('ACCOUNT_ACTIVATION_DAYS', 7))
206 AUTHENTICATION_BACKENDS = (
207 'mygpo.users.backend.CaseInsensitiveModelBackend',
208 'mygpo.web.auth.EmailAuthenticationBackend',
211 SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
213 # TODO: use (default) JSON serializer for security
214 # this would currently fail as we're (de)serializing datetime objects
215 # https://docs.djangoproject.com/en/1.5/topics/http/sessions/#session-serialization
216 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
219 MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
221 USER_CLASS = 'mygpo.users.models.User'
223 LOGIN_URL = '/login/'
225 CSRF_FAILURE_VIEW = 'mygpo.web.views.csrf_failure'
228 DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', '')
230 SECRET_KEY = os.getenv('SECRET_KEY', '')
232 if 'test' in sys.argv:
233 SECRET_KEY = 'test'
235 GOOGLE_ANALYTICS_PROPERTY_ID = os.getenv('GOOGLE_ANALYTICS_PROPERTY_ID', '')
237 DIRECTORY_EXCLUDED_TAGS = os.getenv('DIRECTORY_EXCLUDED_TAGS', '').split()
239 FLICKR_API_KEY = os.getenv('FLICKR_API_KEY', '')
241 SOUNDCLOUD_CONSUMER_KEY = os.getenv('SOUNDCLOUD_CONSUMER_KEY', '')
243 MAINTENANCE = get_bool('MAINTENANCE', False)
246 ALLOWED_HOSTS = ['*']
249 LOGGING = {
250 'version': 1,
251 'disable_existing_loggers': False,
252 'formatters': {
253 'verbose': {
254 'format': '%(asctime)s %(name)s %(levelname)s %(message)s',
257 'filters': {
258 'require_debug_false': {
259 '()': 'django.utils.log.RequireDebugFalse'
262 'handlers': {
263 'console': {
264 'level': os.getenv('LOGGING_CONSOLE_LEVEL', 'DEBUG'),
265 'class': 'logging.StreamHandler',
266 'formatter': 'verbose',
268 'mail_admins': {
269 'level': 'ERROR',
270 'filters': ['require_debug_false'],
271 'class': 'django.utils.log.AdminEmailHandler',
274 'loggers': {
275 'django': {
276 'handlers': os.getenv('LOGGING_DJANGO_HANDLERS',
277 'console').split(),
278 'propagate': True,
279 'level': os.getenv('LOGGING_DJANGO_LEVEL', 'WARN'),
281 'mygpo': {
282 'handlers': os.getenv('LOGGING_MYGPO_HANDLERS', 'console').split(),
283 'level': os.getenv('LOGGING_MYGPO_LEVEL', 'INFO'),
285 'celery': {
286 'handlers': os.getenv('LOGGING_CELERY_HANDLERS',
287 'console').split(),
288 'level': os.getenv('LOGGING_CELERY_LEVEL', 'DEBUG'),
293 _use_log_file = bool(os.getenv('LOGGING_FILENAME', False))
295 if _use_log_file:
296 LOGGING['handlers']['file'] = {
297 'level': 'INFO',
298 'class': 'logging.handlers.RotatingFileHandler',
299 'filename': os.getenv('LOGGING_FILENAME'),
300 'maxBytes': 10000000,
301 'backupCount': 10,
302 'formatter': 'verbose',
306 # minimum number of subscribers a podcast must have to be assigned a slug
307 PODCAST_SLUG_SUBSCRIBER_LIMIT = int(os.getenv(
308 'PODCAST_SLUG_SUBSCRIBER_LIMIT', 10))
310 # minimum number of subscribers that a podcast needs to "push" one of its
311 # categories to the top
312 MIN_SUBSCRIBERS_CATEGORY = int(os.getenv('MIN_SUBSCRIBERS_CATEGORY', 10))
314 # maximum number of episode actions that the API processes immediatelly before
315 # returning the response. Larger requests will be handled in background.
316 # Handler can be set to None to disable
317 API_ACTIONS_MAX_NONBG = int(os.getenv('API_ACTIONS_MAX_NONBG', 100))
318 API_ACTIONS_BG_HANDLER = 'mygpo.api.tasks.episode_actions_celery_handler'
321 ADSENSE_CLIENT = os.getenv('ADSENSE_CLIENT', '')
323 ADSENSE_SLOT_BOTTOM = os.getenv('ADSENSE_SLOT_BOTTOM', '')
325 # we're running behind a proxy that sets the X-Forwarded-Proto header correctly
326 # see https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
327 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
330 # enabled access to staff-only areas with ?staff=<STAFF_TOKEN>
331 STAFF_TOKEN = os.getenv('STAFF_TOKEN', None)
333 # The User-Agent string used for outgoing HTTP requests
334 USER_AGENT = 'gpodder.net (+https://github.com/gpodder/mygpo)'
336 # Base URL of the website that is used if the actually used parameters is not
337 # available. Request handlers, for example, can access the requested domain.
338 # Code that runs in background can not do this, and therefore requires a
339 # default value. This should be set to something like 'http://example.com'
340 DEFAULT_BASE_URL = os.getenv('DEFAULT_BASE_URL', '')
343 ### Celery
345 CELERY_BROKER_URL = os.getenv('BROKER_URL', 'redis://localhost')
346 CELERY_RESULT_BACKEND = 'django-db'
348 CELERY_RESULT_EXPIRES = 60 * 60 # 1h expiry time in seconds
350 CELERY_ACCEPT_CONTENT = ['json']
353 ### Google API
355 GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID', '')
356 GOOGLE_CLIENT_SECRET = os.getenv('GOOGLE_CLIENT_SECRET', '')
358 # URL where users of the site can get support
359 SUPPORT_URL = os.getenv('SUPPORT_URL', '')
362 FEEDSERVICE_URL = os.getenv('FEEDSERVICE_URL', 'http://feeds.gpodder.net/')
365 # time for how long an activation is valid; after that, an unactivated user
366 # will be deleted
367 ACTIVATION_VALID_DAYS = int(os.getenv('ACTIVATION_VALID_DAYS', 10))
370 OPBEAT = {
371 "ORGANIZATION_ID": os.getenv('OPBEAT_ORGANIZATION_ID', ''),
372 "APP_ID": os.getenv('OPBEAT_APP_ID', ''),
373 "SECRET_TOKEN": os.getenv('OPBEAT_SECRET_TOKEN', ''),
376 LOCALE_PATHS = [
377 os.path.abspath(os.path.join(BASE_DIR, 'locale')),
380 INTERNAL_IPS = os.getenv('INTERNAL_IPS', '').split()
382 EMAIL_BACKEND = os.getenv('EMAIL_BACKEND',
383 'django.core.mail.backends.smtp.EmailBackend')
385 PODCAST_AD_ID = os.getenv('PODCAST_AD_ID')
387 TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
389 NOSE_ARGS = [
390 '--with-doctest',
391 '--stop',
392 '--where=mygpo',
396 SEARCH_CUTOFF = float(os.getenv('SEARCH_CUTOFF', 0.3))