Switch to SVG for all provider icons (#782)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Wed, 19 Jul 2023 23:11:36 +0000 (01:11 +0200)
committerGitHub <noreply@github.com>
Wed, 19 Jul 2023 23:11:36 +0000 (01:11 +0200)
51 files changed:
music_assistant/common/models/config_entries.py
music_assistant/common/models/provider.py
music_assistant/constants.py
music_assistant/server/controllers/cache.py
music_assistant/server/controllers/config.py
music_assistant/server/controllers/metadata.py
music_assistant/server/controllers/music.py
music_assistant/server/controllers/player_queues.py
music_assistant/server/controllers/players.py
music_assistant/server/controllers/streams.py
music_assistant/server/controllers/webserver.py
music_assistant/server/helpers/images.py
music_assistant/server/models/core_controller.py
music_assistant/server/providers/airplay/manifest.json
music_assistant/server/providers/chromecast/manifest.json
music_assistant/server/providers/deezer/icon.svg
music_assistant/server/providers/dlna/icon.png [deleted file]
music_assistant/server/providers/dlna/icon.svg [new file with mode: 0755]
music_assistant/server/providers/dlna/manifest.json
music_assistant/server/providers/fanarttv/manifest.json
music_assistant/server/providers/filesystem_local/manifest.json
music_assistant/server/providers/filesystem_smb/manifest.json
music_assistant/server/providers/musicbrainz/icon.svg [new file with mode: 0644]
music_assistant/server/providers/musicbrainz/icon_dark.svg [new file with mode: 0644]
music_assistant/server/providers/plex/icon.png [deleted file]
music_assistant/server/providers/plex/icon.svg [new file with mode: 0644]
music_assistant/server/providers/qobuz/icon.png [deleted file]
music_assistant/server/providers/qobuz/icon.svg [new file with mode: 0755]
music_assistant/server/providers/qobuz/icon_dark.svg [new file with mode: 0755]
music_assistant/server/providers/radiobrowser/icon.png [deleted file]
music_assistant/server/providers/radiobrowser/manifest.json
music_assistant/server/providers/slimproto/cli.py
music_assistant/server/providers/slimproto/icon.png [deleted file]
music_assistant/server/providers/slimproto/icon.svg [new file with mode: 0755]
music_assistant/server/providers/sonos/icon.png [deleted file]
music_assistant/server/providers/sonos/icon.svg [new file with mode: 0644]
music_assistant/server/providers/soundcloud/icon.png [deleted file]
music_assistant/server/providers/soundcloud/icon.svg [new file with mode: 0644]
music_assistant/server/providers/spotify/icon.png [deleted file]
music_assistant/server/providers/spotify/icon.svg [new file with mode: 0644]
music_assistant/server/providers/theaudiodb/manifest.json
music_assistant/server/providers/tidal/icon.png [deleted file]
music_assistant/server/providers/tidal/icon.svg [new file with mode: 0755]
music_assistant/server/providers/tidal/icon_dark.svg [new file with mode: 0755]
music_assistant/server/providers/tunein/icon.png [deleted file]
music_assistant/server/providers/tunein/icon.svg [new file with mode: 0644]
music_assistant/server/providers/ugp/manifest.json
music_assistant/server/providers/url/manifest.json
music_assistant/server/providers/ytmusic/icon.png [deleted file]
music_assistant/server/providers/ytmusic/icon.svg [new file with mode: 0755]
music_assistant/server/server.py

index 4e9974dc644bf2a5f6ea2e32bc3d956ac14b2ad3..ae2c673ac5176864934b62994bcde42dbf68149e 100644 (file)
@@ -10,7 +10,6 @@ from typing import Any
 from mashumaro import DataClassDictMixin
 
 from music_assistant.common.models.enums import ProviderType
-from music_assistant.common.models.provider import ProviderManifest
 from music_assistant.constants import (
     CONF_AUTO_PLAY,
     CONF_CROSSFADE_DURATION,
@@ -183,7 +182,6 @@ class Config(DataClassDictMixin):
             return value.value
 
         res = self.to_dict()
-        res.pop("manifest", None)  # filter out from storage
         res["values"] = {
             x.key: _handle_value(x)
             for x in self.values.values()
@@ -244,7 +242,6 @@ class ProviderConfig(Config):
     type: ProviderType
     domain: str
     instance_id: str
-    manifest: ProviderManifest | None = None  # copied here for UI convenience only
     # enabled: boolean to indicate if the provider is enabled
     enabled: bool = True
     # name: an (optional) custom name for this provider instance/config
@@ -274,7 +271,6 @@ class CoreConfig(Config):
     """CoreController Configuration."""
 
     domain: str  # domain/name of the core module
-    manifest: ProviderManifest | None = None  # copied here for UI convenience only
     # last_error: an optional error message if the module could not be setup with this config
     last_error: str | None = None
 
index 5e6a66f78bc3b7421dcce365f737ddbc9b7e7331..b953ee3e536c60d8d7fed4dc1b0b07f8d046968c 100644 (file)
@@ -37,15 +37,16 @@ class ProviderManifest(DataClassORJSONMixin):
     load_by_default: bool = False
     # depends_on: depends on another provider to function
     depends_on: str | None = None
-    # icon: icon url (svg or transparent png) max 256 pixels
-    # may also be a direct base64 encoded image string
-    # if this attribute is omitted and an icon.svg or icon.png is found in the provider
-    # folder, it will be read instead.
+    # icon: name of the material design icon (https://pictogrammers.com/library/mdi)
     icon: str | None = None
-    # icon_dark: optional separate dark icon
-    # if this attribute is omitted and an icon_dark.svg or icon_dark.png is found in the provider
-    # folder, it will be read instead.
-    icon_dark: str | None = None
+    # icon_svg: svg icon (full xml string)
+    # if this attribute is omitted and an icon.svg is found in the provider
+    # folder, the file contents will be read instead.
+    icon_svg: str | None = None
+    # icon_svg_dark: optional separate dark svg icon (full xml string)
+    # if this attribute is omitted and an icon_dark.svg is found in the provider
+    # folder, the file contents will be read instead.
+    icon_svg_dark: str | None = None
 
     @classmethod
     async def parse(cls: "ProviderManifest", manifest_file: str) -> "ProviderManifest":
index 8ed067acb07279c57005020a3ae6b0dc1cca51a8..38c06e89bcbc3fb4fcd8d4a3a635136b931abdb6 100755 (executable)
@@ -76,3 +76,12 @@ MASS_LOGO_ONLINE: Final[
 ] = "https://github.com/home-assistant/brands/raw/master/custom_integrations/mass/icon%402x.png"
 ENCRYPT_SUFFIX = "_encrypted_"
 SECURE_STRING_SUBSTITUTE = "this_value_is_encrypted"
+CONFIGURABLE_CORE_CONTROLLERS = (
+    "streams",
+    "webserver",
+    "players",
+    "metadata",
+    "cache",
+    "music",
+    "player_queues",
+)
index 7e84dce25a8fa89f1658da958d9b0aa062ef5e79..fdb2cddce92097e5e8772d657f5ad6964e083279 100644 (file)
@@ -43,7 +43,7 @@ class CacheController(CoreController):
         self.manifest.description = (
             "Music Assistant's core controller for caching data throughout the application."
         )
-        self.manifest.icon = "mdi-memory"
+        self.manifest.icon = "memory"
 
     async def get_config_entries(
         self,
index 08a2ec8edc48bdcfb79a651f785f9384d951c873..a08784efc4ab0ea09461f2bc2368e968ce1a31a6 100644 (file)
@@ -32,6 +32,7 @@ from music_assistant.constants import (
     CONF_PLAYERS,
     CONF_PROVIDERS,
     CONF_SERVER_ID,
+    CONFIGURABLE_CORE_CONTROLLERS,
     ENCRYPT_SUFFIX,
 )
 from music_assistant.server.helpers.api import api_command
@@ -50,16 +51,6 @@ isfile = wrap(os.path.isfile)
 remove = wrap(os.remove)
 rename = wrap(os.rename)
 
-CONFIGURABLE_CORE_CONTROLLERS = (
-    "streams",
-    "webserver",
-    "players",
-    "metadata",
-    "cache",
-    "music",
-    "player_queues",
-)
-
 
 class ConfigController:
     """Controller that handles storage of persistent configuration settings."""
@@ -172,7 +163,7 @@ class ConfigController:
     ) -> list[ProviderConfig]:
         """Return all known provider configurations, optionally filtered by ProviderType."""
         raw_values: dict[str, dict] = self.get(CONF_PROVIDERS, {})
-        prov_entries = {x.domain for x in self.mass.get_available_providers()}
+        prov_entries = {x.domain for x in self.mass.get_provider_manifests()}
         return [
             await self.get_provider_config(prov_conf["instance_id"])
             for prov_conf in raw_values.values()
@@ -189,16 +180,12 @@ class ConfigController:
             config_entries = await self.get_provider_config_entries(
                 raw_conf["domain"], instance_id=instance_id, values=raw_conf.get("values")
             )
-            for prov in self.mass.get_available_providers():
+            for prov in self.mass.get_provider_manifests():
                 if prov.domain == raw_conf["domain"]:
-                    manifest = prov
                     break
             else:
                 raise KeyError(f'Unknown provider domain: {raw_conf["domain"]}')
-            conf: ProviderConfig = ProviderConfig.parse(config_entries, raw_conf)
-            # always copy the manifest to help the UI a bit
-            conf.manifest = manifest
-            return conf
+            return ProviderConfig.parse(config_entries, raw_conf)
         raise KeyError(f"No config found for provider id {instance_id}")
 
     @api_command("config/providers/get_value")
@@ -234,7 +221,7 @@ class ConfigController:
         values: the (intermediate) raw values for config entries sent with the action.
         """
         # lookup provider manifest and module
-        for prov in self.mass.get_available_providers():
+        for prov in self.mass.get_provider_manifests():
             if prov.domain == provider_domain:
                 prov_mod = await get_provider_module(provider_domain)
                 break
@@ -446,7 +433,7 @@ class ConfigController:
         for conf in await self.get_provider_configs(provider_domain=provider_domain):
             # return if there is already a config
             return
-        for prov in self.mass.get_available_providers():
+        for prov in self.mass.get_provider_manifests():
             if prov.domain == provider_domain:
                 manifest = prov
                 break
@@ -482,13 +469,9 @@ class ConfigController:
     @api_command("config/core/get")
     async def get_core_config(self, domain: str) -> CoreConfig:
         """Return configuration for a single core controller."""
-        core_controller: CoreController = getattr(self.mass, domain)
         raw_conf = self.get(f"{CONF_CORE}/{domain}", {"domain": domain})
         config_entries = await self.get_core_config_entries(domain)
-        conf: CoreConfig = CoreConfig.parse(config_entries, raw_conf)
-        # always copy the manifest to help the UI a bit
-        conf.manifest = core_controller.manifest
-        return conf
+        return CoreConfig.parse(config_entries, raw_conf)
 
     @api_command("config/core/get_value")
     async def get_core_config_value(self, domain: str, key: str) -> ConfigValueType:
@@ -662,7 +645,7 @@ class ConfigController:
         Returns: newly created ProviderConfig.
         """
         # lookup provider manifest and module
-        for prov in self.mass.get_available_providers():
+        for prov in self.mass.get_provider_manifests():
             if prov.domain == provider_domain:
                 manifest = prov
                 break
index 4ab8ce52f62b0daf483d8ee96210e640248259da..2c46a6185b4dc89f3ebe94a3ecdec0b1f5d4ba94 100755 (executable)
@@ -53,7 +53,7 @@ class MetaDataController(CoreController):
         self.manifest.description = (
             "Music Assistant's core controller which handles all metadata for music."
         )
-        self.manifest.icon = "mdi-book-information-variant"
+        self.manifest.icon = "book-information-variant"
 
     async def setup(self, config: CoreConfig) -> None:  # noqa: ARG002
         """Async initialize of module."""
index c61c12c229ed754188373e17f17341ac6498883f..664553cd6b0c4a44e0c3aa7b40b624f4ac8ac3db 100755 (executable)
@@ -75,7 +75,7 @@ class MusicController(CoreController):
         self.manifest.description = (
             "Music Assistant's core controller which manages all music from all providers."
         )
-        self.manifest.icon = "mdi-archive-music"
+        self.manifest.icon = "archive-music"
         self._sync_task: asyncio.Task | None = None
 
     async def get_config_entries(
index 592f76f3e98bcc3180159fe0001c11e9b4e044e7..5e9e59fe67bbe7928580c3bed32bd53843b7a972 100755 (executable)
@@ -49,7 +49,7 @@ class PlayerQueuesController(CoreController):
         self.manifest.description = (
             "Music Assistant's core controller which manages the queues for all players."
         )
-        self.manifest.icon = "mdi-playlist-music"
+        self.manifest.icon = "playlist-music"
 
     async def close(self) -> None:
         """Cleanup on exit."""
index 86e7203dcb7ae0e1cf769c266faea72408160e46..977c8967b7a81a16145d9db95a33efeae695b764 100755 (executable)
@@ -51,7 +51,7 @@ class PlayerController(CoreController):
         self.manifest.description = (
             "Music Assistant's core controller which manages all players from all providers."
         )
-        self.manifest.icon = "mdi-speaker-multiple"
+        self.manifest.icon = "speaker-multiple"
         self._poll_task: asyncio.Task | None = None
 
     async def setup(self, config: CoreConfig) -> None:  # noqa: ARG002
index cd461da421669513926533510e6960801f553f03..85f48103d05dfe96e287e5f51b2f861e6a9fe90d 100644 (file)
@@ -271,7 +271,7 @@ class StreamsController(CoreController):
             "streaming audio to players on the local network as well as "
             "some player specific local control callbacks."
         )
-        self.manifest.icon = "mdi-cast-audio"
+        self.manifest.icon = "cast-audio"
 
     @property
     def base_url(self) -> str:
index 28317193194a68704a10283db53d188404c1aa97..2c802102e76c69bb3902f244358090d504d5489d 100644 (file)
@@ -64,7 +64,7 @@ class WebserverController(CoreController):
         self.manifest.description = (
             "The built-in webserver that hosts the Music Assistant Websockets API and frontend"
         )
-        self.manifest.icon = "mdi-web-box"
+        self.manifest.icon = "web-box"
 
     @property
     def base_url(self) -> str:
index fa1536270cdfe34119b65befb6a453175e416d8e..66880ee521d29dfa110caf33bd9411b35859e0c6 100644 (file)
@@ -3,7 +3,6 @@ from __future__ import annotations
 
 import asyncio
 import random
-from base64 import b64encode
 from io import BytesIO
 from typing import TYPE_CHECKING
 
@@ -79,12 +78,10 @@ async def create_collage(mass: MusicAssistant, images: list[MediaItemImage]) ->
 
 
 async def get_icon_string(icon_path: str) -> str:
-    """Get icon as (base64 encoded) string."""
+    """Get svg icon as string."""
     ext = icon_path.rsplit(".")[-1]
-    assert ext in ("png", "svg", "ico", "jpg")
-    async with aiofiles.open(icon_path, "rb") as _file:
-        img_data = await _file.read()
-    enc_image = b64encode(img_data).decode()
-    if ext == "svg":
-        return f"data:image/svg+xml;base64,{enc_image}"
-    return f"data:image/{ext};base64,{enc_image}"
+    assert ext == "svg"
+    async with aiofiles.open(icon_path, "r") as _file:
+        xml_data = await _file.read()
+        xml_data = xml_data.replace("\n", "").strip()
+        return xml_data
index 782299cafeaf6108f43be42476695c0556934b6d..6018c095aa8caeeacd34aeb784467ae53cb3e324 100644 (file)
@@ -38,7 +38,7 @@ class CoreController:
             name=f"{self.domain.title()} Core controller",
             description=f"{self.domain.title()} Core controller",
             codeowners=["@music-assistant"],
-            icon="mdi:puzzle-outline",
+            icon="puzzle-outline",
         )
 
     async def get_config_entries(
index 4e26fb48a6e12ad0bfe5cab93065581f42a28cd8..38598a2f84ef66b89cb0455b64a941c1e7db094c 100644 (file)
@@ -10,5 +10,5 @@
   "builtin": false,
   "load_by_default": true,
   "depends_on": "slimproto",
-  "icon": "md:airplay"
+  "icon":"cast-variant"
 }
index 8dd1f46f5aa1969a7d098e62c8374cb1fee86725..dcb77c89009b1f03b4d0df2e88ad9c10f55491b2 100644 (file)
@@ -9,5 +9,5 @@
   "multi_instance": false,
   "builtin": false,
   "load_by_default": true,
-  "icon": "md:cast"
+  "icon": "cast"
 }
index 0704de6cc3eaaa9b32ee6b7ae76296fba422ff25..04948c258e6013fa3e4d36884b86fa97df618762 100644 (file)
@@ -1,53 +1 @@
-<svg width="116" height="76" viewBox="0 0 116 76" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M115.35 0.52002H90.5195V15.01H115.35V0.52002Z" fill="#29AB70"/>
-<path d="M115.35 20.7H90.5195V35.19H115.35V20.7Z" fill="url(#paint0_linear)"/>
-<path d="M115.35 40.87H90.5195V55.36H115.35V40.87Z" fill="url(#paint1_linear)"/>
-<path d="M25.3398 61.05H0.509766V75.54H25.3398V61.05Z" fill="url(#paint2_linear)"/>
-<path d="M55.3398 61.05H30.5098V75.54H55.3398V61.05Z" fill="url(#paint3_linear)"/>
-<path d="M85.3495 61.05H60.5195V75.54H85.3495V61.05Z" fill="url(#paint4_linear)"/>
-<path d="M115.35 61.05H90.5195V75.54H115.35V61.05Z" fill="url(#paint5_linear)"/>
-<path d="M85.3495 40.87H60.5195V55.36H85.3495V40.87Z" fill="url(#paint6_linear)"/>
-<path d="M55.3398 40.87H30.5098V55.36H55.3398V40.87Z" fill="url(#paint7_linear)"/>
-<path d="M55.3398 20.7H30.5098V35.19H55.3398V20.7Z" fill="url(#paint8_linear)"/>
-<defs>
-<linearGradient id="paint0_linear" x1="104.55" y1="37.09" x2="101.32" y2="18.79" gradientUnits="userSpaceOnUse">
-<stop stop-color="#2C8C9D"/>
-<stop offset="0.04" stop-color="#298E9A"/>
-<stop offset="0.39" stop-color="#129C83"/>
-<stop offset="0.72" stop-color="#05A475"/>
-<stop offset="1" stop-color="#00A770"/>
-</linearGradient>
-<linearGradient id="paint1_linear" x1="90.1495" y1="54.63" x2="115.72" y2="41.6" gradientUnits="userSpaceOnUse">
-<stop stop-color="#2839BA"/>
-<stop offset="1" stop-color="#148CB3"/>
-</linearGradient>
-<linearGradient id="paint2_linear" x1="0.509766" y1="68.29" x2="25.3398" y2="68.29" gradientUnits="userSpaceOnUse">
-<stop stop-color="#F6A500"/>
-<stop offset="1" stop-color="#F29100"/>
-</linearGradient>
-<linearGradient id="paint3_linear" x1="30.5098" y1="68.29" x2="55.3398" y2="68.29" gradientUnits="userSpaceOnUse">
-<stop stop-color="#F29100"/>
-<stop offset="1" stop-color="#D12F5F"/>
-</linearGradient>
-<linearGradient id="paint4_linear" x1="60.5195" y1="68.29" x2="85.3495" y2="68.29" gradientUnits="userSpaceOnUse">
-<stop stop-color="#B4197C"/>
-<stop offset="1" stop-color="#472EAD"/>
-</linearGradient>
-<linearGradient id="paint5_linear" x1="90.5195" y1="68.29" x2="115.35" y2="68.29" gradientUnits="userSpaceOnUse">
-<stop stop-color="#2839BA"/>
-<stop offset="1" stop-color="#3072B7"/>
-</linearGradient>
-<linearGradient id="paint6_linear" x1="59.5395" y1="52.03" x2="86.3195" y2="44.2" gradientUnits="userSpaceOnUse">
-<stop stop-color="#B4197C"/>
-<stop offset="1" stop-color="#373AAC"/>
-</linearGradient>
-<linearGradient id="paint7_linear" x1="29.6398" y1="43.28" x2="56.2198" y2="52.95" gradientUnits="userSpaceOnUse">
-<stop stop-color="#FFCB00"/>
-<stop offset="1" stop-color="#D12F5F"/>
-</linearGradient>
-<linearGradient id="paint8_linear" x1="32.6098" y1="18.4199" x2="53.2398" y2="37.4599" gradientUnits="userSpaceOnUse">
-<stop stop-color="#FFCF00"/>
-<stop offset="1" stop-color="#ED743B"/>
-</linearGradient>
-</defs>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 512"><defs><linearGradient id="prefix__a" gradientUnits="userSpaceOnUse" x1="229.359" y1="308.357" x2="221.221" y2="354.463"><stop offset="0" stop-color="#2C8C9D"/><stop offset=".039" stop-color="#298E9A"/><stop offset=".388" stop-color="#129C83"/><stop offset=".722" stop-color="#05A475"/><stop offset="1" stop-color="#00A770"/></linearGradient><linearGradient id="prefix__b" gradientUnits="userSpaceOnUse" x1="326.89" y1="243.406" x2="391.311" y2="276.234"><stop offset="0" stop-color="#2839BA"/><stop offset="1" stop-color="#148CB3"/></linearGradient><linearGradient id="prefix__c" gradientUnits="userSpaceOnUse" x1="98.037" y1="171.167" x2="160.586" y2="171.167"><stop offset="0" stop-color="#F6A500"/><stop offset="1" stop-color="#F29100"/></linearGradient><linearGradient id="prefix__d" gradientUnits="userSpaceOnUse" x1="173.609" y1="171.167" x2="236.158" y2="171.167"><stop offset="0" stop-color="#F29100"/><stop offset="1" stop-color="#D12F5F"/></linearGradient><linearGradient id="prefix__e" gradientUnits="userSpaceOnUse" x1="249.206" y1="171.167" x2="311.754" y2="171.167"><stop offset="0" stop-color="#B4197C"/><stop offset="1" stop-color="#472EAD"/></linearGradient><linearGradient id="prefix__f" gradientUnits="userSpaceOnUse" x1="324.779" y1="171.168" x2="387.329" y2="171.168"><stop offset="0" stop-color="#2839BA"/><stop offset="1" stop-color="#3072B7"/></linearGradient><linearGradient id="prefix__g" gradientUnits="userSpaceOnUse" x1="253.733" y1="213.908" x2="321.188" y2="233.63"><stop offset="0" stop-color="#B4197C"/><stop offset="1" stop-color="#373AAC"/></linearGradient><linearGradient id="prefix__h" gradientUnits="userSpaceOnUse" x1="167.193" y1="260.816" x2="234.158" y2="236.453"><stop offset="0" stop-color="#FFCB00"/><stop offset="1" stop-color="#D12F5F"/></linearGradient><linearGradient id="prefix__i" gradientUnits="userSpaceOnUse" x1="215.628" y1="339.641" x2="267.598" y2="291.676"><stop offset="0" stop-color="#FFCF00"/><stop offset="1" stop-color="#ED743B"/></linearGradient></defs><path d="M105 0h302c57.928.155 104.845 47.072 105 104.996V407c-.155 57.926-47.072 104.844-104.996 104.998L105 512C47.074 511.844.156 464.926.002 407.003L0 105C.156 47.072 47.074.155 104.997 0H105z"/><path fill="#29AB70" d="M387.327 152.62h-62.552v36.506h62.552z"/><path fill="url(#prefix__a)" d="M324.779 203.448h62.548v36.518h-62.548z"/><path fill="url(#prefix__b)" d="M324.745 254.294h62.543v36.513h-62.543z"/><path fill="url(#prefix__c)" d="M98.037 305.092h62.549v36.528H98.037z"/><path fill="url(#prefix__d)" d="M173.609 305.092h62.549v36.528h-62.549z"/><path fill="url(#prefix__e)" d="M249.206 305.092h62.549v36.528h-62.549z"/><path fill="url(#prefix__f)" d="M324.779 305.091h62.55v36.53h-62.55z"/><path fill="url(#prefix__g)" d="M249.206 254.242h62.548v36.475h-62.548z"/><path fill="url(#prefix__h)" d="M173.601 254.273h62.566v36.485h-62.566z"/><path fill="url(#prefix__i)" d="M173.625 203.462h62.517v36.492h-62.517z"/></svg>
diff --git a/music_assistant/server/providers/dlna/icon.png b/music_assistant/server/providers/dlna/icon.png
deleted file mode 100644 (file)
index 14c34a4..0000000
Binary files a/music_assistant/server/providers/dlna/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/dlna/icon.svg b/music_assistant/server/providers/dlna/icon.svg
new file mode 100755 (executable)
index 0000000..10e19ef
--- /dev/null
@@ -0,0 +1,3 @@
+<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.1665 21.9022C7.84476 21.5378 5.56352 20.4202 4.00848 18.8854C3.47569 18.3595 3.43927 18.3076 3.45642 18.0976C3.48828 17.7075 3.43013 17.7138 6.98871 17.714C10.5313 17.714 10.6981 17.7287 11.4291 18.1005C11.7345 18.2559 11.9955 18.4747 12.5115 19.0082C13.452 19.9804 13.9907 20.227 15.0225 20.1576C15.6386 20.1162 16.114 19.9338 16.5999 19.5526C18.1253 18.3556 18.1253 15.9318 16.5999 14.7348C16.0779 14.3252 15.6423 14.167 14.9332 14.1297C13.9321 14.0769 13.3736 14.3466 12.458 15.3249C12.0491 15.7618 11.7985 15.9708 11.4804 16.1401C10.7024 16.5543 10.8273 16.5438 6.6526 16.5438H2.86366L2.52755 16.3796C2.10792 16.1745 1.89097 15.9502 1.66513 15.488C1.21208 14.5606 1.00037 13.4768 1 12.0828C0.999609 10.6391 1.28851 9.17976 1.73179 8.3862C1.93859 8.01598 2.33458 7.70094 2.75902 7.56895C3.18116 7.43769 10.1586 7.44557 10.7019 7.57793C11.3888 7.74527 11.7868 8.00512 12.4888 8.74454C12.9931 9.27582 13.2167 9.46278 13.5334 9.6183C14.7074 10.1948 15.9648 9.96823 16.884 9.01457C17.5452 8.32868 17.7848 7.6561 17.729 6.64356C17.7016 6.14806 17.6688 6.02184 17.4468 5.55889C16.7715 4.15088 15.2237 3.49487 13.8332 4.02734C13.3099 4.22773 13.0553 4.42066 12.3971 5.11545C11.7578 5.79025 11.3333 6.06776 10.7148 6.215C10.5454 6.25535 9.16383 6.28065 7.0787 6.28161C3.34562 6.28332 3.44458 6.29413 3.44388 5.88493C3.44359 5.71455 3.52244 5.60501 3.95261 5.17816C5.16372 3.9764 6.87268 2.97953 8.60415 2.46482C9.64901 2.15422 10.4215 2.04102 11.7249 2.00753C13.1133 1.97185 13.9277 2.05834 15.1194 2.36803C18.5393 3.25682 21.2933 5.60754 22.4801 8.651C22.7276 9.28574 23 10.3016 23 10.59C23 10.9149 22.8201 11.2127 22.5463 11.3412C22.3107 11.4518 22.0379 11.4581 17.4999 11.4584C12.2197 11.4587 12.2173 11.4586 11.4499 11.0724C11.1458 10.9193 10.9018 10.7139 10.409 10.196C9.73955 9.49239 9.38402 9.24803 8.79151 9.08425C8.38185 8.97101 7.70716 8.97632 7.26128 9.09629C5.87257 9.46992 4.90505 11.0192 5.14385 12.4869C5.43295 14.2637 7.12291 15.4117 8.78937 14.9632C9.38392 14.8032 9.72805 14.5666 10.411 13.8485C10.9194 13.314 11.1363 13.1334 11.4553 12.9792C12.2411 12.5992 12.2329 12.5997 17.5305 12.5986C22.9666 12.5975 22.6695 12.5716 22.9035 13.067C23.009 13.2903 23.0138 13.359 22.9501 13.7428C22.7712 14.8206 22.1317 16.3376 21.4342 17.3384C19.7464 19.7605 16.9625 21.446 13.8865 21.9081C13.0536 22.0332 10.9805 22.0299 10.1665 21.9022Z" fill="#4AAA42"/>
+</svg>
index a5eea0be98fdedf65c140d8b77bd6c0ac58e7e09..b637e98072a9436cd48e76037fe83524159463d6 100644 (file)
@@ -8,5 +8,6 @@
   "documentation": "https://github.com/music-assistant/hass-music-assistant/discussions/1139",
   "multi_instance": false,
   "builtin": false,
-  "load_by_default": true
+  "load_by_default": true,
+  "icon": "dlna"
 }
index 092c12278758ad4659133ba6c6908feac8291c6e..fcac306e1bbfed40694549c9994c7458365d1934 100644 (file)
@@ -9,5 +9,5 @@
   "multi_instance": false,
   "builtin": true,
   "load_by_default": true,
-  "icon": "mdi-folder-information"
+  "icon": "folder-information"
 }
