build recently added and played via hooks

This commit is contained in:
cwilvx
2024-11-17 20:53:00 +03:00
parent 333fd6603f
commit ef4ecc2499
6 changed files with 79 additions and 96 deletions
+4 -6
View File
@@ -1,20 +1,15 @@
from dataclasses import dataclass
from gettext import ngettext
from itertools import groupby
from math import e
from pprint import pprint
from flask_openapi3 import Tag
from flask_openapi3 import APIBlueprint
import pendulum
from pydantic import Field, BaseModel
from app.api.apischemas import TrackHashSchema
from typing import Literal
from datetime import datetime, timedelta
from collections import defaultdict
import locale
from app.db.userdata import FavoritesTable, ScrobbleTable
from app.lib.extras import get_extra_info
from app.lib.recipes.recents import RecentlyPlayed
from app.models.album import Album
from app.models.stats import StatItem
from app.models.track import Track
@@ -80,6 +75,9 @@ def log_track(body: LogTrackBody):
scrobble_data["extra"] = get_extra_info(body.trackhash, "track")
ScrobbleTable.add(scrobble_data)
# NOTE: Update the recently played homepage for this userid
RecentlyPlayed(userid=scrobble_data["userid"])
# Update play data on the in-memory stores
track = trackentry.tracks[0]
album = AlbumStore.albummap.get(track.albumhash)
+1 -1
View File
@@ -18,7 +18,7 @@ def start_cron_jobs():
RecentlyAdded()
# Initialized CRON jobs
# Mixes()
Mixes()
TopArtists()
TopArtists(duration="week")
+8
View File
@@ -26,6 +26,7 @@ from app.db.utils import (
plugin_to_dataclasses,
similar_artist_to_dataclass,
similar_artists_to_dataclass,
tracklog_to_dataclass,
tracklog_to_dataclasses,
user_to_dataclass,
user_to_dataclasses,
@@ -319,6 +320,13 @@ class ScrobbleTable(Base):
)
return tracklog_to_dataclasses(result.fetchall())
@classmethod
def get_last_entry(cls, userid: int):
result = cls.execute(
select(cls).where(cls.userid == userid).order_by(cls.timestamp.desc())
)
return tracklog_to_dataclass(result.fetchone())
class PlaylistTable(Base):
__tablename__ = "playlist"
+15 -87
View File
@@ -22,7 +22,14 @@ from app.store.tracks import TrackStore
from app.store.artists import ArtistStore
def get_recently_played(limit=7, userid: int | None = None):
def get_recently_played(
limit: int, userid: int | None = None, _entries: list[TrackLog] = []
):
"""
Get the recently played items for the homepage.
Pass a list of track log entries to use a subset of the scrobble table.
"""
# TODO: Paginate this
items = []
added = set()
@@ -48,29 +55,12 @@ def get_recently_played(limit=7, userid: int | None = None):
if album is None:
continue
# album = album_serializer(
# album,
# to_remove={
# "genres",
# "date",
# "count",
# "duration",
# "albumartists_hashes",
# "og_title",
# },
# )
item = {
"type": "album",
"hash": entry.type_src,
"timestamp": entry.timestamp,
}
# album["help_text"] = "album"
# album["time"] = timestamp_to_time_passed(entry.timestamp)
# {
# "type": "album",
# "item": album,
# }
items.append(item)
continue
@@ -80,10 +70,6 @@ def get_recently_played(limit=7, userid: int | None = None):
if artist is None:
continue
# artist = serialize_for_card(artist)
# artist["help_text"] = "artist"
# artist["time"] = timestamp_to_time_passed(entry.timestamp)
items.append(
{
"type": "artist",
@@ -108,7 +94,6 @@ def get_recently_played(limit=7, userid: int | None = None):
if is_home_dir:
folder = os.path.expanduser("~")
# count = FolderStore.count_tracks_containing_paths([folder])
item = {
"type": "folder",
"hash": entry.type_src,
@@ -116,42 +101,12 @@ def get_recently_played(limit=7, userid: int | None = None):
}
items.append(item)
# {
# "type": "folder",
# "item": {
# "path": folder,
# "count": count[0]["trackcount"],
# "help_text": "folder",
# "time": timestamp_to_time_passed(entry.timestamp),
# },
# }
continue
if entry.type == "playlist":
is_custom = entry.type_src in [i["name"] for i in custom_playlists]
if is_custom:
# playlist, _ = next(
# i["handler"]()
# for i in custom_playlists
# if i["name"] == entry.type_src
# )
# playlist.images = [i["image"] for i in playlist.images]
# playlist = serialize_playlist(
# playlist, to_remove={"settings", "duration"}
# )
# playlist["help_text"] = "playlist"
# playlist["time"] = timestamp_to_time_passed(entry.timestamp)
# items.append(
# {
# "type": "playlist",
# "item": playlist,
# }
# )
items.append(
{
"type": "playlist",
@@ -173,37 +128,10 @@ def get_recently_played(limit=7, userid: int | None = None):
}
items.append(item)
# tracks = TrackStore.get_tracks_by_trackhashes(playlist.trackhashes)
# playlist.clear_lists()
# if not playlist.has_image:
# images = get_first_4_images(tracks)
# images = [i["image"] for i in images]
# playlist.images = images
# items.append(
# {
# "type": "playlist",
# "item": {
# "help_text": "playlist",
# "time": timestamp_to_time_passed(entry.timestamp),
# **serialize_playlist(playlist),
# },
# }
# )
continue
if entry.type == "favorite":
items.append(
# {
# "type": "favorite_tracks",
# "item": {
# "help_text": "playlist",
# "count": FavoritesTable.count(),
# "time": timestamp_to_time_passed(entry.timestamp),
# },
# }
{
"type": "favorite",
"timestamp": entry.timestamp,
@@ -221,18 +149,18 @@ def get_recently_played(limit=7, userid: int | None = None):
"hash": entry.trackhash,
"timestamp": entry.timestamp,
}
# track = serialize_track(t.get_best())
# track["help_text"] = "track"
# track["time"] = timestamp_to_time_passed(entry.timestamp)
items.append(item)
BATCH_SIZE = 200
current_index = 0
entries = ScrobbleTable.get_all(0, BATCH_SIZE)
max_iterations = 20 # Safeguard against unexpected infinite loops
if len(_entries):
entries = _entries
limit = 1
else:
entries = ScrobbleTable.get_all(0, BATCH_SIZE)
max_iterations = 20
iterations = 0
while len(items) < limit and iterations < max_iterations:
+4
View File
@@ -7,6 +7,7 @@ from app.lib.mapstuff import (
map_scrobble_data,
)
from app.lib.populate import CordinateMedia
from app.lib.recipes.recents import RecentlyAdded
from app.lib.tagger import IndexTracks
from app.store.albums import AlbumStore
from app.store.artists import ArtistStore
@@ -25,6 +26,9 @@ class IndexEverything:
ArtistStore.load_artists(key)
FolderStore.load_filepaths()
# NOTE: Rebuild recently added items on the homepage store
RecentlyAdded()
# map colors
map_album_colors()
map_artist_colors()
+47 -2
View File
@@ -1,5 +1,5 @@
import pprint
from app.db.userdata import UserTable
from app.db.userdata import ScrobbleTable, UserTable
from app.lib.home.recentlyadded import get_recently_added_items
from app.lib.home.recentlyplayed import get_recently_played
from app.lib.recipes import HomepageRoutine
@@ -7,6 +7,7 @@ from app.store.homepage import HomepageStore
class RecentlyPlayed(HomepageRoutine):
ITEM_LIMIT = 15
store_key = "recently_played"
def __init__(self, userid: int | None = None) -> None:
@@ -15,6 +16,11 @@ class RecentlyPlayed(HomepageRoutine):
outside a cron job. ie. when a user records a new scrobble.
"""
self.userids = [userid] if userid else [user.id for user in UserTable.get_all()]
# NOTE: When the userid is provided
# we need to update the store for that userid only
# using the last scrobble entry.
self.update_only = userid is not None
super().__init__()
@property
@@ -22,8 +28,47 @@ class RecentlyPlayed(HomepageRoutine):
return True
def run(self):
if self.update_only:
last_entry = ScrobbleTable.get_last_entry(self.userids[0])
if last_entry:
items = get_recently_played(
limit=self.ITEM_LIMIT, userid=self.userids[0], _entries=[last_entry]
)
item = items[0]
store_entry = HomepageStore.entries[self.store_key].items[
self.userids[0]
][0]
if (
item["type"] + item["hash"]
== store_entry["type"] + store_entry["hash"]
):
# If the item is the same as the one in the store
# only update the timestamp
HomepageStore.entries[self.store_key].items[self.userids[0]][0][
"timestamp"
] = item["timestamp"]
else:
# Otherwise, insert the new item
# and remove the oldest item if there are more than 15 items
HomepageStore.entries[self.store_key].items[self.userids[0]].insert(
0, item
)
if (
len(
HomepageStore.entries[self.store_key].items[self.userids[0]]
)
> self.ITEM_LIMIT
):
HomepageStore.entries[self.store_key].items[
self.userids[0]
].pop()
for userid in self.userids:
items = get_recently_played(limit=15, userid=userid)
items = get_recently_played(limit=self.ITEM_LIMIT, userid=userid)
HomepageStore.entries[self.store_key].items[userid] = items