Skip to content

Commit

Permalink
Merge branch 'dev' into feature/podcastfeed
Browse files Browse the repository at this point in the history
  • Loading branch information
saeugetier authored Dec 18, 2024
2 parents ee2e491 + c33e766 commit dbe5ee4
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
path: dist/
- name: Publish release to PyPI
if: ${{ github.event.release.prerelease == false }}
uses: pypa/[email protected].2
uses: pypa/[email protected].3
with:
user: __token__
password: ${{ secrets.PYPI_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions music_assistant/controllers/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def __init__(self, *args, **kwargs) -> None:
"Music Assistant's core controller which handles all metadata for music."
)
self.manifest.icon = "book-information-variant"
self._lookup_jobs: MetadataLookupQueue = MetadataLookupQueue()
self._lookup_jobs: MetadataLookupQueue = MetadataLookupQueue(100)
self._lookup_task: asyncio.Task | None = None
self._throttler = Throttler(1, 30)
self._missing_metadata_scan_task: asyncio.Task | None = None
Expand Down Expand Up @@ -796,7 +796,7 @@ async def _scan_missing_metadata(self) -> None:
class MetadataLookupQueue(asyncio.Queue):
"""Representation of a queue for metadata lookups."""

def _init(self, maxlen: int = 100):
def _init(self, maxlen: int):
self._queue: collections.deque[str] = collections.deque(maxlen=maxlen)

def _put(self, item: str) -> None:
Expand Down
10 changes: 10 additions & 0 deletions music_assistant/providers/opensubsonic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
CONF_BASE_URL,
CONF_ENABLE_LEGACY_AUTH,
CONF_ENABLE_PODCASTS,
CONF_OVERRIDE_OFFSET,
OpenSonicProvider,
)

Expand Down Expand Up @@ -90,4 +91,13 @@ async def get_config_entries(
description='Enable OpenSubsonic "legacy" auth support',
default_value=False,
),
ConfigEntry(
key=CONF_OVERRIDE_OFFSET,
type=ConfigEntryType.BOOLEAN,
label="Force player provider seek",
required=True,
description="Some Subsonic implementations advertise that they support seeking when "
"they do not always. If seeking does not work for you, enable this.",
default_value=False,
),
)
8 changes: 7 additions & 1 deletion music_assistant/providers/opensubsonic/sonic_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
CONF_BASE_URL = "baseURL"
CONF_ENABLE_PODCASTS = "enable_podcasts"
CONF_ENABLE_LEGACY_AUTH = "enable_legacy_auth"
CONF_OVERRIDE_OFFSET = "override_transcode_offest"

UNKNOWN_ARTIST_ID = "fake_artist_unknown"

Expand All @@ -71,6 +72,7 @@ class OpenSonicProvider(MusicProvider):
_conn: SonicConnection = None
_enable_podcasts: bool = True
_seek_support: bool = False
_ignore_offset: bool = False

async def handle_async_init(self) -> None:
"""Set up the music provider and test the connection."""
Expand Down Expand Up @@ -101,11 +103,12 @@ async def handle_async_init(self) -> None:
)
raise LoginFailed(msg) from e
self._enable_podcasts = self.config.get_value(CONF_ENABLE_PODCASTS)
self._ignore_offset = self.config.get_value(CONF_OVERRIDE_OFFSET)
try:
ret = await self._run_async(self._conn.getOpenSubsonicExtensions)
extensions = ret["openSubsonicExtensions"]
for entry in extensions:
if entry["name"] == "transcodeOffset":
if entry["name"] == "transcodeOffset" and not self._ignore_offset:
self._seek_support = True
break
except OSError:
Expand Down Expand Up @@ -708,11 +711,14 @@ async def get_stream_details(
)

async def _report_playback_started(self, item_id: str) -> None:
self.logger.debug("scrobble for now playing called for %s", item_id)
await self._run_async(self._conn.scrobble, sid=item_id, submission=False)

async def on_streamed(self, streamdetails: StreamDetails, seconds_streamed: int) -> None:
"""Handle callback when an item completed streaming."""
self.logger.debug("on_streamed called for %s", streamdetails.item_id)
if seconds_streamed >= streamdetails.duration / 2:
self.logger.debug("scrobble for listen count called for %s", streamdetails.item_id)
await self._run_async(self._conn.scrobble, sid=streamdetails.item_id, submission=True)

async def get_audio_stream(
Expand Down
9 changes: 9 additions & 0 deletions music_assistant/providers/siriusxm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ async def get_stream_details(
self, item_id: str, media_type: MediaType = MediaType.RADIO
) -> StreamDetails:
"""Get streamdetails for a track/radio."""
# There's a chance that the SiriusXM auth session has expired
# by the time the user clicks to play a station. The sxm-client
# will attempt to reauthenticate automatically, but this causes
# a delay in streaming, and ffmpeg raises a TimeoutError.
# To prevent this, we're going to explicitly authenticate with
# SiriusXM proactively when a station has been chosen to avoid
# this.
await self._client.authenticate()

hls_path = f"http://{self._base_url}/{item_id}.m3u8"

# Keep a reference to the current `StreamDetails` object so that we can
Expand Down
2 changes: 1 addition & 1 deletion music_assistant/providers/soundcloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ async def _parse_track(self, track_obj: dict, playlist_position: int = 0) -> Tra
if track_obj.get("description"):
track.metadata.description = track_obj["description"]
if track_obj.get("genre"):
track.metadata.genres = track_obj["genre"]
track.metadata.genres = [track_obj["genre"]]
if track_obj.get("tag_list"):
track.metadata.style = track_obj["tag_list"]
return track
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"unidecode==1.3.8",
"xmltodict==0.14.2",
"shortuuid==1.0.13",
"zeroconf==0.136.0",
"zeroconf==0.136.2",
]
description = "Music Assistant"
license = {text = "Apache-2.0"}
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ unidecode==1.3.8
xmltodict==0.14.2
yt-dlp==2024.10.7
ytmusicapi==1.8.2
zeroconf==0.136.0
zeroconf==0.136.2
21 changes: 14 additions & 7 deletions tests/providers/jellyfin/__snapshots__/test_parsers.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
'item_id': '70b7288088b42d318f75dbcc41fd0091',
'media_type': 'album',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
Expand All @@ -45,13 +44,15 @@
}),
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -114,7 +115,6 @@
'item_id': '32ed6a0091733dcff57eae67010f3d4b',
'media_type': 'album',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
Expand All @@ -128,13 +128,15 @@
}),
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -189,21 +191,22 @@
'item_id': '7c8d0bd55291c7fc0451d17ebef30017',
'media_type': 'album',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
'genres': None,
'images': list([
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -246,7 +249,6 @@
'item_id': 'dd954bbf54398e247d803186d3585b79',
'media_type': 'artist',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
Expand All @@ -272,13 +274,15 @@
}),
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -346,21 +350,22 @@
'item_id': 'b5319fb11cde39fca2023184fcfa9862',
'media_type': 'track',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
'genres': None,
'images': list([
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -417,7 +422,6 @@
'item_id': '54918f75ee8f6c8b8dc5efd680644f29',
'media_type': 'track',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
Expand All @@ -431,13 +435,15 @@
}),
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down Expand Up @@ -523,7 +529,6 @@
'item_id': 'fb12a77f49616a9fc56a6fab2b94174c',
'media_type': 'track',
'metadata': dict({
'chapters': None,
'copyright': None,
'description': None,
'explicit': None,
Expand All @@ -537,13 +542,15 @@
}),
]),
'label': None,
'languages': None,
'last_refresh': None,
'links': None,
'lyrics': None,
'mood': None,
'performers': None,
'popularity': None,
'preview': None,
'release_date': None,
'review': None,
'style': None,
}),
Expand Down

0 comments on commit dbe5ee4

Please sign in to comment.