index 16ad423a782f7d241e0aa9acd1e17eb9bd07f2b1..5f8a6a292ce9c06bd75e7fc7947b69655b9b09b3 100644 (file)
@@ -7,5 +7,5 @@
   "requirements": [],
   "documentation": "https://github.com/music-assistant/hass-music-assistant/discussions/820",
   "multi_instance": true,
-  "icon": "mdi:mdi-harddisk"
+  "icon": "harddisk"
 }
index 4566279e4e611b3f05e55b56d0c34e92839d3b45..88981a6d18565f198bbbc5a7da07a024b3dc01b1 100644 (file)
@@ -7,5 +7,5 @@
     "requirements": [],
     "documentation": "https://github.com/music-assistant/hass-music-assistant/discussions/820",
     "multi_instance": true,
-    "icon": "mdi:mdi-network"
+    "icon": "network"
   }
diff --git a/music_assistant/server/providers/musicbrainz/icon.svg b/music_assistant/server/providers/musicbrainz/icon.svg
new file mode 100644 (file)
index 0000000..fde0f68
--- /dev/null
@@ -0,0 +1 @@
+<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>MusicBrainz</title><path d="M11.582 0L1.418 5.832v12.336L11.582 24V10.01L7.1 12.668v3.664c.01.111.01.225 0 .336-.103.435-.54.804-1 1.111-.802.537-1.752.509-2.166-.111-.413-.62-.141-1.631.666-2.168.384-.28.863-.399 1.334-.332V6.619c0-.154.134-.252.226-.308L11.582 3zm.836 0v6.162c.574.03 1.14.16 1.668.387a2.225 2.225 0 0 0 1.656-.717 1.02 1.02 0 1 1 1.832-.803l.004.006a1.022 1.022 0 0 1-1.295 1.197c-.34.403-.792.698-1.297.85.34.263.641.576.891.928a1.04 1.04 0 0 1 .777.125c.768.486.568 1.657-.318 1.857-.886.2-1.574-.77-1.09-1.539.02-.03.042-.06.065-.09a3.598 3.598 0 0 0-1.436-1.166 4.142 4.142 0 0 0-1.457-.369v4.01c.855.06 1.256.493 1.555.834.227.256.356.39.578.402.323.018.568.008.806 0a5.44 5.44 0 0 1 .895.022c.94-.017 1.272-.226 1.605-.446a2.533 2.533 0 0 1 1.131-.463 1.027 1.027 0 0 1 .12-.263 1.04 1.04 0 0 1 .105-.137c.023-.025.047-.044.07-.066a4.775 4.775 0 0 1 0-2.405l-.012-.01a1.02 1.02 0 1 1 .692.272h-.057a4.288 4.288 0 0 0 0 1.877h.063a1.02 1.02 0 1 1-.545 1.883l-.047-.033a1 1 0 0 1-.352-.442 1.885 1.885 0 0 0-.814.354 3.03 3.03 0 0 1-.703.365c.757.555 1.772 1.6 2.199 2.299a1.03 1.03 0 0 1 .256-.033 1.02 1.02 0 1 1-.545 1.88l-.047-.03a1.017 1.017 0 0 1-.27-1.376.72.72 0 0 1 .051-.072c-.445-.775-2.026-2.28-2.46-2.387a4.037 4.037 0 0 0-1.31-.117c-.24.008-.513.018-.866 0-.515-.027-.783-.333-1.043-.629-.26-.296-.51-.56-1.055-.611V18.5a1.877 1.877 0 0 0 .426-.135.333.333 0 0 1 .058-.027c.56-.267 1.421-.91 2.096-2.447a1.02 1.02 0 0 1-.27-1.344 1.02 1.02 0 1 1 .915 1.54 6.273 6.273 0 0 1-1.432 2.136 1.785 1.785 0 0 1 .691.306.667.667 0 0 0 .37.168 3.31 3.31 0 0 0 .888-.222 1.02 1.02 0 0 1 1.787-.79v-.005a1.02 1.02 0 0 1-.773 1.683 1.022 1.022 0 0 1-.719-.287 3.935 3.935 0 0 1-1.168.287h-.05a1.313 1.313 0 0 1-.71-.275c-.262-.177-.51-.345-1.402-.12a2.098 2.098 0 0 1-.707.2V24l10.164-5.832V5.832zm4.154 4.904a.352.352 0 0 0-.197.639l.018.01c.163.1.378.053.484-.108v-.002a.352.352 0 0 0-.303-.539zm-4.99 1.928L7.082 9.5v2l4.5-2.668zm8.385.38a.352.352 0 0 0-.295.165v.002a.35.35 0 0 0 .096.473l.013.01a.357.357 0 0 0 .487-.108.352.352 0 0 0-.301-.541zM16.09 8.647a.352.352 0 0 0-.277.163.355.355 0 0 0 .296.54c.482 0 .463-.73-.02-.703zm3.877 2.477a.352.352 0 0 0-.295.164.35.35 0 0 0 .094.475l.015.01a.357.357 0 0 0 .485-.11.352.352 0 0 0-.3-.539zm-4.375 3.594a.352.352 0 0 0-.291.172.35.35 0 0 0-.04.265.352.352 0 1 0 .33-.437zm4.375.789a.352.352 0 0 0-.295.164v.002a.352.352 0 0 0 .094.473l.015.01a.357.357 0 0 0 .485-.108.352.352 0 0 0-.3-.54zm-2.803 2.488v.002a.347.347 0 0 0-.223.084.352.352 0 0 0 .23.62.347.347 0 0 0 .23-.085.348.348 0 0 0 .12-.24.353.353 0 0 0-.35-.38.347.347 0 0 0-.007 0Z"/></svg>
diff --git a/music_assistant/server/providers/musicbrainz/icon_dark.svg b/music_assistant/server/providers/musicbrainz/icon_dark.svg
new file mode 100644 (file)
index 0000000..249e9ad
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg fill="#ffffff" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff">
+
+<g id="SVGRepo_bgCarrier" stroke-width="0"/>
+
+<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
+
+<g id="SVGRepo_iconCarrier">
+
+<title>MusicBrainz icon</title>
+
+<path d="M11.582 0L1.418 5.832v12.336L11.582 24V10.01L7.1 12.668v3.664c.01.111.01.225 0 .336-.103.435-.54.804-1 1.111-.802.537-1.752.509-2.166-.111-.413-.62-.141-1.631.666-2.168.384-.28.863-.399 1.334-.332V6.619c0-.154.134-.252.226-.308L11.582 3zm.836 0v6.162c.574.03 1.14.16 1.668.387a2.225 2.225 0 0 0 1.656-.717 1.02 1.02 0 1 1 1.832-.803l.004.006a1.022 1.022 0 0 1-1.295 1.197c-.34.403-.792.698-1.297.85.34.263.641.576.891.928a1.04 1.04 0 0 1 .777.125c.768.486.568 1.657-.318 1.857-.886.2-1.574-.77-1.09-1.539.02-.03.042-.06.065-.09a3.598 3.598 0 0 0-1.436-1.166 4.142 4.142 0 0 0-1.457-.369v4.01c.855.06 1.256.493 1.555.834.227.256.356.39.578.402.323.018.568.008.806 0a5.44 5.44 0 0 1 .895.022c.94-.017 1.272-.226 1.605-.446a2.533 2.533 0 0 1 1.131-.463 1.027 1.027 0 0 1 .12-.263 1.04 1.04 0 0 1 .105-.137c.023-.025.047-.044.07-.066a4.775 4.775 0 0 1 0-2.405l-.012-.01a1.02 1.02 0 1 1 .692.272h-.057a4.288 4.288 0 0 0 0 1.877h.063a1.02 1.02 0 1 1-.545 1.883l-.047-.033a1 1 0 0 1-.352-.442 1.885 1.885 0 0 0-.814.354 3.03 3.03 0 0 1-.703.365c.757.555 1.772 1.6 2.199 2.299a1.03 1.03 0 0 1 .256-.033 1.02 1.02 0 1 1-.545 1.88l-.047-.03a1.017 1.017 0 0 1-.27-1.376.72.72 0 0 1 .051-.072c-.445-.775-2.026-2.28-2.46-2.387a4.037 4.037 0 0 0-1.31-.117c-.24.008-.513.018-.866 0-.515-.027-.783-.333-1.043-.629-.26-.296-.51-.56-1.055-.611V18.5a1.877 1.877 0 0 0 .426-.135.333.333 0 0 1 .058-.027c.56-.267 1.421-.91 2.096-2.447a1.02 1.02 0 0 1-.27-1.344 1.02 1.02 0 1 1 .915 1.54 6.273 6.273 0 0 1-1.432 2.136 1.785 1.785 0 0 1 .691.306.667.667 0 0 0 .37.168 3.31 3.31 0 0 0 .888-.222 1.02 1.02 0 0 1 1.787-.79v-.005a1.02 1.02 0 0 1-.773 1.683 1.022 1.022 0 0 1-.719-.287 3.935 3.935 0 0 1-1.168.287h-.05a1.313 1.313 0 0 1-.71-.275c-.262-.177-.51-.345-1.402-.12a2.098 2.098 0 0 1-.707.2V24l10.164-5.832V5.832zm4.154 4.904a.352.352 0 0 0-.197.639l.018.01c.163.1.378.053.484-.108v-.002a.352.352 0 0 0-.303-.539zm-4.99 1.928L7.082 9.5v2l4.5-2.668zm8.385.38a.352.352 0 0 0-.295.165v.002a.35.35 0 0 0 .096.473l.013.01a.357.357 0 0 0 .487-.108.352.352 0 0 0-.301-.541zM16.09 8.647a.352.352 0 0 0-.277.163.355.355 0 0 0 .296.54c.482 0 .463-.73-.02-.703zm3.877 2.477a.352.352 0 0 0-.295.164.35.35 0 0 0 .094.475l.015.01a.357.357 0 0 0 .485-.11.352.352 0 0 0-.3-.539zm-4.375 3.594a.352.352 0 0 0-.291.172.35.35 0 0 0-.04.265.352.352 0 1 0 .33-.437zm4.375.789a.352.352 0 0 0-.295.164v.002a.352.352 0 0 0 .094.473l.015.01a.357.357 0 0 0 .485-.108.352.352 0 0 0-.3-.54zm-2.803 2.488v.002a.347.347 0 0 0-.223.084.352.352 0 0 0 .23.62.347.347 0 0 0 .23-.085.348.348 0 0 0 .12-.24.353.353 0 0 0-.35-.38.347.347 0 0 0-.007 0Z"/>
+
+</g>
+
+</svg>
diff --git a/music_assistant/server/providers/plex/icon.png b/music_assistant/server/providers/plex/icon.png
deleted file mode 100644 (file)
index 85bf53f..0000000
Binary files a/music_assistant/server/providers/plex/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/plex/icon.svg b/music_assistant/server/providers/plex/icon.svg
new file mode 100644 (file)
index 0000000..7c994b8
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 122.88" style="enable-background:new 0 0 122.88 122.88" xml:space="preserve"><style type="text/css"><![CDATA[\r
+       .st0{fill:#E5A00D;}\r
+       .st1{fill:#282A2D;}\r
+]]></style><g><path class="st1" d="M18.43,0h86.02c10.18,0,18.43,8.25,18.43,18.43v86.02c0,10.18-8.25,18.43-18.43,18.43H18.43 C8.25,122.88,0,114.63,0,104.45l0-86.02C0,8.25,8.25,0,18.43,0L18.43,0z"/><polygon class="st0" points="61.44,16.8 35.52,16.8 61.44,61.44 35.52,106.08 61.44,106.08 87.36,61.44 61.44,16.8"/></g></svg>
diff --git a/music_assistant/server/providers/qobuz/icon.png b/music_assistant/server/providers/qobuz/icon.png
deleted file mode 100644 (file)
index 9d7b726..0000000
Binary files a/music_assistant/server/providers/qobuz/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/qobuz/icon.svg b/music_assistant/server/providers/qobuz/icon.svg
new file mode 100755 (executable)
index 0000000..38d3349
--- /dev/null
@@ -0,0 +1,4 @@
+<svg viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 13.4434C12.521 13.4434 12.9434 13.021 12.9434 12.5C12.9434 11.979 12.521 11.5566 12 11.5566C11.479 11.5566 11.0566 11.979 11.0566 12.5C11.0566 13.021 11.479 13.4434 12 13.4434ZM12 15.7075C13.7715 15.7075 15.2075 14.2715 15.2075 12.5C15.2075 10.7285 13.7715 9.29245 12 9.29245C10.2285 9.29245 8.79245 10.7285 8.79245 12.5C8.79245 14.2715 10.2285 15.7075 12 15.7075Z" fill="black"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.5C17.5228 2.5 22 6.97715 22 12.5C22 14.8535 21.1869 17.0172 19.8264 18.7254L21.9029 20.8019L20.3019 22.4029L18.2254 20.3264C16.5172 21.6869 14.3535 22.5 12 22.5C6.47715 22.5 2 18.0228 2 12.5C2 6.97715 6.47715 2.5 12 2.5ZM19.7358 12.5C19.7358 8.22761 16.2724 4.76415 12 4.76415C7.72761 4.76415 4.26415 8.22761 4.26415 12.5C4.26415 16.7724 7.72761 20.2358 12 20.2358C13.7278 20.2358 15.3234 19.6694 16.611 18.712L15.1618 17.2628C14.7197 16.8207 14.7197 16.1039 15.1618 15.6618C15.6039 15.2197 16.3207 15.2197 16.7628 15.6618L18.212 17.111C19.1694 15.8234 19.7358 14.2278 19.7358 12.5Z" fill="black"/>
+</svg>
diff --git a/music_assistant/server/providers/qobuz/icon_dark.svg b/music_assistant/server/providers/qobuz/icon_dark.svg
new file mode 100755 (executable)
index 0000000..2fc68c8
--- /dev/null
@@ -0,0 +1,4 @@
+<svg viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 13.4434C12.521 13.4434 12.9434 13.021 12.9434 12.5C12.9434 11.979 12.521 11.5566 12 11.5566C11.479 11.5566 11.0566 11.979 11.0566 12.5C11.0566 13.021 11.479 13.4434 12 13.4434ZM12 15.7075C13.7715 15.7075 15.2075 14.2715 15.2075 12.5C15.2075 10.7285 13.7715 9.29245 12 9.29245C10.2285 9.29245 8.79245 10.7285 8.79245 12.5C8.79245 14.2715 10.2285 15.7075 12 15.7075Z" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.5C17.5228 2.5 22 6.97715 22 12.5C22 14.8535 21.1869 17.0172 19.8264 18.7254L21.9029 20.8019L20.3019 22.4029L18.2254 20.3264C16.5172 21.6869 14.3535 22.5 12 22.5C6.47715 22.5 2 18.0228 2 12.5C2 6.97715 6.47715 2.5 12 2.5ZM19.7358 12.5C19.7358 8.22761 16.2724 4.76415 12 4.76415C7.72761 4.76415 4.26415 8.22761 4.26415 12.5C4.26415 16.7724 7.72761 20.2358 12 20.2358C13.7278 20.2358 15.3234 19.6694 16.611 18.712L15.1618 17.2628C14.7197 16.8207 14.7197 16.1039 15.1618 15.6618C15.6039 15.2197 16.3207 15.2197 16.7628 15.6618L18.212 17.111C19.1694 15.8234 19.7358 14.2278 19.7358 12.5Z" fill="white"/>
+</svg>
diff --git a/music_assistant/server/providers/radiobrowser/icon.png b/music_assistant/server/providers/radiobrowser/icon.png
deleted file mode 100644 (file)
index 20672a2..0000000
Binary files a/music_assistant/server/providers/radiobrowser/icon.png and /dev/null differ
index e2760875cacaf75c2484c98e5a8b62ea63fe5b42..6e00344edee6bf519d46e533678e7be0d85d47d7 100644 (file)
@@ -6,5 +6,6 @@
   "codeowners": ["@gieljnssns"],
   "requirements": ["git+https://github.com/gieljnssns/python-radios.git@main"],
   "documentation": "https://github.com/orgs/music-assistant/discussions/1202",
