Skip to content
Snippets Groups Projects
settings.py 16.91 KiB
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :

###############################################################################
#                                                                             #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
# Contact: beat.support@idiap.ch                                              #
#                                                                             #
# This file is part of the beat.web module of the BEAT platform.              #
#                                                                             #
# Commercial License Usage                                                    #
# Licensees holding valid commercial BEAT licenses may use this file in       #
# accordance with the terms contained in a written agreement between you      #
# and Idiap. For further information contact tto@idiap.ch                     #
#                                                                             #
# Alternatively, this file may be used under the terms of the GNU Affero      #
# Public License version 3 as published by the Free Software and appearing    #
# in the file LICENSE.AGPL included in the packaging of this file.            #
# The BEAT platform is distributed in the hope that it will be useful, but    #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
#                                                                             #
# You should have received a copy of the GNU Affero Public License along      #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
#                                                                             #
###############################################################################

# Django settings for beat.web project.

import os
import pkg_resources

############################################################################
#
# GENERAL SETTINGS
#
############################################################################

ADMINS = (
    ('name', 'email'),
)

MANAGERS          = ADMINS
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
TIME_ZONE         = 'Europe/Zurich'
# See http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE     = 'en-us'
USE_I18N          = True
USE_L10N          = True
SITE_ID           = 1
# This must be changed for every new instance - don't re-use this key
SECRET_KEY        = '7o9k04*uju)4(-e29g)q+_o+z(%w_&(t^bl=)m_osg$@$y4&98'

# The URL prefix prepends all URLs. Example: '/platform'
# WARNING! **Don't terminate this string with a '/' (slash)**
URL_PREFIX        = ''

# Analytics key, if you'd like to track page visits. If empty, no tracking.
GOOGLE_ANALYTICS_KEY = ''

# Debug settings, set to False for production sites
DEBUG             = True

USE_HTTPS_GRAVATAR = False

ALLOWED_HOSTS = [
    'localhost',
    '127.0.0.1',
]

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '[%(asctime)s] %(levelname)s: %(message)s',
            'datefmt': "%d/%b/%Y %H:%M:%S",
            },
        },
    'handlers': {
        'discard': {
            'level': 'DEBUG',
            'class': 'logging.NullHandler',
            },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
            },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            }
        },
    'loggers': {
        '': {
            'handlers': ['discard'],
            'level': 'INFO',
            },
        'beat.core': {
            'handlers': ['console'],
            },
        'beat.web': {
            'handlers': ['console', 'mail_admins'],
            },
        'beat.web.attestations.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
        'beat.web.search.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
        'beat.web.experiments.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
        'beat.web.reports.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
        'beat.web.backend.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
        'beat.web.utils.management.commands': {
            'handlers': ['console'],
            'propagate': False, #don't e-mail those!
            },
    }
}

##############################################################################
#
# Special code to remove Django 1.10 deprecation warnings caused by
# Django-JSONField while that is not resolved:
# https://bitbucket.org/schinckel/django-jsonfield/issues/46/django-190-complains-about-subfieldbase
# Current django-jsonfield available: 0.9.19 (28.04.2016)
#
##############################################################################
import logging

class SuppressDeprecated(logging.Filter):
    def filter(self, record):
        WARNINGS_TO_SUPPRESS = [
            'RemovedInDjango110Warning',
        ]
        # Return false to suppress message.
        return not any([warn in record.getMessage() for warn in WARNINGS_TO_SUPPRESS])

warn_logger = logging.getLogger('py.warnings')
warn_logger.addFilter(SuppressDeprecated())

##############################################################################
#
# DATABASE
#
##############################################################################

DATABASES = {
    'default': {
      'ENGINE': 'django.db.backends.sqlite3',
      'NAME': 'django.sql3',
      'OPTIONS': {
        'timeout': 10, #seconds
        },
      },
}


##############################################################################
#
# STATIC FILES
#
##############################################################################

STATIC_URL          = '/static/'
STATICFILES_DIRS    = (
        # Bower sources
        pkg_resources.resource_filename('beat.web', 'static'),
        )
STATIC_ROOT         = 'static'


##############################################################################
#
# PREFIX (for BEAT platform files)
#
##############################################################################

