add recently played playlist

This commit is contained in:
cwilvx
2024-05-23 12:42:36 +03:00
parent 30768dd5d6
commit bbcacf81bd
10 changed files with 142 additions and 62 deletions
+4
View File
@@ -3,4 +3,8 @@
<!-- TODO: ELABORATE -->
- Auth
## Improvements
- The context menu now doesn't take forever to open up
- Merged "Save as Playlist" with "Add to Playlist" > "New Playlist"
## Development
+2 -1
View File
@@ -1,11 +1,12 @@
# TODO
- Migrations:
1. Move userdata to new hashing algorithm
- Store on the correct user account:
- Store (and read) from the correct user account:
1. Playlists
2. Favorites
- Package jsoni and publish on PyPi
# DONE
- Add recently played playlist
- Move user track logs to user zero
- Move future logs to appropriate user id
+2 -2
View File
@@ -2,7 +2,7 @@ from flask_openapi3 import Tag
from flask_openapi3 import APIBlueprint
from app.api.apischemas import GenericLimitSchema
from app.lib.home.recentlyadded import get_recent_items
from app.lib.home.recentlyadded import get_recently_added_items
from app.lib.home.recentlyplayed import get_recently_played
bp_tag = Tag(name="Home", description="Homepage items")
@@ -14,7 +14,7 @@ def get_recently_added(query: GenericLimitSchema):
"""
Get recently added
"""
return {"items": get_recent_items(query.limit)}
return {"items": get_recently_added_items(query.limit)}
@api.get("/recents/played")
+26 -12
View File
@@ -15,6 +15,8 @@ from app import models
from app.db.sqlite.playlists import SQLitePlaylistMethods
from app.lib import playlistlib
from app.lib.albumslib import sort_by_track_no
from app.lib.home.recentlyadded import get_recently_added_playlist
from app.lib.home.recentlyplayed import get_recently_played_playlist
from app.serializers.playlist import serialize_for_card
from app.store.tracks import TrackStore
from app.utils.dates import create_new_date, date_string_to_time_passed
@@ -174,6 +176,18 @@ class GetPlaylistQuery(BaseModel):
no_tracks: bool = Field(False, description="Whether to include tracks")
def format_custom_playlist(playlist: models.Playlist, tracks: list[models.Track]):
duration = sum(t.duration for t in tracks)
playlist.set_duration(duration)
playlist = serialize_for_card(playlist)
return {
"info": playlist,
"tracks": tracks,
}
@api.get("/<playlistid>")
def get_playlist(path: PlaylistIDPath, query: GetPlaylistQuery):
"""
@@ -182,18 +196,18 @@ def get_playlist(path: PlaylistIDPath, query: GetPlaylistQuery):
no_tracks = query.no_tracks
playlistid = path.playlistid
is_recently_added = playlistid == "recentlyadded"
custom_playlists = [
{"name": "recentlyadded", "handler": get_recently_added_playlist},
{"name": "recentlyplayed", "handler": get_recently_played_playlist},
]
is_custom = playlistid in {p["name"] for p in custom_playlists}
if is_recently_added:
playlist, tracks = playlistlib.get_recently_added_playlist()
tracks = remove_duplicates(tracks)
duration = sum(t.duration for t in tracks)
playlist.set_duration(duration)
playlist = serialize_for_card(playlist)
return {"info": playlist, "tracks": tracks}
if is_custom:
handler = next(
p["handler"] for p in custom_playlists if p["name"] == playlistid
)
playlist, tracks = handler()
return format_custom_playlist(playlist, tracks)
playlist = PL.get_playlist_by_id(int(playlistid))
@@ -247,7 +261,7 @@ def update_playlist_info(path: PlaylistIDPath, form: UpdatePlaylistForm):
settings["has_gif"] = False
playlist = {
"id": playlistid,
"id": int(playlistid),
"image": db_playlist.image,
"last_updated": create_new_date(),
"name": str(form.name).strip(),
+17 -2
View File
@@ -1,11 +1,12 @@
from app.db.sqlite.utils import SQLiteManager
from app.models.logger import TrackLog as TrackLog
class SQLiteTrackLogger:
@classmethod
def insert_track(cls, trackhash: str, duration: int, source: str, timestamp: int, userid: int):
"""
Inserts a track into the database
Inserts a track play record into the database
"""
with SQLiteManager(userdata_db=True) as cur:
@@ -26,7 +27,7 @@ class SQLiteTrackLogger:
@classmethod
def get_all(cls):
"""
Returns all tracks from the database
Returns all track play records from the database
"""
with SQLiteManager(userdata_db=True) as cur:
@@ -36,3 +37,17 @@ class SQLiteTrackLogger:
rows = cur.fetchall()
return rows
@classmethod
def get_recently_played(cls, start: int = 0, limit: int = 100):
"""
Returns a list of recently played tracks
"""
with SQLiteManager(userdata_db=True) as cur:
sql = """SELECT * FROM track_logger ORDER BY timestamp DESC LIMIT ?,?"""
cur.execute(sql, (start, limit))
rows = cur.fetchall()
return [TrackLog(*row) for row in rows]
+33 -5
View File
@@ -1,6 +1,7 @@
import os
from datetime import datetime
from flask import g
from app.lib.playlistlib import get_first_4_images
from app.models.playlist import Playlist
from app.models.track import Track
from app.store.tracks import TrackStore
from app.store.albums import AlbumStore
@@ -12,7 +13,7 @@ from app.serializers.artist import serialize_for_card
from itertools import groupby
from app.utils.dates import timestamp_to_time_passed
from app.utils.dates import create_new_date, date_string_to_time_passed, timestamp_to_time_passed
older_albums = set()
older_artists = set()
@@ -191,7 +192,7 @@ def group_track_by_folders(tracks: Track):
return sorted(groups, key=lambda group: group["time"], reverse=True)
def get_recent_items(limit: int = 7):
def get_recently_added_items(limit: int = 7):
tracks = sorted(TrackStore.tracks, key=lambda t: t.created_date)
groups = group_track_by_folders(tracks)
@@ -216,6 +217,33 @@ def get_recent_items(limit: int = 7):
return recent_items
def get_recent_tracks(limit: int):
def get_recently_added_playlist(limit: int = 100):
playlist = Playlist(
id="recentlyadded",
name="Recently Added",
image=None,
last_updated="Now",
settings={},
trackhashes=[],
)
tracks = get_recently_added_tracks(limit=limit)
try:
# Create date to show as last updated
date = datetime.fromtimestamp(tracks[0].created_date)
except IndexError:
return playlist, []
playlist.last_updated = date_string_to_time_passed(create_new_date(date))
images = get_first_4_images(tracks=tracks)
playlist.images = images
playlist.set_count(len(tracks))
return playlist, tracks
def get_recently_added_tracks(limit: int):
tracks = sorted(TrackStore.tracks, key=lambda t: t.created_date, reverse=True)
return tracks[:limit]
+47 -6
View File
@@ -1,27 +1,37 @@
from datetime import datetime
import os
from app.models.logger import Track as TrackLog
from app.models.logger import TrackLog
from app.db.sqlite.logger.tracks import SQLiteTrackLogger as db
from app.db.sqlite.playlists import SQLitePlaylistMethods as pdb
from app.db.sqlite.favorite import SQLiteFavoriteMethods as fdb
from app.models.playlist import Playlist
from app.serializers.track import serialize_track
from app.serializers.album import album_serializer
from app.utils.dates import timestamp_to_time_passed
from app.lib.playlistlib import get_first_4_images
from app.utils.dates import create_new_date, date_string_to_time_passed, timestamp_to_time_passed
from app.serializers.artist import serialize_for_card
from app.serializers.playlist import serialize_for_card as serialize_playlist
from app.lib.playlistlib import get_first_4_images, get_recently_added_playlist
from app.lib.home.recentlyadded import get_recently_added_playlist
from app.store.albums import AlbumStore
from app.store.tracks import TrackStore
from app.store.artists import ArtistStore
def get_recently_played(limit=7):
# TODO: Paginate this
entries = db.get_all()
items = []
added = set()
custom_playlists = [
{"name": "recentlyadded", "handler": get_recently_added_playlist},
{"name": "recentlyplayed", "handler": get_recently_played_playlist},
]
for entry in entries:
if len(items) >= limit:
break
@@ -112,10 +122,13 @@ def get_recently_played(limit=7):
continue
if entry.type == "playlist":
is_recently_added = entry.type_src == "recentlyadded"
is_custom = entry.type_src in [i["name"] for i in custom_playlists]
# is_recently_added = entry.type_src == "recentlyadded"
if is_recently_added:
playlist, _ = get_recently_added_playlist()
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(
@@ -186,3 +199,31 @@ def get_recently_played(limit=7):
)
return items
def get_recently_played_tracks(limit: int):
records = db.get_recently_played(start=0, limit=limit)
last_updated = records[0].timestamp
tracks = TrackStore.get_tracks_by_trackhashes([r.trackhash for r in records])
return tracks, last_updated
def get_recently_played_playlist(limit: int = 100):
playlist = Playlist(
id="recentlyplayed",
name="Recently Played",
image=None,
last_updated="Now",
settings={},
trackhashes=[],
)
tracks, timestamp = get_recently_played_tracks(limit)
date = datetime.fromtimestamp(timestamp)
playlist.last_updated = date_string_to_time_passed(create_new_date(date))
images = get_first_4_images(tracks=tracks)
playlist.images = images
playlist.set_count(len(tracks))
return playlist, tracks
-31
View File
@@ -5,18 +5,14 @@ This library contains all the functions related to playlists.
import os
import random
import string
from datetime import datetime
from typing import Any
from PIL import Image, ImageSequence
from app import settings
from app.lib.home.recentlyadded import get_recent_tracks
from app.models.playlist import Playlist
from app.models.track import Track
from app.store.albums import AlbumStore
from app.store.tracks import TrackStore
from app.utils.dates import create_new_date, date_string_to_time_passed
def create_thumbnail(image: Any, img_path: str) -> str:
@@ -133,30 +129,3 @@ def get_first_4_images(
return images
return duplicate_images(images)
def get_recently_added_playlist(limit: int = 100):
playlist = Playlist(
id="recentlyadded",
name="Recently Added",
image=None,
last_updated="Now",
settings={},
trackhashes=[],
)
tracks = get_recent_tracks(limit=limit)
try:
# Create date to show as last updated
date = datetime.fromtimestamp(tracks[0].created_date)
except IndexError:
return playlist, []
playlist.last_updated = date_string_to_time_passed(create_new_date(date))
images = get_first_4_images(tracks=tracks)
playlist.images = images
playlist.set_count(len(tracks))
return playlist, tracks
+1 -1
View File
@@ -3,7 +3,7 @@ from typing import Literal
@dataclass
class Track:
class TrackLog:
"""
Track play logger model
"""
+10 -2
View File
@@ -129,10 +129,18 @@ class TrackStore:
"""
Returns a list of tracks by their hashes.
"""
hash_set = set(trackhashes)
set_len = len(hash_set)
trackhashes = " ".join(trackhashes)
tracks = [track for track in cls.tracks if track.trackhash in trackhashes]
tracks = []
for track in cls.tracks:
if track.trackhash in hash_set:
tracks.append(track)
if len(tracks) == set_len:
break
# sort the tracks in the order of the given trackhashes
tracks.sort(key=lambda t: trackhashes.index(t.trackhash))
return tracks