-  "multi_instance": false
+  "multi_instance": false,
+  "icon": "radio"
 }
index 0e172ff364592b4859ebc01c009be075595e3ef6..bc3232d328cbb4c2a1c5bd73db456311026c64ef 100644 (file)
@@ -745,7 +745,7 @@ class LmsCli:
             players.append(player_item_from_mass(start_index + index, mass_player))
         return ServerStatusResponse(
             {
-                "httpport": self.mass.streams.port,
+                "httpport": self.mass.streams.publish_port,
                 "ip": self.mass.streams.publish_ip,
                 "version": "7.999.999",
                 "uuid": self.mass.server_id,
diff --git a/music_assistant/server/providers/slimproto/icon.png b/music_assistant/server/providers/slimproto/icon.png
deleted file mode 100644 (file)
index 18531d7..0000000
Binary files a/music_assistant/server/providers/slimproto/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/slimproto/icon.svg b/music_assistant/server/providers/slimproto/icon.svg
new file mode 100755 (executable)
index 0000000..20dc9b9
--- /dev/null
@@ -0,0 +1,5 @@
+<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.49875 4.68702C5.49875 4.30759 5.79351 4 6.15711 4H13.8379C14.2015 4 14.4963 4.30759 14.4963 4.68702V16.6527C14.4963 16.7104 14.4931 16.7677 14.4869 16.8244C14.355 18.0406 12.8466 19 11.5885 19C10.1621 19 8.6808 18.2926 8.6808 16.6527C8.6808 15.0128 9.99751 14.1908 11.3691 14.1908C12.018 14.1908 12.6531 14.3811 13.1796 14.6935V8.23664C13.1796 7.92045 12.9339 7.66412 12.6309 7.66412H7.36409C7.06109 7.66412 6.81546 7.92045 6.81546 8.23664V16.6527C6.81546 17.9491 5.22444 19 3.90773 19C2.4813 19 1 18.2926 1 16.6527C1 15.0128 2.31671 14.1908 3.68828 14.1908C4.33718 14.1908 4.97227 14.3811 5.49875 14.6935V4.68702Z" fill="#2BAAA6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5028 7.51765C16.8893 7.16236 17.4787 7.20133 17.8191 7.6047C18.7211 8.67335 19.2693 10.0783 19.2693 11.6145C19.2693 13.1507 18.7211 14.5557 17.8191 15.6243C17.4787 16.0277 16.8893 16.0667 16.5028 15.7114C16.1163 15.3561 16.0789 14.7411 16.4194 14.3377C17.0329 13.6108 17.404 12.6591 17.404 11.6145C17.404 10.5699 17.0329 9.61818 16.4194 8.89133C16.0789 8.48796 16.1163 7.87294 16.5028 7.51765Z" fill="#2BAAA6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M19.2531 4.87572C19.638 4.51854 20.2275 4.55463 20.5698 4.95632C22.081 6.72989 23 9.06177 23 11.6145C23 14.1672 22.081 16.4991 20.5698 18.2727C20.2275 18.6744 19.638 18.7105 19.2531 18.3533C18.8681 17.9961 18.8336 17.3809 19.1758 16.9792C20.3965 15.5466 21.1347 13.6702 21.1347 11.6145C21.1347 9.55882 20.3965 7.68239 19.1758 6.24978C18.8336 5.84809 18.8681 5.2329 19.2531 4.87572Z" fill="#2BAAA6"/>
+</svg>
diff --git a/music_assistant/server/providers/sonos/icon.png b/music_assistant/server/providers/sonos/icon.png
deleted file mode 100644 (file)
index d00f12a..0000000
Binary files a/music_assistant/server/providers/sonos/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/sonos/icon.svg b/music_assistant/server/providers/sonos/icon.svg
new file mode 100644 (file)
index 0000000..60d9e67
--- /dev/null
@@ -0,0 +1,11 @@
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" version="1.1" viewBox="6.4552e-5 0 500 500" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+    <g transform="matrix(.48835 0 0 .48835 -880 0)">
+        <path d="m2595.5 0h-563.12c-127.23 0-230.37 103.14-230.37 230.37v563.12c0 127.23 103.14 230.37 230.37 230.37h563.12c127.23 0 230.37-103.14 230.37-230.37v-563.12c0-127.23-103.14-230.37-230.37-230.37z" fill="#fff" fill-rule="nonzero"/>
+    </g>
+    <g transform="matrix(.48835 0 0 .48835 -880 0)">
+        <path d="m2595.5 0h-563.12c-127.23 0-230.37 103.14-230.37 230.37v563.12c0 127.23 103.14 230.37 230.37 230.37h563.12c127.23 0 230.37-103.14 230.37-230.37v-563.12c0-127.23-103.14-230.37-230.37-230.37z" fill="#d8a158" fill-rule="nonzero"/>
+    </g>
+    <g transform="matrix(.48835 0 0 .48835 .73081 .53181)">
+        <path d="m319.09 429.94c-44.956 0-81.54 36.19-81.54 80.68 0 44.478 36.584 80.67 81.54 80.67 44.952 0 81.526-36.192 81.526-80.67 0-44.49-36.574-80.68-81.526-80.68zm2e-3 132.37c-28.512 0-51.694-23.182-51.694-51.68 0-28.502 23.182-51.684 51.694-51.684 28.508 0 51.702 23.182 51.702 51.684 0 28.498-23.194 51.68-51.702 51.68zm225.94-39.882-98.286-90.664v153.72h29.122v-85.834l98.29 90.528v-154.11h-29.126v86.362zm-390.15-25.794c15.172 4.764 25.351 9.486 33.084 15.324 11.525 8.692 17.368 19.834 17.368 33.072 0 12.342-5.771 24.376-15.84 33.026-10.114 8.664-23.991 13.452-39.089 13.452-31.416 0-49.471-20.83-50.217-21.704l-2.568-3.008 23.489-15.692 2.038 1.502c3.78 2.804 14.024 9.326 27.258 9.326 15.673 0 25.047-8.588 25.047-16.902 0-3.54 0-10.904-29.522-20.188-15.179-4.77-25.351-9.488-33.085-15.326-11.529-8.692-17.382-19.824-17.382-33.072 0-12.344 5.776-24.378 15.849-33.026 10.106-8.676 23.983-13.454 39.084-13.454 31.413 0 49.468 20.816 50.228 21.706l2.554 3.01-23.474 15.692-2.038-1.508c-3.797-2.808-14.063-9.33-27.27-9.33-15.673 0-25.04 8.6-25.04 16.91 0 3.542 0 10.902 29.526 20.19zm546.92-66.094c-44.946 0-81.52 36.192-81.52 80.676s36.574 80.674 81.52 80.674c44.968 0 81.542-36.19 81.542-80.674s-36.574-80.676-81.542-80.676zm-4e-3 132.36c-28.506 0-51.688-23.19-51.688-51.684 0-28.492 23.182-51.674 51.688-51.674s51.7 23.182 51.7 51.674c0 28.494-23.194 51.684-51.7 51.684zm164.22-37.692c-15.184-4.778-25.354-9.496-33.09-15.334-11.526-8.698-17.354-19.826-17.354-33.076 0-12.33 5.764-24.368 15.832-33.024 10.112-8.676 23.988-13.454 39.088-13.454 31.41 0 49.47 20.828 50.214 21.706l2.562 3.012-23.478 15.7-2.04-1.512c-3.792-2.8-14.02-9.324-27.258-9.324-15.68 0-25.052 8.588-25.052 16.896 0 3.544 0 10.906 29.528 20.192 15.182 4.762 25.356 9.486 33.088 15.324 11.526 8.694 17.364 19.832 17.364 33.072 0 12.348-5.77 24.38-15.842 33.024-10.104 8.68-23.98 13.458-39.086 13.458-31.412 0-49.462-20.82-50.214-21.706l-2.566-3.016 23.482-15.682 2.038 1.498c3.792 2.808 14.058 9.332 27.26 9.332 15.678 0 25.05-8.596 25.05-16.908 0-3.54 0-10.906-29.526-20.178z"/>
+    </g>
+</svg>
diff --git a/music_assistant/server/providers/soundcloud/icon.png b/music_assistant/server/providers/soundcloud/icon.png
deleted file mode 100644 (file)
index e9dde20..0000000
Binary files a/music_assistant/server/providers/soundcloud/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/soundcloud/icon.svg b/music_assistant/server/providers/soundcloud/icon.svg
new file mode 100644 (file)
index 0000000..446f2a1
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#f50"/><path d="m59 270-3 22 3 22c0 2 3 2 3 0l3-22-3-22c0-3-3-3-3 0zm18-14c0-3-3-3-3 0l-5 36 4 35c0 3 4 3 4 0l4-35zm59-30-3 66 2 40c0 8 7 8 7 0l4-40-4-66c0-5-6-5-6 0zm-31 22-4 44 3 40c0 6 5 6 5 0l4-40-4-44c0-3-4-3-4 0zm70 84 3-40-3-88c0-6-7-6-7 0l-3 88 2 40c0 8 8 8 8 0zm68 0 2-40-2-102c0-7-10-7-10 0l-2 102 2 40c0 8 10 8 10 0zm-34 0 3-40-3-89c0-6-9-6-9 0l-2 89 2 40c0 8 9 8 9 0zm-83 0 3-40-3-41c0-3-6-3-6 0l-3 41 3 40c0 7 6 7 6 0zm-33 0 4-40-4-43c0-3-4-3-4 0l-4 43 4 40c0 4 4 4 4 0zm124-125-2 85 1 40c0 8 10 8 10 0l2-40-2-85c0-7-9-7-9 0zm-58 125 3-40-3-81c0-6-7-6-7 0l-3 81 2 40c0 8 8 8 8 0zm33 0 3-40-3-91c0-6-8-6-8 0l-3 91 3 40c0 8 8 8 8 0zm196-89c-5-57-64-94-118-73-4 2-5 3-5 6v156c0 3 2 6 5 6h137c27 0 49-22 49-49 0-37-35-57-68-46zm-138-62-3 111 3 40c0 8 10 8 10 0l3-40-3-111c0-7-10-7-10 0z" fill="#fff"/></svg>
diff --git a/music_assistant/server/providers/spotify/icon.png b/music_assistant/server/providers/spotify/icon.png
deleted file mode 100644 (file)
index 1ed4049..0000000
Binary files a/music_assistant/server/providers/spotify/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/spotify/icon.svg b/music_assistant/server/providers/spotify/icon.svg
new file mode 100644 (file)
index 0000000..843cf99
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1333.33 1333.3" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><path d="M666.66 0C298.48 0 0 298.47 0 666.65c0 368.19 298.48 666.65 666.66 666.65 368.22 0 666.67-298.45 666.67-666.65C1333.33 298.49 1034.88.03 666.65.03l.01-.04zm305.73 961.51c-11.94 19.58-37.57 25.8-57.16 13.77-156.52-95.61-353.57-117.26-585.63-64.24-22.36 5.09-44.65-8.92-49.75-31.29-5.12-22.37 8.84-44.66 31.26-49.75 253.95-58.02 471.78-33.04 647.51 74.35 19.59 12.02 25.8 37.57 13.77 57.16zm81.6-181.52c-15.05 24.45-47.05 32.17-71.49 17.13-179.2-110.15-452.35-142.05-664.31-77.7-27.49 8.3-56.52-7.19-64.86-34.63-8.28-27.49 7.22-56.46 34.66-64.82 242.11-73.46 543.1-37.88 748.89 88.58 24.44 15.05 32.16 47.05 17.12 71.46V780zm7.01-189.02c-214.87-127.62-569.36-139.35-774.5-77.09-32.94 9.99-67.78-8.6-77.76-41.55-9.98-32.96 8.6-67.77 41.56-77.78 235.49-71.49 626.96-57.68 874.34 89.18 29.69 17.59 39.41 55.85 21.81 85.44-17.52 29.63-55.89 39.4-85.42 21.8h-.03z" fill="#1ed760" fill-rule="nonzero"/></svg>
index 832c4a5b5599694650a3f598ae7d976c29b3b7db..43e7cf2227650f40f4fd11b9ad9b209127e67e4f 100644 (file)
@@ -9,5 +9,5 @@
   "multi_instance": false,
   "builtin": true,
   "load_by_default": true,
-  "icon": "mdi-folder-information"
+  "icon": "folder-information"
 }
diff --git a/music_assistant/server/providers/tidal/icon.png b/music_assistant/server/providers/tidal/icon.png
deleted file mode 100644 (file)
index 917bb96..0000000
Binary files a/music_assistant/server/providers/tidal/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/tidal/icon.svg b/music_assistant/server/providers/tidal/icon.svg
new file mode 100755 (executable)
index 0000000..8bf8e02
--- /dev/null
@@ -0,0 +1,6 @@
+<svg viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2 9.75L5.33333 6.5L8.66667 9.75L5.33333 13L2 9.75Z" fill="black"/>
+<path d="M8.66667 9.75L12 6.5L15.3333 9.75L12 13L8.66667 9.75Z" fill="black"/>
+<path d="M15.3333 9.75L18.6667 6.5L22 9.75L18.6667 13L15.3333 9.75Z" fill="black"/>
+<path d="M8.66667 16.25L12 13L15.3333 16.25L12 19.5L8.66667 16.25Z" fill="black"/>
+</svg>
diff --git a/music_assistant/server/providers/tidal/icon_dark.svg b/music_assistant/server/providers/tidal/icon_dark.svg
new file mode 100755 (executable)
index 0000000..889198f
--- /dev/null
@@ -0,0 +1,6 @@
+<svg viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2 9.75L5.33333 6.5L8.66667 9.75L5.33333 13L2 9.75Z" fill="white"/>
+<path d="M8.66667 9.75L12 6.5L15.3333 9.75L12 13L8.66667 9.75Z" fill="white"/>
+<path d="M15.3333 9.75L18.6667 6.5L22 9.75L18.6667 13L15.3333 9.75Z" fill="white"/>
+<path d="M8.66667 16.25L12 13L15.3333 16.25L12 19.5L8.66667 16.25Z" fill="white"/>
+</svg>
diff --git a/music_assistant/server/providers/tunein/icon.png b/music_assistant/server/providers/tunein/icon.png
deleted file mode 100644 (file)
index 18c537c..0000000
Binary files a/music_assistant/server/providers/tunein/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/tunein/icon.svg b/music_assistant/server/providers/tunein/icon.svg
new file mode 100644 (file)
index 0000000..55cc9fe
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 122.88" style="enable-background:new 0 0 122.88 122.88" xml:space="preserve"><style type="text/css"><![CDATA[\r
+       .st0{fill:#14D8CC;}\r
+       .st1{fill:#1C203C;}\r
+]]></style><g><path class="st1" d="M18.43,0h86.02c10.18,0,18.43,8.25,18.43,18.43v86.02c0,10.18-8.25,18.43-18.43,18.43H18.43 C8.25,122.88,0,114.63,0,104.45l0-86.02C0,8.25,8.25,0,18.43,0L18.43,0z"/><path class="st0" d="M71.52,36.48c-1.44,0-1.44,1.44-1.44,1.44v8.16H13.44C12,46.08,12,47.52,12,47.52v29.52 c0,1.44,1.44,1.44,1.44,1.44h58.08c1.44,0,1.44-1.44,1.44-1.44v-8.16h32.88c1.44,0,1.44-1.44,1.44-1.44V37.92 c0-1.44-1.44-1.44-1.44-1.44H71.52L71.52,36.48z M80.4,46.08h6.72v2.64l-2.16,0v8.16l2.4,0v2.64h-7.2v-2.64l2.16,0v-8.16l-1.92,0 V46.08L80.4,46.08L80.4,46.08z M89.28,46.08h3.12l2.88,8.16v-8.16h2.64v13.44h-2.88l-3.12-7.92v7.92h-2.64V46.08L89.28,46.08 L89.28,46.08z M14.88,48.96h55.2V75.6h-55.2V48.96L14.88,48.96z M22.08,55.68v2.64h2.88v10.56h2.64V58.32l2.88,0v-2.64H22.08 L22.08,55.68z M32.4,55.68v9.36c0,0,0,4.08,4.56,4.08s4.56-4.08,4.56-4.08v-9.36h-2.64v9.36c0,0,0,1.44-1.92,1.44 s-1.92-1.44-1.92-1.44v-9.36H32.4L32.4,55.68z M43.68,55.68v13.2h2.64v-7.44l2.64,7.44h3.36v-13.2h-2.88v7.44l-2.64-7.44H43.68 L43.68,55.68z M54.24,55.68v13.2h7.92v-2.64h-5.04V63.6h4.8v-2.64h-4.8v-2.64l4.8,0v-2.64H54.24L54.24,55.68z"/></g></svg>
index c8b38de30a9cf97d44f0f8b0efc6d3e29ce232cd..a2aeccea5a8ed85988caf44f6b7ca33ed6bd786a 100644 (file)
@@ -9,5 +9,5 @@
   "multi_instance": false,
   "builtin": false,
   "load_by_default": false,
-  "icon": "mdi:mdi-speaker-multiple"
+  "icon": "speaker-multiple"
 }
