Merge branch 'master' into pg-search
[mygpo.git] / mygpo / settings.py
blob7b208bab16b096e95d168706b7e8c2f563dbbdaa
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
70 STATIC_ROOT = 'staticfiles'
71 STATIC_URL = '/media/'
73 STATICFILES_DIRS = (
74 os.path.abspath(os.path.join(BASE_DIR, '..', 'htdocs', 'media')),
78 TEMPLATES = [{
79 'BACKEND': 'django.template.backends.django.DjangoTemplates',
80 'DIRS': [],
81 'OPTIONS': {
82 'debug': DEBUG,
83 'context_processors': [
84 'django.contrib.auth.context_processors.auth',
85 'django.template.context_processors.debug',
86 'django.template.context_processors.i18n',
87 'django.template.context_processors.media',
88 'django.template.context_processors.static',
89 'django.template.context_processors.tz',
90 'django.contrib.messages.context_processors.messages',
91 'mygpo.web.google.analytics',
92 'mygpo.web.google.adsense',
93 # make the debug variable available in templates
94 # https://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-debug
95 'django.template.context_processors.debug',
97 # required so that the request obj can be accessed from
98 # templates. this is used to direct users to previous
99 # page after login
100 'django.template.context_processors.request',
102 'libraries': {
103 'staticfiles' : 'django.templatetags.static',
105 'loaders': [
106 ('django.template.loaders.cached.Loader', [
107 'django.template.loaders.app_directories.Loader',
114 MIDDLEWARE = [
115 'django.middleware.common.CommonMiddleware',
116 'django.middleware.csrf.CsrfViewMiddleware',
117 'django.contrib.sessions.middleware.SessionMiddleware',
118 'django.contrib.auth.middleware.AuthenticationMiddleware',
119 'django.middleware.locale.LocaleMiddleware',
120 'django.contrib.messages.middleware.MessageMiddleware',
123 ROOT_URLCONF = 'mygpo.urls'
125 INSTALLED_APPS = [
126 'django.contrib.contenttypes',
127 'django.contrib.messages',
128 'django.contrib.admin',
129 'django.contrib.humanize',
130 'django.contrib.auth',
131 'django.contrib.sessions',
132 'django.contrib.staticfiles',
133 'django.contrib.sites',
134 'django.contrib.postgres',
135 'django_celery_results',
136 'django_celery_beat',
137 'mygpo.core',
138 'mygpo.podcasts',
139 'mygpo.chapters',
140 'mygpo.search',
141 'mygpo.users',
142 'mygpo.api',
143 'mygpo.web',
144 'mygpo.publisher',
145 'mygpo.subscriptions',
146 'mygpo.history',
147 'mygpo.favorites',
148 'mygpo.usersettings',
149 'mygpo.data',
150 'mygpo.userfeeds',
151 'mygpo.suggestions',
152 'mygpo.directory',
153 'mygpo.categories',
154 'mygpo.episodestates',
155 'mygpo.maintenance',
156 'mygpo.share',
157 'mygpo.administration',
158 'mygpo.pubsub',
159 'mygpo.podcastlists',
160 'mygpo.votes',
161 'django_nose',
164 try:
165 if DEBUG:
166 import debug_toolbar
167 INSTALLED_APPS += ['debug_toolbar']
168 MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
170 except ImportError:
171 pass
174 try:
175 import opbeat
177 if not DEBUG:
178 INSTALLED_APPS += ['opbeat.contrib.django']
180 except ImportError:
181 pass
184 ACCOUNT_ACTIVATION_DAYS = int(os.getenv('ACCOUNT_ACTIVATION_DAYS', 7))
186 AUTHENTICATION_BACKENDS = (
187 'mygpo.users.backend.CaseInsensitiveModelBackend',
188 'mygpo.web.auth.EmailAuthenticationBackend',
191 SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
193 # TODO: use (default) JSON serializer for security
194 # this would currently fail as we're (de)serializing datetime objects
195 # https://docs.djangoproject.com/en/1.5/topics/http/sessions/#session-serialization
196 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
199 MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
201 USER_CLASS = 'mygpo.users.models.User'
203 LOGIN_URL = '/login/'
205 CSRF_FAILURE_VIEW = 'mygpo.web.views.csrf_failure'
208 DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', '')
210 SECRET_KEY = os.getenv('SECRET_KEY', '')
212 if 'test' in sys.argv:
213 SECRET_KEY = 'test'
215 GOOGLE_ANALYTICS_PROPERTY_ID = os.getenv('GOOGLE_ANALYTICS_PROPERTY_ID', '')
217 DIRECTORY_EXCLUDED_TAGS = os.getenv('DIRECTORY_EXCLUDED_TAGS', '').split()
219 FLICKR_API_KEY = os.getenv('FLICKR_API_KEY', '')
221 SOUNDCLOUD_CONSUMER_KEY = os.getenv('SOUNDCLOUD_CONSUMER_KEY', '')
223 MAINTENANCE = get_bool('MAINTENANCE', False)
226 ALLOWED_HOSTS = ['*']
229 LOGGING = {
230 'version': 1,
231 'disable_existing_loggers': False,
232 'formatters': {
233 'verbose': {
234 'format': '%(asctime)s %(name)s %(levelname)s %(message)s',
237 'filters': {
238 'require_debug_false': {
239 '()': 'django.utils.log.RequireDebugFalse'
242 'handlers': {
243 'console': {
244 'level': os.getenv('LOGGING_CONSOLE_LEVEL', 'DEBUG'),
245 'class': 'logging.StreamHandler',
246 'formatter': 'verbose',
248 'mail_admins': {
249 'level': 'ERROR',
250 'filters': ['require_debug_false'],
251 'class': 'django.utils.log.AdminEmailHandler',
254 'loggers': {
255 'django': {
256 'handlers': os.getenv('LOGGING_DJANGO_HANDLERS',
257 'console').split(),
258 'propagate': True,
259 'level': os.getenv('LOGGING_DJANGO_LEVEL', 'WARN'),
261 'mygpo': {
262 'handlers': os.getenv('LOGGING_MYGPO_HANDLERS', 'console').split(),
263 'level': os.getenv('LOGGING_MYGPO_LEVEL', 'INFO'),
265 'celery': {
266 'handlers': os.getenv('LOGGING_CELERY_HANDLERS',
267 'console').split(),
268 'level': os.getenv('LOGGING_CELERY_LEVEL', 'DEBUG'),
273 _use_log_file = bool(os.getenv('LOGGING_FILENAME', False))
275 if _use_log_file:
276 LOGGING['handlers']['file'] = {
277 'level': 'INFO',
278 'class': 'logging.handlers.RotatingFileHandler',
279 'filename': os.getenv('LOGGING_FILENAME'),
280 'maxBytes': 10000000,
281 'backupCount': 10,
282 'formatter': 'verbose',
286 # minimum number of subscribers a podcast must have to be assigned a slug
287 PODCAST_SLUG_SUBSCRIBER_LIMIT = int(os.getenv(
288 'PODCAST_SLUG_SUBSCRIBER_LIMIT', 10))
290 # minimum number of subscribers that a podcast needs to "push" one of its
291 # categories to the top
292 MIN_SUBSCRIBERS_CATEGORY = int(os.getenv('MIN_SUBSCRIBERS_CATEGORY', 10))
294 # maximum number of episode actions that the API processes immediatelly before
295 # returning the response. Larger requests will be handled in background.
296 # Handler can be set to None to disable
297 API_ACTIONS_MAX_NONBG = int(os.getenv('API_ACTIONS_MAX_NONBG', 100))
298 API_ACTIONS_BG_HANDLER = 'mygpo.api.tasks.episode_actions_celery_handler'
301 ADSENSE_CLIENT = os.getenv('ADSENSE_CLIENT', '')
303 ADSENSE_SLOT_BOTTOM = os.getenv('ADSENSE_SLOT_BOTTOM', '')
305 # we're running behind a proxy that sets the X-Forwarded-Proto header correctly
306 # see https://docs.djangoproject.com/en/dev/ref/settings/#secure-proxy-ssl-header
307 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
310 # enabled access to staff-only areas with ?staff=<STAFF_TOKEN>
311 STAFF_TOKEN = os.getenv('STAFF_TOKEN', None)
313 # Flattr settings -- available after you register your app
314 FLATTR_KEY = os.getenv('FLATTR_KEY', '')
315 FLATTR_SECRET = os.getenv('FLATTR_SECRET', '')
317 # Flattr thing of the webservice. Will be flattr'd when a user sets
318 # the "Auto-Flattr gpodder.net" option
319 FLATTR_MYGPO_THING = os.getenv(
320 'FLATTR_MYGPO_THING',
321 'https://flattr.com/submit/auto?user_id=stefankoegl&url=http://gpodder.net'
324 # The User-Agent string used for outgoing HTTP requests
325 USER_AGENT = 'gpodder.net (+https://github.com/gpodder/mygpo)'
327 # Base URL of the website that is used if the actually used parameters is not
328 # available. Request handlers, for example, can access the requested domain.
329 # Code that runs in background can not do this, and therefore requires a
330 # default value. This should be set to something like 'http://example.com'
331 DEFAULT_BASE_URL = os.getenv('DEFAULT_BASE_URL', '')
334 ### Celery
336 CELERY_BROKER_URL = os.getenv('BROKER_URL', 'redis://localhost')
337 CELERY_RESULT_BACKEND = 'django-db'
339 CELERY_RESULT_EXPIRES = 60 * 60 # 1h expiry time in seconds
341 CELERY_ACCEPT_CONTENT = ['json']
344 ### Google API
346 GOOGLE_CLIENT_ID = os.getenv('GOOGLE_CLIENT_ID', '')
347 GOOGLE_CLIENT_SECRET = os.getenv('GOOGLE_CLIENT_SECRET', '')
349 # URL where users of the site can get support
350 SUPPORT_URL = os.getenv('SUPPORT_URL', '')
353 FEEDSERVICE_URL = os.getenv('FEEDSERVICE_URL', 'http://feeds.gpodder.net/')
356 # time for how long an activation is valid; after that, an unactivated user
357 # will be deleted
358 ACTIVATION_VALID_DAYS = int(os.getenv('ACTIVATION_VALID_DAYS', 10))
361 OPBEAT = {
362 "ORGANIZATION_ID": os.getenv('OPBEAT_ORGANIZATION_ID', ''),
363 "APP_ID": os.getenv('OPBEAT_APP_ID', ''),
364 "SECRET_TOKEN": os.getenv('OPBEAT_SECRET_TOKEN', ''),
367 LOCALE_PATHS = [
368 os.path.abspath(os.path.join(BASE_DIR, 'locale')),
371 INTERNAL_IPS = os.getenv('INTERNAL_IPS', '').split()
373 EMAIL_BACKEND = os.getenv('EMAIL_BACKEND',
374 'django.core.mail.backends.smtp.EmailBackend')
376 PODCAST_AD_ID = os.getenv('PODCAST_AD_ID')
378 TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
380 NOSE_ARGS = [
381 '--with-doctest',
382 '--stop',
383 '--where=mygpo',
387 SEARCH_CUTOFF = float(os.getenv('SEARCH_CUTOFF', 0.3))