// Package client provides methods for interacting with Yandex Music API endpoints. package client import ( "context" "fmt" "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) // GetPlaylists gets playlists by their kind IDs (GET /playlists). // Returns a slice of Playlist pointers, or nil if no kinds are provided. func (c *Client) GetPlaylists(ctx context.Context, kinds []int) ([]*models.Playlist, error) { if len(kinds) == 0 { return nil, nil } // Convert kinds to string kindsStr := "" for i, k := range kinds { if i > 0 { kindsStr += "," } kindsStr += fmt.Sprintf("%d", k) } params := map[string]string{ "kinds": kindsStr, } var result []models.Playlist if err := c.request.Get(ctx, "/playlists", params, &result); err != nil { return nil, err } playlists := make([]*models.Playlist, len(result)) for i := range result { result[i].SetClient(c) playlists[i] = &result[i] } return playlists, nil } // GetPlaylist gets a single playlist by kind using GetPlaylists. // Returns an error if no playlist is found with the given kind. func (c *Client) GetPlaylist(ctx context.Context, kind int) (*models.Playlist, error) { playlists, err := c.GetPlaylists(ctx, []int{kind}) if err != nil { return nil, err } if len(playlists) == 0 { return nil, utils.NewYandexMusicError("playlist not found", utils.ErrNotFound) } return playlists[0], nil } // GetUserPlaylists gets playlists for a user (GET /users/{userID}/playlists). func (c *Client) GetUserPlaylists(ctx context.Context, userID string) ([]*models.Playlist, error) { var result []models.Playlist if err := c.request.Get(ctx, fmt.Sprintf("/users/%s/playlists", userID), nil, &result); err != nil { return nil, err } playlists := make([]*models.Playlist, len(result)) for i := range result { result[i].SetClient(c) playlists[i] = &result[i] } return playlists, nil } // CreatePlaylist creates a new playlist (POST /users/me/playlists). // The visibility parameter should be "public" or "private". func (c *Client) CreatePlaylist(ctx context.Context, title string, visibility string) (*models.Playlist, error) { params := map[string]string{ "title": title, "visibility": visibility, // "public" or "private" } var result models.Playlist if err := c.request.Post(ctx, "/users/me/playlists", params, &result); err != nil { return nil, err } result.SetClient(c) return &result, nil } // EditPlaylist edits an existing playlist (PUT /users/me/playlists). // Only non-empty parameters are updated. func (c *Client) EditPlaylist(ctx context.Context, kind int, title, description, visibility string) (*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), } if title != "" { params["title"] = title } if description != "" { params["description"] = description } if visibility != "" { params["visibility"] = visibility } var result models.Playlist if err := c.request.Put(ctx, "/users/me/playlists", params, &result); err != nil { return nil, err } result.SetClient(c) return &result, nil } // DeletePlaylist deletes a playlist (DELETE /users/me/playlists). func (c *Client) DeletePlaylist(ctx context.Context, kind int) error { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), } var result map[string]any return c.request.Delete(ctx, "/users/me/playlists", params, &result) } // AddTracksToPlaylist adds tracks to a playlist (POST /users/me/playlists/tracks). // The revision parameter is the current playlist revision for optimistic concurrency. func (c *Client) AddTracksToPlaylist(ctx context.Context, kind int, trackIDs []string, revision int) (*models.Playlist, error) { if len(trackIDs) == 0 { return nil, utils.NewYandexMusicError("no tracks provided", utils.ErrBadRequest) } tracksStr := "" for i, id := range trackIDs { if i > 0 { tracksStr += "," } tracksStr += id } params := map[string]string{ "kind": fmt.Sprintf("%d", kind), "track_ids": tracksStr, "revision": fmt.Sprintf("%d", revision), } var result models.Playlist if err := c.request.Post(ctx, "/users/me/playlists/tracks", params, &result); err != nil { return nil, err } result.SetClient(c) return &result, nil } // RemoveTracksFromPlaylist removes tracks from a playlist (DELETE /users/me/playlists/tracks). // The revision parameter is the current playlist revision for optimistic concurrency. func (c *Client) RemoveTracksFromPlaylist(ctx context.Context, kind int, trackIDs []string, revision int) (*models.Playlist, error) { if len(trackIDs) == 0 { return nil, utils.NewYandexMusicError("no tracks provided", utils.ErrBadRequest) } tracksStr := "" for i, id := range trackIDs { if i > 0 { tracksStr += "," } tracksStr += id } params := map[string]string{ "kind": fmt.Sprintf("%d", kind), "track_ids": tracksStr, "revision": fmt.Sprintf("%d", revision), } var result models.Playlist if err := c.request.Delete(ctx, "/users/me/playlists/tracks", params, &result); err != nil { return nil, err } result.SetClient(c) return &result, nil } // ReorderPlaylistTracks reorders tracks in a playlist (PUT /users/me/playlists/tracks/reorder). // The from and to parameters specify the position range to move. func (c *Client) ReorderPlaylistTracks(ctx context.Context, kind int, from, to, revision int) (*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), "from": fmt.Sprintf("%d", from), "to": fmt.Sprintf("%d", to), "revision": fmt.Sprintf("%d", revision), } var result models.Playlist if err := c.request.Put(ctx, "/users/me/playlists/tracks/reorder", params, &result); err != nil { return nil, err } result.SetClient(c) return &result, nil } // GetPlaylistRecommendations gets playlist recommendations based on a playlist kind (GET /playlists/recommendations). func (c *Client) GetPlaylistRecommendations(ctx context.Context, kind int) ([]*models.Playlist, error) { params := map[string]string{ "kind": fmt.Sprintf("%d", kind), } var result []models.Playlist if err := c.request.Get(ctx, "/playlists/recommendations", params, &result); err != nil { return nil, err } playlists := make([]*models.Playlist, len(result)) for i := range result { result[i].SetClient(c) playlists[i] = &result[i] } return playlists, nil }