Permalink
Cannot retrieve contributors at this time
# | |
# Copyright © 2012 - 2021 Michal Čihař <michal@cihar.com> | |
# | |
# This file is part of Weblate <https://weblate.org/> | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU 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 General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <https://www.gnu.org/licenses/>. | |
# | |
import os | |
import platform | |
from logging.handlers import SysLogHandler | |
# | |
# Django settings for Weblate project. | |
# | |
DEBUG = True | |
ADMINS = ( | |
# ("Your Name", "your_email@example.com"), | |
) | |
MANAGERS = ADMINS | |
DATABASES = { | |
"default": { | |
# Use "postgresql" or "mysql". | |
"ENGINE": "django.db.backends.postgresql", | |
# Database name. | |
"NAME": "weblate", | |
# Database user. | |
"USER": "weblate", | |
# Name of role to alter to set parameters in PostgreSQL, | |
# use in case role name is different than user used for authentication. | |
# "ALTER_ROLE": "weblate", | |
# Database password. | |
"PASSWORD": "", | |
# Set to empty string for localhost. | |
"HOST": "127.0.0.1", | |
# Set to empty string for default. | |
"PORT": "", | |
# Customizations for databases. | |
"OPTIONS": { | |
# In case of using an older MySQL server, | |
# which has MyISAM as a default storage | |
# "init_command": "SET storage_engine=INNODB", | |
# Uncomment for MySQL older than 5.7: | |
# "init_command": "SET sql_mode='STRICT_TRANS_TABLES'", | |
# Set emoji capable charset for MySQL: | |
# "charset": "utf8mb4", | |
# Change connection timeout in case you get MySQL gone away error: | |
# "connect_timeout": 28800, | |
}, | |
} | |
} | |
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
# Data directory | |
DATA_DIR = os.path.join(BASE_DIR, "data") | |
# Local time zone for this installation. Choices can be found here: | |
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name | |
# although not all choices may be available on all operating systems. | |
# In a Windows environment this must be set to your system time zone. | |
TIME_ZONE = "UTC" | |
# Language code for this installation. All choices can be found here: | |
# http://www.i18nguy.com/unicode/language-identifiers.html | |
LANGUAGE_CODE = "en-us" | |
LANGUAGES = ( | |
("ar", "العربية"), | |
("az", "Azərbaycan"), | |
("be", "Беларуская"), | |
("be@latin", "Biełaruskaja"), | |
("bg", "Български"), | |
("br", "Brezhoneg"), | |
("ca", "Català"), | |
("cs", "Čeština"), | |
("da", "Dansk"), | |
("de", "Deutsch"), | |
("en", "English"), | |
("el", "Ελληνικά"), | |
("en-gb", "English (United Kingdom)"), | |
("es", "Español"), | |
("fi", "Suomi"), | |
("fr", "Français"), | |
("gl", "Galego"), | |
("he", "עברית"), | |
("hu", "Magyar"), | |
("hr", "Hrvatski"), | |
("id", "Indonesia"), | |
("is", "Íslenska"), | |
("it", "Italiano"), | |
("ja", "日本語"), | |
("kab", "Taqbaylit"), | |
("kk", "Қазақ тілі"), | |
("ko", "한국어"), | |
("nb", "Norsk bokmål"), | |
("nl", "Nederlands"), | |
("pl", "Polski"), | |
("pt", "Português"), | |
("pt-br", "Português brasileiro"), | |
("ru", "Русский"), | |
("sk", "Slovenčina"), | |
("sl", "Slovenščina"), | |
("sq", "Shqip"), | |
("sr", "Српски"), | |
("sv", "Svenska"), | |
("tr", "Türkçe"), | |
("uk", "Українська"), | |
("zh-hans", "简体字"), | |
("zh-hant", "正體字"), | |
) | |
SITE_ID = 1 | |
# If you set this to False, Django will make some optimizations so as not | |
# to load the internationalization machinery. | |
USE_I18N = True | |
# If you set this to False, Django will not format dates, numbers and | |
# calendars according to the current locale. | |
USE_L10N = True | |
# If you set this to False, Django will not use timezone-aware datetimes. | |
USE_TZ = True | |
# URL prefix to use, please see documentation for more details | |
URL_PREFIX = "" | |
# Absolute filesystem path to the directory that will hold user-uploaded files. | |
MEDIA_ROOT = os.path.join(DATA_DIR, "media") | |
# URL that handles the media served from MEDIA_ROOT. Make sure to use a | |
# trailing slash. | |
MEDIA_URL = f"{URL_PREFIX}/media/" | |
# Absolute path to the directory static files should be collected to. | |
# Don't put anything in this directory yourself; store your static files | |
# in apps' "static/" subdirectories and in STATICFILES_DIRS. | |
STATIC_ROOT = os.path.join(DATA_DIR, "static") | |
# URL prefix for static files. | |
STATIC_URL = f"{URL_PREFIX}/static/" | |
# Additional locations of static files | |
STATICFILES_DIRS = ( | |
# Put strings here, like "/home/html/static" or "C:/www/django/static". | |
# Always use forward slashes, even on Windows. | |
# Don't forget to use absolute paths, not relative paths. | |
) | |
# List of finder classes that know how to find static files in | |
# various locations. | |
STATICFILES_FINDERS = ( | |
"django.contrib.staticfiles.finders.FileSystemFinder", | |
"django.contrib.staticfiles.finders.AppDirectoriesFinder", | |
"compressor.finders.CompressorFinder", | |
) | |
# Make this unique, and don't share it with anybody. | |
# You can generate it using weblate/examples/generate-secret-key | |
SECRET_KEY = "" | |
_TEMPLATE_LOADERS = [ | |
"django.template.loaders.filesystem.Loader", | |
"django.template.loaders.app_directories.Loader", | |
] | |
if not DEBUG: | |
_TEMPLATE_LOADERS = [("django.template.loaders.cached.Loader", _TEMPLATE_LOADERS)] | |
TEMPLATES = [ | |
{ | |
"BACKEND": "django.template.backends.django.DjangoTemplates", | |
"OPTIONS": { | |
"context_processors": [ | |
"django.contrib.auth.context_processors.auth", | |
"django.template.context_processors.debug", | |
"django.template.context_processors.i18n", | |
"django.template.context_processors.request", | |
"django.template.context_processors.csrf", | |
"django.contrib.messages.context_processors.messages", | |
"weblate.trans.context_processors.weblate_context", | |
], | |
"loaders": _TEMPLATE_LOADERS, | |
}, | |
} | |
] | |
# GitHub username for sending pull requests. | |
# Please see the documentation for more details. | |
GITHUB_USERNAME = None | |
GITHUB_TOKEN = None | |
# GitLab username for sending merge requests. | |
# Please see the documentation for more details. | |
GITLAB_USERNAME = None | |
GITLAB_TOKEN = None | |
# Authentication configuration | |
AUTHENTICATION_BACKENDS = ( | |
"social_core.backends.email.EmailAuth", | |
# "social_core.backends.google.GoogleOAuth2", | |
# "social_core.backends.github.GithubOAuth2", | |
# "social_core.backends.bitbucket.BitbucketOAuth", | |
# "social_core.backends.suse.OpenSUSEOpenId", | |
# "social_core.backends.ubuntu.UbuntuOpenId", | |
# "social_core.backends.fedora.FedoraOpenId", | |
# "social_core.backends.facebook.FacebookOAuth2", | |
"weblate.accounts.auth.WeblateUserBackend", | |
) | |
# Custom user model | |
AUTH_USER_MODEL = "weblate_auth.User" | |
# Social auth backends setup | |
SOCIAL_AUTH_GITHUB_KEY = "" | |
SOCIAL_AUTH_GITHUB_SECRET = "" | |
SOCIAL_AUTH_GITHUB_SCOPE = ["user:email"] | |
SOCIAL_AUTH_BITBUCKET_KEY = "" | |
SOCIAL_AUTH_BITBUCKET_SECRET = "" | |
SOCIAL_AUTH_BITBUCKET_VERIFIED_EMAILS_ONLY = True | |
SOCIAL_AUTH_FACEBOOK_KEY = "" | |
SOCIAL_AUTH_FACEBOOK_SECRET = "" | |
SOCIAL_AUTH_FACEBOOK_SCOPE = ["email", "public_profile"] | |
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {"fields": "id,name,email"} | |
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = "" | |
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = "" | |
# Social auth settings | |
SOCIAL_AUTH_PIPELINE = ( | |
"social_core.pipeline.social_auth.social_details", | |
"social_core.pipeline.social_auth.social_uid", | |
"social_core.pipeline.social_auth.auth_allowed", | |
"social_core.pipeline.social_auth.social_user", | |
"weblate.accounts.pipeline.store_params", | |
"weblate.accounts.pipeline.verify_open", | |
"social_core.pipeline.user.get_username", | |
"weblate.accounts.pipeline.require_email", | |
"social_core.pipeline.mail.mail_validation", | |
"weblate.accounts.pipeline.revoke_mail_code", | |
"weblate.accounts.pipeline.ensure_valid", | |
"weblate.accounts.pipeline.remove_account", | |
"social_core.pipeline.social_auth.associate_by_email", | |
"weblate.accounts.pipeline.reauthenticate", | |
"weblate.accounts.pipeline.verify_username", | |
"social_core.pipeline.user.create_user", | |
"social_core.pipeline.social_auth.associate_user", | |
"social_core.pipeline.social_auth.load_extra_data", | |
"weblate.accounts.pipeline.cleanup_next", | |
"weblate.accounts.pipeline.user_full_name", | |
"weblate.accounts.pipeline.store_email", | |
"weblate.accounts.pipeline.notify_connect", | |
"weblate.accounts.pipeline.password_reset", | |
) | |
SOCIAL_AUTH_DISCONNECT_PIPELINE = ( | |
"social_core.pipeline.disconnect.allowed_to_disconnect", | |
"social_core.pipeline.disconnect.get_entries", | |
"social_core.pipeline.disconnect.revoke_tokens", | |
"weblate.accounts.pipeline.cycle_session", | |
"weblate.accounts.pipeline.adjust_primary_mail", | |
"weblate.accounts.pipeline.notify_disconnect", | |
"social_core.pipeline.disconnect.disconnect", | |
"weblate.accounts.pipeline.cleanup_next", | |
) | |
# Custom authentication strategy | |
SOCIAL_AUTH_STRATEGY = "weblate.accounts.strategy.WeblateStrategy" | |
# Raise exceptions so that we can handle them later | |
SOCIAL_AUTH_RAISE_EXCEPTIONS = True | |
SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = "weblate.accounts.pipeline.send_validation" | |
SOCIAL_AUTH_EMAIL_VALIDATION_URL = f"{URL_PREFIX}/accounts/email-sent/" | |
SOCIAL_AUTH_LOGIN_ERROR_URL = f"{URL_PREFIX}/accounts/login/" | |
SOCIAL_AUTH_EMAIL_FORM_URL = f"{URL_PREFIX}/accounts/email/" | |
SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = f"{URL_PREFIX}/accounts/profile/#account" | |
SOCIAL_AUTH_PROTECTED_USER_FIELDS = ("email",) | |
SOCIAL_AUTH_SLUGIFY_USERNAMES = True | |
SOCIAL_AUTH_SLUGIFY_FUNCTION = "weblate.accounts.pipeline.slugify_username" | |
# Password validation configuration | |
AUTH_PASSWORD_VALIDATORS = [ | |
{ | |
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" # noqa: E501, pylint: disable=line-too-long | |
}, | |
{ | |
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", | |
"OPTIONS": {"min_length": 10}, | |
}, | |
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, | |
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, | |
{"NAME": "weblate.accounts.password_validation.CharsPasswordValidator"}, | |
{"NAME": "weblate.accounts.password_validation.PastPasswordsValidator"}, | |
# Optional password strength validation by django-zxcvbn-password | |
# { | |
# "NAME": "zxcvbn_password.ZXCVBNValidator", | |
# "OPTIONS": { | |
# "min_score": 3, | |
# "user_attributes": ("username", "email", "full_name") | |
# } | |
# }, | |
] | |
# Allow new user registrations | |
REGISTRATION_OPEN = True | |
# Shortcut for login required setting | |
REQUIRE_LOGIN = False | |
# Middleware | |
MIDDLEWARE = [ | |
"weblate.middleware.RedirectMiddleware", | |
"weblate.middleware.ProxyMiddleware", | |
"django.middleware.security.SecurityMiddleware", | |
"django.contrib.sessions.middleware.SessionMiddleware", | |
"django.middleware.csrf.CsrfViewMiddleware", | |
"weblate.accounts.middleware.AuthenticationMiddleware", | |
"django.contrib.messages.middleware.MessageMiddleware", | |
"django.middleware.clickjacking.XFrameOptionsMiddleware", | |
"social_django.middleware.SocialAuthExceptionMiddleware", | |
"weblate.accounts.middleware.RequireLoginMiddleware", | |
"weblate.api.middleware.ThrottlingMiddleware", | |
"weblate.middleware.SecurityMiddleware", | |
] | |
ROOT_URLCONF = "weblate.urls" | |
# Django and Weblate apps | |
INSTALLED_APPS = [ | |
# Weblate apps on top to override Django locales and templates | |
"weblate.addons", | |
"weblate.auth", | |
"weblate.checks", | |
"weblate.formats", | |
"weblate.glossary", | |
"weblate.machinery", | |
"weblate.trans", | |
"weblate.lang", | |
"weblate_language_data", | |
"weblate.memory", | |
"weblate.screenshots", | |
"weblate.fonts", | |
"weblate.accounts", | |
"weblate.configuration", | |
"weblate.utils", | |
"weblate.vcs", | |
"weblate.wladmin", | |
"weblate", | |
# Optional: Git exporter | |
"weblate.gitexport", | |
# Standard Django modules | |
"django.contrib.auth", | |
"django.contrib.contenttypes", | |
"django.contrib.sessions", | |
"django.contrib.messages", | |
"django.contrib.staticfiles", | |
"django.contrib.admin.apps.SimpleAdminConfig", | |
"django.contrib.admindocs", | |
"django.contrib.sitemaps", | |
"django.contrib.humanize", | |
# Third party Django modules | |
"social_django", | |
"crispy_forms", | |
"compressor", | |
"rest_framework", | |
"rest_framework.authtoken", | |
"django_filters", | |
] | |
# Custom exception reporter to include some details | |
DEFAULT_EXCEPTION_REPORTER_FILTER = "weblate.trans.debug.WeblateExceptionReporterFilter" | |
# Default logging of Weblate messages | |
# - to syslog in production (if available) | |
# - otherwise to console | |
# - you can also choose "logfile" to log into separate file | |
# after configuring it below | |
# Detect if we can connect to syslog | |
HAVE_SYSLOG = False | |
if platform.system() != "Windows": | |
try: | |
handler = SysLogHandler(address="/dev/log", facility=SysLogHandler.LOG_LOCAL2) | |
handler.close() | |
HAVE_SYSLOG = True | |
except OSError: | |
HAVE_SYSLOG = False | |
if DEBUG or not HAVE_SYSLOG: | |
DEFAULT_LOG = "console" | |
else: | |
DEFAULT_LOG = "syslog" | |
DEFAULT_LOGLEVEL = "DEBUG" if DEBUG else "INFO" | |
# A sample logging configuration. The only tangible logging | |
# performed by this configuration is to send an email to | |
# the site admins on every HTTP 500 error when DEBUG=False. | |
# See http://docs.djangoproject.com/en/stable/topics/logging for | |
# more details on how to customize your logging configuration. | |
LOGGING = { | |
"version": 1, | |
"disable_existing_loggers": True, | |
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}}, | |
"formatters": { | |
"syslog": {"format": "weblate[%(process)d]: %(levelname)s %(message)s"}, | |
"simple": {"format": "[%(asctime)s: %(levelname)s/%(process)s] %(message)s"}, | |
"logfile": {"format": "%(asctime)s %(levelname)s %(message)s"}, | |
"django.server": { | |
"()": "django.utils.log.ServerFormatter", | |
"format": "[%(server_time)s] %(message)s", | |
}, | |
}, | |
"handlers": { | |
"mail_admins": { | |
"level": "ERROR", | |
"filters": ["require_debug_false"], | |
"class": "django.utils.log.AdminEmailHandler", | |
"include_html": True, | |
}, | |
"console": { | |
"level": "DEBUG", | |
"class": "logging.StreamHandler", | |
"formatter": "simple", | |
}, | |
"django.server": { | |
"level": "INFO", | |
"class": "logging.StreamHandler", | |
"formatter": "django.server", | |
}, | |
"syslog": { | |
"level": "DEBUG", | |
"class": "logging.handlers.SysLogHandler", | |
"formatter": "syslog", | |
"address": "/dev/log", | |
"facility": SysLogHandler.LOG_LOCAL2, | |
}, | |
# Logging to a file | |
# "logfile": { | |
# "level":"DEBUG", | |
# "class":"logging.handlers.RotatingFileHandler", | |
# "filename": "/var/log/weblate/weblate.log", | |
# "maxBytes": 100000, | |
# "backupCount": 3, | |
# "formatter": "logfile", | |
# }, | |
}, | |
"loggers": { | |
"django.request": { | |
"handlers": ["mail_admins", DEFAULT_LOG], | |
"level": "ERROR", | |
"propagate": True, | |
}, | |
"django.server": { | |
"handlers": ["django.server"], | |
"level": "INFO", | |
"propagate": False, | |
}, | |
# Logging database queries | |
# "django.db.backends": { | |
# "handlers": [DEFAULT_LOG], | |
# "level": "DEBUG", | |
# }, | |
"weblate": {"handlers": [DEFAULT_LOG], "level": DEFAULT_LOGLEVEL}, | |
# Logging VCS operations | |
"weblate.vcs": {"handlers": [DEFAULT_LOG], "level": DEFAULT_LOGLEVEL}, | |
# Python Social Auth | |
"social": {"handlers": [DEFAULT_LOG], "level": DEFAULT_LOGLEVEL}, | |
# Django Authentication Using LDAP | |
"django_auth_ldap": {"handlers": [DEFAULT_LOG], "level": DEFAULT_LOGLEVEL}, | |
# SAML IdP | |
"djangosaml2idp": {"handlers": [DEFAULT_LOG], "level": DEFAULT_LOGLEVEL}, | |
}, | |
} | |
# Remove syslog setup if it's not present | |
if not HAVE_SYSLOG: | |
del LOGGING["handlers"]["syslog"] | |
# List of machine translations | |
MT_SERVICES = ( | |
# "weblate.machinery.apertium.ApertiumAPYTranslation", | |
# "weblate.machinery.baidu.BaiduTranslation", | |
# "weblate.machinery.deepl.DeepLTranslation", | |
# "weblate.machinery.glosbe.GlosbeTranslation", | |
# "weblate.machinery.google.GoogleTranslation", | |
# "weblate.machinery.googlev3.GoogleV3Translation", | |
# "weblate.machinery.microsoft.MicrosoftCognitiveTranslation", | |
# "weblate.machinery.microsoftterminology.MicrosoftTerminologyService", | |
# "weblate.machinery.modernmt.ModernMTTranslation", | |
# "weblate.machinery.mymemory.MyMemoryTranslation", | |
# "weblate.machinery.netease.NeteaseSightTranslation", | |
# "weblate.machinery.tmserver.AmagamaTranslation", | |
# "weblate.machinery.tmserver.TMServerTranslation", | |
# "weblate.machinery.yandex.YandexTranslation", | |
# "weblate.machinery.saptranslationhub.SAPTranslationHub", | |
# "weblate.machinery.youdao.YoudaoTranslation", | |
"weblate.machinery.weblatetm.WeblateTranslation", | |
"weblate.memory.machine.WeblateMemory", | |
) | |
# Machine translation API keys | |
# URL of the Apertium APy server | |
MT_APERTIUM_APY = None | |
# DeepL API key | |
MT_DEEPL_KEY = None | |
# Microsoft Cognitive Services Translator API, register at | |
# https://portal.azure.com/ | |
MT_MICROSOFT_COGNITIVE_KEY = None | |
MT_MICROSOFT_REGION = None | |
# ModernMT | |
MT_MODERNMT_KEY = None | |
# MyMemory identification email, see | |
# https://mymemory.translated.net/doc/spec.php | |
MT_MYMEMORY_EMAIL = None | |
# Optional MyMemory credentials to access private translation memory | |
MT_MYMEMORY_USER = None | |
MT_MYMEMORY_KEY = None | |
# Google API key for Google Translate API v2 | |
MT_GOOGLE_KEY = None | |
# Google Translate API3 credentials and project id | |
MT_GOOGLE_CREDENTIALS = None | |
MT_GOOGLE_PROJECT = None | |
# Baidu app key and secret | |
MT_BAIDU_ID = None | |
MT_BAIDU_SECRET = None | |
# Youdao Zhiyun app key and secret | |
MT_YOUDAO_ID = None | |
MT_YOUDAO_SECRET = None | |
# Netease Sight (Jianwai) app key and secret | |
MT_NETEASE_KEY = None | |
MT_NETEASE_SECRET = None | |
# API key for Yandex Translate API | |
MT_YANDEX_KEY = None | |
# tmserver URL | |
MT_TMSERVER = None | |
# SAP Translation Hub | |
MT_SAP_BASE_URL = None | |
MT_SAP_SANDBOX_APIKEY = None | |
MT_SAP_USERNAME = None | |
MT_SAP_PASSWORD = None | |
MT_SAP_USE_MT = True | |
# Title of site to use | |
SITE_TITLE = "Weblate" | |
# Site domain | |
SITE_DOMAIN = "" | |
# Whether site uses https | |
ENABLE_HTTPS = False | |
# Use HTTPS when creating redirect URLs for social authentication, see | |
# documentation for more details: | |
# https://python-social-auth-docs.readthedocs.io/en/latest/configuration/settings.html#processing-redirects-and-urlopen | |
SOCIAL_AUTH_REDIRECT_IS_HTTPS = ENABLE_HTTPS | |
# Make CSRF cookie HttpOnly, see documentation for more details: | |
# https://docs.djangoproject.com/en/1.11/ref/settings/#csrf-cookie-httponly | |
CSRF_COOKIE_HTTPONLY = True | |
CSRF_COOKIE_SECURE = ENABLE_HTTPS | |
# Store CSRF token in session | |
CSRF_USE_SESSIONS = True | |
# Customize CSRF failure view | |
CSRF_FAILURE_VIEW = "weblate.trans.views.error.csrf_failure" | |
SESSION_COOKIE_SECURE = ENABLE_HTTPS | |
SESSION_COOKIE_HTTPONLY = True | |
# SSL redirect | |
SECURE_SSL_REDIRECT = ENABLE_HTTPS | |
# Sent referrrer only for same origin links | |
SECURE_REFERRER_POLICY = "same-origin" | |
# SSL redirect URL exemption list | |
SECURE_REDIRECT_EXEMPT = (r"healthz/$",) # Allowing HTTP access to health check | |
# Session cookie age (in seconds) | |
SESSION_COOKIE_AGE = 1000 | |
SESSION_COOKIE_AGE_AUTHENTICATED = 1209600 | |
# Increase allowed upload size | |
DATA_UPLOAD_MAX_MEMORY_SIZE = 50000000 | |
# Apply session coookie settings to language cookie as ewll | |
LANGUAGE_COOKIE_SECURE = SESSION_COOKIE_SECURE | |
LANGUAGE_COOKIE_HTTPONLY = SESSION_COOKIE_HTTPONLY | |
LANGUAGE_COOKIE_AGE = SESSION_COOKIE_AGE_AUTHENTICATED * 10 | |
# Some security headers | |
SECURE_BROWSER_XSS_FILTER = True | |
X_FRAME_OPTIONS = "DENY" | |
SECURE_CONTENT_TYPE_NOSNIFF = True | |
# Optionally enable HSTS | |
SECURE_HSTS_SECONDS = 31536000 if ENABLE_HTTPS else 0 | |
SECURE_HSTS_PRELOAD = ENABLE_HTTPS | |
SECURE_HSTS_INCLUDE_SUBDOMAINS = ENABLE_HTTPS | |
# HTTPS detection behind reverse proxy | |
SECURE_PROXY_SSL_HEADER = None | |
# URL of login | |
LOGIN_URL = f"{URL_PREFIX}/accounts/login/" | |
# URL of logout | |
LOGOUT_URL = f"{URL_PREFIX}/accounts/logout/" | |
# Default location for login | |
LOGIN_REDIRECT_URL = f"{URL_PREFIX}/" | |
# Anonymous user name | |
ANONYMOUS_USER_NAME = "anonymous" | |
# Reverse proxy settings | |
IP_PROXY_HEADER = "HTTP_X_FORWARDED_FOR" | |
IP_BEHIND_REVERSE_PROXY = False | |
IP_PROXY_OFFSET = 0 | |
# Sending HTML in mails | |
EMAIL_SEND_HTML = True | |
# Subject of emails includes site title | |
EMAIL_SUBJECT_PREFIX = f"[{SITE_TITLE}] " | |
# Enable remote hooks | |
ENABLE_HOOKS = True | |
# By default the length of a given translation is limited to the length of | |
# the source string * 10 characters. Set this option to False to allow longer | |
# translations (up to 10.000 characters) | |
LIMIT_TRANSLATION_LENGTH_BY_SOURCE_LENGTH = True | |
# Use simple language codes for default language/country combinations | |
SIMPLIFY_LANGUAGES = True | |
# Render forms using bootstrap | |
CRISPY_TEMPLATE_PACK = "bootstrap3" | |
# List of quality checks | |
# CHECK_LIST = ( | |
# "weblate.checks.same.SameCheck", | |
# "weblate.checks.chars.BeginNewlineCheck", | |
# "weblate.checks.chars.EndNewlineCheck", | |
# "weblate.checks.chars.BeginSpaceCheck", | |
# "weblate.checks.chars.EndSpaceCheck", | |
# "weblate.checks.chars.DoubleSpaceCheck", | |
# "weblate.checks.chars.EndStopCheck", | |
# "weblate.checks.chars.EndColonCheck", | |
# "weblate.checks.chars.EndQuestionCheck", | |
# "weblate.checks.chars.EndExclamationCheck", | |
# "weblate.checks.chars.EndEllipsisCheck", | |
# "weblate.checks.chars.EndSemicolonCheck", | |
# "weblate.checks.chars.MaxLengthCheck", | |
# "weblate.checks.chars.KashidaCheck", | |
# "weblate.checks.chars.PunctuationSpacingCheck", | |
# "weblate.checks.format.PythonFormatCheck", | |
# "weblate.checks.format.PythonBraceFormatCheck", | |
# "weblate.checks.format.PHPFormatCheck", | |
# "weblate.checks.format.CFormatCheck", | |
# "weblate.checks.format.PerlFormatCheck", | |
# "weblate.checks.format.JavaScriptFormatCheck", | |
# "weblate.checks.format.CSharpFormatCheck", | |
# "weblate.checks.format.JavaFormatCheck", | |
# "weblate.checks.format.JavaMessageFormatCheck", | |
# "weblate.checks.format.PercentPlaceholdersCheck", | |
# "weblate.checks.format.VueFormattingCheck", | |
# "weblate.checks.format.I18NextInterpolationCheck", | |
# "weblate.checks.format.ESTemplateLiteralsCheck", | |
# "weblate.checks.angularjs.AngularJSInterpolationCheck", | |
# "weblate.checks.qt.QtFormatCheck", | |
# "weblate.checks.qt.QtPluralCheck", | |
# "weblate.checks.ruby.RubyFormatCheck", | |
# "weblate.checks.consistency.PluralsCheck", | |
# "weblate.checks.consistency.SamePluralsCheck", | |
# "weblate.checks.consistency.ConsistencyCheck", | |
# "weblate.checks.consistency.TranslatedCheck", | |
# "weblate.checks.chars.EscapedNewlineCountingCheck", | |
# "weblate.checks.chars.NewLineCountCheck", | |
# "weblate.checks.markup.BBCodeCheck", | |
# "weblate.checks.chars.ZeroWidthSpaceCheck", | |
# "weblate.checks.render.MaxSizeCheck", | |
# "weblate.checks.markup.XMLValidityCheck", | |
# "weblate.checks.markup.XMLTagsCheck", | |
# "weblate.checks.markup.MarkdownRefLinkCheck", | |
# "weblate.checks.markup.MarkdownLinkCheck", | |
# "weblate.checks.markup.MarkdownSyntaxCheck", | |
# "weblate.checks.markup.URLCheck", | |
# "weblate.checks.markup.SafeHTMLCheck", | |
# "weblate.checks.placeholders.PlaceholderCheck", | |
# "weblate.checks.placeholders.RegexCheck", | |
# "weblate.checks.duplicate.DuplicateCheck", | |
# "weblate.checks.source.OptionalPluralCheck", | |
# "weblate.checks.source.EllipsisCheck", | |
# "weblate.checks.source.MultipleFailingCheck", | |
# "weblate.checks.source.LongUntranslatedCheck", | |
# "weblate.checks.format.MultipleUnnamedFormatsCheck", | |
# ) | |
# List of automatic fixups | |
# AUTOFIX_LIST = ( | |
# "weblate.trans.autofixes.whitespace.SameBookendingWhitespace", | |
# "weblate.trans.autofixes.chars.ReplaceTrailingDotsWithEllipsis", | |
# "weblate.trans.autofixes.chars.RemoveZeroSpace", | |
# "weblate.trans.autofixes.chars.RemoveControlChars", | |
# ) | |
# List of enabled addons | |
# WEBLATE_ADDONS = ( | |
# "weblate.addons.gettext.GenerateMoAddon", | |
# "weblate.addons.gettext.UpdateLinguasAddon", | |
# "weblate.addons.gettext.UpdateConfigureAddon", | |
# "weblate.addons.gettext.MsgmergeAddon", | |
# "weblate.addons.gettext.GettextCustomizeAddon", | |
# "weblate.addons.gettext.GettextAuthorComments", | |
# "weblate.addons.cleanup.CleanupAddon", | |
# "weblate.addons.consistency.LangaugeConsistencyAddon", | |
# "weblate.addons.discovery.DiscoveryAddon", | |
# "weblate.addons.flags.SourceEditAddon", | |
# "weblate.addons.flags.TargetEditAddon", | |
# "weblate.addons.flags.SameEditAddon", | |
# "weblate.addons.flags.BulkEditAddon", | |
# "weblate.addons.generate.GenerateFileAddon", | |
# "weblate.addons.json.JSONCustomizeAddon", | |
# "weblate.addons.properties.PropertiesSortAddon", | |
# "weblate.addons.git.GitSquashAddon", | |
# "weblate.addons.removal.RemoveComments", | |
# "weblate.addons.removal.RemoveSuggestions", | |
# "weblate.addons.resx.ResxUpdateAddon", | |
# "weblate.addons.yaml.YAMLCustomizeAddon", | |
# "weblate.addons.cdn.CDNJSAddon", | |
# "weblate.addons.autotranslate.AutoTranslateAddon", | |
# ) | |
# E-mail address that error messages come from. | |
SERVER_EMAIL = "noreply@example.com" | |
# Default email address to use for various automated correspondence from | |
# the site managers. Used for registration emails. | |
DEFAULT_FROM_EMAIL = "noreply@example.com" | |
# List of URLs your site is supposed to serve | |
ALLOWED_HOSTS = ["*"] | |
# Configuration for caching | |
CACHES = { | |
"default": { | |
"BACKEND": "django_redis.cache.RedisCache", | |
"LOCATION": "redis://127.0.0.1:6379/1", | |
# If redis is running on same host as Weblate, you might | |
# want to use unix sockets instead: | |
# "LOCATION": "unix:///var/run/redis/redis.sock?db=1", | |
"OPTIONS": { | |
"CLIENT_CLASS": "django_redis.client.DefaultClient", | |
"PARSER_CLASS": "redis.connection.HiredisParser", | |
# If you set password here, adjust CELERY_BROKER_URL as well | |
"PASSWORD": None, | |
"CONNECTION_POOL_KWARGS": {}, | |
}, | |
"KEY_PREFIX": "weblate", | |
}, | |
"avatar": { | |
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache", | |
"LOCATION": os.path.join(DATA_DIR, "avatar-cache"), | |
"TIMEOUT": 86400, | |
"OPTIONS": {"MAX_ENTRIES": 1000}, | |
}, | |
} | |
# Store sessions in cache | |
SESSION_ENGINE = "django.contrib.sessions.backends.cache" | |
# Store messages in session | |
MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage" | |
# REST framework settings for API | |
REST_FRAMEWORK = { | |
# Use Django's standard `django.contrib.auth` permissions, | |
# or allow read-only access for unauthenticated users. | |
"DEFAULT_PERMISSION_CLASSES": [ | |
# Require authentication for login required sites | |
"rest_framework.permissions.IsAuthenticated" | |
if REQUIRE_LOGIN | |
else "rest_framework.permissions.IsAuthenticatedOrReadOnly" | |
], | |
"DEFAULT_AUTHENTICATION_CLASSES": ( | |
"rest_framework.authentication.TokenAuthentication", | |
"weblate.api.authentication.BearerAuthentication", | |
"rest_framework.authentication.SessionAuthentication", | |
), | |
"DEFAULT_THROTTLE_CLASSES": ( | |
"weblate.api.throttling.UserRateThrottle", | |
"weblate.api.throttling.AnonRateThrottle", | |
), | |
"DEFAULT_THROTTLE_RATES": {"anon": "100/day", "user": "5000/hour"}, | |
"DEFAULT_PAGINATION_CLASS": ("rest_framework.pagination.PageNumberPagination"), | |
"PAGE_SIZE": 20, | |
"VIEW_DESCRIPTION_FUNCTION": "weblate.api.views.get_view_description", | |
"UNAUTHENTICATED_USER": "weblate.auth.models.get_anonymous", | |
} | |
# Fonts CDN URL | |
FONTS_CDN_URL = None | |
# Django compressor offline mode | |
COMPRESS_OFFLINE = False | |
COMPRESS_OFFLINE_CONTEXT = [ | |
{"fonts_cdn_url": FONTS_CDN_URL, "STATIC_URL": STATIC_URL, "LANGUAGE_BIDI": True}, | |
{"fonts_cdn_url": FONTS_CDN_URL, "STATIC_URL": STATIC_URL, "LANGUAGE_BIDI": False}, | |
] | |
# Require login for all URLs | |
if REQUIRE_LOGIN: | |
LOGIN_REQUIRED_URLS = (r"/(.*)$",) | |
# In such case you will want to include some of the exceptions | |
# LOGIN_REQUIRED_URLS_EXCEPTIONS = ( | |
# rf"{URL_PREFIX}/accounts/(.*)$", # Required for login | |
# rf"{URL_PREFIX}/admin/login/(.*)$", # Required for admin login | |
# rf"{URL_PREFIX}/static/(.*)$", # Required for development mode | |
# rf"{URL_PREFIX}/widgets/(.*)$", # Allowing public access to widgets | |
# rf"{URL_PREFIX}/data/(.*)$", # Allowing public access to data exports | |
# rf"{URL_PREFIX}/hooks/(.*)$", # Allowing public access to notification hooks | |
# rf"{URL_PREFIX}/healthz/$", # Allowing public access to health check | |
# rf"{URL_PREFIX}/api/(.*)$", # Allowing access to API | |
# rf"{URL_PREFIX}/js/i18n/$", # JavaScript localization | |
# rf"{URL_PREFIX}/contact/$", # Optional for contact form | |
# rf"{URL_PREFIX}/legal/(.*)$", # Optional for legal app | |
# ) | |
# Silence some of the Django system checks | |
SILENCED_SYSTEM_CHECKS = [ | |
# We have modified django.contrib.auth.middleware.AuthenticationMiddleware | |
# as weblate.accounts.middleware.AuthenticationMiddleware | |
"admin.E408" | |
] | |
# Celery worker configuration for testing | |
# CELERY_TASK_ALWAYS_EAGER = True | |
# CELERY_BROKER_URL = "memory://" | |
# CELERY_TASK_EAGER_PROPAGATES = True | |
# Celery worker configuration for production | |
CELERY_TASK_ALWAYS_EAGER = False | |
CELERY_BROKER_URL = "redis://localhost:6379" | |
CELERY_RESULT_BACKEND = CELERY_BROKER_URL | |
# Celery settings, it is not recommended to change these | |
CELERY_WORKER_MAX_MEMORY_PER_CHILD = 200000 | |
CELERY_BEAT_SCHEDULE_FILENAME = os.path.join(DATA_DIR, "celery", "beat-schedule") | |
CELERY_TASK_ROUTES = { | |
"weblate.trans.tasks.auto_translate": {"queue": "translate"}, | |
"weblate.accounts.tasks.notify_*": {"queue": "notify"}, | |
"weblate.accounts.tasks.send_mails": {"queue": "notify"}, | |
"weblate.utils.tasks.settings_backup": {"queue": "backup"}, | |
"weblate.utils.tasks.database_backup": {"queue": "backup"}, | |
"weblate.wladmin.tasks.backup": {"queue": "backup"}, | |
"weblate.wladmin.tasks.backup_service": {"queue": "backup"}, | |
"weblate.memory.tasks.*": {"queue": "memory"}, | |
} | |
# Enable plain database backups | |
DATABASE_BACKUP = "plain" | |
# Enable auto updating | |
AUTO_UPDATE = False | |
# PGP commits signing | |
WEBLATE_GPG_IDENTITY = None | |
# Third party services integration | |
MATOMO_SITE_ID = None | |
MATOMO_URL = None | |
GOOGLE_ANALYTICS_ID = None | |
SENTRY_DSN = None | |
AKISMET_API_KEY = None |