taiga-back/settings/common.py

473 lines
14 KiB
Python

# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os.path, sys, os
# This is defined here as a do-nothing function because we can't import
# django.utils.translation -- that module depends on the settings.
gettext_noop = lambda s: s
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
APPEND_SLASH = False
ALLOWED_HOSTS = ["*"]
ADMINS = (
("Admin", "example@example.com"),
)
DATABASES = {
"default": {
"ENGINE": "transaction_hooks.backends.postgresql_psycopg2",
"NAME": "taiga",
}
}
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "unique-snowflake"
}
}
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
]
# Default configuration for reverse proxy
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTOCOL", "https")
# Errors report configuration
SEND_BROKEN_LINK_EMAILS = True
IGNORABLE_404_ENDS = (".php", ".cgi")
IGNORABLE_404_STARTS = ("/phpmyadmin/",)
ATOMIC_REQUESTS = True
TIME_ZONE = "UTC"
LOGIN_URL="/auth/login/"
USE_TZ = True
USE_I18N = True
USE_L10N = True
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
# Languages we provide translations for, out of the box.
LANGUAGES = [
('af', gettext_noop('Afrikaans')),
('ar', gettext_noop('Arabic')),
('ast', gettext_noop('Asturian')),
('az', gettext_noop('Azerbaijani')),
('bg', gettext_noop('Bulgarian')),
('be', gettext_noop('Belarusian')),
('bn', gettext_noop('Bengali')),
('br', gettext_noop('Breton')),
('bs', gettext_noop('Bosnian')),
('ca', gettext_noop('Catalan')),
('cs', gettext_noop('Czech')),
('cy', gettext_noop('Welsh')),
('da', gettext_noop('Danish')),
('de', gettext_noop('German')),
('el', gettext_noop('Greek')),
('en', gettext_noop('English')),
('en-au', gettext_noop('Australian English')),
('en-gb', gettext_noop('British English')),
('eo', gettext_noop('Esperanto')),
('es', gettext_noop('Spanish')),
('es-ar', gettext_noop('Argentinian Spanish')),
('es-mx', gettext_noop('Mexican Spanish')),
('es-ni', gettext_noop('Nicaraguan Spanish')),
('es-ve', gettext_noop('Venezuelan Spanish')),
('et', gettext_noop('Estonian')),
('eu', gettext_noop('Basque')),
('fa', gettext_noop('Persian')),
('fi', gettext_noop('Finnish')),
('fr', gettext_noop('French')),
('fy', gettext_noop('Frisian')),
('ga', gettext_noop('Irish')),
('gl', gettext_noop('Galician')),
('he', gettext_noop('Hebrew')),
('hi', gettext_noop('Hindi')),
('hr', gettext_noop('Croatian')),
('hu', gettext_noop('Hungarian')),
('ia', gettext_noop('Interlingua')),
('id', gettext_noop('Indonesian')),
('io', gettext_noop('Ido')),
('is', gettext_noop('Icelandic')),
('it', gettext_noop('Italian')),
('ja', gettext_noop('Japanese')),
('ka', gettext_noop('Georgian')),
('kk', gettext_noop('Kazakh')),
('km', gettext_noop('Khmer')),
('kn', gettext_noop('Kannada')),
('ko', gettext_noop('Korean')),
('lb', gettext_noop('Luxembourgish')),
('lt', gettext_noop('Lithuanian')),
('lv', gettext_noop('Latvian')),
('mk', gettext_noop('Macedonian')),
('ml', gettext_noop('Malayalam')),
('mn', gettext_noop('Mongolian')),
('mr', gettext_noop('Marathi')),
('my', gettext_noop('Burmese')),
('nb', gettext_noop('Norwegian Bokmal')),
('ne', gettext_noop('Nepali')),
('nl', gettext_noop('Dutch')),
('nn', gettext_noop('Norwegian Nynorsk')),
('os', gettext_noop('Ossetic')),
('pa', gettext_noop('Punjabi')),
('pl', gettext_noop('Polish')),
('pt', gettext_noop('Portuguese')),
('pt-br', gettext_noop('Brazilian Portuguese')),
('ro', gettext_noop('Romanian')),
('ru', gettext_noop('Russian')),
('sk', gettext_noop('Slovak')),
('sl', gettext_noop('Slovenian')),
('sq', gettext_noop('Albanian')),
('sr', gettext_noop('Serbian')),
('sr-latn', gettext_noop('Serbian Latin')),
('sv', gettext_noop('Swedish')),
('sw', gettext_noop('Swahili')),
('ta', gettext_noop('Tamil')),
('te', gettext_noop('Telugu')),
('th', gettext_noop('Thai')),
('tr', gettext_noop('Turkish')),
('tt', gettext_noop('Tatar')),
('udm', gettext_noop('Udmurt')),
('uk', gettext_noop('Ukrainian')),
('ur', gettext_noop('Urdu')),
('vi', gettext_noop('Vietnamese')),
('zh-hans', gettext_noop('Simplified Chinese')),
('zh-hant', gettext_noop('Traditional Chinese')),
]
# Languages using BiDi (right-to-left) layout
LANGUAGES_BIDI = ["he", "ar", "fa", "ur"]
SITES = {
"api": {"domain": "localhost:8000", "scheme": "http", "name": "api"},
"front": {"domain": "localhost:9001", "scheme": "http", "name": "front"},
}
SITE_ID = "api"
# Session configuration (only used for admin)
SESSION_ENGINE = "django.contrib.sessions.backends.db"
SESSION_COOKIE_AGE = 1209600 # (2 weeks)
# MAIL OPTIONS
DEFAULT_FROM_EMAIL = "john@doe.com"
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
DJMAIL_REAL_BACKEND = "django.core.mail.backends.console.EmailBackend"
DJMAIL_SEND_ASYNC = True
DJMAIL_MAX_RETRY_NUMBER = 3
DJMAIL_TEMPLATE_EXTENSION = "jinja"
# Events backend
EVENTS_PUSH_BACKEND = "taiga.events.backends.postgresql.EventsPushBackend"
# EVENTS_PUSH_BACKEND = "taiga.events.backends.rabbitmq.EventsPushBackend"
# EVENTS_PUSH_BACKEND_OPTIONS = {"url": "//guest:guest@127.0.0.1/"}
# Message System
MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage"
# The absolute url is mandatory because attachments
# urls depends on it. On production should be set
# something like https://media.taiga.io/
MEDIA_URL = "http://localhost:8000/media/"
# Static url is not widelly used by taiga (only
# if admin is activated).
STATIC_URL = "http://localhost:8000/static/"
ADMIN_MEDIA_PREFIX = "http://localhost:8000/static/admin/"
# Static configuration.
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Don't forget to use absolute paths, not relative paths.
)
# Defautl storage
DEFAULT_FILE_STORAGE = "taiga.base.storage.FileSystemStorage"
LOCALE_PATHS = (
os.path.join(BASE_DIR, "locale"),
)
SECRET_KEY = "aw3+t2r(8(0kkrhg8)gx6i96v5^kv%6cfep9wxfom0%7dy0m9e"
TEMPLATE_LOADERS = [
"django_jinja.loaders.AppLoader",
"django_jinja.loaders.FileSystemLoader",
]
MIDDLEWARE_CLASSES = [
"taiga.base.middleware.cors.CoorsMiddleware",
"taiga.events.middleware.SessionIDMiddleware",
# Common middlewares
"django.middleware.common.CommonMiddleware",
"django.middleware.locale.LocaleMiddleware",
# Only needed by django admin
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
]
TEMPLATE_CONTEXT_PROCESSORS = [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.request",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages",
]
ROOT_URLCONF = "taiga.urls"
TEMPLATE_DIRS = [
os.path.join(BASE_DIR, "templates"),
]
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.admin",
"django.contrib.staticfiles",
"taiga.base",
"taiga.base.api",
"taiga.events",
"taiga.front",
"taiga.users",
"taiga.userstorage",
"taiga.projects",
"taiga.projects.references",
"taiga.projects.custom_attributes",
"taiga.projects.history",
"taiga.projects.notifications",
"taiga.projects.attachments",
"taiga.projects.votes",
"taiga.projects.milestones",
"taiga.projects.userstories",
"taiga.projects.tasks",
"taiga.projects.issues",
"taiga.projects.wiki",
"taiga.searches",
"taiga.timeline",
"taiga.mdrender",
"taiga.export_import",
"taiga.feedback",
"taiga.hooks.github",
"taiga.hooks.gitlab",
"taiga.hooks.bitbucket",
"taiga.webhooks",
"djmail",
"django_jinja",
"django_jinja.contrib._humanize",
"sr",
"easy_thumbnails",
"raven.contrib.django.raven_compat",
"django_transactional_cleanup",
]
WSGI_APPLICATION = "taiga.wsgi.application"
LOGGING = {
"version": 1,
"disable_existing_loggers": True,
"filters": {
"require_debug_false": {
"()": "django.utils.log.RequireDebugFalse"
}
},
"formatters": {
"complete": {
"format": "%(levelname)s:%(asctime)s:%(module)s %(message)s"
},
"simple": {
"format": "%(levelname)s:%(asctime)s: %(message)s"
},
"null": {
"format": "%(message)s",
},
},
"handlers": {
"null": {
"level":"DEBUG",
"class":"django.utils.log.NullHandler",
},
"console":{
"level":"DEBUG",
"class":"logging.StreamHandler",
"formatter": "simple",
},
"mail_admins": {
"level": "ERROR",
"filters": ["require_debug_false"],
"class": "django.utils.log.AdminEmailHandler",
}
},
"loggers": {
"django": {
"handlers":["null"],
"propagate": True,
"level":"INFO",
},
"django.request": {
"handlers": ["mail_admins", "console"],
"level": "ERROR",
"propagate": False,
},
"taiga": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": False,
}
}
}
AUTH_USER_MODEL = "users.User"
FORMAT_MODULE_PATH = "taiga.base.formats"
DATE_INPUT_FORMATS = (
"%Y-%m-%d", "%m/%d/%Y", "%d/%m/%Y", "%b %d %Y",
"%b %d, %Y", "%d %b %Y", "%d %b, %Y", "%B %d %Y",
"%B %d, %Y", "%d %B %Y", "%d %B, %Y"
)
# Authentication settings (only for django admin)
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend", # default
)
MAX_AGE_AUTH_TOKEN = None
MAX_AGE_CANCEL_ACCOUNT = 30 * 24 * 60 * 60 # 30 days in seconds
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
# Mainly used by taiga-front
"taiga.auth.backends.Token",
# Mainly used for api debug.
"taiga.auth.backends.Session",
),
"DEFAULT_THROTTLE_CLASSES": (
"taiga.base.throttling.AnonRateThrottle",
"taiga.base.throttling.UserRateThrottle"
),
"DEFAULT_THROTTLE_RATES": {
"anon": None,
"user": None,
"import-mode": None,
"import-dump-mode": "1/minute",
},
"FILTER_BACKEND": "taiga.base.filters.FilterBackend",
"EXCEPTION_HANDLER": "taiga.base.exceptions.exception_handler",
"PAGINATE_BY": 30,
"PAGINATE_BY_PARAM": "page_size",
"MAX_PAGINATE_BY": 1000,
"DATETIME_FORMAT": "%Y-%m-%dT%H:%M:%S%z"
}
DEFAULT_PROJECT_TEMPLATE = "scrum"
PUBLIC_REGISTER_ENABLED = False
SEARCHES_MAX_RESULTS = 150
SOUTH_MIGRATION_MODULES = {
'easy_thumbnails': 'easy_thumbnails.south_migrations',
}
DEFAULT_AVATAR_SIZE = 80 # 80x80 pixels
DEFAULT_BIG_AVATAR_SIZE = 300 # 300x300 pixels
THUMBNAIL_ALIASES = {
'': {
'avatar': {'size': (DEFAULT_AVATAR_SIZE, DEFAULT_AVATAR_SIZE), 'crop': True},
'big-avatar': {'size': (DEFAULT_BIG_AVATAR_SIZE, DEFAULT_BIG_AVATAR_SIZE), 'crop': True},
},
}
# GRAVATAR_DEFAULT_AVATAR = "img/user-noimage.png"
GRAVATAR_DEFAULT_AVATAR = ""
GRAVATAR_AVATAR_SIZE = DEFAULT_AVATAR_SIZE
TAGS_PREDEFINED_COLORS = ["#fce94f", "#edd400", "#c4a000", "#8ae234",
"#73d216", "#4e9a06", "#d3d7cf", "#fcaf3e",
"#f57900", "#ce5c00", "#729fcf", "#3465a4",
"#204a87", "#888a85", "#ad7fa8", "#75507b",
"#5c3566", "#ef2929", "#cc0000", "#a40000",
"#2e3436",]
# Feedback module settings
FEEDBACK_ENABLED = True
FEEDBACK_EMAIL = "support@taiga.io"
# 0 notifications will work in a synchronous way
# >0 an external process will check the pending notifications and will send them
# collapsed during that interval
CHANGE_NOTIFICATIONS_MIN_INTERVAL = 0 #seconds
# List of functions called for filling correctly the ProjectModulesConfig associated to a project
# This functions should receive a Project parameter and return a dict with the desired configuration
PROJECT_MODULES_CONFIGURATORS = {
"github": "taiga.hooks.github.services.get_or_generate_config",
"gitlab": "taiga.hooks.gitlab.services.get_or_generate_config",
"bitbucket": "taiga.hooks.bitbucket.services.get_or_generate_config",
}
BITBUCKET_VALID_ORIGIN_IPS = ["131.103.20.165", "131.103.20.166"]
GITLAB_VALID_ORIGIN_IPS = []
EXPORTS_TTL = 60 * 60 * 24 # 24 hours
CELERY_ENABLED = False
WEBHOOKS_ENABLED = False
from .sr import *
# NOTE: DON'T INSERT MORE SETTINGS AFTER THIS LINE
TEST_RUNNER="django.test.runner.DiscoverRunner"
if "test" in sys.argv:
print ("\033[1;91mNo django tests.\033[0m")
print ("Try: \033[1;33mpy.test\033[0m")
sys.exit(0)