kemono2/schema/config.schema.json
2025-04-11 00:58:59 +02:00

643 lines
18 KiB
JSON

{
"$id": "configuration",
"title": "Configuration",
"description": "Configuration for Kemono.",
"type": "object",
"additionalProperties": false,
"required": ["site", "development_mode", "automatic_migrations", "webserver"],
"properties": {
"site": {
"description": "Deprecated in favour of `#/webserver/site`.",
"$comment": "`$deprecated` keyword was in introduced in draft `2019-09`, so just using `description` field instead.",
"type": "string"
},
"favicon": {
"description": "favicon.ico file path.",
"type": "string"
},
"development_mode": {
"type": "boolean"
},
"automatic_migrations": {
"type": "boolean"
},
"sentry_dsn": {
"type": "string"
},
"sentry_dsn_js": {
"type": "string"
},
"open_telemetry_endpoint": {
"type": "null"
},
"ban_url": {
"description": "Kemono3 `BAN` URL prefix for cache purging.",
"anyOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"enable_notifications": {
"type": "boolean"
},
"cache_ttl_for_recent_posts": {
"type": "integer"
},
"webserver": {
"$ref": "#/definitions/webserver"
},
"database": {
"$ref": "#/definitions/database"
},
"redis": {
"$ref": "#/definitions/redis"
},
"archive_server": {
"$ref": "#/definitions/archive-server"
},
"filehaus": {
"$ref": "#/definitions/filehaus"
}
},
"definitions": {
"webserver": {
"description": "Configuration for the frontend server.",
"type": "object",
"additionalProperties": false,
"required": ["secret", "ui"],
"properties": {
"secret": {
"description": "Secret key used to encrypt sessions.",
"type": "string"
},
"workers": {
"description": "Amount of workers to run at once.",
"type": "integer"
},
"harakiri": {
"$comment": "This one isn't used by server code.",
"type": "integer"
},
"threads": {
"description": "Amount of thread to run at once.",
"type": "integer"
},
"ip_security": {
"description": "If you've dealt with how the trust of forwarding IPs works upstream, flip this off.",
"type": "boolean"
},
"country_header_key": {
"description": "Header for user country iso, generater by DDOS-GUARD.",
"anyOf": [{ "type": "string" }, { "const": "DDG-Connecting-Country" }]
},
"uwsgi_options": {
"$ref": "#/definitions/uwsgi-options"
},
"logging": {
"description": "Logging mode.",
"enum": ["DEBUG", "ERROR"]
},
"site": {
"description": "The URL at which the site is publicly accessible.",
"type": "string"
},
"static_folder": {
"description": "The location of the resources that will be served.",
"type": "string"
},
"template_folder": {
"type": "string"
},
"jinja_bytecode_cache_path": {
"type": "null"
},
"max_full_text_search_input_len": {
"type": "integer"
},
"table_sample_bernoulli_sample_size": {
"type": "number"
},
"extra_pages_to_load_on_posts": {
"type": "integer"
},
"pages_in_popular": {
"type": "integer"
},
"earliest_date_for_popular": {
"type": "string"
},
"use_redis_by_lock_default_on_queries": {
"type": "boolean"
},
"api": {
"type": "object",
"additionalProperties": false,
"properties": {
"creators_location": {
"type": "string"
}
}
},
"base_url": {
"type": "string"
},
"port": {
"description": "The port the site will be served on.",
"type": "integer"
},
"ui": {
"$ref": "#/definitions/ui"
}
}
},
"ui": {
"description": "Interface preferences and customization options.",
"type": "object",
"additionalProperties": false,
"required": ["home", "config"],
"properties": {
"home": {
"$ref": "#/definitions/ui-home"
},
"config": {
"$ref": "#/definitions/ui-config"
},
"fileservers": {
"type": "array",
"items": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": [
{ "type": "string" },
{ "anyOf": [{ "type": "integer" }, { "type": "string" }] }
]
}
},
"sidebar": {
"type": "object",
"additionalProperties": false,
"properties": {
"disable_filehaus": {
"type": "boolean"
},
"disable_faq": {
"type": "boolean"
},
"disable_dms": {
"type": "boolean"
}
}
},
"sidebar_items": {
"description": "Add custom links to the bottom of the sidebar.",
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["text"],
"properties": {
"header": { "type": "boolean" },
"text": { "type": "string" },
"class_name": { "type": "string" },
"link": { "type": "string" },
"is_external": { "type": "boolean" },
"color": { "type": "string" }
}
}
},
"footer_items": {
"description": "Add custom HTML elements to the footer.",
"type": "array",
"items": {
"type": "string"
}
},
"banner": {
"description": "Banner HTML. Each entry should be Base64-encoded.",
"type": "object",
"additionalProperties": false,
"properties": {
"global": {
"description": "B64-encoded html fragment.",
"type": "string"
},
"announcement_global": {
"description": "B64-encoded html fragment.",
"type": "string"
},
"welcome": {
"description": "B64-encoded html fragment.",
"type": "string"
}
}
},
"ads": {
"$ref": "#/definitions/ui-ads"
},
"matomo": {
"$ref": "#/definitions/matomo"
},
"video_extensions": {
"description": "File extensions recognized as (browser-friendly) video. Will automatically be embedded in post pages.",
"type": "array",
"uniqueItems": true,
"items": {
"enum": [".mp4", ".webm", ".m4v", ".3gp", ".mov"]
}
},
"files_url_prepend": {
"type": "object",
"additionalProperties": false,
"properties": {
"icons_base_url": {
"type": "string"
},
"banners_base_url": {
"type": "string"
},
"thumbnails_base_url": {
"type": "string"
}
}
}
}
},
"ui-home": {
"type": "object",
"additionalProperties": false,
"properties": {
"site_name": { "type": "string" },
"welcome_credits": {
"description": "B64-encoded html fragment.",
"type": "string"
},
"home_background_image": {
"description": "A path to background image on server.",
"type": "string"
},
"logo_path": {
"type": "string"
},
"mascot_path": {
"type": "string"
},
"announcements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"title": { "type": "string" },
"date": { "type": "string" },
"content": { "type": "string" }
}
}
}
}
},
"ui-config": {
"type": "object",
"additionalProperties": false,
"required": ["paysite_list"],
"properties": {
"paysite_list": {
"type": "array",
"uniqueItems": true,
"items": {
"enum": [
"patreon",
"fanbox",
"afdian",
"discord",
"fantia",
"boosty",
"gumroad",
"subscribestar",
"dlsite",
"candfans",
"fansly",
"onlyfans"
]
}
},
"artists_or_creators": {
"type": "string"
}
}
},
"ui-ads": {
"description": "Ads preferences. Each spot should be Base64-encoded.",
"type": "object",
"additionalProperties": false,
"properties": {
"header": {
"description": "Base64-encoded html fragment.",
"type": "string"
},
"middle": {
"description": "Base64-encoded html fragment.",
"type": "string"
},
"footer": {
"description": "Base64-encoded html fragment.",
"type": "string"
},
"slider": {
"description": "Base64-encoded html fragment.",
"type": "string"
},
"video": {
"description": "Base64-encoded JSON list of objects.\nSee https://docs.fluidplayer.com/docs/configuration/ads/#adlist .",
"type": "string"
}
}
},
"matomo": {
"description": "Matomo preferences.",
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": { "type": "boolean" },
"tracking_domain": {
"type": "string"
},
"tracking_code": {
"type": "string"
},
"site_id": {
"type": "integer"
},
"plain_code": {
"description": "Base64-encoded html fragment.",
"type": "string"
}
}
},
"database": {
"description": "Database configuration.",
"type": "object",
"additionalProperties": false,
"required": ["host", "user", "password", "database"],
"properties": {
"host": { "type": "string" },
"port": { "type": "integer" },
"user": { "type": "string" },
"password": { "type": "string" },
"database": { "type": "string" },
"application_name": { "type": "string" }
}
},
"redis": {
"type": "object",
"additionalProperties": false,
"required": ["defaults"],
"properties": {
"defaults": { "$ref": "#/definitions/redis-defaults" },
"compression": { "type": "string" },
"default_ttl": { "type": "string" },
"node_options": {
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string"
},
"port": {
"type": "integer"
},
"db": {
"type": "integer"
},
"password": {
"type": "string"
}
}
},
"nodes": {
"anyOf": [
{
"type": "object",
"additionalProperties": { "type": "string" }
},
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"port": {
"type": "integer"
},
"db": {
"type": "integer"
}
}
}
}
]
},
"keyspaces": {
"type": "object",
"propertyNames": {
"$ref": "#/definitions/redis-keyspaces"
},
"additionalProperties": {
"type": "integer"
}
}
}
},
"redis-defaults": {
"type": "object",
"additionalProperties": false,
"required": ["host"],
"properties": {
"host": {
"type": "string"
},
"password": {
"type": "string"
},
"port": {
"type": "integer"
},
"db": {
"type": "integer"
}
}
},
"redis-keyspaces": {
"enum": [
"account",
"saved_key_import_ids",
"saved_keys",
"random_artist_keys",
"top_artists",
"artists_by_update_time",
"artists_faved",
"artists_faved_count",
"artists_recently_faved_count",
"top_artists_recently",
"non_discord_artist_keys",
"non_discord_artists",
"artists_by_service",
"artist",
"artist_post_count",
"artist_post_offset",
"artist_last_updated",
"artist_favorited",
"dms",
"all_dms",
"all_dms_count",
"all_dms_by_query",
"all_dms_by_query_count",
"dms_count",
"unapproved_dms",
"favorite_artists",
"favorite_posts",
"notifications_for_account",
"random_post_keys",
"post",
"next_post",
"previous_post",
"posts_incomplete_rewards",
"post_favorited",
"posts_by_artist",
"posts_by_artists",
"posts_by_favorited_artists",
"comments",
"artist_posts_offset",
"is_post_flagged",
"importer_logs",
"ratelimit",
"all_posts",
"all_post_keys",
"all_shares",
"all_shares_count",
"all_posts_for_query",
"global_post_count",
"global_post_count_for_query",
"lock",
"lock-signal",
"imports",
"share_files",
"account_notifications",
"new_notifications",
"share",
"artist_shares",
"post_revisions",
"post_revision",
"files",
"post_by_id",
"fancards",
"announcements",
"announcement_count",
"artist_share_count",
"discord_channels_for_server",
"discord_posts",
"popular_posts",
"tagged_posts",
"tags",
"file",
"archive_files",
"linked_accounts",
"running_imports",
"importer_configuration"
]
},
"archive-server": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"api_url": {
"type": "string"
},
"serve_files": {
"type": "boolean"
},
"file_serving_enabled": {
"type": "boolean"
}
}
},
"filehaus": {
"description": "Filehaus configuration.",
"type": "object",
"additionalProperties": false,
"properties": {
"requires_account": {
"description": "If true, an account will be required for uploading.",
"type": "boolean"
},
"required_roles": {
"description": "Required account roles for uploading. If set to an empty list, no permissions will be required.",
"type": "array",
"uniqueItems": true,
"items": {
"enum": ["administrator", "moderator", "uploader"]
}
},
"tus": {
"description": "`tusd` configuration.",
"type": "object",
"additionalProperties": false,
"properties": {
"manage": {
"description": "Automatically manage `tusd` on port 1080. If you intend to store uploads on a different server from Kemono3, set a custom URL instead...",
"type": "boolean"
},
"url": {
"description": "...right here. Note that if you do not allow automatic management and did not set a custom URL, uploads will be blackholed to a demo instance and Filehaus sharing will not function correctly.\nDo note that using `tusd` instances to enable Filehaus functionality requires the `post-create` hook to be pointed at Kemono's `/shares/tus` endpoint.\n`tusd --hooks-enabled-events post-create -hooks-http \"http://127.0.0.1:6942/shares/tus\" -upload-dir=./data`",
"type": "string"
}
}
}
}
},
"uwsgi-options": {
"description": "Set additional uWSGI options if you want. Overrides any of the other options.",
"type": "object",
"additionalProperties": false,
"properties": {
"cheaper-algo": {
"enum": ["busyness"]
},
"cheaper": {
"type": "integer"
},
"cheaper-initial": {
"type": "integer"
},
"cheaper-overload": {
"type": "integer"
},
"cheaper-step": {
"type": "integer"
},
"cheaper-busyness-multiplier": {
"type": "integer"
},
"cheaper-busyness-min": {
"type": "integer"
},
"cheaper-busyness-max": {
"type": "integer"
},
"cheaper-busyness-backlog-alert": {
"type": "integer"
},
"cheaper-busyness-backlog-step": {
"type": "integer"
},
"disable-logging": {
"type": "boolean"
}
}
}
}
}