more configurable

This commit is contained in:
Your Name 2023-08-24 05:48:14 +00:00 committed by Henri Dickson
parent 605d8373bf
commit 65a2b82383
11 changed files with 186 additions and 190 deletions

View file

@ -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

View file

@ -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")

View file

@ -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
)

View file

@ -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">

View file

@ -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 }}">

View file

@ -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
------------

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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}/"

View file

@ -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):