Feed: Added can_get_more_events, pumpkin, is_wizard_passed, headlines, today, next_revision Label: Added description_formatted, image, links ([]Link), type Landing: Added pumpkin, content_id Pin: Added content_restrictions Search: Added search_request_id, text, best, podcasts, podcast_episodes, clips, banner, page, per_page, misspell fields Clip: Rewrote with all missing fields (version, player_id, uuid, thumbnail, track_ids, disclaimers, explicit, cover, content_restrictions) Concert: Added datetime, afisha_url, city, place, address, content_rating, data_session_id, event_info
304 lines
8.2 KiB
Go
304 lines
8.2 KiB
Go
// Package models provides data models for the Yandex Music API.
|
|
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
)
|
|
|
|
// Feed represents the main feed from the Yandex Music API.
|
|
type Feed struct {
|
|
BaseModel
|
|
CanGetMoreEvents bool `json:"can_get_more_events"`
|
|
Pumpkin bool `json:"pumpkin"`
|
|
IsWizardPassed bool `json:"is_wizard_passed"`
|
|
Headlines []string `json:"headlines"`
|
|
Today string `json:"today"`
|
|
Days []Day `json:"days"`
|
|
GeneratedPlaylists []GeneratedPlaylist `json:"generated_playlists"`
|
|
PlayContexts []PlayContext `json:"play_contexts"`
|
|
NextRevision string `json:"next_revision"`
|
|
}
|
|
|
|
// DeJSON deserializes a Feed from JSON data.
|
|
func (f *Feed) DeJSON(data []byte, c ClientInterface) (Model, error) {
|
|
var raw map[string]json.RawMessage
|
|
if err := json.Unmarshal(data, &raw); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
feed := &Feed{BaseModel: *NewBaseModel(c)}
|
|
|
|
if v, ok := raw["can_get_more_events"]; ok {
|
|
json.Unmarshal(v, &feed.CanGetMoreEvents)
|
|
}
|
|
if v, ok := raw["pumpkin"]; ok {
|
|
json.Unmarshal(v, &feed.Pumpkin)
|
|
}
|
|
if v, ok := raw["is_wizard_passed"]; ok {
|
|
json.Unmarshal(v, &feed.IsWizardPassed)
|
|
}
|
|
if v, ok := raw["headlines"]; ok {
|
|
json.Unmarshal(v, &feed.Headlines)
|
|
}
|
|
if v, ok := raw["today"]; ok {
|
|
json.Unmarshal(v, &feed.Today)
|
|
}
|
|
if v, ok := raw["days"]; ok {
|
|
var days []Day
|
|
json.Unmarshal(v, &days)
|
|
feed.Days = days
|
|
}
|
|
if v, ok := raw["generated_playlists"]; ok {
|
|
var playlists []GeneratedPlaylist
|
|
json.Unmarshal(v, &playlists)
|
|
feed.GeneratedPlaylists = playlists
|
|
}
|
|
if v, ok := raw["play_contexts"]; ok {
|
|
var contexts []PlayContext
|
|
json.Unmarshal(v, &contexts)
|
|
feed.PlayContexts = contexts
|
|
}
|
|
if v, ok := raw["next_revision"]; ok {
|
|
json.Unmarshal(v, &feed.NextRevision)
|
|
}
|
|
|
|
return feed, nil
|
|
}
|
|
|
|
// DeList deserializes a list of Feeds from JSON data.
|
|
func (f *Feed) 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 {
|
|
feed := &Feed{BaseModel: *NewBaseModel(c)}
|
|
if err := json.Unmarshal(item, feed); err != nil {
|
|
continue
|
|
}
|
|
result = append(result, feed)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// Day represents a day in the feed.
|
|
type Day struct {
|
|
BaseModel
|
|
Date string `json:"date"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Blocks []DayBlock `json:"blocks"`
|
|
GeneratedPlaylists []GeneratedPlaylist `json:"generated_playlists"`
|
|
}
|
|
|
|
// DeJSON deserializes a Day from JSON data.
|
|
func (d *Day) DeJSON(data []byte, c ClientInterface) (Model, error) {
|
|
var raw map[string]json.RawMessage
|
|
if err := json.Unmarshal(data, &raw); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
day := &Day{BaseModel: *NewBaseModel(c)}
|
|
|
|
if v, ok := raw["date"]; ok {
|
|
json.Unmarshal(v, &day.Date)
|
|
}
|
|
if v, ok := raw["title"]; ok {
|
|
json.Unmarshal(v, &day.Title)
|
|
}
|
|
if v, ok := raw["description"]; ok {
|
|
json.Unmarshal(v, &day.Description)
|
|
}
|
|
if v, ok := raw["blocks"]; ok {
|
|
var blocks []DayBlock
|
|
json.Unmarshal(v, &blocks)
|
|
day.Blocks = blocks
|
|
}
|
|
if v, ok := raw["generated_playlists"]; ok {
|
|
var playlists []GeneratedPlaylist
|
|
json.Unmarshal(v, &playlists)
|
|
day.GeneratedPlaylists = playlists
|
|
}
|
|
|
|
return day, nil
|
|
}
|
|
|
|
// DeList deserializes a list of Days from JSON data.
|
|
func (d *Day) 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 {
|
|
day := &Day{BaseModel: *NewBaseModel(c)}
|
|
if err := json.Unmarshal(item, day); err != nil {
|
|
continue
|
|
}
|
|
result = append(result, day)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// DayBlock represents a block in a day.
|
|
type DayBlock struct {
|
|
BaseModel
|
|
ID JSONID `json:"id"`
|
|
Type string `json:"type"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Data *DayBlockData `json:"data"`
|
|
}
|
|
|
|
// DayBlockData represents data in a day block.
|
|
type DayBlockData struct {
|
|
Tracks []Track `json:"tracks"`
|
|
Playlists []Playlist `json:"playlists"`
|
|
Albums []Album `json:"albums"`
|
|
Artists []Artist `json:"artists"`
|
|
GeneratedPlaylist *GeneratedPlaylist `json:"generated_playlist"`
|
|
}
|
|
|
|
// GeneratedPlaylist represents a generated playlist.
|
|
type GeneratedPlaylist struct {
|
|
BaseModel
|
|
ID JSONID `json:"id"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
CoverURI string `json:"cover_uri"`
|
|
TrackCount int `json:"track_count"`
|
|
DurationMs int `json:"duration_ms"`
|
|
Kind int `json:"kind"`
|
|
Revision int `json:"revision"`
|
|
Type string `json:"type"`
|
|
Available bool `json:"available"`
|
|
Tracks []Track `json:"tracks"`
|
|
}
|
|
|
|
// DeJSON deserializes a GeneratedPlaylist from JSON data.
|
|
func (gp *GeneratedPlaylist) 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 := &GeneratedPlaylist{BaseModel: *NewBaseModel(c)}
|
|
|
|
if v, ok := raw["id"]; ok {
|
|
json.Unmarshal(v, &playlist.ID)
|
|
}
|
|
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["track_count"]; ok {
|
|
json.Unmarshal(v, &playlist.TrackCount)
|
|
}
|
|
if v, ok := raw["duration_ms"]; ok {
|
|
json.Unmarshal(v, &playlist.DurationMs)
|
|
}
|
|
if v, ok := raw["kind"]; ok {
|
|
json.Unmarshal(v, &playlist.Kind)
|
|
}
|
|
if v, ok := raw["revision"]; ok {
|
|
json.Unmarshal(v, &playlist.Revision)
|
|
}
|
|
if v, ok := raw["type"]; ok {
|
|
json.Unmarshal(v, &playlist.Type)
|
|
}
|
|
if v, ok := raw["available"]; ok {
|
|
json.Unmarshal(v, &playlist.Available)
|
|
}
|
|
if v, ok := raw["tracks"]; ok {
|
|
var tracks []Track
|
|
json.Unmarshal(v, &tracks)
|
|
playlist.Tracks = tracks
|
|
}
|
|
|
|
return playlist, nil
|
|
}
|
|
|
|
// DeList deserializes a list of GeneratedPlaylists from JSON data.
|
|
func (gp *GeneratedPlaylist) 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 := &GeneratedPlaylist{BaseModel: *NewBaseModel(c)}
|
|
if err := json.Unmarshal(item, playlist); err != nil {
|
|
continue
|
|
}
|
|
result = append(result, playlist)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// Event represents a feed event.
|
|
type Event struct {
|
|
BaseModel
|
|
Timestamp string `json:"timestamp"`
|
|
Type string `json:"type"`
|
|
TrackID string `json:"track_id"`
|
|
AlbumID string `json:"album_id"`
|
|
ArtistID string `json:"artist_id"`
|
|
PlaylistID string `json:"playlist_id"`
|
|
Action string `json:"action"`
|
|
}
|
|
|
|
// AlbumEvent represents an album event.
|
|
type AlbumEvent struct {
|
|
BaseModel
|
|
Album *Album `json:"album"`
|
|
Timestamp string `json:"timestamp"`
|
|
Type string `json:"type"`
|
|
Action string `json:"action"`
|
|
}
|
|
|
|
// ArtistEvent represents an artist event.
|
|
type ArtistEvent struct {
|
|
BaseModel
|
|
Artist *Artist `json:"artist"`
|
|
Timestamp string `json:"timestamp"`
|
|
Type string `json:"type"`
|
|
Action string `json:"action"`
|
|
}
|
|
|
|
// TrackWithAds represents a track with ads.
|
|
type TrackWithAds struct {
|
|
BaseModel
|
|
Track *Track `json:"track"`
|
|
Ads []Ad `json:"ads"`
|
|
AdParams *AdParams `json:"ad_params"`
|
|
}
|
|
|
|
// Ad represents an ad.
|
|
type Ad struct {
|
|
BaseModel
|
|
ID JSONID `json:"id"`
|
|
Type string `json:"type"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Image string `json:"image"`
|
|
URL string `json:"url"`
|
|
Duration int `json:"duration"`
|
|
}
|
|
|
|
// AdParams represents ad parameters.
|
|
type AdParams struct {
|
|
BaseModel
|
|
Frequency int `json:"frequency"`
|
|
MaxPerDay int `json:"max_per_day"`
|
|
Targeting string `json:"targeting"`
|
|
}
|