index 4a68a459d469922b94a1c0fe44e8c3e84b7747e0..3658a1db0bcc34251d0004dc1498026146506b04 100644 (file)
@@ -10,5 +10,5 @@
   "builtin": true,
   "hidden": true,
   "load_by_default": true,
-  "icon": "mdi:mdi-web"
+  "icon": "web"
 }
diff --git a/music_assistant/server/providers/ytmusic/icon.png b/music_assistant/server/providers/ytmusic/icon.png
deleted file mode 100644 (file)
index cf6726d..0000000
Binary files a/music_assistant/server/providers/ytmusic/icon.png and /dev/null differ
diff --git a/music_assistant/server/providers/ytmusic/icon.svg b/music_assistant/server/providers/ytmusic/icon.svg
new file mode 100755 (executable)
index 0000000..22ba913
--- /dev/null
@@ -0,0 +1,4 @@
+<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="12" cy="12" r="6" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22ZM10.1818 14.6136L14.6136 11.8864L10.1818 9.38636V14.6136ZM6.77273 12C6.77273 9.11364 9.11364 6.77273 12 6.77273C14.8864 6.77273 17.2273 9.11364 17.2273 12C17.2273 14.8864 14.8864 17.2273 12 17.2273C9.11364 17.2273 6.77273 14.8864 6.77273 12ZM12 7.22727C14.625 7.22727 16.7727 9.36364 16.7727 12C16.7727 14.6364 14.6364 16.7727 12 16.7727C9.36364 16.7727 7.22727 14.6364 7.22727 12C7.22727 9.36364 9.375 7.22727 12 7.22727Z" fill="#FF0000"/>
+</svg>
index 049298409b54312584019ed5990c11cb4f2e8ad0..99e79b09c8a26ba8ad0fb14dc655032ca25a3871 100644 (file)
@@ -24,6 +24,7 @@ from music_assistant.constants import (
     API_SCHEMA_VERSION,
     CONF_PROVIDERS,
     CONF_SERVER_ID,
+    CONFIGURABLE_CORE_CONTROLLERS,
     MIN_SCHEMA_VERSION,
     ROOT_LOGGER_NAME,
 )
