Fix R128 and remaining ID fields to accept both JSON types
- Track.R128 and TrackShort.R128: float64 → JSONR128 (accepts both JSON number and object) - All remaining primary ID fields: string → JSONID (accepts both JSON string and number) Fixed in: account, artist, clip, concert, feed, label, landing, metatag, music_history, pin, queue, radio, search, settings, supplement
This commit is contained in:
1 parent
d0173f795d
commit
dbb823ade3
18 files changed
+75
-44
No files matched your search
@@ -112,7 +112,7 @@ func (a *AccountSettings) DeList(data []byte, c ClientInterface) ([]Model, error
|
||||
// Subscription represents subscription info.
|
||||
type Subscription struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
StartDate string `json:"start_date"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Artist represents a full artist from the Yandex Music API.
|
||||
type Artist struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
Genres []string `json:"genres"`
|
||||
@@ -210,7 +210,7 @@ type ArtistDonations struct {
|
||||
|
||||
// DonationItem represents a donation item.
|
||||
type DonationItem struct {
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Amount int `json:"amount"`
|
||||
@@ -222,7 +222,7 @@ type DonationItem struct {
|
||||
// ConcertShort represents a concert (minimal for artist).
|
||||
type ConcertShort struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Date string `json:"date"`
|
||||
Venue string `json:"venue"`
|
||||
@@ -298,7 +298,7 @@ func (c *ConcertShort) DeList(data []byte, client ClientInterface) ([]Model, err
|
||||
// ClipShort represents a clip (minimal for artist).
|
||||
type ClipShort struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Duration int `json:"duration"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
|
||||
@@ -110,3 +110,34 @@ func (id *JSONID) UnmarshalJSON(data []byte) error {
|
||||
func (id JSONID) String() string {
|
||||
return string(id)
|
||||
}
|
||||
|
||||
// JSONR128 is a flexible R128 loudness normalization value that accepts both JSON numbers and objects.
|
||||
// The Yandex Music API sometimes returns r128 as a number (e.g., -23.5) and sometimes
|
||||
// as an object (e.g., {"value": -23.5}). JSONR128 accepts both and stores as float64.
|
||||
type JSONR128 float64
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler, accepting both JSON numbers and objects.
|
||||
func (r *JSONR128) UnmarshalJSON(data []byte) error {
|
||||
// Try float64 first
|
||||
var f float64
|
||||
if err := json.Unmarshal(data, &f); err == nil {
|
||||
*r = JSONR128(f)
|
||||
return nil
|
||||
}
|
||||
// Try object with "value" key
|
||||
var obj struct {
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &obj); err == nil {
|
||||
*r = JSONR128(obj.Value)
|
||||
return nil
|
||||
}
|
||||
// Default to 0 if neither format works
|
||||
*r = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64 returns the R128 value as a float64.
|
||||
func (r JSONR128) Float64() float64 {
|
||||
return float64(r)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Clip represents a clip (short video) from the Yandex Music API.
|
||||
type Clip struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Duration int `json:"duration"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
@@ -132,7 +132,7 @@ type ArtistClipItem struct {
|
||||
// Shot represents a shot (short video).
|
||||
type Shot struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Duration int `json:"duration"`
|
||||
@@ -258,7 +258,7 @@ type ShotEvent struct {
|
||||
// ShotType represents a shot type.
|
||||
type ShotType struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Concert represents a concert from the Yandex Music API.
|
||||
type Concert struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Date string `json:"date"`
|
||||
@@ -133,7 +133,7 @@ func (c *Concert) DeList(data []byte, client ClientInterface) ([]Model, error) {
|
||||
// ConcertVenue represents a concert venue.
|
||||
type ConcertVenue struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Address string `json:"address"`
|
||||
City string `json:"city"`
|
||||
@@ -145,7 +145,7 @@ type ConcertVenue struct {
|
||||
// ConcertLocation represents a concert location.
|
||||
type ConcertLocation struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
City string `json:"city"`
|
||||
Country string `json:"country"`
|
||||
@@ -214,7 +214,7 @@ type ConcertMinPrice struct {
|
||||
// ConcertTabConfig represents concert tab config.
|
||||
type ConcertTabConfig struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
Active bool `json:"active"`
|
||||
@@ -237,7 +237,7 @@ type ConcertSkeleton struct {
|
||||
// ConcertSkeletonBlock represents a concert skeleton block.
|
||||
type ConcertSkeletonBlock struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
|
||||
@@ -122,7 +122,7 @@ func (d *Day) DeList(data []byte, c ClientInterface) ([]Model, error) {
|
||||
// DayBlock represents a block in a day.
|
||||
type DayBlock struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
@@ -141,7 +141,7 @@ type DayBlockData struct {
|
||||
// GeneratedPlaylist represents a generated playlist.
|
||||
type GeneratedPlaylist struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
@@ -261,7 +261,7 @@ type TrackWithAds struct {
|
||||
// Ad represents an ad.
|
||||
type Ad struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Label represents a label from the Yandex Music API.
|
||||
type Label struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Landing represents a landing page from the Yandex Music API.
|
||||
type Landing struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
@@ -75,7 +75,7 @@ func (l *Landing) DeList(data []byte, c ClientInterface) ([]Model, error) {
|
||||
// LandingBlock represents a block in a landing.
|
||||
type LandingBlock struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Metatag represents a metatag from the Yandex Music API.
|
||||
type Metatag struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
@@ -81,7 +81,7 @@ type MetatagTree struct {
|
||||
// MetatagLeaf represents a metatag leaf.
|
||||
type MetatagLeaf struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
@@ -139,7 +139,7 @@ type MetatagArtistEntry struct {
|
||||
// Genre represents a genre from the Yandex Music API.
|
||||
type Genre struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
@@ -205,7 +205,7 @@ func (g *Genre) DeList(data []byte, client ClientInterface) ([]Model, error) {
|
||||
// Chart represents a chart from the Yandex Music API.
|
||||
type Chart struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
@@ -286,7 +286,7 @@ type ChartItem struct {
|
||||
// ChartInfoMenu represents a chart info menu.
|
||||
type ChartInfoMenu struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Items []ChartInfoMenuItem `json:"items"`
|
||||
@@ -295,7 +295,7 @@ type ChartInfoMenu struct {
|
||||
// ChartInfoMenuItem represents a chart info menu item.
|
||||
type ChartInfoMenuItem struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Action string `json:"action"`
|
||||
|
||||
@@ -68,7 +68,7 @@ func (mh *MusicHistory) DeList(data []byte, client ClientInterface) ([]Model, er
|
||||
// MusicHistoryTab represents a music history tab.
|
||||
type MusicHistoryTab struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Icon string `json:"icon"`
|
||||
@@ -79,7 +79,7 @@ type MusicHistoryTab struct {
|
||||
// MusicHistoryGroup represents a music history group.
|
||||
type MusicHistoryGroup struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Items []MusicHistoryItem `json:"items"`
|
||||
@@ -89,7 +89,7 @@ type MusicHistoryGroup struct {
|
||||
// MusicHistoryItem represents a music history item.
|
||||
type MusicHistoryItem struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"` // "track", "album", "artist", "playlist"
|
||||
Track *Track `json:"track"`
|
||||
Album *Album `json:"album"`
|
||||
@@ -116,7 +116,7 @@ type MusicHistoryItemData struct {
|
||||
// MusicHistoryItemID represents music history item ID.
|
||||
type MusicHistoryItemID struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Pin represents a pin from the Yandex Music API.
|
||||
type Pin struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
@@ -130,7 +130,7 @@ type Presaves struct {
|
||||
// Presave represents a presave.
|
||||
type Presave struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// Queue represents a playback queue from the Yandex Music API.
|
||||
type Queue struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
TrackIDs []string `json:"track_ids"`
|
||||
CurrentIndex int `json:"current_index"`
|
||||
QueueType string `json:"queue_type"`
|
||||
@@ -162,7 +162,7 @@ func (qi *QueueItem) DeList(data []byte, c ClientInterface) ([]Model, error) {
|
||||
// PlayContext represents a play context.
|
||||
type PlayContext struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"` // "playlist", "album", "artist", "radio", "search"
|
||||
SourceID string `json:"source_id"`
|
||||
SourceKind string `json:"source_kind"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// RadioStation represents a radio station from the Yandex Music API.
|
||||
type RadioStation struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
@@ -122,7 +122,7 @@ func (s *StationTracksResult) DeList(data []byte, client ClientInterface) ([]Mod
|
||||
// RotorStation represents a rotor (generative) station.
|
||||
type RotorStation struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
|
||||
@@ -49,7 +49,7 @@ type SearchUsersResult struct {
|
||||
|
||||
// SearchBanner represents a search banner.
|
||||
type SearchBanner struct {
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Image string `json:"image"`
|
||||
@@ -60,7 +60,7 @@ type SearchBanner struct {
|
||||
|
||||
// Tag represents a search tag.
|
||||
type Tag struct {
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Count int `json:"count"`
|
||||
@@ -70,7 +70,7 @@ type Tag struct {
|
||||
// Video represents a video (minimal).
|
||||
type Video struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Duration int `json:"duration"`
|
||||
CoverURI string `json:"cover_uri"`
|
||||
|
||||
@@ -54,7 +54,7 @@ func (e *Experiments) DeList(data []byte, client ClientInterface) ([]Model, erro
|
||||
// ExperimentDetail represents experiment details.
|
||||
type ExperimentDetail struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Status string `json:"status"`
|
||||
@@ -240,7 +240,7 @@ func (p *PermissionAlerts) DeList(data []byte, client ClientInterface) ([]Model,
|
||||
// PermissionAlert represents a permission alert.
|
||||
type PermissionAlert struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -333,7 +333,7 @@ func (vs *VideoSupplement) DeList(data []byte, c ClientInterface) ([]Model, erro
|
||||
// Supplement represents a track supplement.
|
||||
type Supplement struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Lyrics *LyricsInfo `json:"lyrics"`
|
||||
Videos []VideoSupplement `json:"videos"`
|
||||
RadioIsAvailable bool `json:"radio_is_available"`
|
||||
|
||||
@@ -20,7 +20,7 @@ type Track struct {
|
||||
Explicit bool `json:"explicit"`
|
||||
Available bool `json:"available"`
|
||||
AvailableForPremiumUsers bool `json:"available_for_premium_users"`
|
||||
R128 float64 `json:"r128"`
|
||||
R128 JSONR128 `json:"r128"`
|
||||
TrackSharingFlag string `json:"track_sharing_flag"`
|
||||
Major *Major `json:"major"`
|
||||
Lyrics *TrackLyricsInfo `json:"lyrics"`
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
// TrackShort represents a lightweight track used in lists.
|
||||
type TrackShort struct {
|
||||
BaseModel
|
||||
ID string `json:"id"`
|
||||
ID JSONID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
DurationMs int `json:"duration_ms"`
|
||||
StorageID string `json:"storage_id"`
|
||||
@@ -20,7 +20,7 @@ type TrackShort struct {
|
||||
Explicit bool `json:"explicit"`
|
||||
Available bool `json:"available"`
|
||||
AvailableForPremiumUsers bool `json:"available_for_premium_users"`
|
||||
R128 float64 `json:"r128"`
|
||||
R128 JSONR128 `json:"r128"`
|
||||
TrackSharingFlag string `json:"track_sharing_flag"`
|
||||
Major *Major `json:"major"`
|
||||
Lyrics *SupplementLyrics `json:"lyrics"`
|
||||
|
||||
Reference in new issue
Block a user