PREFIX           = os.path.join(os.getcwd(), 'prefix')
ALGORITHMS_ROOT  = os.path.join(PREFIX, 'algorithms')
PLOTTERS_ROOT    = os.path.join(PREFIX, 'plotters')
LIBRARIES_ROOT   = os.path.join(PREFIX, 'libraries')
DATABASES_ROOT   = os.path.join(PREFIX, 'databases')
DATAFORMATS_ROOT = os.path.join(PREFIX, 'dataformats')
TOOLCHAINS_ROOT  = os.path.join(PREFIX, 'toolchains')
EXPERIMENTS_ROOT = os.path.join(PREFIX, 'experiments')
CACHE_ROOT       = os.path.join(PREFIX, 'cache')


##############################################################################
#
# IF ACCESS TO THE DATASETS IS RESTRICTED TO A SPECIFIC USER
#
##############################################################################

DATASETS_UID = None
DATASETS_ROOT_PATH = None


##############################################################################
#
# ACCOUNTS
#
##############################################################################

ACCOUNT_ACTIVATION_DAYS  = 2
ACCOUNT_ACTIVATION_DAYS_FROM_GODFATHER  = 7
ACCOUNT_EXPIRATION_DAYS  = 365

LOGIN_REDIRECT_URL       = '/'
LOGIN_URL                = '/login/'
SYSTEM_ACCOUNT           = 'system'
PLOT_ACCOUNT             = 'plot'
PREREGISTRATION_ONLY     = False
TERMS_OF_SERVICE_VERSION = 1
LEGAL_DISCLAIMER_VERSION = 1

ACCOUNTS_TO_EXCLUDE_FROM_SEARCH = ['AnonymousUser']
ACCOUNTS_TO_EXCLUDE_FROM_TEAMS = [SYSTEM_ACCOUNT, PLOT_ACCOUNT, 'AnonymousUser']


###########################################################################
#
# E-MAILS
#
###########################################################################

DEFAULT_FROM_EMAIL   = 'BEAT Development Platform <beat.support@idiap.ch>'
SERVER_EMAIL         = DEFAULT_FROM_EMAIL

EMAIL_BACKEND        = 'django.core.mail.backends.console.EmailBackend'
EMAIL_SUBJECT_PREFIX = '[BEAT/Development] '
EMAIL_HOST           = 'localhost'
EMAIL_PORT           = 1025
EMAIL_HOST_USER      = ''
EMAIL_HOST_PASSWORD  = ''
EMAIL_USE_TLS        = False


##############################################################################
#
# SCHEDULER
#
##############################################################################

# The scheduling interval controls the number of seconds between
# scheduling attempts (calls to :py:func:`beat.web.backend.schedule.schedule`)
SCHEDULING_INTERVAL = 5 #seconds

# The worker interval controls the number of seconds between checks
# a particular worker will run to verify jobs are not scheduled to itself
WORKER_INTERVAL = 5 #seconds

# If set, a testing panel that can accomplish scheduling activities will appear
# at the scheduler page allowing administrators to launch scheduling activities
# manually.
SCHEDULING_PANEL = True

# The maximum index split errors control the maximum number of times we can
# incur in an index split error condition without cancelling the block
# execution altogether. This number, multiplied by the scheduling interval,
# must be larger than 60 seconds, as this is the default NFS caching interval.
# If you run on a reliable networked filesystem (i.e., not NFS) or on the local
# node, you may set this value to 0, which will cause the scheduling activity
# to consider even a single splitting error as enough reason to cancel the
# block execution (and, by consequence), the experiment.
MAXIMUM_SPLIT_ERRORS = 0 #attempts to split without errors

# The maximum number of IOErrors (due to cache loading) which are acceptable
# for a particular split. If the number of cache errors is bigger than the
# value set, then the split is considered as failed. This variable serves the
# same purpose as ``MAXIMUM_SPLIT_ERRORS`` above and fills-in where NFS caching
# does not. If you're running on a reliable filesystem, you can't leave it to
# zero.
MAXIMUM_IO_ERRORS = 0 #attempts to load cache files without errors

# The maximum number of retries for saving (mostly at start() and end()), job
# splits from remote processes. If you're using a SQLite database backend, this
# number should be higher than 1 (recommended value is 3 to 5). In case you're
# using another database, then this can value can be ignored. If set to a value
# of one or more and there are "database is locked" errors, then job split
# saving at ``start()`` or ``end()`` will be retried with a 1-second interval.
MAXIMUM_SPLIT_SAVE_RETRIES = 5

