From: Marcel van der Veldt Date: Fri, 16 Jun 2023 01:04:27 +0000 (+0200) Subject: Some small fixes and improvements (#721) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=547a04edf535a43b5031bcbfc35412d71ee1d716;p=music-assistant-server.git Some small fixes and improvements (#721) * Support m3u8 playlists in file providers * Fix creating collage/thumbnail for local playlists * bump frontend to 20230616.0 * support relative filenames in playlists --- diff --git a/music_assistant/server/controllers/metadata.py b/music_assistant/server/controllers/metadata.py index 28eff55a..fa435bcc 100755 --- a/music_assistant/server/controllers/metadata.py +++ b/music_assistant/server/controllers/metadata.py @@ -172,14 +172,14 @@ class MetaDataController: # retrieve genres from tracks # TODO: retrieve style/mood ? playlist.metadata.genres = set() - image_urls = set() + images = set() try: playlist_genres: dict[str, int] = {} async for track in self.mass.music.playlists.tracks( playlist.item_id, playlist.provider ): if not playlist.image and track.image: - image_urls.add(track.image.path) + images.add(track.image) if track.media_type != MediaType.TRACK: # filter out radio items continue @@ -202,12 +202,12 @@ class MetaDataController: playlist.metadata.genres.update(playlist_genres_filtered) # create collage thumb/fanart from playlist tracks - if image_urls: + if images: if playlist.image and self.mass.storage_path in playlist.image: img_path = playlist.image else: img_path = os.path.join(self.mass.storage_path, f"{uuid4().hex}.png") - img_data = await create_collage(self.mass, list(image_urls)) + img_data = await create_collage(self.mass, list(images)) async with aiofiles.open(img_path, "wb") as _file: await _file.write(img_data) playlist.metadata.images = [MediaItemImage(ImageType.THUMB, img_path, True)] diff --git a/music_assistant/server/helpers/images.py b/music_assistant/server/helpers/images.py index 15896f6e..fa153627 100644 --- a/music_assistant/server/helpers/images.py +++ b/music_assistant/server/helpers/images.py @@ -10,6 +10,7 @@ from typing import TYPE_CHECKING import aiofiles from PIL import Image +from music_assistant.common.models.media_items import MediaItemImage from music_assistant.server.helpers.tags import get_embedded_image if TYPE_CHECKING: @@ -49,7 +50,7 @@ async def get_image_thumb( return await asyncio.to_thread(_create_image) -async def create_collage(mass: MusicAssistant, images: list[str]) -> bytes: +async def create_collage(mass: MusicAssistant, images: list[MediaItemImage]) -> bytes: """Create a basic collage image from multiple image urls.""" def _new_collage(): @@ -65,7 +66,8 @@ async def create_collage(mass: MusicAssistant, images: list[str]) -> bytes: for x_co in range(0, 1500, 500): for y_co in range(0, 1500, 500): - img_data = await get_image_data(mass, random.choice(images)) + img = random.choice(images) + img_data = await get_image_data(mass, img.path, img.provider) await asyncio.to_thread(_add_to_collage, img_data, x_co, y_co) def _save_collage(): diff --git a/music_assistant/server/providers/filesystem_local/base.py b/music_assistant/server/providers/filesystem_local/base.py index fc47b44d..e4235149 100644 --- a/music_assistant/server/providers/filesystem_local/base.py +++ b/music_assistant/server/providers/filesystem_local/base.py @@ -67,7 +67,7 @@ CONF_ENTRY_MISSING_ALBUM_ARTIST = ConfigEntry( ) TRACK_EXTENSIONS = ("mp3", "m4a", "m4b", "mp4", "flac", "wav", "ogg", "aiff", "wma", "dsf") -PLAYLIST_EXTENSIONS = ("m3u", "pls") +PLAYLIST_EXTENSIONS = ("m3u", "pls", "m3u8") SUPPORTED_EXTENSIONS = TRACK_EXTENSIONS + PLAYLIST_EXTENSIONS IMAGE_EXTENSIONS = ("jpg", "jpeg", "JPG", "JPEG", "png", "PNG", "gif", "GIF") SEEKABLE_FILES = (ContentType.MP3, ContentType.WAV, ContentType.FLAC) @@ -472,14 +472,25 @@ class FileSystemProviderBase(MusicProvider): async def _parse_playlist_line(self, line: str, playlist_path: str) -> Track | Radio | None: """Try to parse a track from a playlist line.""" try: - # try to treat uri as (relative) filename - if "://" not in line: - for filename in (line, os.path.join(playlist_path, line)): - if not await self.exists(filename): - continue - return await self.get_track(filename) - # fallback to generic uri parsing - return await self.mass.music.get_item_by_uri(line) + if "://" in line: + # handle as generic uri + return await self.mass.music.get_item_by_uri(line) + + # if a relative path was given in an upper level from the playlist, + # try to resolve it + for parentpart in ("../", "..\\"): + while line.startswith(parentpart): + if len(playlist_path) < 3: + break # guard + playlist_path = parentpart[:-3] + line = line[3:] + + # try to resolve the filename + for filename in (line, os.path.join(playlist_path, line)): + with contextlib.suppress(FileNotFoundError): + item = await self.resolve(filename) + return await self._parse_track(item) + except MusicAssistantError as err: self.logger.warning("Could not parse uri/file %s to track: %s", line, str(err)) return None diff --git a/pyproject.toml b/pyproject.toml index 0ff7c958..369da271 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ server = [ "python-slugify==8.0.1", "mashumaro==3.7", "memory-tempfile==2.2.3", - "music-assistant-frontend==20230609.0", + "music-assistant-frontend==20230616.0", "pillow==9.5.0", "unidecode==1.3.6", "xmltodict==0.13.0", diff --git a/requirements_all.txt b/requirements_all.txt index e7a6ebaa..8d705aa0 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -18,7 +18,7 @@ git+https://github.com/jozefKruszynski/python-tidal.git@v0.7.1 git+https://github.com/pytube/pytube.git@refs/pull/1501/head mashumaro==3.7 memory-tempfile==2.2.3 -music-assistant-frontend==20230609.0 +music-assistant-frontend==20230616.0 orjson==3.9.1 pillow==9.5.0 plexapi==4.14.0