package models import ( "encoding/json" ) // Playlist represents a playlist type Playlist struct { BaseModel Kind int `json:"kind"` Title string `json:"title"` Description string `json:"description"` CoverURI string `json:"cover_uri"` Created string `json:"created"` Modified string `json:"modified"` TrackCount int `json:"track_count"` DurationMs int `json:"duration_ms"` Availability *Availability `json:"availability"` Owner *User `json:"owner"` Tracks []Track `json:"tracks"` LikesCount int `json:"likes_count"` IsPublic bool `json:"is_public"` Revision int `json:"revision"` UUID string `json:"uuid"` Tags []string `json:"tags"` SimilarPlaylists []Playlist `json:"similar_playlists"` // Additional fields AccessType string `json:"access_type"` Available bool `json:"available"` ContentWarning string `json:"content_warning"` Genre string `json:"genre"` Image []Image `json:"image"` OwnerUID int64 `json:"owner_uid"` Shared bool `json:"shared"` SnapshotID string `json:"snapshot_id"` Trailer *TrailerInfo `json:"trailer"` } // DeJSON deserializes a Playlist from JSON func (p *Playlist) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } playlist := &Playlist{BaseModel: *NewBaseModel(c)} // Simple fields if v, ok := raw["kind"]; ok { json.Unmarshal(v, &playlist.Kind) } if v, ok := raw["title"]; ok { json.Unmarshal(v, &playlist.Title) } if v, ok := raw["description"]; ok { json.Unmarshal(v, &playlist.Description) } if v, ok := raw["cover_uri"]; ok { json.Unmarshal(v, &playlist.CoverURI) } if v, ok := raw["created"]; ok { json.Unmarshal(v, &playlist.Created) } if v, ok := raw["modified"]; ok { json.Unmarshal(v, &playlist.Modified) } if v, ok := raw["track_count"]; ok { json.Unmarshal(v, &playlist.TrackCount) } if v, ok := raw["duration_ms"]; ok { json.Unmarshal(v, &playlist.DurationMs) } if v, ok := raw["likes_count"]; ok { json.Unmarshal(v, &playlist.LikesCount) } if v, ok := raw["is_public"]; ok { json.Unmarshal(v, &playlist.IsPublic) } if v, ok := raw["revision"]; ok { json.Unmarshal(v, &playlist.Revision) } if v, ok := raw["uuid"]; ok { json.Unmarshal(v, &playlist.UUID) } if v, ok := raw["tags"]; ok { json.Unmarshal(v, &playlist.Tags) } if v, ok := raw["access_type"]; ok { json.Unmarshal(v, &playlist.AccessType) } if v, ok := raw["available"]; ok { json.Unmarshal(v, &playlist.Available) } if v, ok := raw["content_warning"]; ok { json.Unmarshal(v, &playlist.ContentWarning) } if v, ok := raw["genre"]; ok { json.Unmarshal(v, &playlist.Genre) } if v, ok := raw["owner_uid"]; ok { json.Unmarshal(v, &playlist.OwnerUID) } if v, ok := raw["shared"]; ok { json.Unmarshal(v, &playlist.Shared) } if v, ok := raw["snapshot_id"]; ok { json.Unmarshal(v, &playlist.SnapshotID) } // Nested objects if v, ok := raw["availability"]; ok { var avail Availability json.Unmarshal(v, &avail) playlist.Availability = &avail } if v, ok := raw["owner"]; ok { var user User json.Unmarshal(v, &user) playlist.Owner = &user } if v, ok := raw["tracks"]; ok { var tracks []Track json.Unmarshal(v, &tracks) playlist.Tracks = tracks } if v, ok := raw["similar_playlists"]; ok { var similar []Playlist json.Unmarshal(v, &similar) playlist.SimilarPlaylists = similar } if v, ok := raw["image"]; ok { var images []Image json.Unmarshal(v, &images) playlist.Image = images } if v, ok := raw["trailer"]; ok { var trailer TrailerInfo json.Unmarshal(v, &trailer) playlist.Trailer = &trailer } return playlist, nil } // DeList deserializes a list of Playlists func (p *Playlist) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { playlist := &Playlist{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, playlist); err != nil { continue } result = append(result, playlist) } return result, nil } // User represents a user (playlist owner) type User struct { BaseModel UID int64 `json:"uid"` Login string `json:"login"` DisplayName string `json:"display_name"` CoverURI string `json:"cover_uri"` Sex string `json:"sex"` PublicPlaylists int `json:"public_playlists"` FollowersCount int `json:"followers_count"` FollowingsCount int `json:"followings_count"` HasPlaylists bool `json:"has_playlists"` Available bool `json:"available"` // Additional fields Description string `json:"description"` IsVerified bool `json:"is_verified"` City string `json:"city"` Country string `json:"country"` Birthday string `json:"birthday"` RegistrationDate string `json:"registration_date"` Settings *UserSettings `json:"settings"` Counters *UserCounters `json:"counters"` } // DeJSON deserializes a User from JSON func (u *User) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } user := &User{BaseModel: *NewBaseModel(c)} if v, ok := raw["uid"]; ok { json.Unmarshal(v, &user.UID) } if v, ok := raw["login"]; ok { json.Unmarshal(v, &user.Login) } if v, ok := raw["display_name"]; ok { json.Unmarshal(v, &user.DisplayName) } if v, ok := raw["cover_uri"]; ok { json.Unmarshal(v, &user.CoverURI) } if v, ok := raw["sex"]; ok { json.Unmarshal(v, &user.Sex) } if v, ok := raw["public_playlists"]; ok { json.Unmarshal(v, &user.PublicPlaylists) } if v, ok := raw["followers_count"]; ok { json.Unmarshal(v, &user.FollowersCount) } if v, ok := raw["followings_count"]; ok { json.Unmarshal(v, &user.FollowingsCount) } if v, ok := raw["has_playlists"]; ok { json.Unmarshal(v, &user.HasPlaylists) } if v, ok := raw["available"]; ok { json.Unmarshal(v, &user.Available) } if v, ok := raw["description"]; ok { json.Unmarshal(v, &user.Description) } if v, ok := raw["is_verified"]; ok { json.Unmarshal(v, &user.IsVerified) } if v, ok := raw["city"]; ok { json.Unmarshal(v, &user.City) } if v, ok := raw["country"]; ok { json.Unmarshal(v, &user.Country) } if v, ok := raw["birthday"]; ok { json.Unmarshal(v, &user.Birthday) } if v, ok := raw["registration_date"]; ok { json.Unmarshal(v, &user.RegistrationDate) } if v, ok := raw["settings"]; ok { var settings UserSettings json.Unmarshal(v, &settings) user.Settings = &settings } if v, ok := raw["counters"]; ok { var counters UserCounters json.Unmarshal(v, &counters) user.Counters = &counters } return user, nil } // DeList deserializes a list of Users func (u *User) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { user := &User{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, user); err != nil { continue } result = append(result, user) } return result, nil } // UserSettings represents user settings (from /account/settings) type UserSettings struct { BaseModel UID int64 `json:"uid"` LastFMScrobblingEnabled bool `json:"last_fm_scrobbling_enabled"` ShuffleEnabled bool `json:"shuffle_enabled"` VolumePercents int `json:"volume_percents"` Modified string `json:"modified"` FacebookScrobblingEnabled bool `json:"facebook_scrobbling_enabled"` AddNewTrackOnPlaylistTop bool `json:"add_new_track_on_playlist_top"` UserMusicVisibility string `json:"user_music_visibility"` UserSocialVisibility string `json:"user_social_visibility"` RBTDisabled bool `json:"rbt_disabled"` Theme string `json:"theme"` PromosDisabled bool `json:"promos_disabled"` AutoPlayRadio bool `json:"auto_play_radio"` SyncQueueEnabled bool `json:"sync_queue_enabled"` AdsDisabled *bool `json:"ads_disabled,omitempty"` DiskEnabled *bool `json:"disk_enabled,omitempty"` ShowDiskTracksInLibrary *bool `json:"show_disk_tracks_in_library,omitempty"` } // DeJSON deserializes UserSettings from JSON func (u *UserSettings) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } settings := &UserSettings{BaseModel: *NewBaseModel(c)} if v, ok := raw["uid"]; ok { json.Unmarshal(v, &settings.UID) } if v, ok := raw["last_fm_scrobbling_enabled"]; ok { json.Unmarshal(v, &settings.LastFMScrobblingEnabled) } if v, ok := raw["shuffle_enabled"]; ok { json.Unmarshal(v, &settings.ShuffleEnabled) } if v, ok := raw["volume_percents"]; ok { json.Unmarshal(v, &settings.VolumePercents) } if v, ok := raw["modified"]; ok { json.Unmarshal(v, &settings.Modified) } if v, ok := raw["facebook_scrobbling_enabled"]; ok { json.Unmarshal(v, &settings.FacebookScrobblingEnabled) } if v, ok := raw["add_new_track_on_playlist_top"]; ok { json.Unmarshal(v, &settings.AddNewTrackOnPlaylistTop) } if v, ok := raw["user_music_visibility"]; ok { json.Unmarshal(v, &settings.UserMusicVisibility) } if v, ok := raw["user_social_visibility"]; ok { json.Unmarshal(v, &settings.UserSocialVisibility) } if v, ok := raw["rbt_disabled"]; ok { json.Unmarshal(v, &settings.RBTDisabled) } if v, ok := raw["theme"]; ok { json.Unmarshal(v, &settings.Theme) } if v, ok := raw["promos_disabled"]; ok { json.Unmarshal(v, &settings.PromosDisabled) } if v, ok := raw["auto_play_radio"]; ok { json.Unmarshal(v, &settings.AutoPlayRadio) } if v, ok := raw["sync_queue_enabled"]; ok { json.Unmarshal(v, &settings.SyncQueueEnabled) } if v, ok := raw["ads_disabled"]; ok { var val bool json.Unmarshal(v, &val) settings.AdsDisabled = &val } if v, ok := raw["disk_enabled"]; ok { var val bool json.Unmarshal(v, &val) settings.DiskEnabled = &val } if v, ok := raw["show_disk_tracks_in_library"]; ok { var val bool json.Unmarshal(v, &val) settings.ShowDiskTracksInLibrary = &val } return settings, nil } // DeList deserializes a list of UserSettings func (u *UserSettings) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { settings := &UserSettings{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, settings); err != nil { continue } result = append(result, settings) } return result, nil } // UserCounters represents user counters type UserCounters struct { Tracks int `json:"tracks"` Albums int `json:"albums"` Playlists int `json:"playlists"` Followers int `json:"followers"` Followings int `json:"followings"` Likes int `json:"likes"` } // Image represents an image with multiple sizes type Image struct { URI string `json:"uri"` Type string `json:"type"` Width int `json:"width"` Height int `json:"height"` Size int64 `json:"size"` Extension string `json:"extension"` } // Re-export types from other files for convenience // Availability, TrailerInfo are defined in album.go