A few small bugfixes (#753)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sat, 8 Jul 2023 12:44:03 +0000 (14:44 +0200)
committerGitHub <noreply@github.com>
Sat, 8 Jul 2023 12:44:03 +0000 (14:44 +0200)
* Fix typo in ProviderMappings resulting in wrong contenttype

* move preview stream into webserver

* Fix detection check of homeassistant addon

music_assistant/server/controllers/media/base.py
music_assistant/server/controllers/streams.py
music_assistant/server/controllers/webserver.py
music_assistant/server/helpers/util.py
music_assistant/server/server.py

index ad0cbcc8e5fa9842117236f5c22fa81ab015d490..e29bb3d0e29f1313a07a67f44c008b79c1aaa6ee 100644 (file)
@@ -573,7 +573,7 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
             return org_item.provider_mappings
         if overwrite and update_item.provider_mappings:
             return update_item.provider_mappings
-        return {*org_item.provider_mappings, *update_item.provider_mappings}
+        return {*update_item.provider_mappings, *org_item.provider_mappings}
 
     async def _get_artist_mappings(
         self,
index 91442b217853414f015395571687f8b4b0ba02e8..ce301b0d72570107d8f2680879bc701402096cf4 100644 (file)
@@ -38,7 +38,6 @@ from music_assistant.server.helpers.audio import (
     check_audio_support,
     crossfade_pcm_parts,
     get_media_stream,
-    get_preview_stream,
     get_stream_details,
 )
 from music_assistant.server.helpers.process import AsyncProcess
@@ -330,7 +329,6 @@ class StreamsController(CoreController):
             bind_port=self.publish_port,
             base_url=f"http://{self.publish_ip}:{self.publish_port}",
             static_routes=[
-                ("GET", "/preview", self.serve_preview_stream),
                 (
                     "GET",
                     "/{queue_id}/multi/{job_id}/{player_id}/{queue_item_id}.{fmt}",
@@ -729,17 +727,6 @@ class StreamsController(CoreController):
 
         return resp
 
-    async def serve_preview_stream(self, request: web.Request):
-        """Serve short preview sample."""
-        self._log_request(request)
-        provider_instance_id_or_domain = request.query["provider"]
-        item_id = urllib.parse.unquote(request.query["item_id"])
-        resp = web.StreamResponse(status=200, reason="OK", headers={"Content-Type": "audio/mp3"})
-        await resp.prepare(request)
-        async for chunk in get_preview_stream(self.mass, provider_instance_id_or_domain, item_id):
-            await resp.write(chunk)
-        return resp
-
     async def get_flow_stream(
         self,
         queue: PlayerQueue,
index b9d08dc661c5f48d3dadb8da0efc2bb024a67e75..a7c2a1e33295f1005ba280ad185b2bcf7834874a 100644 (file)
@@ -10,6 +10,7 @@ import asyncio
 import inspect
 import logging
 import os
+import urllib.parse
 from collections.abc import Awaitable
 from concurrent import futures
 from contextlib import suppress
@@ -33,6 +34,7 @@ from music_assistant.common.models.errors import InvalidCommand
 from music_assistant.common.models.event import MassEvent
 from music_assistant.constants import CONF_BIND_IP, CONF_BIND_PORT
 from music_assistant.server.helpers.api import APICommandHandler, parse_arguments
+from music_assistant.server.helpers.audio import get_preview_stream
 from music_assistant.server.helpers.util import get_ips
 from music_assistant.server.helpers.webserver import Webserver
 from music_assistant.server.models.core_controller import CoreController
@@ -81,7 +83,7 @@ class WebserverController(CoreController):
             # if a user also wants to expose a the webserver non securely on his internal
             # network he/she should open the port in the add-on config.
             internal_ip = next((x for x in await get_ips() if x.startswith("172")), await get_ip())
-            base_url = f"http://{internal_ip:8095}"
+            base_url = f"http://{internal_ip}:8095"
             return (
                 ConfigEntry(
                     key=CONF_BIND_PORT,
@@ -174,11 +176,13 @@ class WebserverController(CoreController):
         # also host the image proxy on the webserver
         routes.append(("GET", "/imageproxy", self.mass.metadata.handle_imageproxy))
         # also host the audio preview service
-        routes.append(("GET", "/preview", self.mass.streams.serve_preview_stream))
+        routes.append(("GET", "/preview", self.serve_preview_stream))
         # start the webserver
+        self.publish_port = config.get_value(CONF_BIND_PORT)
+        self.publish_ip = config.get_value(CONF_BIND_IP)
         await self._server.setup(
-            bind_ip=config.get_value(CONF_BIND_IP),
-            bind_port=config.get_value(CONF_BIND_PORT),
+            bind_ip=self.publish_ip,
+            bind_port=self.publish_port,
             base_url=config.get_value(CONF_BASE_URL),
             static_routes=routes,
             # add assets subdir as static_content
@@ -191,6 +195,17 @@ class WebserverController(CoreController):
             await client.disconnect()
         await self._server.close()
 
+    async def serve_preview_stream(self, request: web.Request):
+        """Serve short preview sample."""
+        self._log_request(request)
+        provider_instance_id_or_domain = request.query["provider"]
+        item_id = urllib.parse.unquote(request.query["item_id"])
+        resp = web.StreamResponse(status=200, reason="OK", headers={"Content-Type": "audio/mp3"})
+        await resp.prepare(request)
+        async for chunk in get_preview_stream(self.mass, provider_instance_id_or_domain, item_id):
+            await resp.write(chunk)
+        return resp
+
     async def _handle_server_info(self, request: web.Request) -> web.Response:  # noqa: ARG002
         """Handle request for server info."""
         return web.json_response(self.mass.get_server_info().to_dict())
index 504e74b17a1d78917531faaf94d363074883e8bc..c4299544d45e4d8f0763f0162195f252346d1134 100644 (file)
@@ -10,7 +10,6 @@ import tempfile
 import urllib.error
 import urllib.parse
 import urllib.request
-from contextlib import suppress
 from functools import lru_cache
 from importlib.metadata import PackageNotFoundError
 from importlib.metadata import version as pkg_version
@@ -73,11 +72,17 @@ async def get_ips(include_ipv6: bool = False) -> set[str]:
 
 async def is_hass_supervisor() -> bool:
     """Return if we're running inside the HA Supervisor (e.g. HAOS)."""
-    with suppress(urllib.error.URLError):
-        res = await asyncio.to_thread(urllib.request.urlopen, "http://supervisor/core")
-        # this should return a 401 unauthorized if it exists
-        return res.code == 401
-    return False
+
+    def _check():
+        try:
+            urllib.request.urlopen("http://supervisor/core")
+        except urllib.error.URLError as err:
+            # this should return a 401 unauthorized if it exists
+            return getattr(err, "code", 999) == 401
+        except Exception:
+            return False
+
+    return await asyncio.to_thread(_check)
 
 
 async def get_provider_module(domain: str) -> ProviderModuleType:
index 24a505cd35b0cbf2ac9b63ed9ce863bfe0254762..55c886906177c48b27a88e2389d53f276b53f350 100644 (file)
@@ -517,8 +517,8 @@ class MusicAssistant:
         info = ServiceInfo(
             zeroconf_type,
             name=f"{server_id}.{zeroconf_type}",
-            addresses=[await get_ip_pton(self.streams.publish_ip)],
-            port=self.streams.publish_port,
+            addresses=[await get_ip_pton(self.webserver.publish_ip)],
+            port=self.webserver.publish_port,
             properties=self.get_server_info().to_dict(),
             server="mass.local.",
         )