@@ -48,6 +49,8 @@ from .models import ProviderInstanceType
 if TYPE_CHECKING:
     from types import TracebackType
 
+    from music_assistant.server.models.core_controller import CoreController
+
 EventCallBackType = Callable[[MassEvent], None]
 EventSubscriptionType = tuple[
     EventCallBackType, tuple[EventType, ...] | None, tuple[str, ...] | None
@@ -86,7 +89,7 @@ class MusicAssistant:
         # we dynamically register command handlers which can be consumed by the apis
         self.command_handlers: dict[str, APICommandHandler] = {}
         self._subscribers: set[EventSubscriptionType] = set()
-        self._available_providers: dict[str, ProviderManifest] = {}
+        self._provider_manifests: dict[str, ProviderManifest] = {}
         self._providers: dict[str, ProviderInstanceType] = {}
         self._tracked_tasks: dict[str, asyncio.Task] = {}
         self.closing = False
@@ -122,6 +125,10 @@ class MusicAssistant:
         self.players = PlayerController(self)
         self.player_queues = PlayerQueuesController(self)
         self.streams = StreamsController(self)
+        # add manifests for core controllers
+        for controller_name in CONFIGURABLE_CORE_CONTROLLERS:
+            controller: CoreController = getattr(self, controller_name)
+            self._provider_manifests[controller.domain] = controller.manifest
         await self.cache.setup(await self.config.get_core_config("cache"))
         await self.webserver.setup(await self.config.get_core_config("webserver"))
         await self.music.setup(await self.config.get_core_config("music"))
@@ -181,10 +188,10 @@ class MusicAssistant:
             homeassistant_addon=self.running_as_hass_addon,
         )
 
