kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
555 wiersze
19 KiB
Python
555 wiersze
19 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Django settings for funkwhale_api project.
|
|
|
|
For more information on this file, see
|
|
https://docs.djangoproject.com/en/dev/topics/settings/
|
|
|
|
For the full list of settings and their values, see
|
|
https://docs.djangoproject.com/en/dev/ref/settings/
|
|
"""
|
|
from __future__ import absolute_import, unicode_literals
|
|
|
|
import datetime
|
|
from urllib.parse import urlparse, urlsplit
|
|
|
|
import environ
|
|
from celery.schedules import crontab
|
|
|
|
from funkwhale_api import __version__
|
|
|
|
ROOT_DIR = environ.Path(__file__) - 3 # (/a/b/myfile.py - 3 = /)
|
|
APPS_DIR = ROOT_DIR.path("funkwhale_api")
|
|
|
|
env = environ.Env()
|
|
try:
|
|
env.read_env(ROOT_DIR.file(".env"))
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
FUNKWHALE_HOSTNAME = None
|
|
FUNKWHALE_HOSTNAME_SUFFIX = env("FUNKWHALE_HOSTNAME_SUFFIX", default=None)
|
|
FUNKWHALE_HOSTNAME_PREFIX = env("FUNKWHALE_HOSTNAME_PREFIX", default=None)
|
|
if FUNKWHALE_HOSTNAME_PREFIX and FUNKWHALE_HOSTNAME_SUFFIX:
|
|
# We're in traefik case, in development
|
|
FUNKWHALE_HOSTNAME = "{}.{}".format(
|
|
FUNKWHALE_HOSTNAME_PREFIX, FUNKWHALE_HOSTNAME_SUFFIX
|
|
)
|
|
FUNKWHALE_PROTOCOL = env("FUNKWHALE_PROTOCOL", default="https")
|
|
else:
|
|
try:
|
|
FUNKWHALE_HOSTNAME = env("FUNKWHALE_HOSTNAME")
|
|
FUNKWHALE_PROTOCOL = env("FUNKWHALE_PROTOCOL", default="https")
|
|
except Exception:
|
|
FUNKWHALE_URL = env("FUNKWHALE_URL")
|
|
_parsed = urlsplit(FUNKWHALE_URL)
|
|
FUNKWHALE_HOSTNAME = _parsed.netloc
|
|
FUNKWHALE_PROTOCOL = _parsed.scheme
|
|
|
|
FUNKWHALE_URL = "{}://{}".format(FUNKWHALE_PROTOCOL, FUNKWHALE_HOSTNAME)
|
|
|
|
|
|
# XXX: deprecated, see #186
|
|
FEDERATION_ENABLED = env.bool("FEDERATION_ENABLED", default=True)
|
|
FEDERATION_HOSTNAME = env("FEDERATION_HOSTNAME", default=FUNKWHALE_HOSTNAME)
|
|
# XXX: deprecated, see #186
|
|
FEDERATION_COLLECTION_PAGE_SIZE = env.int("FEDERATION_COLLECTION_PAGE_SIZE", default=50)
|
|
# XXX: deprecated, see #186
|
|
FEDERATION_MUSIC_NEEDS_APPROVAL = env.bool(
|
|
"FEDERATION_MUSIC_NEEDS_APPROVAL", default=True
|
|
)
|
|
# XXX: deprecated, see #186
|
|
FEDERATION_ACTOR_FETCH_DELAY = env.int("FEDERATION_ACTOR_FETCH_DELAY", default=60 * 12)
|
|
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS")
|
|
|
|
# APP CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
DJANGO_APPS = (
|
|
"channels",
|
|
# Default Django apps:
|
|
"django.contrib.auth",
|
|
"django.contrib.contenttypes",
|
|
"django.contrib.sessions",
|
|
"django.contrib.sites",
|
|
"django.contrib.messages",
|
|
"django.contrib.staticfiles",
|
|
"django.contrib.postgres",
|
|
# Useful template tags:
|
|
# 'django.contrib.humanize',
|
|
# Admin
|
|
"django.contrib.admin",
|
|
)
|
|
THIRD_PARTY_APPS = (
|
|
# 'crispy_forms', # Form layouts
|
|
"allauth", # registration
|
|
"allauth.account", # registration
|
|
"allauth.socialaccount", # registration
|
|
"corsheaders",
|
|
"rest_framework",
|
|
"rest_framework.authtoken",
|
|
"taggit",
|
|
"rest_auth",
|
|
"rest_auth.registration",
|
|
"dynamic_preferences",
|
|
"django_filters",
|
|
"django_cleanup",
|
|
"versatileimagefield",
|
|
)
|
|
|
|
|
|
# Sentry
|
|
RAVEN_ENABLED = env.bool("RAVEN_ENABLED", default=False)
|
|
RAVEN_DSN = env("RAVEN_DSN", default="")
|
|
|
|
if RAVEN_ENABLED:
|
|
RAVEN_CONFIG = {
|
|
"dsn": RAVEN_DSN,
|
|
# If you are using git, you can also automatically configure the
|
|
# release based on the git info.
|
|
"release": __version__,
|
|
}
|
|
THIRD_PARTY_APPS += ("raven.contrib.django.raven_compat",)
|
|
|
|
|
|
# Apps specific for this project go here.
|
|
LOCAL_APPS = (
|
|
"funkwhale_api.common",
|
|
"funkwhale_api.activity.apps.ActivityConfig",
|
|
"funkwhale_api.users", # custom users app
|
|
# Your stuff: custom apps go here
|
|
"funkwhale_api.instance",
|
|
"funkwhale_api.music",
|
|
"funkwhale_api.requests",
|
|
"funkwhale_api.favorites",
|
|
"funkwhale_api.federation",
|
|
"funkwhale_api.radios",
|
|
"funkwhale_api.history",
|
|
"funkwhale_api.playlists",
|
|
"funkwhale_api.providers.acoustid",
|
|
"funkwhale_api.subsonic",
|
|
)
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
|
|
|
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
|
|
|
|
# MIDDLEWARE CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
MIDDLEWARE = (
|
|
# Make sure djangosecure.middleware.SecurityMiddleware is listed first
|
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
"corsheaders.middleware.CorsMiddleware",
|
|
"django.middleware.common.CommonMiddleware",
|
|
"django.middleware.csrf.CsrfViewMiddleware",
|
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
"django.contrib.messages.middleware.MessageMiddleware",
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
"funkwhale_api.users.middleware.RecordActivityMiddleware",
|
|
)
|
|
|
|
# MIGRATIONS CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
MIGRATION_MODULES = {"sites": "funkwhale_api.contrib.sites.migrations"}
|
|
|
|
# DEBUG
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
|
|
DEBUG = env.bool("DJANGO_DEBUG", False)
|
|
|
|
# FIXTURE CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
|
|
FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),)
|
|
|
|
# EMAIL CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# EMAIL
|
|
# ------------------------------------------------------------------------------
|
|
DEFAULT_FROM_EMAIL = env(
|
|
"DEFAULT_FROM_EMAIL", default="Funkwhale <noreply@{}>".format(FUNKWHALE_HOSTNAME)
|
|
)
|
|
|
|
EMAIL_SUBJECT_PREFIX = env("EMAIL_SUBJECT_PREFIX", default="[Funkwhale] ")
|
|
SERVER_EMAIL = env("SERVER_EMAIL", default=DEFAULT_FROM_EMAIL)
|
|
|
|
|
|
EMAIL_CONFIG = env.email_url("EMAIL_CONFIG", default="consolemail://")
|
|
|
|
vars().update(EMAIL_CONFIG)
|
|
|
|
# DATABASE CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
|
DATABASES = {
|
|
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
|
|
"default": env.db("DATABASE_URL")
|
|
}
|
|
DATABASES["default"]["ATOMIC_REQUESTS"] = True
|
|
#
|
|
# DATABASES = {
|
|
# 'default': {
|
|
# 'ENGINE': 'django.db.backends.sqlite3',
|
|
# 'NAME': 'db.sqlite3',
|
|
# }
|
|
# }
|
|
# GENERAL CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# 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"
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
|
|
LANGUAGE_CODE = "en-us"
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
|
|
SITE_ID = 1
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
|
|
USE_I18N = True
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
|
|
USE_L10N = True
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
|
|
USE_TZ = True
|
|
|
|
# TEMPLATE CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#templates
|
|
TEMPLATES = [
|
|
{
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
|
|
"DIRS": [str(APPS_DIR.path("templates"))],
|
|
"OPTIONS": {
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
|
|
"debug": DEBUG,
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
|
|
# https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
|
|
"loaders": [
|
|
"django.template.loaders.filesystem.Loader",
|
|
"django.template.loaders.app_directories.Loader",
|
|
],
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
|
|
"context_processors": [
|
|
"django.template.context_processors.debug",
|
|
"django.template.context_processors.request",
|
|
"django.contrib.auth.context_processors.auth",
|
|
"django.template.context_processors.i18n",
|
|
"django.template.context_processors.media",
|
|
"django.template.context_processors.static",
|
|
"django.template.context_processors.tz",
|
|
"django.contrib.messages.context_processors.messages",
|
|
# Your stuff: custom template context processors go here
|
|
],
|
|
},
|
|
}
|
|
]
|
|
|
|
# See: http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs
|
|
CRISPY_TEMPLATE_PACK = "bootstrap3"
|
|
|
|
# STATIC FILE CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
|
|
STATIC_ROOT = env("STATIC_ROOT", default=str(ROOT_DIR("staticfiles")))
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
|
|
STATIC_URL = env("STATIC_URL", default="/staticfiles/")
|
|
DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIFileSystemStorage"
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
|
|
STATICFILES_DIRS = (str(APPS_DIR.path("static")),)
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
|
|
STATICFILES_FINDERS = (
|
|
"django.contrib.staticfiles.finders.FileSystemFinder",
|
|
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
|
)
|
|
|
|
# MEDIA CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
|
|
MEDIA_ROOT = env("MEDIA_ROOT", default=str(APPS_DIR("media")))
|
|
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
|
|
MEDIA_URL = env("MEDIA_URL", default="/media/")
|
|
FILE_UPLOAD_PERMISSIONS = 0o644
|
|
# URL Configuration
|
|
# ------------------------------------------------------------------------------
|
|
ROOT_URLCONF = "config.urls"
|
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
|
|
WSGI_APPLICATION = "config.wsgi.application"
|
|
ASGI_APPLICATION = "config.routing.application"
|
|
|
|
# This ensures that Django will be able to detect a secure connection
|
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
|
|
# AUTHENTICATION CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
AUTHENTICATION_BACKENDS = (
|
|
"django.contrib.auth.backends.ModelBackend",
|
|
"allauth.account.auth_backends.AuthenticationBackend",
|
|
)
|
|
SESSION_COOKIE_HTTPONLY = False
|
|
# Some really nice defaults
|
|
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
|
|
ACCOUNT_EMAIL_REQUIRED = True
|
|
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
|
ACCOUNT_USERNAME_VALIDATORS = "funkwhale_api.users.serializers.username_validators"
|
|
|
|
# Custom user app defaults
|
|
# Select the correct user model
|
|
AUTH_USER_MODEL = "users.User"
|
|
LOGIN_REDIRECT_URL = "users:redirect"
|
|
LOGIN_URL = "account_login"
|
|
|
|
# LDAP AUTHENTICATION CONFIGURATION
|
|
# ------------------------------------------------------------------------------
|
|
AUTH_LDAP_ENABLED = env.bool("LDAP_ENABLED", default=False)
|
|
if AUTH_LDAP_ENABLED:
|
|
|
|
# Import the LDAP modules here; this way, we don't need the dependency unless someone
|
|
# actually enables the LDAP support
|
|
import ldap
|
|
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType
|
|
|
|
# Add LDAP to the authentication backends
|
|
AUTHENTICATION_BACKENDS += ("django_auth_ldap.backend.LDAPBackend",)
|
|
|
|
# Basic configuration
|
|
AUTH_LDAP_SERVER_URI = env("LDAP_SERVER_URI")
|
|
AUTH_LDAP_BIND_DN = env("LDAP_BIND_DN", default="")
|
|
AUTH_LDAP_BIND_PASSWORD = env("LDAP_BIND_PASSWORD", default="")
|
|
AUTH_LDAP_SEARCH_FILTER = env("LDAP_SEARCH_FILTER", default="(uid={0})").format(
|
|
"%(user)s"
|
|
)
|
|
AUTH_LDAP_START_TLS = env.bool("LDAP_START_TLS", default=False)
|
|
|
|
DEFAULT_USER_ATTR_MAP = [
|
|
"first_name:givenName",
|
|
"last_name:sn",
|
|
"username:cn",
|
|
"email:mail",
|
|
]
|
|
LDAP_USER_ATTR_MAP = env.list("LDAP_USER_ATTR_MAP", default=DEFAULT_USER_ATTR_MAP)
|
|
AUTH_LDAP_USER_ATTR_MAP = {}
|
|
for m in LDAP_USER_ATTR_MAP:
|
|
funkwhale_field, ldap_field = m.split(":")
|
|
AUTH_LDAP_USER_ATTR_MAP[funkwhale_field.strip()] = ldap_field.strip()
|
|
|
|
# Determine root DN supporting multiple root DNs
|
|
AUTH_LDAP_ROOT_DN = env("LDAP_ROOT_DN")
|
|
AUTH_LDAP_ROOT_DN_LIST = []
|
|
for ROOT_DN in AUTH_LDAP_ROOT_DN.split():
|
|
AUTH_LDAP_ROOT_DN_LIST.append(
|
|
LDAPSearch(ROOT_DN, ldap.SCOPE_SUBTREE, AUTH_LDAP_SEARCH_FILTER)
|
|
)
|
|
# Search for the user in all the root DNs
|
|
AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(*AUTH_LDAP_ROOT_DN_LIST)
|
|
|
|
# Search for group types
|
|
LDAP_GROUP_DN = env("LDAP_GROUP_DN", default="")
|
|
if LDAP_GROUP_DN:
|
|
AUTH_LDAP_GROUP_DN = LDAP_GROUP_DN
|
|
# Get filter
|
|
AUTH_LDAP_GROUP_FILTER = env("LDAP_GROUP_FILER", default="")
|
|
# Search for the group in the specified DN
|
|
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
|
|
AUTH_LDAP_GROUP_DN, ldap.SCOPE_SUBTREE, AUTH_LDAP_GROUP_FILTER
|
|
)
|
|
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
|
|
|
|
# Configure basic group support
|
|
LDAP_REQUIRE_GROUP = env("LDAP_REQUIRE_GROUP", default="")
|
|
if LDAP_REQUIRE_GROUP:
|
|
AUTH_LDAP_REQUIRE_GROUP = LDAP_REQUIRE_GROUP
|
|
LDAP_DENY_GROUP = env("LDAP_DENY_GROUP", default="")
|
|
if LDAP_DENY_GROUP:
|
|
AUTH_LDAP_DENY_GROUP = LDAP_DENY_GROUP
|
|
|
|
|
|
# SLUGLIFIER
|
|
AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify"
|
|
|
|
CACHE_DEFAULT = "redis://127.0.0.1:6379/0"
|
|
CACHES = {"default": env.cache_url("CACHE_URL", default=CACHE_DEFAULT)}
|
|
|
|
CACHES["default"]["BACKEND"] = "django_redis.cache.RedisCache"
|
|
|
|
cache_url = urlparse(CACHES["default"]["LOCATION"])
|
|
CHANNEL_LAYERS = {
|
|
"default": {
|
|
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
|
"CONFIG": {"hosts": [(cache_url.hostname, cache_url.port)]},
|
|
}
|
|
}
|
|
|
|
CACHES["default"]["OPTIONS"] = {
|
|
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
|
"IGNORE_EXCEPTIONS": True, # mimics memcache behavior.
|
|
# http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior
|
|
}
|
|
|
|
|
|
# CELERY
|
|
INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",)
|
|
CELERY_BROKER_URL = env(
|
|
"CELERY_BROKER_URL", default=env("CACHE_URL", default=CACHE_DEFAULT)
|
|
)
|
|
# END CELERY
|
|
# Location of root django.contrib.admin URL, use {% url 'admin:index' %}
|
|
|
|
# Your common stuff: Below this line define 3rd party library settings
|
|
CELERY_TASK_DEFAULT_RATE_LIMIT = 1
|
|
CELERY_TASK_TIME_LIMIT = 300
|
|
CELERY_BEAT_SCHEDULE = {
|
|
"federation.clean_music_cache": {
|
|
"task": "federation.clean_music_cache",
|
|
"schedule": crontab(hour="*/2"),
|
|
"options": {"expires": 60 * 2},
|
|
},
|
|
"music.clean_transcoding_cache": {
|
|
"task": "music.clean_transcoding_cache",
|
|
"schedule": crontab(hour="*"),
|
|
"options": {"expires": 60 * 2},
|
|
},
|
|
}
|
|
|
|
JWT_AUTH = {
|
|
"JWT_ALLOW_REFRESH": True,
|
|
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=7),
|
|
"JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(days=30),
|
|
"JWT_AUTH_HEADER_PREFIX": "JWT",
|
|
"JWT_GET_USER_SECRET_KEY": lambda user: user.secret_key,
|
|
}
|
|
OLD_PASSWORD_FIELD_ENABLED = True
|
|
ACCOUNT_ADAPTER = "funkwhale_api.users.adapters.FunkwhaleAccountAdapter"
|
|
CORS_ORIGIN_ALLOW_ALL = True
|
|
# CORS_ORIGIN_WHITELIST = (
|
|
# 'localhost',
|
|
# 'funkwhale.localhost',
|
|
# )
|
|
CORS_ALLOW_CREDENTIALS = True
|
|
|
|
REST_FRAMEWORK = {
|
|
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
|
|
"DEFAULT_PAGINATION_CLASS": "funkwhale_api.common.pagination.FunkwhalePagination",
|
|
"PAGE_SIZE": 25,
|
|
"DEFAULT_PARSER_CLASSES": (
|
|
"rest_framework.parsers.JSONParser",
|
|
"rest_framework.parsers.FormParser",
|
|
"rest_framework.parsers.MultiPartParser",
|
|
"funkwhale_api.federation.parsers.ActivityParser",
|
|
),
|
|
"DEFAULT_AUTHENTICATION_CLASSES": (
|
|
"funkwhale_api.common.authentication.JSONWebTokenAuthenticationQS",
|
|
"funkwhale_api.common.authentication.BearerTokenHeaderAuth",
|
|
"funkwhale_api.common.authentication.JSONWebTokenAuthentication",
|
|
"rest_framework.authentication.SessionAuthentication",
|
|
"rest_framework.authentication.BasicAuthentication",
|
|
),
|
|
"DEFAULT_FILTER_BACKENDS": (
|
|
"rest_framework.filters.OrderingFilter",
|
|
"django_filters.rest_framework.DjangoFilterBackend",
|
|
),
|
|
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
|
|
}
|
|
|
|
BROWSABLE_API_ENABLED = env.bool("BROWSABLE_API_ENABLED", default=False)
|
|
if BROWSABLE_API_ENABLED:
|
|
REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] += (
|
|
"rest_framework.renderers.BrowsableAPIRenderer",
|
|
)
|
|
|
|
REST_AUTH_SERIALIZERS = {
|
|
"PASSWORD_RESET_SERIALIZER": "funkwhale_api.users.serializers.PasswordResetSerializer" # noqa
|
|
}
|
|
REST_SESSION_LOGIN = False
|
|
REST_USE_JWT = True
|
|
|
|
ATOMIC_REQUESTS = False
|
|
USE_X_FORWARDED_HOST = True
|
|
USE_X_FORWARDED_PORT = True
|
|
|
|
# Wether we should use Apache, Nginx (or other) headers when serving audio files
|
|
# Default to Nginx
|
|
REVERSE_PROXY_TYPE = env("REVERSE_PROXY_TYPE", default="nginx")
|
|
assert REVERSE_PROXY_TYPE in ["apache2", "nginx"], "Unsupported REVERSE_PROXY_TYPE"
|
|
|
|
# Which path will be used to process the internal redirection
|
|
# **DO NOT** put a slash at the end
|
|
PROTECT_FILES_PATH = env("PROTECT_FILES_PATH", default="/_protected")
|
|
|
|
|
|
# use this setting to tweak for how long you want to cache
|
|
# musicbrainz results. (value is in seconds)
|
|
MUSICBRAINZ_CACHE_DURATION = env.int("MUSICBRAINZ_CACHE_DURATION", default=300)
|
|
|
|
# Use this setting to change the musicbrainz hostname, for instance to
|
|
# use a mirror. The hostname can also contain a port number (so, e.g.,
|
|
# "localhost:5000" is a valid name to set).
|
|
MUSICBRAINZ_HOSTNAME = env("MUSICBRAINZ_HOSTNAME", default="musicbrainz.org")
|
|
|
|
# Custom Admin URL, use {% url 'admin:index' %}
|
|
ADMIN_URL = env("DJANGO_ADMIN_URL", default="^api/admin/")
|
|
CSRF_USE_SESSIONS = True
|
|
|
|
# Playlist settings
|
|
# XXX: deprecated, see #186
|
|
PLAYLISTS_MAX_TRACKS = env.int("PLAYLISTS_MAX_TRACKS", default=250)
|
|
|
|
ACCOUNT_USERNAME_BLACKLIST = [
|
|
"funkwhale",
|
|
"library",
|
|
"instance",
|
|
"test",
|
|
"status",
|
|
"root",
|
|
"admin",
|
|
"owner",
|
|
"superuser",
|
|
"staff",
|
|
"service",
|
|
"me",
|
|
"ghost",
|
|
"_",
|
|
"-",
|
|
"hello",
|
|
"contact",
|
|
"inbox",
|
|
"outbox",
|
|
"shared-inbox",
|
|
"shared_inbox",
|
|
"actor",
|
|
] + env.list("ACCOUNT_USERNAME_BLACKLIST", default=[])
|
|
|
|
EXTERNAL_REQUESTS_VERIFY_SSL = env.bool("EXTERNAL_REQUESTS_VERIFY_SSL", default=True)
|
|
# XXX: deprecated, see #186
|
|
API_AUTHENTICATION_REQUIRED = env.bool("API_AUTHENTICATION_REQUIRED", True)
|
|
|
|
MUSIC_DIRECTORY_PATH = env("MUSIC_DIRECTORY_PATH", default=None)
|
|
# on Docker setup, the music directory may not match the host path,
|
|
# and we need to know it for it to serve stuff properly
|
|
MUSIC_DIRECTORY_SERVE_PATH = env(
|
|
"MUSIC_DIRECTORY_SERVE_PATH", default=MUSIC_DIRECTORY_PATH
|
|
)
|
|
|
|
USERS_INVITATION_EXPIRATION_DAYS = env.int(
|
|
"USERS_INVITATION_EXPIRATION_DAYS", default=14
|
|
)
|
|
|
|
VERSATILEIMAGEFIELD_RENDITION_KEY_SETS = {
|
|
"square": [
|
|
("original", "url"),
|
|
("square_crop", "crop__400x400"),
|
|
("medium_square_crop", "crop__200x200"),
|
|
("small_square_crop", "crop__50x50"),
|
|
]
|
|
}
|
|
VERSATILEIMAGEFIELD_SETTINGS = {"create_images_on_demand": False}
|