mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
fixes for frontend card renderers
This commit is contained in:
+61
-32
@@ -9,7 +9,7 @@ from flask_openapi3 import APIBlueprint
|
|||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from app.db.userdata import PageTable
|
from app.db.userdata import PageTable
|
||||||
from app.lib.pagelib import recover_page_items, validate_page_items
|
from app.lib.pagelib import recover_page_items, remove_page_items, validate_page_items
|
||||||
from app.utils.auth import get_current_userid
|
from app.utils.auth import get_current_userid
|
||||||
|
|
||||||
bp_tag = Tag(name="Pages", description="Pages")
|
bp_tag = Tag(name="Pages", description="Pages")
|
||||||
@@ -32,7 +32,7 @@ def create_page(body: CreatePageBody):
|
|||||||
"""
|
"""
|
||||||
Create a new page.
|
Create a new page.
|
||||||
"""
|
"""
|
||||||
items = validate_page_items(body.items)
|
items = validate_page_items(body.items, existing=[])
|
||||||
|
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
return {"error": "No items to add"}, 400
|
return {"error": "No items to add"}, 400
|
||||||
@@ -46,41 +46,11 @@ def create_page(body: CreatePageBody):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
print(payload)
|
|
||||||
PageTable.insert_one(payload)
|
PageTable.insert_one(payload)
|
||||||
|
|
||||||
return {"message": "Page created"}, 201
|
return {"message": "Page created"}, 201
|
||||||
|
|
||||||
|
|
||||||
class AddPageItemsBody(BaseModel):
|
|
||||||
items: list[dict[str, Any]] = Field(
|
|
||||||
description="The items to add to the page",
|
|
||||||
example=[{"type": "album", "hash": "1234567890"}],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AddPageItemsPath(BaseModel):
|
|
||||||
page_id: int = Field(description="The ID of the page to add items to", example=1)
|
|
||||||
|
|
||||||
|
|
||||||
@api.post("/<int:page_id>/items")
|
|
||||||
def add_page_items(path: AddPageItemsPath, body: AddPageItemsBody):
|
|
||||||
"""
|
|
||||||
Add items to a page.
|
|
||||||
"""
|
|
||||||
new_items = validate_page_items(body.items)
|
|
||||||
|
|
||||||
page = PageTable.get_by_id(path.page_id)
|
|
||||||
|
|
||||||
if page is None:
|
|
||||||
return {"error": "Page not found"}, 404
|
|
||||||
|
|
||||||
page["items"].extend(new_items)
|
|
||||||
PageTable.update_items(page["id"], page["items"])
|
|
||||||
|
|
||||||
return {"message": "Items added to page"}
|
|
||||||
|
|
||||||
|
|
||||||
@api.get("")
|
@api.get("")
|
||||||
def get_pages():
|
def get_pages():
|
||||||
"""
|
"""
|
||||||
@@ -89,6 +59,65 @@ def get_pages():
|
|||||||
return PageTable.get_all()
|
return PageTable.get_all()
|
||||||
|
|
||||||
|
|
||||||
|
class AddPageItemBody(BaseModel):
|
||||||
|
item: dict[str, Any] = Field(
|
||||||
|
description="The item to add to the page",
|
||||||
|
example={"type": "album", "hash": "1234567890"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddPageItemPath(BaseModel):
|
||||||
|
page_id: int = Field(description="The ID of the page to add items to", example=1)
|
||||||
|
|
||||||
|
|
||||||
|
@api.post("/<int:page_id>/items")
|
||||||
|
def add_page_item(path: AddPageItemPath, body: AddPageItemBody):
|
||||||
|
"""
|
||||||
|
Add an item to a page.
|
||||||
|
"""
|
||||||
|
page = PageTable.get_by_id(path.page_id)
|
||||||
|
|
||||||
|
if page is None:
|
||||||
|
return {"error": "Page not found"}, 404
|
||||||
|
|
||||||
|
new_items = validate_page_items([body.item], existing=page["items"])
|
||||||
|
|
||||||
|
if len(new_items) == 0:
|
||||||
|
return {"error": "items already in page"}, 400
|
||||||
|
|
||||||
|
page["items"].extend(new_items)
|
||||||
|
PageTable.update_items(page["id"], page["items"])
|
||||||
|
|
||||||
|
return {"message": "Items added to page"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemovePageItemBody(BaseModel):
|
||||||
|
item: dict[str, Any] = Field(
|
||||||
|
description="The item to remove from the page",
|
||||||
|
example={"type": "album", "hash": "1234567890"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RemovePageItemPath(BaseModel):
|
||||||
|
page_id: int = Field(description="The ID of the page to remove items from")
|
||||||
|
|
||||||
|
|
||||||
|
@api.delete("/<int:page_id>/items")
|
||||||
|
def remove_page_item(path: RemovePageItemPath, body: RemovePageItemBody):
|
||||||
|
"""
|
||||||
|
Remove an item from a page.
|
||||||
|
"""
|
||||||
|
page = PageTable.get_by_id(path.page_id)
|
||||||
|
|
||||||
|
if page is None:
|
||||||
|
return {"error": "Page not found"}, 404
|
||||||
|
|
||||||
|
remaining = remove_page_items(page["items"], body.item)
|
||||||
|
PageTable.update_items(page["id"], remaining)
|
||||||
|
|
||||||
|
return {"message": "Item removed from page"}
|
||||||
|
|
||||||
|
|
||||||
class GetPageBody(BaseModel):
|
class GetPageBody(BaseModel):
|
||||||
page_id: int = Field(description="The ID of the page to get", example=1)
|
page_id: int = Field(description="The ID of the page to get", example=1)
|
||||||
|
|
||||||
|
|||||||
+30
-8
@@ -1,17 +1,23 @@
|
|||||||
|
import json
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from app.serializers.album import serialize_for_card
|
from app.serializers.album import serialize_for_card
|
||||||
from app.serializers.artist import serialize_for_card as serialize_artist
|
from app.serializers.artist import serialize_for_card as serialize_artist
|
||||||
from app.store.albums import AlbumStore
|
from app.store.albums import AlbumStore
|
||||||
from app.store.artists import ArtistStore
|
from app.store.artists import ArtistStore
|
||||||
|
from app.utils.hashing import create_hash
|
||||||
|
|
||||||
|
|
||||||
def validate_page_items(items: list[dict[str, str]]):
|
def validate_page_items(items: list[dict[str, str]], existing: list[dict[str, str]]):
|
||||||
"""
|
"""
|
||||||
Validate the items in a page before adding them to the database.
|
Validate the items in a page before adding them to the database.
|
||||||
"""
|
"""
|
||||||
validated: list[dict[str, str]] = []
|
validated: list[dict[str, str]] = []
|
||||||
|
indexed = set(create_hash(json.dumps(item)) for item in existing)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
|
if create_hash(json.dumps(item)) in indexed:
|
||||||
|
continue
|
||||||
|
|
||||||
if item["type"] == "album":
|
if item["type"] == "album":
|
||||||
album = AlbumStore.albummap.get(item["hash"])
|
album = AlbumStore.albummap.get(item["hash"])
|
||||||
|
|
||||||
@@ -28,7 +34,15 @@ def validate_page_items(items: list[dict[str, str]]):
|
|||||||
return validated
|
return validated
|
||||||
|
|
||||||
|
|
||||||
def recover_page_items(items: list[dict[str, str]]):
|
def remove_page_items(existing: list[dict[str, str]], item: dict[str, str]):
|
||||||
|
return [
|
||||||
|
i
|
||||||
|
for i in existing
|
||||||
|
if create_hash(json.dumps(i)) != create_hash(json.dumps(item))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def recover_page_items(items: list[dict[str, str]], for_homepage: bool = False):
|
||||||
"""
|
"""
|
||||||
Recover the items in a page.
|
Recover the items in a page.
|
||||||
"""
|
"""
|
||||||
@@ -39,16 +53,24 @@ def recover_page_items(items: list[dict[str, str]]):
|
|||||||
album = AlbumStore.albummap.get(item["hash"])
|
album = AlbumStore.albummap.get(item["hash"])
|
||||||
|
|
||||||
if album is not None:
|
if album is not None:
|
||||||
recovered.append(
|
item = serialize_for_card(album.album)
|
||||||
{"item": serialize_for_card(album.album), "type": "album"}
|
|
||||||
)
|
if for_homepage:
|
||||||
|
del item["type"]
|
||||||
|
item = {"item": item, "type": "album"}
|
||||||
|
|
||||||
|
recovered.append(item)
|
||||||
elif item["type"] == "artist":
|
elif item["type"] == "artist":
|
||||||
artist = ArtistStore.artistmap.get(item["hash"])
|
artist = ArtistStore.artistmap.get(item["hash"])
|
||||||
|
|
||||||
if artist is not None:
|
if artist is not None:
|
||||||
recovered.append(
|
item = serialize_artist(artist.artist)
|
||||||
{"item": serialize_artist(artist.artist), "type": "artist"}
|
|
||||||
)
|
if for_homepage:
|
||||||
|
del item["type"]
|
||||||
|
item = {"item": item, "type": "artist"}
|
||||||
|
|
||||||
|
recovered.append(item)
|
||||||
|
|
||||||
recovered.reverse()
|
recovered.reverse()
|
||||||
return recovered
|
return recovered
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ def album_serializer(album: Album, to_remove: set[str]) -> dict:
|
|||||||
for artist in album_dict["albumartists"]:
|
for artist in album_dict["albumartists"]:
|
||||||
artist.pop("image", None)
|
artist.pop("image", None)
|
||||||
|
|
||||||
|
album_dict["type"] = "album"
|
||||||
return album_dict
|
return album_dict
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ def serialize_for_card(artist: Artist):
|
|||||||
for key in props_to_remove:
|
for key in props_to_remove:
|
||||||
artist_dict.pop(key, None)
|
artist_dict.pop(key, None)
|
||||||
|
|
||||||
|
artist_dict["type"] = "artist"
|
||||||
return artist_dict
|
return artist_dict
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class HomepageStore:
|
|||||||
"id": page["id"],
|
"id": page["id"],
|
||||||
"title": page["name"],
|
"title": page["name"],
|
||||||
"description": page["extra"]["description"],
|
"description": page["extra"]["description"],
|
||||||
"items": recover_page_items(page["items"]),
|
"items": recover_page_items(page["items"], for_homepage=True),
|
||||||
"url": f"pages/{page['id']}",
|
"url": f"pages/{page['id']}",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user