/
/
/
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, ProviderFeature
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 label="Action when a track is missing the Albumartist ID3 tag",
17 default_value="various_artists",
18 help_link="https://music-assistant.io/music-providers/filesystem/#tagging-files",
19 required=False,
20 options=[
21 ConfigValueOption("Use Track artist(s)", "track_artist"),
22 ConfigValueOption("Use Various Artists", "various_artists"),
23 ConfigValueOption("Use Folder name (if possible)", "folder_name"),
24 ],
25 depends_on=CONF_CONTENT_TYPE,
26 depends_on_value="music",
27)
28
29
30CONF_ENTRY_PATH = ConfigEntry(
31 key="path",
32 type=ConfigEntryType.STRING,
33 label="Path",
34 default_value="/media",
35)
36
37CONF_ENTRY_CONTENT_TYPE = ConfigEntry(
38 key=CONF_CONTENT_TYPE,
39 type=ConfigEntryType.STRING,
40 label="Content type in media folder(s)",
41 default_value="music",
42 description="The type of content to expect in the media folder(s)",
43 required=False,
44 options=[
45 ConfigValueOption("Music", "music"),
46 ConfigValueOption("Audiobooks", "audiobooks"),
47 ConfigValueOption("Podcasts", "podcasts"),
48 ],
49)
50CONF_ENTRY_CONTENT_TYPE_READ_ONLY = ConfigEntry.from_dict(
51 {**CONF_ENTRY_CONTENT_TYPE.to_dict(), "read_only": True}
52)
53
54CONF_ENTRY_LIBRARY_SYNC_TRACKS = ConfigEntry(
55 key="library_sync_tracks",
56 type=ConfigEntryType.BOOLEAN,
57 label="Import tracks/files into the Music Assistant library",
58 description="Define how/if you want to import tracks/files from the filesystem "
59 "into the Music Assistant Library. \nWhen not importing into the library, "
60 "they can still be manually browsed using the Browse feature. \n\n"
61 "Please note that by adding a Track into the Music Assistant library, "
62 "the track artists and album will always be imported as well.",
63 default_value=True,
64 category="sync_options",
65 depends_on=CONF_CONTENT_TYPE,
66 depends_on_value="music",
67)
68CONF_ENTRY_LIBRARY_SYNC_PLAYLISTS = ConfigEntry(
69 key="library_sync_playlists",
70 type=ConfigEntryType.BOOLEAN,
71 label="Import playlists (m3u files) into the Music Assistant library",
72 description="Define how/if you want to import playlists (m3u files) from the filesystem "
73 "into the Music Assistant Library. \nWhen not importing into the library, "
74 "they can still be manually browsed using the Browse feature.",
75 default_value=True,
76 category="sync_options",
77 depends_on=CONF_CONTENT_TYPE,
78 depends_on_value="music",
79)
80CONF_ENTRY_LIBRARY_SYNC_PODCASTS = ConfigEntry(
81 key="library_sync_podcasts",
82 type=ConfigEntryType.BOOLEAN,
83 label="Import Podcasts(files) into the Music Assistant library",
84 description="Define how/if you want to import Podcasts(files) from the filesystem "
85 "into the Music Assistant Library. \nWhen not importing into the library, "
86 "they can still be manually browsed using the Browse feature.",
87 default_value=True,
88 category="sync_options",
89 depends_on=CONF_CONTENT_TYPE,
90 depends_on_value="podcasts",
91)
92CONF_ENTRY_LIBRARY_SYNC_AUDIOBOOKS = ConfigEntry(
93 key="library_sync_audiobooks",
94 type=ConfigEntryType.BOOLEAN,
95 label="Import Audiobooks(files) into the Music Assistant library",
96 description="Define how/if you want to import Audiobooks(files) from the filesystem "
97 "into the Music Assistant Library. \nWhen not importing into the library, "
98 "they can still be manually browsed using the Browse feature.",
99 default_value=True,
100 category="sync_options",
101 depends_on=CONF_CONTENT_TYPE,
102 depends_on_value="audiobooks",
103)
104
105CONF_ENTRY_IGNORE_ALBUM_PLAYLISTS = ConfigEntry(
106 key="ignore_album_playlists",
107 type=ConfigEntryType.BOOLEAN,
108 label="Ignore playlists with album tracks within album folders",
109 description="A digital album often comes with a playlist file (.m3u) "
110 "that contains the tracks of the album. \nAdding all these playlists to the library, "
111 "is not very practical so it's better to just ignore them.\n\n"
112 "If this option is enabled, all playlists will be ignored which are more than "
113 "1 level deep anywhere in the folder structure. E.g. /music/artistname/albumname/playlist.m3u",
114 default_value=True,
115 required=False,
116 depends_on=CONF_CONTENT_TYPE,
117 depends_on_value="music",
118)
119
120TRACK_EXTENSIONS = {
121 "aac",
122 "mp3",
123 "m4a",
124 "mp4",
125 "flac",
126 "wav",
127 "ogg",
128 "aiff",
129 "wma",
130 "dsf",
131 "opus",
132 "wv",
133 "amr",
134 "awb",
135 "spx",
136 "tak",
137 "ape",
138 "mpc",
139 "mp2",
140 "m2a",
141 "mp1",
142 "dra",
143 "mpeg",
144 "mpg",
145 "ac3",
146 "ec3",
147 "aif",
148 "oga",
149 "dff",
150 "ts",
151 "m2ts",
152 "mp+",
153}
154PLAYLIST_EXTENSIONS = {"m3u", "pls", "m3u8"}
155IMAGE_EXTENSIONS = {"jpg", "jpeg", "png", "gif"}
156AUDIOBOOK_EXTENSIONS = {"aa", "aax", "m4b", "m4a", "mp3", "mp4", "flac", "ogg", "opus"}
157PODCAST_EPISODE_EXTENSIONS = {"aa", "aax", "m4b", "m4a", "mp3", "mp4", "flac", "ogg"}
158PLAYLIST_EXTENSIONS = {"m3u", "pls", "m3u8"}
159SUPPORTED_EXTENSIONS = {
160 *TRACK_EXTENSIONS,
161 *AUDIOBOOK_EXTENSIONS,
162 *PODCAST_EPISODE_EXTENSIONS,
163 *PLAYLIST_EXTENSIONS,
164}
165
166
167SUPPORTED_FEATURES = {
168 ProviderFeature.LIBRARY_ARTISTS,
169 ProviderFeature.LIBRARY_ALBUMS,
170 ProviderFeature.LIBRARY_TRACKS,
171 ProviderFeature.LIBRARY_PLAYLISTS,
172 ProviderFeature.BROWSE,
173 ProviderFeature.SEARCH,
174}
175
176
177class IsChapterFile(Exception):
178 """Exception to indicate that a file is part of a multi-part media (e.g. audiobook chapter)."""
179
180
181CACHE_CATEGORY_ARTIST_INFO: Final[int] = 1
182CACHE_CATEGORY_ALBUM_INFO: Final[int] = 2
183CACHE_CATEGORY_FOLDER_IMAGES: Final[int] = 3
184CACHE_CATEGORY_AUDIOBOOK_CHAPTERS: Final[int] = 4
185CACHE_CATEGORY_PODCAST_METADATA: Final[int] = 5
186