-    @api_command("providers/available")
-    def get_available_providers(self) -> list[ProviderManifest]:
-        """Return all available Providers."""
-        return list(self._available_providers.values())
+    @api_command("providers/manifests")
+    def get_provider_manifests(self) -> list[ProviderManifest]:
+        """Return all Provider manifests."""
+        return list(self._provider_manifests.values())
 
     @api_command("providers")
     def get_providers(
@@ -356,7 +363,7 @@ class MusicAssistant:
             raise SetupFailedError("Configuration is invalid") from err
 
         domain = conf.domain
-        prov_manifest = self._available_providers.get(domain)
+        prov_manifest = self._provider_manifests.get(domain)
         # check for other instances of this provider
         existing = next((x for x in self.providers if x.domain == domain), None)
         if existing and not prov_manifest.multi_instance:
@@ -437,10 +444,10 @@ class MusicAssistant:
     async def _load_providers(self) -> None:
         """Load providers from config."""
         # load all available providers from manifest files
-        await self.__load_available_providers()
+        await self.__load_provider_manifests()
 
         # create default config for any 'load_by_default' providers (e.g. URL provider)
-        for prov_manifest in self._available_providers.values():
+        for prov_manifest in self._provider_manifests.values():
             if not prov_manifest.load_by_default:
                 continue
             await self.config.create_default_provider_config(prov_manifest.domain)
@@ -469,7 +476,7 @@ class MusicAssistant:
                     continue
                 tg.create_task(load_provider(prov_conf))
 
-    async def __load_available_providers(self) -> None:
+    async def __load_provider_manifests(self) -> None:
         """Preload all available provider manifest files."""
         for dir_str in os.listdir(PROVIDERS_PATH):
             dir_path = os.path.join(PROVIDERS_PATH, dir_str)
@@ -484,21 +491,17 @@ class MusicAssistant:
                     continue
                 try:
                     provider_manifest = await ProviderManifest.parse(file_path)
-                    # check for icon file
-                    if not provider_manifest.icon:
-                        for icon_file in ("icon.svg", "icon.png"):
-                            icon_path = os.path.join(dir_path, icon_file)
-                            if os.path.isfile(icon_path):
-                                provider_manifest.icon = await get_icon_string(icon_path)
-                                break
+                    # check for icon.svg file
+                    if not provider_manifest.icon_svg:
+                        icon_path = os.path.join(dir_path, "icon.svg")
+                        if os.path.isfile(icon_path):
+                            provider_manifest.icon_svg = await get_icon_string(icon_path)
                     # check for dark_icon file
-                    if not provider_manifest.icon_dark:
-                        for icon_file in ("icon_dark.svg", "icon_dark.png"):
-                            icon_path = os.path.join(dir_path, icon_file)
-                            if os.path.isfile(icon_path):
-                                provider_manifest.icon_dark = await get_icon_string(icon_path)
-                                break
-                    self._available_providers[provider_manifest.domain] = provider_manifest
+                    if not provider_manifest.icon_svg_dark:
+                        icon_path = os.path.join(dir_path, "icon_dark.svg")
+                        if os.path.isfile(icon_path):
+                            provider_manifest.icon_svg_dark = await get_icon_string(icon_path)
+                    self._provider_manifests[provider_manifest.domain] = provider_manifest
                     LOGGER.debug("Loaded manifest for provider %s", dir_str)
                 except Exception as exc:  # pylint: disable=broad-except
                     LOGGER.exception(