Fix Artist model to match Python reference

- Link field removed (not in Python Artist model)
- Description: string → *Description object (text, uri fields)
- SocialLinks []SocialLink → Links []Link (title, href, type, social_network)
- Donations *ArtistDonations → DonationInfo *ArtistDonationInfo (title, url)
- Decomposed []Artist → []Decomposed (accepts string or Artist object)
- Added Decomposed, Link, Description, ArtistDonationInfo types
This commit is contained in:
Mrixs committed 2026-10-18 12:44:17 +03:00
1 parent 277a3e6924
commit 577c4a418c
1 file changed
+197 -30
+197 -30
View File
@@ -14,25 +14,24 @@ type Artist struct {
Genres []string `json:"genres"` Genres []string `json:"genres"`
Tracks int `json:"tracks"` Tracks int `json:"tracks"`
Albums int `json:"albums"` Albums int `json:"albums"`
Link string `json:"link"`
Available bool `json:"available"` Available bool `json:"available"`
Description string `json:"description"`
Composer bool `json:"composer"` Composer bool `json:"composer"`
Various bool `json:"various"` Various bool `json:"various"`
Decomposed []Artist `json:"decomposed"` Decomposed []Decomposed `json:"decomposed"`
Ratings *Ratings `json:"ratings"` Ratings *Ratings `json:"ratings"`
Counts *Counts `json:"counts"` Counts *Counts `json:"counts"`
SocialLinks []SocialLink `json:"social_links"` Links []Link `json:"social_links"`
Description *Description `json:"description"`
// Additional fields // Additional fields
IDForFrom string `json:"id_for_from"` IDForFrom string `json:"id_for_from"`
Cover *Cover `json:"cover"` Cover *Cover `json:"cover"`
BriefInfo *ArtistBriefInfo `json:"brief_info"` BriefInfo *ArtistBriefInfo `json:"brief_info"`
Donations *ArtistDonations `json:"donations"` DonationInfo *ArtistDonationInfo `json:"donation_info"`
Concerts []Concert `json:"concerts"` Concerts []Concert `json:"concerts"`
Clips []Clip `json:"clips"` Clips []Clip `json:"clips"`
Similar []Artist `json:"similar"` Similar []Artist `json:"similar"`
AlbumsData []Album `json:"albums_data"` AlbumsData []Album `json:"albums_data"`
TracksData []Track `json:"tracks_data"` TracksData []Track `json:"tracks_data"`
} }
// DeJSON deserializes an Artist from JSON data. // DeJSON deserializes an Artist from JSON data.
@@ -63,15 +62,9 @@ func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) {
if v, ok := raw["albums"]; ok { if v, ok := raw["albums"]; ok {
json.Unmarshal(v, &artist.Albums) json.Unmarshal(v, &artist.Albums)
} }
if v, ok := raw["link"]; ok {
json.Unmarshal(v, &artist.Link)
}
if v, ok := raw["available"]; ok { if v, ok := raw["available"]; ok {
json.Unmarshal(v, &artist.Available) json.Unmarshal(v, &artist.Available)
} }
if v, ok := raw["description"]; ok {
json.Unmarshal(v, &artist.Description)
}
if v, ok := raw["composer"]; ok { if v, ok := raw["composer"]; ok {
json.Unmarshal(v, &artist.Composer) json.Unmarshal(v, &artist.Composer)
} }
@@ -84,9 +77,10 @@ func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) {
// Nested objects // Nested objects
if v, ok := raw["decomposed"]; ok { if v, ok := raw["decomposed"]; ok {
var decomposed []Artist var decomposed []Decomposed
json.Unmarshal(v, &decomposed) if err := json.Unmarshal(v, &decomposed); err == nil {
artist.Decomposed = decomposed artist.Decomposed = decomposed
}
} }
if v, ok := raw["ratings"]; ok { if v, ok := raw["ratings"]; ok {
var ratings Ratings var ratings Ratings
@@ -99,9 +93,10 @@ func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) {
artist.Counts = &counts artist.Counts = &counts
} }
if v, ok := raw["social_links"]; ok { if v, ok := raw["social_links"]; ok {
var links []SocialLink var links []Link
json.Unmarshal(v, &links) if err := json.Unmarshal(v, &links); err == nil {
artist.SocialLinks = links artist.Links = links
}
} }
if v, ok := raw["cover"]; ok { if v, ok := raw["cover"]; ok {
var cover Cover var cover Cover
@@ -113,10 +108,10 @@ func (a *Artist) DeJSON(data []byte, c ClientInterface) (Model, error) {
json.Unmarshal(v, &brief) json.Unmarshal(v, &brief)
artist.BriefInfo = &brief artist.BriefInfo = &brief
} }
if v, ok := raw["donations"]; ok { if v, ok := raw["donation_info"]; ok {
var donations ArtistDonations var donation ArtistDonationInfo
json.Unmarshal(v, &donations) json.Unmarshal(v, &donation)
artist.Donations = &donations artist.DonationInfo = &donation
} }
if v, ok := raw["concerts"]; ok { if v, ok := raw["concerts"]; ok {
var concerts []Concert var concerts []Concert
@@ -210,7 +205,7 @@ type ArtistDonations struct {
// DonationItem represents a donation item. // DonationItem represents a donation item.
type DonationItem struct { type DonationItem struct {
ID JSONID `json:"id"` ID JSONID `json:"id"`
Title string `json:"title"` Title string `json:"title"`
Description string `json:"description"` Description string `json:"description"`
Amount int `json:"amount"` Amount int `json:"amount"`
@@ -219,6 +214,178 @@ type DonationItem struct {
Currency string `json:"currency"` Currency string `json:"currency"`
} }
// Decomposed represents a decomposed artist that can be either a string or an Artist object.
type Decomposed struct {
Artist *Artist `json:"-"`
Str string `json:"-"`
IsStr bool `json:"-"`
}
// UnmarshalJSON implements json.Unmarshaler, accepting both string and Artist object.
func (d *Decomposed) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err == nil {
d.Str = s
d.IsStr = true
return nil
}
var artist Artist
if err := json.Unmarshal(data, &artist); err != nil {
return err
}
d.Artist = &artist
d.IsStr = false
return nil
}
// MarshalJSON implements json.Marshaler.
func (d Decomposed) MarshalJSON() ([]byte, error) {
if d.IsStr {
return json.Marshal(d.Str)
}
return json.Marshal(d.Artist)
}
// Link represents a link to an artist's official page or social network.
type Link struct {
BaseModel
Title string `json:"title"`
Href string `json:"href"`
Type string `json:"type"`
SocialNetwork string `json:"social_network"`
}
// DeJSON deserializes Link from JSON data.
func (l *Link) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
link := &Link{BaseModel: *NewBaseModel(c)}
if v, ok := raw["title"]; ok {
json.Unmarshal(v, &link.Title)
}
if v, ok := raw["href"]; ok {
json.Unmarshal(v, &link.Href)
}
if v, ok := raw["type"]; ok {
json.Unmarshal(v, &link.Type)
}
if v, ok := raw["social_network"]; ok {
json.Unmarshal(v, &link.SocialNetwork)
}
return link, nil
}
// DeList deserializes a list of Links from JSON data.
func (l *Link) 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 {
link := &Link{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, link); err != nil {
continue
}
result = append(result, link)
}
return result, nil
}
// Description represents artist description.
type Description struct {
BaseModel
Text string `json:"text"`
URI string `json:"uri"`
}
// DeJSON deserializes Description from JSON data.
func (d *Description) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
desc := &Description{BaseModel: *NewBaseModel(c)}
if v, ok := raw["text"]; ok {
json.Unmarshal(v, &desc.Text)
}
if v, ok := raw["uri"]; ok {
json.Unmarshal(v, &desc.URI)
}
return desc, nil
}
// DeList deserializes a list of Descriptions from JSON data.
func (d *Description) 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 {
desc := &Description{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, desc); err != nil {
continue
}
result = append(result, desc)
}
return result, nil
}
// ArtistDonationInfo represents artist donation info.
type ArtistDonationInfo struct {
BaseModel
Title string `json:"title"`
URL string `json:"url"`
}
// DeJSON deserializes ArtistDonationInfo from JSON data.
func (adi *ArtistDonationInfo) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
info := &ArtistDonationInfo{BaseModel: *NewBaseModel(c)}
if v, ok := raw["title"]; ok {
json.Unmarshal(v, &info.Title)
}
if v, ok := raw["url"]; ok {
json.Unmarshal(v, &info.URL)
}
return info, nil
}
// DeList deserializes a list of ArtistDonationInfo from JSON data.
func (adi *ArtistDonationInfo) 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 {
info := &ArtistDonationInfo{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, info); err != nil {
continue
}
result = append(result, info)
}
return result, nil
}
// ConcertShort represents a concert (minimal for artist). // ConcertShort represents a concert (minimal for artist).
type ConcertShort struct { type ConcertShort struct {
BaseModel BaseModel