Skip to content

fix #294[,#294]#461

Open
yajathb wants to merge 1 commit into
swingmx:masterfrom
yajathb:collection-navbar
Open

fix #294[,#294]#461
yajathb wants to merge 1 commit into
swingmx:masterfrom
yajathb:collection-navbar

Conversation

@yajathb
Copy link
Copy Markdown

@yajathb yajathb commented Mar 30, 2026

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe:

The PR fulfills these requirements:

  • When resolving a specific issue, it's referenced in the PR's title (e.g. fix #xxx[,#xxx], where "xxx" is the issue number)

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature (it's best to open a suggestion issue first and wait for approval before working on it)

Other information:
I added the serverside implementation of collections and added playlist and track adding to collections.

Copilot AI review requested due to automatic review settings March 30, 2026 02:27
@yajathb yajathb marked this pull request as draft March 30, 2026 02:30
@yajathb yajathb marked this pull request as ready for review March 30, 2026 02:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds backend support for including playlists and tracks in Collections (a.k.a. pages) so they can be validated, stored, and recovered/serialized consistently across the API and homepage.

Changes:

  • Extend validate_page_items / recover_page_items to support playlist and track item types.
  • Update Collections API schemas (defaults + examples) and wrap validation errors as HTTP 400 responses.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/swingmusic/lib/pagelib.py Adds validation + recovery logic for playlist/track items and updates album/artist lookups to store getters.
src/swingmusic/api/collections.py Makes collection request fields more permissive (defaults) and returns 400 on validation errors with improved examples.

Comment on lines 20 to 24
indexed = set(create_hash(json.dumps(item)) for item in existing)

for item in items:
if create_hash(json.dumps(item)) in indexed:
continue
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In validate_page_items, the dedupe check uses create_hash(json.dumps(item)) before any normalization/coercion of the payload. For playlist IDs, hash may arrive as an int (e.g. 1) but be stored as a string (e.g. "1"), which makes the JSON hash differ and allows duplicates to slip through even though you later normalize the stored value. Consider canonicalizing type/hash (e.g. coerce playlist hash to str(int(...))) before computing the dedupe hash/index key (or dedupe based on a (type, canonical_hash) tuple).

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +53
playlist = PlaylistTable.get_by_id(playlist_id)
if playlist is not None:
# Normalize hash for stable dedupe/remove behavior.
normalized_item = dict(item)
normalized_item["hash"] = str(playlist_id)
validated.append(normalized_item)
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The playlist branch normalizes hash to a string before persisting. With the current JSON-hash based equality used elsewhere (e.g. remove_page_items), clients sending {type:"playlist", hash: 1} vs {..., hash: "1"} will no longer match what’s stored, so removing the item (and some dedupe scenarios) can silently fail. To avoid type-mismatch bugs, ensure playlist hashes are canonicalized consistently in all code paths (add + remove), or switch comparison/dedupe to use (type, canonical_hash) instead of hashing raw json.dumps output.

Copilot uses AI. Check for mistakes.
Comment on lines +117 to +123
if not playlist.has_image:
tracks = TrackStore.get_tracks_by_trackhashes(playlist.trackhashes)
playlist.images = get_first_4_images(tracks)

playlist.clear_lists()
item = serialize_playlist(playlist)
item["type"] = "playlist"
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For playlist items, get_first_4_images returns a list of {image,color} dicts, and this code assigns it directly to playlist.images. On the homepage, other playlist recovery code (lib/home/recover_items.py) converts images to a list of image strings, so collections rendered via recover_page_items(..., for_homepage=True) will return a different shape for item.images than the other homepage sections. Align the response shape (either always dicts or always strings) to avoid breaking consumers that expect one format.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants