-
-
Notifications
You must be signed in to change notification settings - Fork 466
Store track artist in playlog #4169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,7 @@ | |
| from copy import deepcopy | ||
| from datetime import datetime | ||
| from itertools import zip_longest | ||
| from typing import TYPE_CHECKING, Any, cast | ||
| from typing import TYPE_CHECKING, Any, NamedTuple, cast | ||
|
|
||
| from music_assistant_models.background_task import BackgroundTask, TaskMetadata, TaskSchedule | ||
| from music_assistant_models.config_entries import ConfigEntry, ConfigValueType | ||
|
|
@@ -110,6 +110,15 @@ | |
| from music_assistant.providers.builtin import BuiltinProvider | ||
|
|
||
|
|
||
| class RecentPlayedTrack(NamedTuple): | ||
| """A recently played track from the playlog, with the artist recorded at play time.""" | ||
|
|
||
| item_id: str | ||
| provider: str | ||
| name: str | ||
| artist: str | None | ||
|
|
||
|
|
||
| class MusicController(MusicDatabaseSetupMixin, CoreController): | ||
| """Several helpers around the musicproviders.""" | ||
|
|
||
|
|
@@ -727,6 +736,45 @@ async def recently_played( | |
| ) | ||
| return result | ||
|
|
||
| async def recently_played_tracks( | ||
| self, | ||
| limit: int, | ||
| played_after_timestamp: int, | ||
| userid: str | None = None, | ||
| ) -> list[RecentPlayedTrack]: | ||
| """ | ||
| Return recently played, fully played tracks with their recorded artist, most recent first. | ||
|
|
||
| :param limit: Maximum number of plays to return. | ||
| :param played_after_timestamp: Only include plays at or after this epoch-seconds timestamp. | ||
| :param userid: Restrict to this user (defaults to the current session user, else all users). | ||
| """ | ||
| query = ( | ||
| f"SELECT item_id, provider, name, artist FROM {DB_TABLE_PLAYLOG} " | ||
| "WHERE media_type = 'track' AND fully_played = 1 " | ||
| "AND timestamp >= :played_after_timestamp " | ||
| ) | ||
| params: dict[str, Any] = {"played_after_timestamp": played_after_timestamp} | ||
| if userid: | ||
| query += "AND userid = :userid " | ||
| params["userid"] = userid | ||
| elif user := get_current_user(): | ||
| query += "AND userid = :userid " | ||
| params["userid"] = user.user_id | ||
| query += "ORDER BY timestamp DESC" | ||
| db_rows = await self.mass.music.database.get_rows_from_query( | ||
| query, params=params, limit=limit | ||
| ) | ||
| return [ | ||
| RecentPlayedTrack( | ||
| item_id=db_row["item_id"], | ||
| provider=db_row["provider"], | ||
| name=db_row["name"], | ||
| artist=db_row["artist"], | ||
| ) | ||
| for db_row in db_rows | ||
| ] | ||
|
|
||
| @api_command("music/recently_added_tracks") | ||
| async def recently_added_tracks(self, limit: int = 10) -> list[Track]: | ||
| """Return a list of the last added tracks.""" | ||
|
|
@@ -1358,11 +1406,16 @@ async def mark_item_played( | |
| # one-off items like TTS or some sound effect etc. | ||
| return | ||
|
|
||
| # store the primary artist so streaming plays not in the library remain seedable | ||
| item_artists = getattr(media_item, "artists", None) | ||
| artist = item_artists[0].name if item_artists else None | ||
|
|
||
| params = { | ||
| "item_id": media_item.item_id, | ||
| "provider": media_item.provider, | ||
| "media_type": media_item.media_type.value, | ||
| "name": media_item.name, | ||
| "artist": artist, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what problem is this going to solve ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PR description explains it in detail. Basically I can t use the play log to provide seeds for last.fm without an artist
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and we cant just do a cheap library lookup ? so that lastfm lookups only act on library items ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for people who are listening to streaming tracks which are not in their library. If we limited to library only then we may not get enough seeds or they wont be representative of the users actual play history.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @marcelveldt see my comment above |
||
| "image": serialize_to_json(media_item.image.to_dict()) if media_item.image else None, | ||
| "fully_played": fully_played, | ||
| "seconds_played": seconds_played, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this hacky bandaid tbh