# silence PIL logger
logging.getLogger("PIL").setLevel(logging.WARNING)
# make sure that our directory with collage images exists
- self._collage_images_dir = os.path.join(self.mass.storage_path, "collage_images")
+ self._collage_images_dir = os.path.join(self.mass.cache_path, "collage_images")
if not await asyncio.to_thread(os.path.exists, self._collage_images_dir):
await asyncio.to_thread(os.mkdir, self._collage_images_dir)
self.mass.streams.register_dynamic_route("/imageproxy", self.handle_imageproxy)
isdir = wrap(os.path.isdir)
isfile = wrap(os.path.isfile)
+mkdirs = wrap(os.makedirs)
+rmfile = wrap(os.remove)
+listdir = wrap(os.listdir)
+rename = wrap(os.rename)
EventCallBackType = Callable[[MassEvent], None]
EventSubscriptionType = tuple[
def __init__(self, storage_path: str, safe_mode: bool = False) -> None:
"""Initialize the MusicAssistant Server."""
self.storage_path = storage_path
+ self.cache_path = os.path.join(storage_path, ".cache")
self.safe_mode = safe_mode
# we dynamically register command handlers which can be consumed by the apis
self.command_handlers: dict[str, APICommandHandler] = {}
# setup config controller first and fetch important config values
self.config = ConfigController(self)
await self.config.setup()
+ # setup/migrate storage
+ await self._setup_storage()
LOGGER.info(
"Starting Music Assistant Server (%s) version %s - HA add-on: %s - Safe mode: %s",
self.server_id,
},
}
)
+
+ async def _setup_storage(self) -> None:
+ """Handle Setup of storage/cache folder(s)."""
+ if not await isdir(self.storage_path):
+ await mkdirs(self.storage_path)
+ if not await isdir(self.cache_path):
+ await mkdirs(self.cache_path)
+ # cleanup old cache files from their old locations
+ # TODO: Remove this code after MA version 2.5+
+ old_cache_db = os.path.join(self.storage_path, "cache.db")
+ if await isfile(old_cache_db):
+ await rmfile(old_cache_db)
+ for filename in await listdir(self.storage_path):
+ if filename.startswith(("spotify", "collage")):
+ old_loc = os.path.join(self.storage_path, filename)
+ new_loc = os.path.join(self.cache_path, filename)
+ await rename(old_loc, new_loc)
CALLBACK_REDIRECT_URL = "https://music-assistant.io/callback"
-CACHE_DIR = "/tmp/spotify_cache" # noqa: S108
LIKED_SONGS_FAKE_PLAYLIST_ID_PREFIX = "liked_songs"
SUPPORTED_FEATURES = (
ProviderFeature.LIBRARY_ARTISTS,
async def handle_async_init(self) -> None:
"""Handle async initialization of the provider."""
- self.config_dir = os.path.join(self.mass.storage_path, self.instance_id)
+ self.cache_dir = os.path.join(self.mass.cache_path, self.instance_id)
self.throttler = ThrottlerManager(rate_limit=1, period=2)
if self.config.get_value(CONF_CLIENT_ID):
# loosen the throttler a bit when a custom client id is used
args = [
librespot,
"--cache",
- CACHE_DIR,
- "--system-cache",
- self.config_dir,
+ self.cache_dir,
"--cache-size-limit",
"1G",
"--passthrough",
librespot = await self.get_librespot_binary()
args = [
librespot,
- "--system-cache",
- self.config_dir,
+ "--cache",
+ self.cache_dir,
"--check-auth",
]
ret_code, stdout = await check_output(*args)
# cached librespot creds are invalid, re-authenticate
# we can use the check-token option to send a new token to librespot
# librespot will then get its own token from spotify (somehow) and cache that.
- args = [
- librespot,
- "--system-cache",
- self.config_dir,
- "--check-auth",
+ args += [
"--access-token",
auth_info["access_token"],
]