/
/
/
1"""Constants for the Metadata Controller."""
2
3from __future__ import annotations
4
5# Map of normalised imageproxy `fmt` values to standards-compliant MIME types.
6# Used both to validate the client-supplied `fmt` query parameter and to set
7# the Content-Type on the response.
8_IMAGEPROXY_CONTENT_TYPES: dict[str, str] = {
9 "jpg": "image/jpeg",
10 "jpeg": "image/jpeg",
11 "png": "image/png",
12 "svg": "image/svg+xml",
13}
14
15LOCALES = {
16 "af_ZA": "African",
17 "ar_AE": "Arabic (United Arab Emirates)",
18 "ar_EG": "Arabic (Egypt)",
19 "ar_SA": "Saudi Arabia",
20 "bg_BG": "Bulgarian",
21 "cs_CZ": "Czech",
22 "zh_CN": "Chinese",
23 "zh_TW": "Chinese (Traditional)",
24 "hr_HR": "Croatian",
25 "da_DK": "Danish",
26 "de_DE": "German",
27 "el_GR": "Greek",
28 "en_AU": "English (AU)",
29 "en_US": "English (US)",
30 "en_GB": "English (UK)",
31 "es_ES": "Spanish",
32 "et_EE": "Estonian",
33 "fi_FI": "Finnish",
34 "fr_FR": "French",
35 "hu_HU": "Hungarian",
36 "is_IS": "Icelandic",
37 "it_IT": "Italian",
38 "lt_LT": "Lithuanian",
39 "lv_LV": "Latvian",
40 "ja_JP": "Japanese",
41 "ko_KR": "Korean",
42 "nl_NL": "Dutch",
43 "nb_NO": "Norwegian Bokmål",
44 "pl_PL": "Polish",
45 "pt_PT": "Portuguese",
46 "ro_RO": "Romanian",
47 "ru_RU": "Russian",
48 "sk_SK": "Slovak",
49 "sl_SI": "Slovenian",
50 "sr_RS": "Serbian",
51 "sv_SE": "Swedish",
52 "tr_TR": "Turkish",
53 "uk_UA": "Ukrainian",
54}
55
56DEFAULT_LANGUAGE = "en_US"
57
58# Radio stream artwork cache settings
59CACHE_CATEGORY_RADIO_ARTWORK = 101
60
61CACHE_EXPIRATION_RADIO_ARTWORK = 86400 * 90 # 90 days
62
63CACHE_EXPIRATION_RADIO_ARTWORK_MISS = 86400 * 7 # 7 days
64
65AD_DETECTION_PHRASES = ("asset link", "asset stop", "asset spot", "advert", "promo")
66
67REFRESH_INTERVAL = 60 * 60 * 24 * 90 # 90 days
68
69CONF_ENABLE_ONLINE_METADATA = "enable_online_metadata"
70
71CONF_PREFER_LOCAL_GENRES = "prefer_local_genres"
72
73CONF_ENABLE_RADIO_METADATA_LOOKUP = "enable_radio_metadata_lookup"
74
75MISSING_ARTIST_METADATA_SCAN_TASK_ID = "metadata_missing_artist_metadata_scan_v2"
76
77PLAYLIST_METADATA_SCAN_TASK_ID = "metadata_playlist_metadata_scan_v2"
78
79THUMB_CACHE_CLEANUP_TASK_ID = "metadata_thumb_cache_cleanup_v2"
80
81ALBUM_RECONCILIATION_TASK_ID = "metadata_album_reconciliation_v1"
82
83METADATA_LOOKUP_TASK_ID_PREFIX = "metadata_lookup"
84
85METADATA_SCAN_BATCH_SIZE = 25
86
87CONF_THUMB_CACHE_MAX_SIZE = "thumb_cache_max_size"
88
89DEFAULT_THUMB_CACHE_MAX_SIZE_MB = 500
90
91# Image-id system: maps a sha256(provider+path) hash to the (provider, path) tuple
92# so the imageproxy can be addressed by an opaque short id instead of a long
93# query string carrying the raw (often URL-shaped) path. The high category
94# number matches the convention used elsewhere in this controller and avoids
95# collisions with providers that use low category integers under the default
96# cache namespace.
97CACHE_CATEGORY_IMAGE_IDS = 102
98
99# Bounds each of the in-memory image-id maps (forward memo, reverse LRU and
100# persisted markers). The maps share their key/id string objects, so the
101# combined worst-case footprint stays in the single-digit MB range. Overflow is
102# harmless: an evicted entry merely costs one re-hash and/or one cache-db probe
103# on the next encounter.
104_IMAGE_ID_LRU_MAX = 10000
105
106# 1 year; a stored mapping is refreshed once the row burns through half its TTL
107_IMAGE_ID_CACHE_TTL = 86400 * 365
108
109# Sizes accepted by the imageproxy. 0 means "no resize". The set is small enough
110# to bound PIL memory + thumbnail cache cardinality; expand if a real use case appears.
111_ALLOWED_IMAGEPROXY_SIZES = frozenset({0, 80, 160, 256, 512, 1024})
112
113# Human-readable form of the allowed sizes, used in error responses.
114_ALLOWED_IMAGEPROXY_SIZES_STR = ", ".join(str(size) for size in sorted(_ALLOWED_IMAGEPROXY_SIZES))
115
116_IMAGEPROXY_PATH_PREFIX = "/imageproxy/"
117