more configurable
This commit is contained in:
parent
605d8373bf
commit
65a2b82383
11 changed files with 186 additions and 190 deletions
2
.github/workflows/docker-dev.yml
vendored
2
.github/workflows/docker-dev.yml
vendored
|
@ -5,7 +5,7 @@ on: [push, pull_request]
|
|||
jobs:
|
||||
push_to_docker_hub:
|
||||
name: build image and push to Docker Hub
|
||||
if: github.repository_owner == 'neodb-social'
|
||||
# if: github.repository_owner == 'neodb-social'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
|
|
|
@ -6,6 +6,149 @@ env = environ.Env(
|
|||
# set casting, default value
|
||||
DEBUG=(bool, False)
|
||||
)
|
||||
# TODO: use django-environ or similar package for env parsing
|
||||
|
||||
# ====== USER CONFIGUTRATION START ======
|
||||
|
||||
# SECURITY WARNING: use your own secret key and keep it!
|
||||
SECRET_KEY = os.environ.get("NEODB_SECRET_KEY", "insecure")
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = os.environ.get("NEODB_DEBUG", "") != ""
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": os.environ.get("NEODB_DB_NAME", "test_neodb"),
|
||||
"USER": os.environ.get("NEODB_DB_USER", "testuser"),
|
||||
"PASSWORD": os.environ.get("NEODB_DB_PASSWORD", "testpass"),
|
||||
"HOST": os.environ.get("NEODB_DB_HOST", "127.0.0.1"),
|
||||
"PORT": int(os.environ.get("NEODB_DB_PORT", 5432)),
|
||||
"OPTIONS": {
|
||||
"client_encoding": "UTF8",
|
||||
# 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT,
|
||||
},
|
||||
"TEST": {
|
||||
"DEPENDENCIES": ["takahe"],
|
||||
},
|
||||
},
|
||||
"takahe": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": os.environ.get("TAKAHE_DB_NAME", "test_neodb_takahe"),
|
||||
"USER": os.environ.get("TAKAHE_DB_USER", "testuser"),
|
||||
"PASSWORD": os.environ.get("TAKAHE_DB_PASSWORD", "testpass"),
|
||||
"HOST": os.environ.get("TAKAHE_DB_HOST", "127.0.0.1"),
|
||||
"PORT": os.environ.get("TAKAHE_DB_PORT", 15432),
|
||||
"OPTIONS": {
|
||||
"client_encoding": "UTF8",
|
||||
# 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT,
|
||||
},
|
||||
"TEST": {
|
||||
"DEPENDENCIES": [],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
REDIS_HOST = os.environ.get("NEODB_REDIS_HOST", "127.0.0.1")
|
||||
REDIS_PORT = int(os.environ.get("NEODB_REDIS_PORT", 6379))
|
||||
REDIS_DB = int(os.environ.get("NEODB_REDIS_DB", 0))
|
||||
|
||||
if os.environ.get("NEODB_TYPESENSE_ENABLE", ""):
|
||||
SEARCH_BACKEND = "TYPESENSE"
|
||||
|
||||
SEARCH_BACKEND = None
|
||||
|
||||
# SEARCH_BACKEND = 'MEILISEARCH'
|
||||
# MEILISEARCH_SERVER = 'http://127.0.0.1:7700'
|
||||
# MEILISEARCH_KEY = 'deadbeef'
|
||||
|
||||
TYPESENSE_CONNECTION = {
|
||||
"api_key": os.environ.get("NEODB_TYPESENSE_KEY", "insecure"),
|
||||
"nodes": [
|
||||
{
|
||||
"host": os.environ.get("NEODB_TYPESENSE_HOST", "127.0.0.1"),
|
||||
"port": os.environ.get("NEODB_TYPESENSE_PORT", "8108"),
|
||||
"protocol": "http",
|
||||
}
|
||||
],
|
||||
"connection_timeout_seconds": 2,
|
||||
}
|
||||
|
||||
SITE_DOMAIN = os.environ.get("NEODB_SITE_DOMAIN", "nicedb.org")
|
||||
SITE_INFO = {
|
||||
"site_name": os.environ.get("NEODB_SITE_NAME", "NiceDB"),
|
||||
"site_domain": SITE_DOMAIN,
|
||||
"site_url": os.environ.get("NEODB_SITE_URL", "https://" + SITE_DOMAIN),
|
||||
"site_logo": os.environ.get("NEODB_SITE_LOGO", "/s/img/logo.svg"),
|
||||
"site_icon": os.environ.get("NEODB_SITE_ICON", "/s/img/logo.svg"),
|
||||
"user_icon": os.environ.get("NEODB_USER_ICON", "/s/img/avatar.svg"),
|
||||
"social_link": "https://donotban.com/@testie",
|
||||
"support_link": "https://github.com/doubaniux/boofilsic/issues",
|
||||
"donation_link": "https://patreon.com/tertius",
|
||||
}
|
||||
|
||||
SETUP_ADMIN_USERNAMES = [
|
||||
u for u in os.environ.get("NEODB_ADMIN_USERNAMES", "").split(",") if u
|
||||
]
|
||||
|
||||
|
||||
# Mastodon/Pleroma instance allowed to login, keep empty to allow any instance to login
|
||||
MASTODON_ALLOWED_SITES = []
|
||||
|
||||
# Allow user to create account with email (and link to Mastodon account later)
|
||||
ALLOW_EMAIL_ONLY_ACCOUNT = False
|
||||
|
||||
# Timeout of requests to Mastodon, in seconds
|
||||
MASTODON_TIMEOUT = 30
|
||||
|
||||
MASTODON_CLIENT_SCOPE = "read:accounts read:follows read:search read:blocks read:mutes write:statuses write:media"
|
||||
# use the following to avoid re-authorize when migrating to a future version with more features
|
||||
# MASTODON_CLIENT_SCOPE = "read write follow"
|
||||
|
||||
# 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:"
|
||||
|
||||
DISCORD_WEBHOOKS = {"user-report": None}
|
||||
|
||||
# Spotify credentials
|
||||
SPOTIFY_CREDENTIAL = "***REMOVED***"
|
||||
|
||||
# The Movie Database (TMDB) API Keys
|
||||
TMDB_API3_KEY = "***REMOVED***"
|
||||
# TMDB_API4_KEY = "deadbeef.deadbeef.deadbeef"
|
||||
|
||||
# Google Books API Key
|
||||
GOOGLE_API_KEY = "***REMOVED***"
|
||||
|
||||
# Discogs API Key
|
||||
# How to get: a personal access token from https://www.discogs.com/settings/developers
|
||||
DISCOGS_API_KEY = "***REMOVED***"
|
||||
|
||||
# IGDB
|
||||
IGDB_CLIENT_ID = "deadbeef"
|
||||
IGDB_CLIENT_SECRET = ""
|
||||
|
||||
# List of available proxies for proxy downloader, in format of ["http://x.y:port?url=__URL__", ...]
|
||||
DOWNLOADER_PROXY_LIST = [
|
||||
u for u in os.environ.get("NEODB_DOWNLOADER_PROXY_LIST", "").split(",") if u
|
||||
]
|
||||
|
||||
# Backup proxy for proxy downloader, in format of "http://xyz:port?url=__URL__"
|
||||
DOWNLOADER_BACKUP_PROXY = os.environ.get("NEODB_DOWNLOADER_BACKUP_PROXY", "")
|
||||
|
||||
# Timeout of downloader requests, in seconds
|
||||
DOWNLOADER_REQUEST_TIMEOUT = 90
|
||||
# Timeout of downloader cache, in seconds
|
||||
DOWNLOADER_CACHE_TIMEOUT = 300
|
||||
# Number of retries of downloader, when site is using RetryDownloader
|
||||
DOWNLOADER_RETRIES = 3
|
||||
|
||||
# ====== USER CONFIGUTRATION END ======
|
||||
|
||||
NEODB_VERSION = "0.8"
|
||||
DATABASE_ROUTERS = ["takahe.db_routes.TakaheRouter"]
|
||||
|
@ -17,16 +160,6 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||
# for legacy deployment:
|
||||
# DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: use your own secret key and keep it!
|
||||
SECRET_KEY = os.environ.get("NEODB_SECRET_KEY", "insecure")
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = os.environ.get("NEODB_DEBUG", "") != ""
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
# To allow debug in template context
|
||||
|
@ -118,51 +251,6 @@ WSGI_APPLICATION = "boofilsic.wsgi.application"
|
|||
|
||||
SESSION_COOKIE_NAME = "neodbsid"
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
|
||||
}
|
||||
}
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": os.environ.get("NEODB_DB_NAME", "test_neodb"),
|
||||
"USER": os.environ.get("NEODB_DB_USER", "testuser"),
|
||||
"PASSWORD": os.environ.get("NEODB_DB_PASSWORD", "testpass"),
|
||||
"HOST": os.environ.get("NEODB_DB_HOST", "127.0.0.1"),
|
||||
"PORT": int(os.environ.get("NEODB_DB_PORT", 5432)),
|
||||
"OPTIONS": {
|
||||
"client_encoding": "UTF8",
|
||||
# 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT,
|
||||
},
|
||||
"TEST": {
|
||||
"DEPENDENCIES": ["takahe"],
|
||||
},
|
||||
},
|
||||
"takahe": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": os.environ.get("TAKAHE_DB_NAME", "test_neodb_takahe"),
|
||||
"USER": os.environ.get("TAKAHE_DB_USER", "testuser"),
|
||||
"PASSWORD": os.environ.get("TAKAHE_DB_PASSWORD", "testpass"),
|
||||
"HOST": os.environ.get("TAKAHE_DB_HOST", "127.0.0.1"),
|
||||
"PORT": os.environ.get("TAKAHE_DB_PORT", 15432),
|
||||
"OPTIONS": {
|
||||
"client_encoding": "UTF8",
|
||||
# 'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_DEFAULT,
|
||||
},
|
||||
"TEST": {
|
||||
"DEPENDENCIES": [],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# Customized auth backend, glue OAuth2 and Django User model together
|
||||
# https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#authentication-backends
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
"mastodon.auth.OAuth2Backend",
|
||||
"oauth2_provider.backends.OAuth2Backend",
|
||||
|
@ -171,7 +259,6 @@ AUTHENTICATION_BACKENDS = [
|
|||
|
||||
MARKDOWNX_MARKDOWNIFY_FUNCTION = "journal.models.render_md"
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||
|
||||
|
@ -185,21 +272,19 @@ USE_L10N = True
|
|||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
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
|
||||
|
||||
if os.getenv("NEODB_SSL", "") != "":
|
||||
# FIXME: remove this since user may enforce SSL in reverse proxy
|
||||
SECURE_SSL_REDIRECT = True
|
||||
SECURE_HSTS_PRELOAD = True
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
|
||||
SECURE_HSTS_SECONDS = 31536000
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
||||
STATIC_URL = "/s/"
|
||||
STATIC_ROOT = os.environ.get("NEODB_STATIC_ROOT", os.path.join(BASE_DIR, "static/"))
|
||||
if DEBUG:
|
||||
|
@ -240,16 +325,9 @@ STORAGES = { # TODO: support S3
|
|||
},
|
||||
},
|
||||
}
|
||||
SITE_DOMAIN = os.environ.get("NEODB_SITE_DOMAIN", "nicedb.org")
|
||||
SITE_INFO = {
|
||||
"site_name": os.environ.get("NEODB_SITE_NAME", "NiceDB"),
|
||||
"site_domain": SITE_DOMAIN,
|
||||
"site_url": os.environ.get("NEODB_SITE_URL", "https://" + SITE_DOMAIN),
|
||||
"support_link": "https://github.com/doubaniux/boofilsic/issues",
|
||||
"social_link": "https://donotban.com/@testie",
|
||||
"donation_link": "https://patreon.com/tertius",
|
||||
"settings_module": os.getenv("DJANGO_SETTINGS_MODULE"),
|
||||
}
|
||||
|
||||
# Allow user to login via any Mastodon/Pleroma sites
|
||||
MASTODON_ALLOW_ANY_SITE = False if MASTODON_ALLOWED_SITES else True
|
||||
|
||||
REDIRECT_URIS = SITE_INFO["site_url"] + "/account/login/oauth"
|
||||
# for sites migrated from previous version, either wipe mastodon client ids or use:
|
||||
|
@ -277,60 +355,12 @@ DEFAULT_COLLECTION_IMAGE = os.path.join(COLLECTION_MEDIA_PATH_ROOT, "default.svg
|
|||
SYNC_FILE_PATH_ROOT = "sync/"
|
||||
EXPORT_FILE_PATH_ROOT = "export/"
|
||||
|
||||
# Allow user to login via any Mastodon/Pleroma sites
|
||||
MASTODON_ALLOW_ANY_SITE = True
|
||||
|
||||
# Allow user to create account with email (and link to Mastodon account later)
|
||||
ALLOW_EMAIL_ONLY_ACCOUNT = False
|
||||
|
||||
# Timeout of requests to Mastodon, in seconds
|
||||
MASTODON_TIMEOUT = 30
|
||||
|
||||
MASTODON_CLIENT_SCOPE = "read write follow"
|
||||
# use the following if it's a new site
|
||||
# MASTODON_CLIENT_SCOPE = 'read:accounts read:follows read:search read:blocks read:mutes write:statuses write:media'
|
||||
|
||||
MASTODON_LEGACY_CLIENT_SCOPE = "read write follow"
|
||||
|
||||
# Emoji code in mastodon
|
||||
STAR_SOLID = ":star_solid:"
|
||||
STAR_HALF = ":star_half:"
|
||||
STAR_EMPTY = ":star_empty:"
|
||||
|
||||
# Default redirect loaction when access login required view
|
||||
LOGIN_URL = "/account/login"
|
||||
|
||||
# Admin site root url
|
||||
ADMIN_URL = "tertqX7256n7ej8nbv5cwvsegdse6w7ne5rHd"
|
||||
|
||||
SCRAPING_TIMEOUT = 90
|
||||
|
||||
# ScraperAPI api key
|
||||
SCRAPERAPI_KEY = "***REMOVED***"
|
||||
PROXYCRAWL_KEY = None
|
||||
SCRAPESTACK_KEY = None
|
||||
|
||||
# Spotify credentials
|
||||
SPOTIFY_CREDENTIAL = "***REMOVED***"
|
||||
|
||||
# IMDb API service https://imdb-api.com/
|
||||
IMDB_API_KEY = "***REMOVED***"
|
||||
|
||||
# The Movie Database (TMDB) API Keys
|
||||
TMDB_API3_KEY = "***REMOVED***"
|
||||
# TMDB_API4_KEY = "deadbeef.deadbeef.deadbeef"
|
||||
|
||||
# Google Books API Key
|
||||
GOOGLE_API_KEY = "***REMOVED***"
|
||||
|
||||
# Discogs API Key
|
||||
# How to get: a personal access token from https://www.discogs.com/settings/developers
|
||||
DISCOGS_API_KEY = "***REMOVED***"
|
||||
|
||||
# IGDB
|
||||
IGDB_CLIENT_ID = "deadbeef"
|
||||
IGDB_CLIENT_SECRET = ""
|
||||
|
||||
BLEACH_STRIP_COMMENTS = True
|
||||
BLEACH_STRIP_TAGS = True
|
||||
|
||||
|
@ -349,12 +379,6 @@ THUMBNAIL_ALIASES = {
|
|||
if DEBUG:
|
||||
THUMBNAIL_DEBUG = True
|
||||
|
||||
# https://django-debug-toolbar.readthedocs.io/en/latest/
|
||||
# maybe benchmarking before deployment
|
||||
|
||||
REDIS_HOST = os.environ.get("NEODB_REDIS_HOST", "127.0.0.1")
|
||||
REDIS_PORT = int(os.environ.get("NEODB_REDIS_PORT", 6379))
|
||||
REDIS_DB = int(os.environ.get("NEODB_REDIS_DB", 0))
|
||||
CACHES = {
|
||||
"default": {
|
||||
"BACKEND": "django_redis.cache.RedisCache",
|
||||
|
@ -379,32 +403,10 @@ RQ_SHOW_ADMIN_LINK = True
|
|||
|
||||
SEARCH_INDEX_NEW_ONLY = False
|
||||
|
||||
SEARCH_BACKEND = None
|
||||
|
||||
# SEARCH_BACKEND = 'MEILISEARCH'
|
||||
# MEILISEARCH_SERVER = 'http://127.0.0.1:7700'
|
||||
# MEILISEARCH_KEY = 'deadbeef'
|
||||
|
||||
if os.environ.get("NEODB_TYPESENSE_ENABLE", ""):
|
||||
SEARCH_BACKEND = "TYPESENSE"
|
||||
|
||||
TYPESENSE_INDEX_NAME = "catalog"
|
||||
TYPESENSE_CONNECTION = {
|
||||
"api_key": os.environ.get("NEODB_TYPESENSE_KEY", "insecure"),
|
||||
"nodes": [
|
||||
{
|
||||
"host": os.environ.get("NEODB_TYPESENSE_HOST", "127.0.0.1"),
|
||||
"port": os.environ.get("NEODB_TYPESENSE_PORT", "8108"),
|
||||
"protocol": "http",
|
||||
}
|
||||
],
|
||||
"connection_timeout_seconds": 2,
|
||||
}
|
||||
|
||||
|
||||
DOWNLOADER_CACHE_TIMEOUT = 300
|
||||
DOWNLOADER_RETRIES = 3
|
||||
DOWNLOADER_SAVEDIR = None
|
||||
|
||||
DISABLE_MODEL_SIGNAL = False # disable index and social feeds during importing/etc
|
||||
|
||||
# MAINTENANCE_MODE = False
|
||||
|
@ -419,9 +421,6 @@ DISABLE_MODEL_SIGNAL = False # disable index and social feeds during importing/
|
|||
# SILKY_MAX_RESPONSE_BODY_SIZE = 1024 # If response body>1024 bytes, ignore
|
||||
# SILKY_INTERCEPT_PERCENT = 10
|
||||
|
||||
DISCORD_WEBHOOKS = {"user-report": None}
|
||||
|
||||
|
||||
NINJA_PAGINATION_PER_PAGE = 20
|
||||
OAUTH2_PROVIDER = {
|
||||
"ACCESS_TOKEN_EXPIRE_SECONDS": 3600 * 24 * 365,
|
||||
|
@ -430,9 +429,3 @@ OAUTH2_PROVIDER = {
|
|||
OAUTH2_PROVIDER_APPLICATION_MODEL = "developer.Application"
|
||||
|
||||
DEVELOPER_CONSOLE_APPLICATION_CLIENT_ID = "NEODB_DEVELOPER_CONSOLE"
|
||||
|
||||
SETUP_ADMIN_USERNAMES = [
|
||||
u for u in os.environ.get("NEODB_ADMIN_USERNAMES", "").split(",") if u
|
||||
]
|
||||
|
||||
SITE_INFO["site_logo"] = os.environ.get("NEODB_SITE_LOGO", "/s/img/logo.svg")
|
||||
|
|
|
@ -141,7 +141,7 @@ class BasicDownloader:
|
|||
self.headers = headers
|
||||
|
||||
def get_timeout(self):
|
||||
return settings.SCRAPING_TIMEOUT
|
||||
return settings.DOWNLOADER_REQUEST_TIMEOUT
|
||||
|
||||
def validate_response(self, response):
|
||||
if response is None:
|
||||
|
@ -191,26 +191,17 @@ class BasicDownloader:
|
|||
|
||||
class ProxiedDownloader(BasicDownloader):
|
||||
def get_proxied_urls(self):
|
||||
if not settings.DOWNLOADER_PROXY_LIST:
|
||||
return [self.url]
|
||||
urls = []
|
||||
if settings.SCRAPESTACK_KEY is not None:
|
||||
# urls.append(f'http://api.scrapestack.com/scrape?access_key={settings.SCRAPESTACK_KEY}&url={self.url}')
|
||||
urls.append(
|
||||
f"http://api.scrapestack.com/scrape?keep_headers=1&access_key={settings.SCRAPESTACK_KEY}&url={quote(self.url)}"
|
||||
)
|
||||
if settings.PROXYCRAWL_KEY is not None:
|
||||
urls.append(
|
||||
f"https://api.proxycrawl.com/?token={settings.PROXYCRAWL_KEY}&url={quote(self.url)}"
|
||||
)
|
||||
if settings.SCRAPERAPI_KEY is not None:
|
||||
urls.append(
|
||||
f"http://api.scraperapi.com/?api_key={settings.SCRAPERAPI_KEY}&url={quote(self.url)}"
|
||||
)
|
||||
for p in settings.DOWNLOADER_PROXY_LIST:
|
||||
urls.append(p.replace("__URL__", quote(self.url)))
|
||||
return urls
|
||||
|
||||
def get_special_proxied_url(self):
|
||||
return (
|
||||
f"{settings.LOCAL_PROXY}?url={quote(self.url)}"
|
||||
if settings.LOCAL_PROXY is not None
|
||||
settings.DOWNLOADER_BACKUP_PROXY.replace("__URL__", quote(self.url))
|
||||
if settings.DOWNLOADER_BACKUP_PROXY
|
||||
else None
|
||||
)
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<summary aria-haspopup="listbox">
|
||||
<span class="avatar">
|
||||
<img alt=""
|
||||
src="{% if request.user.is_authenticated %}{{ request.user.avatar }}{% else %}{% static 'img/avatar.svg' %}{% endif %}" />
|
||||
src="{% if request.user.is_authenticated %}{{ request.user.avatar }}{% else %}{{ user_icon }}{% endif %}" />
|
||||
</span>
|
||||
</summary>
|
||||
<ul role="listbox" style="min-width:-webkit-max-content;" dir="rtl">
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
}
|
||||
})();
|
||||
</script>
|
||||
<link rel="icon" href="{{ site_logo }}">
|
||||
<link rel="icon" href="{{ site_icon }}">
|
||||
<link rel="apple-touch-icon" href="{{ site_logo }}">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-title" content="{{ site_name }}">
|
||||
|
|
|
@ -43,9 +43,9 @@ OK
|
|||
Preserving test database for alias 'default'...
|
||||
```
|
||||
|
||||
Debug in Docker
|
||||
---------------
|
||||
To debug source code with `docker compose`, add `NEODB_DEBUG=True` in `.env`, and use `--profile dev` instead of `--profile production` in commands. The `dev` profile is different from `production`:
|
||||
Development in Docker
|
||||
---------------------
|
||||
To run local source code with `docker compose`, add `NEODB_DEBUG=True` in `.env`, and use `--profile dev` instead of `--profile production` in commands. The `dev` profile is different from `production`:
|
||||
|
||||
- code in `NEODB_SRC` (default: .) and `TAKAHE_SRC` (default: ./neodb-takahe) will be mounted and used in the container instead of code in the image
|
||||
- `runserver` with autoreload will be used instead of `gunicorn` for both neodb and takahe web server
|
||||
|
@ -55,12 +55,12 @@ To debug source code with `docker compose`, add `NEODB_DEBUG=True` in `.env`, an
|
|||
- there's no automatic `migration` container, but it can be triggered manually via `docker compose run dev-shell neodb-init`
|
||||
|
||||
Note:
|
||||
- Python virtual environments inside docker image, which are `/neodb-venv` and `/takahe-venv`, will be used by default. They can be changed to different locations with `TAKAHE_VENV` and `NEODB_VENV` if needed, usually in a case of the local code using a package not in docker venv.
|
||||
- Some packages inside python virtual environments are platform dependent, so mount venv from macOS into the Linux container will likely not work.
|
||||
- Python virtual environments inside docker image, which are `/neodb-venv` and `/takahe-venv`, will be used by default. They can be changed to different locations with `TAKAHE_VENV` and `NEODB_VENV` if needed, usually in a case of development code using a package not in docker venv.
|
||||
- Some packages inside python virtual environments are platform dependent, so mount venv built by macOS host into the Linux container will likely not work.
|
||||
- Python servers are launched as `app` user, who has no write access to anywhere except /tmp and media path, that's by design.
|
||||
- Database/redis used in the container cluster are not accessible outside, which is by design. Querying them can be done by either apt update/install client packages in `dev-root` or `root` container, or a modified `docker-compose.yml` with `ports` section uncommented.
|
||||
|
||||
requires `${NEODB_SRC}/.venv` and `${TAKAHE_SRC}/.venv` both ready with all the requirements installed, and python binary pointing to `/usr/local/bin/python` (because that's where python is in the docker base image).
|
||||
To run local unit tests, use `docker compose run dev-shell neodb-manage test`
|
||||
|
||||
Applications
|
||||
------------
|
||||
|
|
|
@ -47,7 +47,7 @@ $ sudo usermod -aG docker neouser
|
|||
- grab `docker-compose.yml` and `neodb.env.example` from source code
|
||||
- rename `neodb.env.example` to `.env`
|
||||
|
||||
## Set up .env file
|
||||
## Set up .env file and www root
|
||||
Change essential options like `NEODB_SITE_DOMAIN` in `.env` before starting the cluster for the first time. Changing them later may have unintended consequences, please make sure they are correct before exposing the service externally.
|
||||
|
||||
- `NEODB_SITE_NAME` - name of your site
|
||||
|
@ -55,6 +55,8 @@ Change essential options like `NEODB_SITE_DOMAIN` in `.env` before starting the
|
|||
- `NEODB_SECRET_KEY` - encryption key of session data
|
||||
- `NEODB_DATA` is the path to store db/media/cache, it's `../data` by default, but can be any path that's writable
|
||||
|
||||
Optionally, `robots.txt` and `logo.png` may be placed under `$NEODB_DATA/www-root/`.
|
||||
|
||||
See `neodb.env.example` and `configuration.md` for more options
|
||||
|
||||
## Start docker
|
||||
|
@ -105,6 +107,10 @@ $ docker compose --profile production up -d
|
|||
- `docker compose run shell` to run a shell into the cluster; or `docker compose run root` for root shell, and `apt` is available if extra package needed
|
||||
- see `Debug in Docker` in [development doc](development.md) for debugging tips
|
||||
|
||||
## Multiple instance
|
||||
|
||||
It's possible to run multiple clusters in one host server, as long as `NEODB_SITE_DOMAIN`, `NEODB_PORT` and `NEODB_DATA` are different.
|
||||
|
||||
## Scaling
|
||||
|
||||
If you are running a high-traffic instance, spin up `NEODB_WEB_WORKER_NUM`, `TAKAHE_WEB_WORKER_NUM`, `TAKAHE_STATOR_CONCURRENCY` and `TAKAHE_STATOR_CONCURRENCY_PER_MODEL` as long as your host server can handle them.
|
||||
|
|
|
@ -13,7 +13,7 @@ version: "3.8"
|
|||
x-shared:
|
||||
neodb-service: &neodb-service
|
||||
build: .
|
||||
image: neodb/neodb:${NEODB_TAG:-latest}
|
||||
image: ${NEODB_IMAGE:-neodb/neodb:latest}
|
||||
environment:
|
||||
NEODB_SITE_NAME:
|
||||
NEODB_SITE_DOMAIN:
|
||||
|
@ -34,6 +34,8 @@ x-shared:
|
|||
NEODB_TYPESENSE_PORT: 8108
|
||||
NEODB_TYPESENSE_KEY: eggplant
|
||||
NEODB_FROM_EMAIL: no-reply@${NEODB_SITE_DOMAIN}
|
||||
NEODB_DOWNLOADER_PROXY_LIST:
|
||||
NEODB_DOWNLOADER_BACKUP_PROXY:
|
||||
NEODB_MEDIA_ROOT: /www/m
|
||||
NEODB_VENV: /neodb-venv
|
||||
TAKAHE_DB_NAME: takahe
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
|
||||
# copy along with docker-compose.yml, rename it to .env
|
||||
|
||||
# Change these before start the instance for the first time
|
||||
# Change these before start the instance for the first time!!
|
||||
NEODB_SECRET_KEY=change_me
|
||||
NEODB_SITE_DOMAIN=example.site
|
||||
|
||||
# Change these
|
||||
# Change these too
|
||||
NEODB_SITE_NAME=Example Site
|
||||
NEODB_SITE_LOGO=/logo.svg
|
||||
NEODB_SITE_LOGO=/logo.png
|
||||
NEODB_SITE_ICON=/icon.png
|
||||
|
||||
# HTTP port your reverse proxy should set request to
|
||||
# HTTP port your reverse proxy should send request to
|
||||
# NEODB_PORT=8000
|
||||
|
||||
# Path to store db/media/cache/etc, must be writable
|
||||
|
@ -29,4 +30,4 @@ NEODB_SITE_LOGO=/logo.svg
|
|||
# NEODB_DEBUG=True
|
||||
|
||||
# pull NeoDB Docker image from another tag/branch
|
||||
# TAG=latest
|
||||
# NEODB_IMAGE=neodb/neodb:latest
|
||||
|
|
|
@ -78,11 +78,12 @@ class APIdentity(models.Model):
|
|||
|
||||
@property
|
||||
def avatar(self):
|
||||
print(self.takahe_identity)
|
||||
if self.local:
|
||||
return (
|
||||
self.takahe_identity.icon.url
|
||||
if self.takahe_identity.icon
|
||||
else static("img/avatar.svg")
|
||||
else settings.SITE_INFO["user_icon"]
|
||||
)
|
||||
else:
|
||||
return f"/proxy/identity_icon/{self.pk}/"
|
||||
|
|
|
@ -186,7 +186,9 @@ class User(AbstractUser):
|
|||
|
||||
@property
|
||||
def avatar(self):
|
||||
return self.identity.avatar if self.identity else static("img/avatar.svg")
|
||||
return (
|
||||
self.identity.avatar if self.identity else settings.SITE_INFO["user_icon"]
|
||||
)
|
||||
|
||||
@property
|
||||
def handler(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue