2024-07-01 17:29:38 -04:00
|
|
|
import logging
|
2020-05-01 22:46:15 +08:00
|
|
|
import os
|
2024-05-12 22:39:44 -04:00
|
|
|
import sys
|
2022-12-09 19:38:11 -05:00
|
|
|
|
2023-08-20 18:27:20 +00:00
|
|
|
import environ
|
2024-03-10 20:55:50 -04:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2023-07-20 21:59:49 -04:00
|
|
|
|
2023-11-19 10:59:51 -05:00
|
|
|
from boofilsic import __version__
|
|
|
|
|
|
|
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
|
|
try:
|
|
|
|
with open(os.path.join(BASE_DIR, "build_version")) as f:
|
|
|
|
NEODB_VERSION = __version__ + "-" + f.read().strip()
|
2024-04-06 00:13:50 -04:00
|
|
|
except Exception:
|
2023-12-01 17:29:40 -05:00
|
|
|
NEODB_VERSION = __version__ + "-unknown"
|
2023-11-19 10:59:51 -05:00
|
|
|
|
2024-06-17 15:10:34 -04:00
|
|
|
TESTING = len(sys.argv) > 1 and sys.argv[1] == "test"
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
# Parse configuration from:
|
|
|
|
# - environment variables
|
2023-12-02 23:28:58 -05:00
|
|
|
# - neodb.env file in project root directory
|
|
|
|
# - /etc/neodb.env
|
|
|
|
environ.Env.read_env("/etc/neodb.env")
|
|
|
|
environ.Env.read_env(os.path.join(BASE_DIR, "neodb.env"))
|
2023-09-25 19:47:46 +00:00
|
|
|
|
|
|
|
# ====== List of user configuration variables ======
|
|
|
|
env = environ.FileAwareEnv(
|
|
|
|
# WARNING: do not run with debug mode turned on in production
|
2023-12-09 16:25:41 -05:00
|
|
|
NEODB_DEBUG=(bool, False),
|
2023-09-25 19:47:46 +00:00
|
|
|
# WARNING: must use your own key and keep it secret
|
|
|
|
NEODB_SECRET_KEY=(str),
|
|
|
|
# Site information
|
|
|
|
NEODB_SITE_NAME=(str),
|
|
|
|
NEODB_SITE_DOMAIN=(str),
|
|
|
|
NEODB_SITE_LOGO=(str, "/s/img/logo.svg"),
|
2024-04-07 16:50:26 -04:00
|
|
|
NEODB_SITE_ICON=(str, "/s/img/icon.png"),
|
2023-09-25 19:47:46 +00:00
|
|
|
NEODB_USER_ICON=(str, "/s/img/avatar.svg"),
|
2023-10-20 21:04:31 +00:00
|
|
|
NEODB_SITE_INTRO=(str, ""),
|
2023-12-01 18:09:49 -05:00
|
|
|
NEODB_SITE_HEAD=(str, ""),
|
2024-03-10 20:55:50 -04:00
|
|
|
NEODB_SITE_DESCRIPTION=(
|
|
|
|
str,
|
|
|
|
"reviews about book, film, music, podcast and game.",
|
|
|
|
),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Links in site footer
|
|
|
|
NEODB_SITE_LINKS=(dict, {}),
|
2024-04-06 11:53:31 -04:00
|
|
|
# Alternative domains
|
|
|
|
NEODB_ALTERNATIVE_DOMAINS=(list, []),
|
2024-04-03 23:10:21 -04:00
|
|
|
# Default language
|
|
|
|
NEODB_LANGUAGE=(str, "zh-hans"),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Invite only mode
|
|
|
|
# when True: user will not be able to register unless with invite token
|
|
|
|
# (generated by `neodb-manage invite --create`)
|
|
|
|
NEODB_INVITE_ONLY=(bool, False),
|
2023-12-10 19:13:45 -05:00
|
|
|
NEODB_ENABLE_LOCAL_ONLY=(bool, False),
|
2023-12-23 23:55:33 -05:00
|
|
|
NEODB_EXTRA_APPS=(list, []),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Mastodon/Pleroma instance allowed to login, keep empty to allow any instance to login
|
|
|
|
NEODB_LOGIN_MASTODON_WHITELIST=(list, []),
|
|
|
|
# DATABASE
|
|
|
|
NEODB_DB_URL=(str, "postgres://user:pass@127.0.0.1:5432/neodb"),
|
|
|
|
# Redis, for cache and job queue
|
|
|
|
NEODB_REDIS_URL=(str, "redis://127.0.0.1:6379/0"),
|
|
|
|
# Search backend, in one of these formats:
|
|
|
|
# typesense://user:insecure@127.0.0.1:8108/catalog
|
|
|
|
NEODB_SEARCH_URL=(str, ""),
|
|
|
|
# EMAIL CONFIGURATION, in one of these formats:
|
|
|
|
# "smtp://<username>:<password>@<host>:<port>"
|
|
|
|
# "smtp+tls://<username>:<password>@<host>:<port>"
|
|
|
|
# "smtp+ssl://<username>:<password>@<host>:<port>"
|
|
|
|
# "anymail://<anymail_backend_name>?<anymail_args>"
|
|
|
|
NEODB_EMAIL_URL=(str, ""),
|
|
|
|
# EMAIL FROM
|
|
|
|
NEODB_EMAIL_FROM=(str, "🧩 NeoDB <no-reply@neodb.social>"),
|
|
|
|
# ADMIN_USERS
|
|
|
|
NEODB_ADMIN_USERNAMES=(list, []),
|
|
|
|
# List of available proxies for proxy downloader, in format of http://server1?url=__URL__,http://s2?url=__URL__,...
|
|
|
|
NEODB_DOWNLOADER_PROXY_LIST=(list, []),
|
|
|
|
# Timeout of downloader requests, in seconds
|
|
|
|
NEODB_DOWNLOADER_REQUEST_TIMEOUT=(int, 90),
|
|
|
|
# Timeout of downloader cache, in seconds
|
|
|
|
NEODB_DOWNLOADER_CACHE_TIMEOUT=(int, 300),
|
|
|
|
# Number of retries of downloader, when site is using RetryDownloader
|
|
|
|
NEODB_DOWNLOADER_RETRIES=(int, 3),
|
2024-01-14 13:12:43 -05:00
|
|
|
# Number of marks required for an item to be included in discover
|
|
|
|
NEODB_MIN_MARKS_FOR_DISCOVER=(int, 1),
|
2024-01-14 13:17:58 -05:00
|
|
|
# Disable cron jobs, * for all
|
2023-12-28 22:12:07 -05:00
|
|
|
NEODB_DISABLE_CRON_JOBS=(list, []),
|
2023-09-25 19:47:46 +00:00
|
|
|
# INTEGRATED TAKAHE CONFIGURATION
|
|
|
|
TAKAHE_DB_URL=(str, "postgres://takahe:takahepass@127.0.0.1:5432/takahe"),
|
|
|
|
# Spotify - https://developer.spotify.com/
|
2023-09-25 23:22:34 +00:00
|
|
|
SPOTIFY_API_KEY=(str, "TESTONLY"),
|
2023-09-25 19:47:46 +00:00
|
|
|
# The Movie Database (TMDB) - https://developer.themoviedb.org/
|
2023-09-25 23:22:34 +00:00
|
|
|
TMDB_API_V3_KEY=(str, "TESTONLY"),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Google Books - https://developers.google.com/books/docs/v1/using - not used at the moment
|
2023-09-25 23:22:34 +00:00
|
|
|
GOOGLE_API_KEY=(str, "TESTONLY"),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Discogs - personal access token from https://www.discogs.com/settings/developers
|
2023-09-25 23:22:34 +00:00
|
|
|
DISCOGS_API_KEY=(str, "TESTONLY"),
|
2023-09-25 19:47:46 +00:00
|
|
|
# IGDB - https://api-docs.igdb.com/
|
2023-09-25 23:22:34 +00:00
|
|
|
IGDB_API_CLIENT_ID=(str, "TESTONLY"),
|
|
|
|
IGDB_API_CLIENT_SECRET=(str, ""),
|
2023-09-25 19:47:46 +00:00
|
|
|
# Discord webhooks
|
|
|
|
DISCORD_WEBHOOKS=(dict, {"user-report": None}),
|
|
|
|
# Slack API token, for sending exceptions to Slack, may deprecate in future
|
|
|
|
SLACK_API_TOKEN=(str, ""),
|
2024-07-03 00:07:07 -04:00
|
|
|
THREADS_APP_ID=(str, ""),
|
|
|
|
THREADS_APP_SECRET=(str, ""),
|
2024-07-04 00:17:12 -04:00
|
|
|
NEODB_ENABLE_LOGIN_BLUESKY=(bool, False),
|
|
|
|
NEODB_ENABLE_LOGIN_THREADS=(bool, False),
|
2023-11-24 20:41:28 -05:00
|
|
|
# SSL only, better be True for production security
|
|
|
|
SSL_ONLY=(bool, False),
|
2023-11-21 00:49:42 -05:00
|
|
|
NEODB_SENTRY_DSN=(str, ""),
|
2024-05-12 22:39:44 -04:00
|
|
|
NEODB_SENTRY_SAMPLE_RATE=(float, 0),
|
2023-11-23 10:11:42 -05:00
|
|
|
NEODB_FANOUT_LIMIT_DAYS=(int, 9),
|
2023-09-25 19:47:46 +00:00
|
|
|
)
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
# ====== End of user configuration variables ======
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
SECRET_KEY = env("NEODB_SECRET_KEY")
|
|
|
|
DEBUG = env("NEODB_DEBUG")
|
2023-08-24 05:48:14 +00:00
|
|
|
DATABASES = {
|
2023-09-25 19:47:46 +00:00
|
|
|
"takahe": env.db_url("TAKAHE_DB_URL"),
|
2024-04-08 20:25:14 -04:00
|
|
|
"default": env.db_url("NEODB_DB_URL"),
|
2023-08-24 05:48:14 +00:00
|
|
|
}
|
2023-09-25 19:47:46 +00:00
|
|
|
DATABASES["default"]["OPTIONS"] = {"client_encoding": "UTF8"}
|
|
|
|
DATABASES["default"]["TEST"] = {"DEPENDENCIES": ["takahe"]}
|
|
|
|
DATABASES["takahe"]["OPTIONS"] = {"client_encoding": "UTF8"}
|
|
|
|
DATABASES["takahe"]["TEST"] = {"DEPENDENCIES": []}
|
2023-11-24 20:41:28 -05:00
|
|
|
REDIS_URL = env("NEODB_REDIS_URL")
|
2023-09-25 19:47:46 +00:00
|
|
|
CACHES = {"default": env.cache_url("NEODB_REDIS_URL")}
|
|
|
|
_parsed_redis_url = env.url("NEODB_REDIS_URL")
|
|
|
|
RQ_QUEUES = {
|
|
|
|
q: {
|
|
|
|
"HOST": _parsed_redis_url.hostname,
|
|
|
|
"PORT": _parsed_redis_url.port,
|
|
|
|
"DB": _parsed_redis_url.path[1:],
|
|
|
|
"DEFAULT_TIMEOUT": -1,
|
|
|
|
}
|
2023-10-21 05:41:38 +00:00
|
|
|
for q in ["mastodon", "export", "import", "fetch", "crawl", "ap", "cron"]
|
2023-08-24 05:48:14 +00:00
|
|
|
}
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
_parsed_search_url = env.url("NEODB_SEARCH_URL")
|
|
|
|
SEARCH_BACKEND = None
|
|
|
|
TYPESENSE_CONNECTION = {}
|
|
|
|
if _parsed_search_url.scheme == "typesense":
|
|
|
|
SEARCH_BACKEND = "TYPESENSE"
|
|
|
|
TYPESENSE_CONNECTION = {
|
|
|
|
"api_key": _parsed_search_url.password,
|
|
|
|
"nodes": [
|
|
|
|
{
|
|
|
|
"host": _parsed_search_url.hostname,
|
|
|
|
"port": _parsed_search_url.port,
|
|
|
|
"protocol": "http",
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"connection_timeout_seconds": 2,
|
|
|
|
}
|
|
|
|
TYPESENSE_INDEX_NAME = _parsed_search_url.path[1:]
|
|
|
|
# elif _parsed_search_url.scheme == "meilisearch":
|
|
|
|
# SEARCH_BACKEND = 'MEILISEARCH'
|
|
|
|
# MEILISEARCH_SERVER = 'http://127.0.0.1:7700'
|
|
|
|
# MEILISEARCH_KEY = _parsed_search_url.password
|
|
|
|
|
|
|
|
DEFAULT_FROM_EMAIL = env("NEODB_EMAIL_FROM")
|
|
|
|
_parsed_email_url = env.url("NEODB_EMAIL_URL")
|
|
|
|
if _parsed_email_url.scheme == "anymail":
|
|
|
|
# "anymail://<anymail_backend_name>?<anymail_args>"
|
|
|
|
# see https://anymail.dev/
|
|
|
|
from urllib import parse
|
|
|
|
|
|
|
|
EMAIL_BACKEND = _parsed_email_url.hostname
|
|
|
|
ANYMAIL = dict(parse.parse_qsl(_parsed_email_url.query))
|
2024-07-01 17:29:38 -04:00
|
|
|
ENABLE_LOGIN_EMAIL = True
|
2023-09-25 19:47:46 +00:00
|
|
|
elif _parsed_email_url.scheme:
|
|
|
|
_parsed_email_config = env.email("NEODB_EMAIL_URL")
|
|
|
|
EMAIL_TIMEOUT = 5
|
|
|
|
vars().update(_parsed_email_config)
|
2024-07-01 17:29:38 -04:00
|
|
|
ENABLE_LOGIN_EMAIL = True
|
|
|
|
else:
|
|
|
|
ENABLE_LOGIN_EMAIL = False
|
|
|
|
|
2024-07-03 00:07:07 -04:00
|
|
|
|
|
|
|
THREADS_APP_ID = env("THREADS_APP_ID")
|
|
|
|
THREADS_APP_SECRET = env("THREADS_APP_SECRET")
|
|
|
|
|
2024-07-04 00:17:12 -04:00
|
|
|
ENABLE_LOGIN_BLUESKY = env("NEODB_ENABLE_LOGIN_BLUESKY")
|
|
|
|
ENABLE_LOGIN_THREADS = env("NEODB_ENABLE_LOGIN_THREADS")
|
2023-09-25 19:47:46 +00:00
|
|
|
|
2024-04-07 13:02:52 -04:00
|
|
|
SITE_DOMAIN = env("NEODB_SITE_DOMAIN").lower()
|
2023-08-24 05:48:14 +00:00
|
|
|
SITE_INFO = {
|
2023-12-01 17:29:40 -05:00
|
|
|
"neodb_version": NEODB_VERSION,
|
2023-09-25 19:47:46 +00:00
|
|
|
"site_name": env("NEODB_SITE_NAME"),
|
2023-08-24 05:48:14 +00:00
|
|
|
"site_domain": SITE_DOMAIN,
|
2023-09-25 19:47:46 +00:00
|
|
|
"site_url": env("NEODB_SITE_URL", default="https://" + SITE_DOMAIN),
|
|
|
|
"site_logo": env("NEODB_SITE_LOGO"),
|
|
|
|
"site_icon": env("NEODB_SITE_ICON"),
|
|
|
|
"user_icon": env("NEODB_USER_ICON"),
|
2023-10-20 21:04:31 +00:00
|
|
|
"site_intro": env("NEODB_SITE_INTRO"),
|
2023-12-06 19:40:23 -05:00
|
|
|
"site_description": env("NEODB_SITE_DESCRIPTION"),
|
2023-12-01 18:09:49 -05:00
|
|
|
"site_head": env("NEODB_SITE_HEAD"),
|
2023-09-25 19:47:46 +00:00
|
|
|
"site_links": [{"title": k, "url": v} for k, v in env("NEODB_SITE_LINKS").items()],
|
2024-05-29 10:50:41 -04:00
|
|
|
"cdn_url": "https://cdn.jsdelivr.net" if DEBUG else "/jsdelivr",
|
2024-04-06 22:52:35 -04:00
|
|
|
# "cdn_url": "https://cdn.jsdelivr.net",
|
2024-04-07 00:01:11 -04:00
|
|
|
# "cdn_url": "https://fastly.jsdelivr.net",
|
2023-08-24 05:48:14 +00:00
|
|
|
}
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
SETUP_ADMIN_USERNAMES = env("NEODB_ADMIN_USERNAMES")
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
INVITE_ONLY = env("NEODB_INVITE_ONLY")
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-03 21:25:30 +00:00
|
|
|
# By default, NeoDB will relay with relay.neodb.net so that public user ratings/etc can be shared across instances
|
|
|
|
# If you are running a development server, set this to True to disable this behavior
|
2023-09-25 19:47:46 +00:00
|
|
|
DISABLE_DEFAULT_RELAY = env("NEODB_DISABLE_DEFAULT_RELAY", default=DEBUG)
|
2023-09-03 21:25:30 +00:00
|
|
|
|
2024-01-14 13:12:43 -05:00
|
|
|
MIN_MARKS_FOR_DISCOVER = env("NEODB_MIN_MARKS_FOR_DISCOVER")
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
MASTODON_ALLOWED_SITES = env("NEODB_LOGIN_MASTODON_WHITELIST")
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
# Allow user to login via any Mastodon/Pleroma sites
|
|
|
|
MASTODON_ALLOW_ANY_SITE = len(MASTODON_ALLOWED_SITES) == 0
|
|
|
|
|
2024-04-07 13:02:52 -04:00
|
|
|
ALTERNATIVE_DOMAINS = [d.lower() for d in env("NEODB_ALTERNATIVE_DOMAINS", default=[])] # type: ignore
|
2024-04-06 11:53:31 -04:00
|
|
|
|
|
|
|
SITE_DOMAINS = [SITE_DOMAIN] + ALTERNATIVE_DOMAINS
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2024-04-07 22:17:52 -04:00
|
|
|
# ALLOWED_HOSTS = SITE_DOMAINS + ["127.0.0.1"]
|
|
|
|
ALLOWED_HOSTS = ["*"]
|
2024-04-07 13:02:52 -04:00
|
|
|
|
2023-12-10 19:13:45 -05:00
|
|
|
ENABLE_LOCAL_ONLY = env("NEODB_ENABLE_LOCAL_ONLY")
|
|
|
|
|
2023-08-24 05:48:14 +00:00
|
|
|
# Timeout of requests to Mastodon, in seconds
|
2024-05-14 10:54:49 -04:00
|
|
|
MASTODON_TIMEOUT = env("NEODB_LOGIN_MASTODON_TIMEOUT", default=5) # type: ignore
|
2024-07-03 16:42:20 -04:00
|
|
|
THREADS_TIMEOUT = 10 # Threads is really slow when publishing post
|
2023-11-26 17:23:53 -05:00
|
|
|
TAKAHE_REMOTE_TIMEOUT = MASTODON_TIMEOUT
|
|
|
|
|
|
|
|
NEODB_USER_AGENT = f"NeoDB/{NEODB_VERSION} (+{SITE_INFO.get('site_url', 'undefined')})"
|
|
|
|
TAKAHE_USER_AGENT = NEODB_USER_AGENT
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
# Scope when creating Mastodon apps
|
|
|
|
# Alternatively, use "read write follow" to avoid re-authorize when migrating to a future version with more features
|
|
|
|
MASTODON_CLIENT_SCOPE = env(
|
|
|
|
"NEODB_MASTODON_CLIENT_SCOPE",
|
|
|
|
default="read:accounts read:follows read:search read:blocks read:mutes write:statuses write:media", # type: ignore
|
|
|
|
)
|
2023-08-24 05:48:14 +00:00
|
|
|
|
|
|
|
# some Mastodon-compatible software like Pixelfed does not support granular scopes
|
|
|
|
MASTODON_LEGACY_CLIENT_SCOPE = "read write follow"
|
|
|
|
|
|
|
|
# Emoji code in mastodon
|
|
|
|
STAR_SOLID = ":star_solid:"
|
|
|
|
STAR_HALF = ":star_half:"
|
|
|
|
STAR_EMPTY = ":star_empty:"
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
DISCORD_WEBHOOKS = env("DISCORD_WEBHOOKS")
|
|
|
|
SPOTIFY_CREDENTIAL = env("SPOTIFY_API_KEY")
|
|
|
|
TMDB_API3_KEY = env("TMDB_API_V3_KEY")
|
|
|
|
# TMDB_API4_KEY = env('TMDB_API_V4_KEY')
|
|
|
|
# GOOGLE_API_KEY = env('GOOGLE_API_KEY')
|
|
|
|
DISCOGS_API_KEY = env("DISCOGS_API_KEY")
|
2023-09-25 23:22:34 +00:00
|
|
|
IGDB_CLIENT_ID = env("IGDB_API_CLIENT_ID")
|
|
|
|
IGDB_CLIENT_SECRET = env("IGDB_API_CLIENT_SECRET")
|
2023-09-25 19:47:46 +00:00
|
|
|
SLACK_TOKEN = env("SLACK_API_TOKEN")
|
|
|
|
SLACK_CHANNEL = "alert"
|
|
|
|
|
|
|
|
DOWNLOADER_PROXY_LIST = env("NEODB_DOWNLOADER_PROXY_LIST")
|
|
|
|
DOWNLOADER_BACKUP_PROXY = env("NEODB_DOWNLOADER_BACKUP_PROXY", default="") # type: ignore
|
|
|
|
DOWNLOADER_REQUEST_TIMEOUT = env("NEODB_DOWNLOADER_REQUEST_TIMEOUT")
|
|
|
|
DOWNLOADER_CACHE_TIMEOUT = env("NEODB_DOWNLOADER_CACHE_TIMEOUT")
|
|
|
|
DOWNLOADER_RETRIES = env("NEODB_DOWNLOADER_RETRIES")
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-12-28 22:12:07 -05:00
|
|
|
DISABLE_CRON_JOBS = env("NEODB_DISABLE_CRON_JOBS")
|
2023-11-23 10:11:42 -05:00
|
|
|
FANOUT_LIMIT_DAYS = env("NEODB_FANOUT_LIMIT_DAYS")
|
2023-08-24 05:48:14 +00:00
|
|
|
# ====== USER CONFIGUTRATION END ======
|
2023-07-20 21:59:49 -04:00
|
|
|
|
|
|
|
DATABASE_ROUTERS = ["takahe.db_routes.TakaheRouter"]
|
2023-08-10 11:27:31 -04:00
|
|
|
|
2023-08-17 02:09:36 -04:00
|
|
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
|
|
# for legacy deployment:
|
|
|
|
# DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2021-02-25 19:49:50 +01:00
|
|
|
# To allow debug in template context
|
|
|
|
# https://docs.djangoproject.com/en/3.1/ref/settings/#internal-ips
|
2023-01-02 00:03:13 -05:00
|
|
|
INTERNAL_IPS = ["127.0.0.1"]
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
# Application definition
|
|
|
|
|
|
|
|
INSTALLED_APPS = [
|
2023-07-08 17:58:45 -04:00
|
|
|
# "maintenance_mode", # this has to be first if enabled
|
2023-01-02 00:03:13 -05:00
|
|
|
"django.contrib.admin",
|
|
|
|
"hijack",
|
|
|
|
"hijack.contrib.admin",
|
|
|
|
"django.contrib.auth",
|
|
|
|
"django.contrib.contenttypes",
|
|
|
|
"django.contrib.sessions",
|
|
|
|
"django.contrib.messages",
|
|
|
|
"django.contrib.staticfiles",
|
|
|
|
"django.contrib.humanize",
|
|
|
|
"django.contrib.postgres",
|
|
|
|
"django_rq",
|
2023-01-26 17:31:20 -05:00
|
|
|
"django_bleach",
|
2023-06-05 13:16:10 -04:00
|
|
|
"django_jsonform",
|
2023-01-10 22:36:13 -05:00
|
|
|
"tz_detect",
|
2023-05-20 11:01:18 -04:00
|
|
|
"sass_processor",
|
2023-06-18 23:13:30 -04:00
|
|
|
"auditlog",
|
2023-01-02 00:03:13 -05:00
|
|
|
"markdownx",
|
2023-01-11 00:55:56 -05:00
|
|
|
"polymorphic",
|
|
|
|
"easy_thumbnails",
|
|
|
|
"user_messages",
|
2023-11-02 21:28:11 +01:00
|
|
|
"corsheaders",
|
2023-09-25 19:47:46 +00:00
|
|
|
"anymail",
|
2023-07-08 17:58:45 -04:00
|
|
|
# "silk",
|
2023-01-11 00:55:56 -05:00
|
|
|
]
|
|
|
|
|
|
|
|
INSTALLED_APPS += [
|
2023-01-02 00:03:13 -05:00
|
|
|
"mastodon.apps.MastodonConfig",
|
|
|
|
"common.apps.CommonConfig",
|
|
|
|
"users.apps.UsersConfig",
|
|
|
|
"catalog.apps.CatalogConfig",
|
|
|
|
"journal.apps.JournalConfig",
|
|
|
|
"social.apps.SocialConfig",
|
2023-07-20 21:59:49 -04:00
|
|
|
"takahe.apps.TakaheConfig",
|
2023-01-02 00:03:13 -05:00
|
|
|
"legacy.apps.LegacyConfig",
|
2023-01-11 00:55:56 -05:00
|
|
|
]
|
|
|
|
|
2023-12-23 23:55:33 -05:00
|
|
|
for app in env("NEODB_EXTRA_APPS"):
|
|
|
|
INSTALLED_APPS.append(app)
|
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
MIDDLEWARE = [
|
2023-01-02 00:03:13 -05:00
|
|
|
"django.middleware.security.SecurityMiddleware",
|
2023-07-08 17:58:45 -04:00
|
|
|
# "silk.middleware.SilkyMiddleware",
|
2023-01-02 00:03:13 -05:00
|
|
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
2023-11-02 21:28:11 +01:00
|
|
|
"corsheaders.middleware.CorsMiddleware",
|
2023-01-02 00:03:13 -05:00
|
|
|
"django.middleware.common.CommonMiddleware",
|
|
|
|
"django.middleware.csrf.CsrfViewMiddleware",
|
|
|
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
|
|
"django.contrib.messages.middleware.MessageMiddleware",
|
|
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
|
|
"hijack.middleware.HijackUserMiddleware",
|
2024-04-03 23:10:21 -04:00
|
|
|
# "django.middleware.locale.LocaleMiddleware",
|
|
|
|
"users.middlewares.LanguageMiddleware",
|
2023-01-10 22:36:13 -05:00
|
|
|
"tz_detect.middleware.TimezoneMiddleware",
|
2023-06-18 23:13:30 -04:00
|
|
|
"auditlog.middleware.AuditlogMiddleware",
|
2023-07-08 17:58:45 -04:00
|
|
|
# "maintenance_mode.middleware.MaintenanceModeMiddleware", # this should be last if enabled
|
2020-05-01 22:46:15 +08:00
|
|
|
]
|
|
|
|
|
2023-01-02 00:03:13 -05:00
|
|
|
ROOT_URLCONF = "boofilsic.urls"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
TEMPLATES = [
|
|
|
|
{
|
2023-01-02 00:03:13 -05:00
|
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
|
|
"DIRS": [],
|
|
|
|
"APP_DIRS": True,
|
|
|
|
"OPTIONS": {
|
|
|
|
"context_processors": [
|
2023-07-08 17:58:45 -04:00
|
|
|
# "django.template.context_processors.debug",
|
2023-01-02 00:03:13 -05:00
|
|
|
"django.template.context_processors.request",
|
|
|
|
"django.contrib.auth.context_processors.auth",
|
2022-11-09 13:56:50 -05:00
|
|
|
# 'django.contrib.messages.context_processors.messages',
|
|
|
|
"user_messages.context_processors.messages",
|
2023-01-02 00:03:13 -05:00
|
|
|
"boofilsic.context_processors.site_info",
|
2020-05-01 22:46:15 +08:00
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
2023-01-02 00:03:13 -05:00
|
|
|
WSGI_APPLICATION = "boofilsic.wsgi.application"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-07-20 21:59:49 -04:00
|
|
|
SESSION_COOKIE_NAME = "neodbsid"
|
2024-04-12 20:42:36 -04:00
|
|
|
SESSION_COOKIE_AGE = 90 * 24 * 60 * 60 # 90 days
|
2023-07-20 21:59:49 -04:00
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
AUTHENTICATION_BACKENDS = [
|
2023-01-02 00:03:13 -05:00
|
|
|
"mastodon.auth.OAuth2Backend",
|
2020-05-11 19:16:56 +08:00
|
|
|
]
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2024-05-20 23:17:47 -04:00
|
|
|
LOG_LEVEL = env("NEODB_LOG_LEVEL", default="DEBUG" if DEBUG else "INFO") # type:ignore
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
LOGGING = {
|
|
|
|
"version": 1,
|
|
|
|
"disable_existing_loggers": False,
|
|
|
|
"handlers": {
|
|
|
|
"console": {"class": "logging.StreamHandler"},
|
|
|
|
},
|
|
|
|
"loggers": {
|
|
|
|
"": {
|
|
|
|
"handlers": ["console"],
|
2024-05-20 23:17:47 -04:00
|
|
|
"level": LOG_LEVEL,
|
2023-09-25 19:47:46 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-07-01 17:29:38 -04:00
|
|
|
logging.getLogger("requests").setLevel(logging.WARNING)
|
|
|
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
if SLACK_TOKEN:
|
2023-11-21 20:57:06 -05:00
|
|
|
INSTALLED_APPS += [
|
|
|
|
"django_slack",
|
|
|
|
]
|
2023-09-25 19:47:46 +00:00
|
|
|
LOGGING["handlers"]["slack"] = {
|
|
|
|
"level": "ERROR",
|
|
|
|
"class": "django_slack.log.SlackExceptionHandler",
|
|
|
|
}
|
|
|
|
LOGGING["loggers"]["django"] = {"handlers": ["slack"], "level": "ERROR"}
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-08-11 01:43:19 -04:00
|
|
|
MARKDOWNX_MARKDOWNIFY_FUNCTION = "journal.models.render_md"
|
2023-01-30 22:11:47 -05:00
|
|
|
|
2024-04-03 23:10:21 -04:00
|
|
|
LANGUAGE_CODE = env("NEODB_LANGUAGE", default="zh-hans") # type: ignore
|
2024-03-10 20:55:50 -04:00
|
|
|
LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")]
|
2024-04-03 23:10:21 -04:00
|
|
|
LANGUAGES = (
|
2024-04-03 23:20:35 -04:00
|
|
|
("en", _("English")),
|
2024-04-03 23:10:21 -04:00
|
|
|
("zh-hans", _("Simplified Chinese")),
|
2024-06-02 15:11:36 -04:00
|
|
|
("zh-hant", _("Traditional Chinese")),
|
2024-04-03 23:10:21 -04:00
|
|
|
)
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
TIME_ZONE = env("NEODB_TIMEZONE", default="Asia/Shanghai") # type: ignore
|
2020-05-01 22:46:15 +08:00
|
|
|
|
|
|
|
USE_I18N = True
|
|
|
|
|
|
|
|
USE_L10N = True
|
|
|
|
|
|
|
|
USE_TZ = True
|
|
|
|
|
2023-08-17 02:09:36 -04:00
|
|
|
USE_X_FORWARDED_HOST = True
|
|
|
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
|
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 100 * 1024 * 1024
|
|
|
|
CSRF_COOKIE_SECURE = True
|
|
|
|
SESSION_COOKIE_SECURE = True
|
2023-11-24 20:41:28 -05:00
|
|
|
SSL_ONLY = env("SSL_ONLY")
|
|
|
|
SECURE_SSL_REDIRECT = SSL_ONLY
|
|
|
|
SECURE_HSTS_PRELOAD = SSL_ONLY
|
|
|
|
SECURE_HSTS_INCLUDE_SUBDOMAINS = SSL_ONLY
|
|
|
|
SECURE_HSTS_SECONDS = 2592000 if SSL_ONLY else 0
|
2021-02-25 19:49:50 +01:00
|
|
|
|
2023-08-14 08:15:55 -04:00
|
|
|
STATIC_URL = "/s/"
|
2023-09-25 19:47:46 +00:00
|
|
|
STATIC_ROOT = env("NEODB_STATIC_ROOT", default=os.path.join(BASE_DIR, "static/")) # type: ignore
|
|
|
|
|
2023-08-20 04:27:23 +00:00
|
|
|
if DEBUG:
|
|
|
|
# django-sass-processor will generate neodb.css on-the-fly when DEBUG
|
|
|
|
# NEODB_STATIC_ROOT is readonly in docker mode, so we give it a writable place
|
|
|
|
SASS_PROCESSOR_ROOT = "/tmp"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-05-20 11:01:18 -04:00
|
|
|
STATICFILES_FINDERS = [
|
|
|
|
"django.contrib.staticfiles.finders.FileSystemFinder",
|
|
|
|
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
|
|
|
"sass_processor.finders.CssFinder",
|
|
|
|
]
|
2021-02-25 19:49:50 +01:00
|
|
|
|
2023-01-02 00:03:13 -05:00
|
|
|
AUTH_USER_MODEL = "users.User"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2022-11-09 13:56:50 -05:00
|
|
|
SILENCED_SYSTEM_CHECKS = [
|
2023-01-02 00:03:13 -05:00
|
|
|
"admin.E404", # Required by django-user-messages
|
2023-07-20 21:59:49 -04:00
|
|
|
"models.W035", # Required by takahe: identical table name in different database
|
|
|
|
"fields.W344", # Required by takahe: identical table name in different database
|
2022-11-09 13:56:50 -05:00
|
|
|
]
|
|
|
|
|
2023-12-10 19:13:45 -05:00
|
|
|
TAKAHE_SESSION_COOKIE_NAME = "sessionid"
|
|
|
|
|
2023-08-14 08:15:55 -04:00
|
|
|
MEDIA_URL = "/m/"
|
2023-09-25 19:47:46 +00:00
|
|
|
MEDIA_ROOT = env("NEODB_MEDIA_ROOT", default=os.path.join(BASE_DIR, "media")) # type: ignore
|
|
|
|
|
|
|
|
TAKAHE_MEDIA_URL = env("TAKAHE_MEDIA_URL", default="/media/") # type: ignore
|
|
|
|
TAKAHE_MEDIA_ROOT = env("TAKAHE_MEDIA_ROOT", default="media") # type: ignore
|
|
|
|
|
2023-08-22 17:13:52 +00:00
|
|
|
STORAGES = { # TODO: support S3
|
|
|
|
"default": {
|
|
|
|
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
|
|
|
},
|
|
|
|
"staticfiles": {
|
|
|
|
"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage",
|
|
|
|
},
|
|
|
|
"takahe": {
|
|
|
|
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
|
|
|
"OPTIONS": {
|
|
|
|
"location": TAKAHE_MEDIA_ROOT,
|
|
|
|
"base_url": TAKAHE_MEDIA_URL,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-08-17 18:54:00 -04:00
|
|
|
CSRF_TRUSTED_ORIGINS = [SITE_INFO["site_url"]]
|
|
|
|
if DEBUG:
|
|
|
|
CSRF_TRUSTED_ORIGINS += ["http://127.0.0.1:8000", "http://localhost:8000"]
|
|
|
|
|
2021-02-25 19:49:50 +01:00
|
|
|
# Path to save report related images, ends with slash
|
2023-01-02 00:03:13 -05:00
|
|
|
REPORT_MEDIA_PATH_ROOT = "report/"
|
|
|
|
MARKDOWNX_MEDIA_PATH = "review/"
|
|
|
|
BOOK_MEDIA_PATH_ROOT = "book/"
|
|
|
|
DEFAULT_BOOK_IMAGE = os.path.join(BOOK_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
MOVIE_MEDIA_PATH_ROOT = "movie/"
|
|
|
|
DEFAULT_MOVIE_IMAGE = os.path.join(MOVIE_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
SONG_MEDIA_PATH_ROOT = "song/"
|
|
|
|
DEFAULT_SONG_IMAGE = os.path.join(SONG_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
ALBUM_MEDIA_PATH_ROOT = "album/"
|
|
|
|
DEFAULT_ALBUM_IMAGE = os.path.join(ALBUM_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
GAME_MEDIA_PATH_ROOT = "game/"
|
|
|
|
DEFAULT_GAME_IMAGE = os.path.join(GAME_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
COLLECTION_MEDIA_PATH_ROOT = "collection/"
|
|
|
|
DEFAULT_COLLECTION_IMAGE = os.path.join(COLLECTION_MEDIA_PATH_ROOT, "default.svg")
|
|
|
|
SYNC_FILE_PATH_ROOT = "sync/"
|
|
|
|
EXPORT_FILE_PATH_ROOT = "export/"
|
2022-11-09 13:56:50 -05:00
|
|
|
|
2020-05-01 22:46:15 +08:00
|
|
|
# Default redirect loaction when access login required view
|
2023-07-05 14:36:50 -04:00
|
|
|
LOGIN_URL = "/account/login"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
ADMIN_ENABLED = DEBUG
|
|
|
|
ADMIN_URL = "neodb-admin"
|
2020-05-01 22:46:15 +08:00
|
|
|
|
2023-01-26 17:31:20 -05:00
|
|
|
BLEACH_STRIP_COMMENTS = True
|
|
|
|
BLEACH_STRIP_TAGS = True
|
|
|
|
|
2021-02-25 19:49:50 +01:00
|
|
|
# Thumbnail setting
|
|
|
|
# It is possible to optimize the image size even more: https://easy-thumbnails.readthedocs.io/en/latest/ref/optimize/
|
|
|
|
THUMBNAIL_ALIASES = {
|
2023-01-02 00:03:13 -05:00
|
|
|
"": {
|
|
|
|
"normal": {
|
|
|
|
"size": (200, 200),
|
|
|
|
"crop": "scale",
|
|
|
|
"autocrop": True,
|
2021-02-25 19:49:50 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
# THUMBNAIL_PRESERVE_EXTENSIONS = ('svg',)
|
2023-09-25 19:47:46 +00:00
|
|
|
THUMBNAIL_DEBUG = DEBUG
|
2020-07-03 15:36:23 +08:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
DJANGO_REDIS_IGNORE_EXCEPTIONS = not DEBUG
|
2022-11-09 13:56:50 -05:00
|
|
|
|
2023-09-25 19:47:46 +00:00
|
|
|
RQ_SHOW_ADMIN_LINK = DEBUG
|
2022-11-09 13:56:50 -05:00
|
|
|
|
|
|
|
SEARCH_INDEX_NEW_ONLY = False
|
|
|
|
|
2024-01-09 16:36:39 -05:00
|
|
|
DOWNLOADER_SAVEDIR = env("NEODB_DOWNLOADER_SAVE_DIR", default="/tmp") # type: ignore
|
2023-08-24 05:48:14 +00:00
|
|
|
|
2023-01-02 00:03:13 -05:00
|
|
|
DISABLE_MODEL_SIGNAL = False # disable index and social feeds during importing/etc
|
2023-01-11 00:55:56 -05:00
|
|
|
|
2023-07-08 17:58:45 -04:00
|
|
|
# MAINTENANCE_MODE = False
|
|
|
|
# MAINTENANCE_MODE_IGNORE_ADMIN_SITE = True
|
|
|
|
# MAINTENANCE_MODE_IGNORE_SUPERUSER = True
|
|
|
|
# MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = True
|
|
|
|
# MAINTENANCE_MODE_IGNORE_URLS = (r"^/users/connect/", r"^/users/OAuth2_login/")
|
|
|
|
|
|
|
|
# SILKY_AUTHENTICATION = True # User must login
|
|
|
|
# SILKY_AUTHORISATION = True # User must have permissions
|
|
|
|
# SILKY_PERMISSIONS = lambda user: user.is_superuser
|
|
|
|
# SILKY_MAX_RESPONSE_BODY_SIZE = 1024 # If response body>1024 bytes, ignore
|
|
|
|
# SILKY_INTERCEPT_PERCENT = 10
|
2023-05-20 11:01:18 -04:00
|
|
|
|
2023-06-02 21:54:48 -04:00
|
|
|
NINJA_PAGINATION_PER_PAGE = 20
|
2023-09-03 21:25:30 +00:00
|
|
|
|
2023-11-02 21:28:11 +01:00
|
|
|
# https://github.com/adamchainz/django-cors-headers#configuration
|
|
|
|
# CORS_ALLOWED_ORIGINS = []
|
|
|
|
# CORS_ALLOWED_ORIGIN_REGEXES = []
|
|
|
|
CORS_ALLOW_ALL_ORIGINS = True
|
2023-11-22 20:55:45 -05:00
|
|
|
CORS_URLS_REGEX = r"^/(api|nodeinfo)/.*$"
|
2023-11-02 21:28:11 +01:00
|
|
|
CORS_ALLOW_METHODS = (
|
|
|
|
"DELETE",
|
|
|
|
"GET",
|
|
|
|
"OPTIONS",
|
|
|
|
# "PATCH",
|
|
|
|
"POST",
|
|
|
|
# "PUT",
|
|
|
|
)
|
2023-11-24 09:49:23 -05:00
|
|
|
|
|
|
|
DEACTIVATE_AFTER_UNREACHABLE_DAYS = 120
|
|
|
|
|
2024-01-15 13:09:12 -05:00
|
|
|
DEFAULT_RELAY_SERVER = "https://relay.neodb.net/inbox"
|
2023-11-21 00:49:42 -05:00
|
|
|
|
|
|
|
SENTRY_DSN = env("NEODB_SENTRY_DSN")
|
|
|
|
if SENTRY_DSN:
|
|
|
|
import sentry_sdk
|
|
|
|
from sentry_sdk.integrations.django import DjangoIntegration
|
2023-12-08 02:54:26 -05:00
|
|
|
from sentry_sdk.integrations.loguru import LoguruIntegration
|
2023-11-21 00:49:42 -05:00
|
|
|
|
2024-05-12 22:39:44 -04:00
|
|
|
sentry_env = sys.argv[0].split("/")[-1]
|
|
|
|
if len(sys.argv) > 1 and sentry_env in ("manage.py", "django-admin"):
|
|
|
|
sentry_env = sys.argv[1]
|
2023-11-21 00:49:42 -05:00
|
|
|
sentry_sdk.init(
|
|
|
|
dsn=SENTRY_DSN,
|
2024-05-12 22:39:44 -04:00
|
|
|
environment=sentry_env or "unknown",
|
2024-05-25 23:38:11 -04:00
|
|
|
integrations=[
|
|
|
|
DjangoIntegration(),
|
|
|
|
LoguruIntegration(event_format="{name}:{function}:{line} - {message}"),
|
|
|
|
],
|
2023-11-21 00:49:42 -05:00
|
|
|
release=NEODB_VERSION,
|
2023-12-26 18:57:09 -05:00
|
|
|
send_default_pii=True,
|
2024-05-12 22:39:44 -04:00
|
|
|
traces_sample_rate=env("NEODB_SENTRY_SAMPLE_RATE"),
|
2023-11-21 00:49:42 -05:00
|
|
|
)
|