mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
build recently added and played via hooks
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -18,7 +18,7 @@ def start_cron_jobs():
|
||||
RecentlyAdded()
|
||||
|
||||
# Initialized CRON jobs
|
||||
# Mixes()
|
||||
Mixes()
|
||||
TopArtists()
|
||||
TopArtists(duration="week")
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
if len(_entries):
|
||||
entries = _entries
|
||||
limit = 1
|
||||
else:
|
||||
entries = ScrobbleTable.get_all(0, BATCH_SIZE)
|
||||
max_iterations = 20 # Safeguard against unexpected infinite loops
|
||||
|
||||
max_iterations = 20
|
||||
iterations = 0
|
||||
|
||||
while len(items) < limit and iterations < max_iterations:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user