/
/
/
1"""Constants for the Filesystem Local provider."""
2
3from __future__ import annotations
4
5from typing import Final
6
7from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption
8from music_assistant_models.enums import ConfigEntryType
9
10CONF_MISSING_ALBUM_ARTIST_ACTION = "missing_album_artist_action"
11CONF_CONTENT_TYPE = "content_type"
12
13CONF_ENTRY_MISSING_ALBUM_ARTIST = ConfigEntry(
14 key=CONF_MISSING_ALBUM_ARTIST_ACTION,
15 type=ConfigEntryType.STRING,
16 default_value="various_artists",
17 help_link="https://music-assistant.io/music-providers/local-files/#tagging-files",
18 required=False,
19 options=[
20 ConfigValueOption("track_artist"),
21 ConfigValueOption("various_artists"),
22 ConfigValueOption("folder_name"),
23 ],
24 depends_on=CONF_CONTENT_TYPE,
25 depends_on_value="music",
26)
27
28
29CONF_ENTRY_PATH = ConfigEntry(
30 key="path",
31 type=ConfigEntryType.STRING,
32 default_value="/media",
33)
34
35CONF_ENTRY_CONTENT_TYPE = ConfigEntry(
36 key=CONF_CONTENT_TYPE,
37 type=ConfigEntryType.STRING,
38 default_value="music",
39 required=False,
40 options=[
41 ConfigValueOption("music"),
42 ConfigValueOption("audiobooks"),
43 ConfigValueOption("podcasts"),
44 ConfigValueOption("sound_effects"),
45 ],
46)
47CONF_ENTRY_CONTENT_TYPE_READ_ONLY = ConfigEntry.from_dict(
48 {**CONF_ENTRY_CONTENT_TYPE.to_dict(), "read_only": True}
49)
50
51CONF_ENTRY_LIBRARY_SYNC_TRACKS = ConfigEntry(
52 key="library_sync_tracks",
53 type=ConfigEntryType.BOOLEAN,
54 default_value=True,
55 category="sync_options",
56 depends_on=CONF_CONTENT_TYPE,
57 depends_on_value="music",
58)
59CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS = ConfigEntry(
60 key="library_sync_playlists",
61 type=ConfigEntryType.BOOLEAN,
62 default_value=True,
63 category="sync_options",
64 depends_on=CONF_CONTENT_TYPE,
65 depends_on_value="music",
66)
67CONF_ENTRY_LIBRARY_SYNC_PODCASTS = ConfigEntry(
68 key="library_sync_podcasts",
69 type=ConfigEntryType.BOOLEAN,
70 default_value=True,
71 category="sync_options",
72 depends_on=CONF_CONTENT_TYPE,
73 depends_on_value="podcasts",
74)
75CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS = ConfigEntry(
76 key="library_sync_audiobooks",
77 type=ConfigEntryType.BOOLEAN,
78 default_value=True,
79 category="sync_options",
80 depends_on=CONF_CONTENT_TYPE,
81 depends_on_value="audiobooks",
82)
83
84CONF_ENTRY_PROPAGATE_GENRES = ConfigEntry(
85 key="propagate_track_genres",
86 type=ConfigEntryType.BOOLEAN,
87 default_value=False,
88 required=False,
89 category="sync_options",
90 depends_on=CONF_CONTENT_TYPE,
91 depends_on_value="music",
92)
93
94CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS = ConfigEntry(
95 key="ignore_album_playlists",
96 type=ConfigEntryType.BOOLEAN,
97 default_value=True,
98 required=False,
99 depends_on=CONF_CONTENT_TYPE,
100 depends_on_value="music",
101)
102
103TRACK_EXTENSIONS = {
104 "aac",
105 "mp3",
106 "m4a",
107 "mp4",
108 "flac",
109 "wav",
110 "ogg",
111 "aiff",
112 "wma",
113 "dsf",
114 "opus",
115 "wv",
116 "amr",
117 "awb",
118 "spx",
119 "tak",
120 "ape",
121 "mpc",
122 "mp2",
123 "m2a",
124 "mp1",
125 "dra",
126 "mpeg",
127 "mpg",
128 "ac3",
129 "ec3",
130 "aif",
131 "oga",
132 "dff",
133 "ts",
134 "m2ts",
135 "mp+",
136}
137PLAYLIST_EXTENSIONS = {"m3u", "pls", "m3u8"}
138CUE_EXTENSIONS = {"cue"}
139IMAGE_EXTENSIONS = {"jpg", "jpeg", "png", "gif"}
140AUDIOBOOK_EXTENSIONS = {"aa", "aax", "m4b", "m4a", "mp3", "mp4", "flac", "ogg", "opus"}
141PODCAST_EPISODE_EXTENSIONS = {"aa", "aax", "m4b", "m4a", "mp3", "mp4", "flac", "ogg", "opus"}
142SOUND_EFFECT_EXTENSIONS = TRACK_EXTENSIONS
143SUPPORTED_EXTENSIONS = {
144 *TRACK_EXTENSIONS,
145 *AUDIOBOOK_EXTENSIONS,
146 *PODCAST_EPISODE_EXTENSIONS,
147 *PLAYLIST_EXTENSIONS,
148 *CUE_EXTENSIONS,
149}
150
151
152class IsChapterFile(Exception):
153 """Exception to indicate that a file is part of a multi-part media (e.g. audiobook chapter)."""
154
155
156CACHE_CATEGORY_ARTIST_INFO: Final[int] = 1
157CACHE_CATEGORY_ALBUM_INFO: Final[int] = 2
158CACHE_CATEGORY_FOLDER_IMAGES: Final[int] = 3
159CACHE_CATEGORY_AUDIOBOOK_CHAPTERS: Final[int] = 4
160CACHE_CATEGORY_PODCAST_METADATA: Final[int] = 5
161CACHE_CATEGORY_CUE_SHEETS: Final[int] = 6
162CACHE_CATEGORY_SOUND_EFFECTS: Final[int] = 7
163CACHE_CATEGORY_PODCAST_EPISODES: Final[int] = 8
164
165# how long a podcast episode listing that lost a file to a parse failure is cached for:
166# the missing episode cannot reappear any sooner than this
167PARTIAL_LISTING_CACHE_EXPIRATION: Final[int] = 300
168
169DEFAULT_AUDIOBOOK_PODCAST_GENRE: Final[str] = "Spoken Word"
170