# The default user error is a message string that is set upon the failure of
# execution of a particular block if the root cause of the problem is NOT a
# user error, but the systems'. In this case, the system administrators receive
# an e-mail indicating the exception caught and the user block for a given
# experiment is marked with this informative message.
DEFAULT_USER_ERROR = "A system error occurred and we could not run your " \
    "algorithm.\nThe administrators have been informed.\nYou may try to run " \
    "the experiment again at another moment."

# If set, then detach children processes (I/O daemons) from the worker process
# group. In this case, signals sent to the worker process will not be forwarded
# to the processing children. This is desirable in a production environment, to
# avoid user processes to be terminated in case the worker is updated.
WORKER_DETACH_CHILDREN = False


##############################################################################
#
# DJANGO MACHINERY
#
##############################################################################

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            pkg_resources.resource_filename('beat.web', 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.contrib.auth.context_processors.auth',
                'django.core.context_processors.request',
                'django.template.context_processors.csrf',
                'django.contrib.messages.context_processors.messages',
                'beat.web.navigation.context_processors.exported_settings',
                'beat.web.navigation.context_processors.beat_version',
                'beat.web.navigation.context_processors.google_analytics',
            ],
            'debug': DEBUG,
        },
    },
]

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'beat.web.navigation.middleware.AgreementMiddleware',
)

ROOT_URLCONF = 'beat.web.urls'

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.messages',
    'django.contrib.humanize',
    'django.contrib.sites',
    #'django.contrib.admindocs',

    'guardian',
    'rest_framework',
    'rest_framework_swagger',
    'rest_framework.authtoken',
    'jsonfield',
    'actstream',

    'beat.web.ui.registration',

    'beat.web.accounts',
    'beat.web.algorithms',
    'beat.web.plotters',
    'beat.web.attestations',
    'beat.web.backend',
    'beat.web.common',
    'beat.web.databases',
    'beat.web.dataformats',
    'beat.web.experiments',
    'beat.web.libraries',
    'beat.web.navigation',
    'beat.web.search',
    'beat.web.statistics',
    'beat.web.toolchains',
    'beat.web.ui',
    'beat.web.utils',
    'beat.web.team',
    'beat.web.reports',
)

# Secure re-estructured text markup parsing
RESTRUCTUREDTEXT_FILTER_SETTINGS = {
    'file_insertion_enabled': 0,
    'raw_enabled': 0,
    }

# Where CodeMirror is installed and some other settings
CODEMIRROR_PATH = 'codemirror' #w.r.t to STATIC_URL
CODEMIRROR_THEME = 'default'
CODEMIRROR_MODE = 'javascript'

##############################################################################
#
# DJANGO CACHING: https://docs.djangoproject.com/en/1.7/topics/cache/
#
##############################################################################

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}

##############################################################################
#
# DJANGO SESSIONS: https://docs.djangoproject.com/en/1.7/topics/http/sessions/
#
##############################################################################

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

##############################################################################
#
# DJANGO AUTHENTICATION BACKENDS: https://docs.djangoproject.com/en/1.7/topics/auth/customizing/
# DJANGO-GUARDIAN CONFIGURATION http://django-guardian.readthedocs.org/en/v1.2/configuration.html
#
##############################################################################
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', # this is default
    'guardian.backends.ObjectPermissionBackend',
)

ANONYMOUS_USER_ID = -1

AUTH_PROFILE_MODULE = 'accounts.Profile'

##############################################################################
#
# REST FRAMEWORK PERMISSION CLASSES: http://www.django-rest-framework.org/api-guide/permissions/
#
##############################################################################
REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly'
    ],

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ],

    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer'
    ],
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser'
    ]
}

##############################################################################
#
# Attestations
#
##############################################################################

#In days
EXPIRATION_DELTA = 180
EXPIRATION_REMINDERS = [1, 7, 30]

##############################################################################
#
# Django Activity Stream
#
##############################################################################

ACTSTREAM_SETTINGS = {
    'USE_JSONFIELD': True,
    'MANAGER': 'beat.web.common.managers.BeatActionManager'
}

ABSOLUTE_URL_OVERRIDES = {
    'auth.user': lambda u: URL_PREFIX + "/events/%s/" % u.username,
}

SERIALIZATION_MODULES = { 'json' : 'beat.web.utils.activity_stream_serializer' }