mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 20:43:04 +00:00
implement saving mixes
+ add: get mixes + handle mixes on recently played + move modules around to fix circular deps
This commit is contained in:
+21
-117
@@ -1,123 +1,16 @@
|
||||
from abc import ABC
|
||||
from typing import Any
|
||||
from app.lib.home.recentlyplayed import recover_items
|
||||
from app.models.mix import Mix
|
||||
|
||||
from app.store.homepageentries import (
|
||||
BecauseYouListenedToArtistHomepageEntry,
|
||||
GenericRecoverableEntry,
|
||||
HomepageEntry,
|
||||
MixHomepageEntry,
|
||||
RecentlyAddedHomepageEntry,
|
||||
RecentlyPlayedHomepageEntry,
|
||||
)
|
||||
from app.utils.auth import get_current_userid
|
||||
|
||||
|
||||
class HomepageEntry(ABC):
|
||||
"""
|
||||
Base class for all homepage entries.
|
||||
|
||||
items is a dict of userid to a dict of stuff.
|
||||
"""
|
||||
|
||||
title: str
|
||||
description: str
|
||||
items: dict[int, Any]
|
||||
|
||||
def __init__(self, title: str, description: str):
|
||||
self.title = title
|
||||
self.description = description
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
"""
|
||||
Return usable items for the homepage.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class MixHomepageEntry(HomepageEntry):
|
||||
"""
|
||||
A homepage entry for mixes.
|
||||
self.items is a dict of userid to a dict of mixid to mix.
|
||||
"""
|
||||
|
||||
items: dict[int, dict[str, Mix]]
|
||||
|
||||
def __init__(self, title: str, description: str):
|
||||
super().__init__(title, description)
|
||||
self.items = {}
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
items = []
|
||||
|
||||
for mix in self.items.get(userid, {}).values():
|
||||
if limit and len(items) >= limit:
|
||||
break
|
||||
|
||||
items.append(
|
||||
{
|
||||
"type": "mix",
|
||||
"item": mix.to_dict(),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"title": self.title,
|
||||
"description": self.description,
|
||||
"items": items,
|
||||
}
|
||||
|
||||
|
||||
class RecentlyPlayedHomepageEntry(HomepageEntry):
|
||||
"""
|
||||
A homepage entry for recently played.
|
||||
"""
|
||||
|
||||
items: dict[int, list[dict[str, Any]]]
|
||||
|
||||
def __init__(self, title: str, description: str = ""):
|
||||
super().__init__(title, description)
|
||||
self.items = {}
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
items = self.items.get(userid, [])[:limit]
|
||||
|
||||
return {
|
||||
"title": self.title,
|
||||
"description": self.description,
|
||||
"items": recover_items(items),
|
||||
}
|
||||
|
||||
|
||||
class RecentlyAddedHomepageEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for recently added.
|
||||
"""
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
return super().get_items(0, limit)
|
||||
|
||||
|
||||
class GenericRecoverableEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for top streamed.
|
||||
"""
|
||||
|
||||
# NOTE: This extends RecentlyPlayedHomepageEntry because
|
||||
# the shape of the data is the same.
|
||||
pass
|
||||
|
||||
|
||||
class BecauseYouListenedToArtistHomepageEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for because you listened to artist.
|
||||
"""
|
||||
|
||||
# SHAPE: {userid: {title: str, items: list[RecoverableItem]}}
|
||||
items: dict[int, dict[str, Any]]
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
title = self.items.get(userid, {}).get("title")
|
||||
items = self.items.get(userid, {}).get("items", [])[:limit]
|
||||
|
||||
return {
|
||||
"title": title,
|
||||
"items": recover_items(items),
|
||||
}
|
||||
|
||||
|
||||
class HomepageStore:
|
||||
"""
|
||||
Stores the homepage items.
|
||||
@@ -159,7 +52,7 @@ class HomepageStore:
|
||||
|
||||
@classmethod
|
||||
def set_mixes(cls, items: list[Any], entrykey: str, userid: int | None = None):
|
||||
idmap = {item.id[1:]: item for item in items}
|
||||
idmap = {item.id: item for item in items}
|
||||
cls.entries[entrykey].items[userid or get_current_userid()] = idmap
|
||||
|
||||
@classmethod
|
||||
@@ -175,3 +68,14 @@ class HomepageStore:
|
||||
for entry in cls.entries.keys()
|
||||
if len(cls.entries[entry].items)
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def find_mix(cls, mixid: str):
|
||||
mixentries = ["artist_mixes", "custom_mixes"]
|
||||
|
||||
for entry in mixentries:
|
||||
mix = cls.entries[entry].items.get(get_current_userid(), {}).get(mixid)
|
||||
if mix:
|
||||
return mix
|
||||
|
||||
return None
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
from abc import ABC
|
||||
from typing import Any
|
||||
|
||||
from app.lib.home import recover_items
|
||||
from app.models.mix import Mix
|
||||
|
||||
class HomepageEntry(ABC):
|
||||
"""
|
||||
Base class for all homepage entries.
|
||||
|
||||
items is a dict of userid to a dict of stuff.
|
||||
"""
|
||||
|
||||
title: str
|
||||
description: str
|
||||
items: dict[int, Any]
|
||||
|
||||
def __init__(self, title: str, description: str):
|
||||
self.title = title
|
||||
self.description = description
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
"""
|
||||
Return usable items for the homepage.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class MixHomepageEntry(HomepageEntry):
|
||||
"""
|
||||
A homepage entry for mixes.
|
||||
self.items is a dict of userid to a dict of mixid to mix.
|
||||
"""
|
||||
|
||||
items: dict[int, dict[str, Mix]]
|
||||
|
||||
def __init__(self, title: str, description: str):
|
||||
super().__init__(title, description)
|
||||
self.items = {}
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
items = []
|
||||
|
||||
for mix in self.items.get(userid, {}).values():
|
||||
if limit and len(items) >= limit:
|
||||
break
|
||||
|
||||
items.append(
|
||||
{
|
||||
"type": "mix",
|
||||
"item": mix.to_dict(),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"title": self.title,
|
||||
"description": self.description,
|
||||
"items": items,
|
||||
}
|
||||
|
||||
|
||||
class RecentlyPlayedHomepageEntry(HomepageEntry):
|
||||
"""
|
||||
A homepage entry for recently played.
|
||||
"""
|
||||
|
||||
items: dict[int, list[dict[str, Any]]]
|
||||
|
||||
def __init__(self, title: str, description: str = ""):
|
||||
super().__init__(title, description)
|
||||
self.items = {}
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
items = self.items.get(userid, [])[:limit]
|
||||
|
||||
return {
|
||||
"title": self.title,
|
||||
"description": self.description,
|
||||
"items": recover_items(items),
|
||||
}
|
||||
|
||||
|
||||
class RecentlyAddedHomepageEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for recently added.
|
||||
"""
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
return super().get_items(0, limit)
|
||||
|
||||
|
||||
class GenericRecoverableEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for top streamed.
|
||||
"""
|
||||
|
||||
# NOTE: This extends RecentlyPlayedHomepageEntry because
|
||||
# the shape of the data is the same.
|
||||
pass
|
||||
|
||||
|
||||
class BecauseYouListenedToArtistHomepageEntry(RecentlyPlayedHomepageEntry):
|
||||
"""
|
||||
A homepage entry for because you listened to artist.
|
||||
"""
|
||||
|
||||
# SHAPE: {userid: {title: str, items: list[RecoverableItem]}}
|
||||
items: dict[int, dict[str, Any]]
|
||||
|
||||
def get_items(self, userid: int, limit: int | None = None):
|
||||
title = self.items.get(userid, {}).get("title")
|
||||
items = self.items.get(userid, {}).get("items", [])[:limit]
|
||||
|
||||
return {
|
||||
"title": title,
|
||||
"items": recover_items(items),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user