refactor: use track terminology instead of song
This commit is contained in:
@@ -22,8 +22,8 @@ type Album struct {
|
||||
Copyright string `json:"COPYRIGHT"`
|
||||
Duration string `json:"DURATION"`
|
||||
} `json:"DATA"`
|
||||
Songs struct {
|
||||
Data []*Song `json:"data"`
|
||||
Tracks struct {
|
||||
Data []*Track `json:"data"`
|
||||
} `json:"SONGS"`
|
||||
} `json:"results"`
|
||||
}
|
||||
@@ -43,7 +43,7 @@ Duration: %s
|
||||
==================================================`,
|
||||
a.Results.Data.Title,
|
||||
a.Results.Data.Artist,
|
||||
len(a.Results.Songs.Data),
|
||||
len(a.Results.Tracks.Data),
|
||||
time.Duration(duration)*time.Second,
|
||||
)
|
||||
}
|
||||
@@ -56,12 +56,12 @@ func (a *Album) GetTitle() string {
|
||||
return a.Results.Data.Title
|
||||
}
|
||||
|
||||
func (a *Album) GetSongs() []*Song {
|
||||
return a.Results.Songs.Data
|
||||
func (a *Album) GetTracks() []*Track {
|
||||
return a.Results.Tracks.Data
|
||||
}
|
||||
|
||||
func (a *Album) SetSongs(s []*Song) {
|
||||
a.Results.Songs.Data = s
|
||||
func (a *Album) SetTracks(t []*Track) {
|
||||
a.Results.Tracks.Data = t
|
||||
}
|
||||
|
||||
func (a *Album) GetOutputDir(outputDir string) string {
|
||||
|
||||
+12
-12
@@ -16,19 +16,19 @@ type Artist struct {
|
||||
Data struct {
|
||||
Name string `json:"ART_NAME"`
|
||||
} `json:"DATA"`
|
||||
Songs struct {
|
||||
Data []*Song `json:"data"`
|
||||
Tracks struct {
|
||||
Data []*Track `json:"data"`
|
||||
} `json:"TOP"`
|
||||
} `json:"results"`
|
||||
}
|
||||
|
||||
func (a *Artist) String() string {
|
||||
songs := a.Results.Songs.Data
|
||||
count := len(songs)
|
||||
tracks := a.Results.Tracks.Data
|
||||
count := len(tracks)
|
||||
|
||||
totalSec := 0
|
||||
for _, s := range songs {
|
||||
if d, err := strconv.Atoi(s.Duration); err == nil {
|
||||
for _, t := range tracks {
|
||||
if d, err := strconv.Atoi(t.Duration); err == nil {
|
||||
totalSec += d
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,8 @@ func (a *Artist) String() string {
|
||||
fmt.Fprintf(&b, "-------------------------------------------\n")
|
||||
fmt.Fprintf(&b, "Top %d most popular tracks:\n", limit)
|
||||
for i := 0; i < limit; i++ {
|
||||
s := songs[i]
|
||||
fmt.Fprintf(&b, " %2d. %s – %s\n", i+1, s.Artist, s.GetTitle())
|
||||
t := tracks[i]
|
||||
fmt.Fprintf(&b, " %2d. %s – %s\n", i+1, t.Artist, t.GetTitle())
|
||||
}
|
||||
fmt.Fprintf(&b, "===========================================\n")
|
||||
|
||||
@@ -59,12 +59,12 @@ func (a *Artist) GetTitle() string {
|
||||
return a.Results.Data.Name
|
||||
}
|
||||
|
||||
func (a *Artist) GetSongs() []*Song {
|
||||
return a.Results.Songs.Data
|
||||
func (a *Artist) GetTracks() []*Track {
|
||||
return a.Results.Tracks.Data
|
||||
}
|
||||
|
||||
func (a *Artist) SetSongs(s []*Song) {
|
||||
a.Results.Songs.Data = s
|
||||
func (a *Artist) SetTracks(t []*Track) {
|
||||
a.Results.Tracks.Data = t
|
||||
}
|
||||
|
||||
func (a *Artist) GetOutputDir(outputDir string) string {
|
||||
|
||||
@@ -79,7 +79,7 @@ func (c *Client) FetchResource(ctx context.Context, resource Resource, id string
|
||||
idKey = "alb_id"
|
||||
case *Artist:
|
||||
idKey = "art_id"
|
||||
case *Track:
|
||||
case *Single:
|
||||
idKey = "sng_id"
|
||||
default:
|
||||
return fmt.Errorf("unsupported resource type: %T", resource)
|
||||
@@ -134,14 +134,14 @@ func (c *Client) FetchResource(ctx context.Context, resource Resource, id string
|
||||
return resource.Unmarshal(body)
|
||||
}
|
||||
|
||||
func (c *Client) FetchMedia(ctx context.Context, song *Song, quality string) (*Media, error) {
|
||||
func (c *Client) FetchMedia(ctx context.Context, track *Track, quality string) (*Media, error) {
|
||||
qualityFormats := map[string]string{
|
||||
"mp3_128": `[{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`,
|
||||
"mp3_320": `[{"cipher":"BF_CBC_STRIPE","format":"MP3_320"},{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`,
|
||||
"flac": `[{"cipher":"BF_CBC_STRIPE","format":"FLAC"},{"cipher":"BF_CBC_STRIPE","format":"MP3_320"},{"cipher":"BF_CBC_STRIPE","format":"MP3_128"}]`,
|
||||
}
|
||||
|
||||
reqBody := fmt.Sprintf(`{"license_token":"%s","media":[{"type":"FULL","formats":%s}],"track_tokens":["%s"]}`, c.Session.LicenseToken, qualityFormats[quality], song.TrackToken)
|
||||
reqBody := fmt.Sprintf(`{"license_token":"%s","media":[{"type":"FULL","formats":%s}],"track_tokens":["%s"]}`, c.Session.LicenseToken, qualityFormats[quality], track.TrackToken)
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", "https://media.deezer.com/v1/get_url", bytes.NewBuffer([]byte(reqBody)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -188,8 +188,8 @@ func (c *Client) FetchMedia(ctx context.Context, song *Song, quality string) (*M
|
||||
return &media, nil
|
||||
}
|
||||
|
||||
func (c *Client) FetchCoverImage(ctx context.Context, song *Song) ([]byte, error) {
|
||||
url := fmt.Sprintf("https://e-cdn-images.dzcdn.net/images/cover/%s/500x500-000000-80-0-0.jpg", song.Cover)
|
||||
func (c *Client) FetchCoverImage(ctx context.Context, track *Track) ([]byte, error) {
|
||||
url := fmt.Sprintf("https://e-cdn-images.dzcdn.net/images/cover/%s/500x500-000000-80-0-0.jpg", track.Cover)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -16,8 +16,8 @@ type Playlist struct {
|
||||
Creator string `json:"PARENT_USERNAME"`
|
||||
Duration int `json:"DURATION"`
|
||||
} `json:"DATA"`
|
||||
Songs struct {
|
||||
Data []*Song `json:"data"`
|
||||
Tracks struct {
|
||||
Data []*Track `json:"data"`
|
||||
} `json:"SONGS"`
|
||||
} `json:"results"`
|
||||
}
|
||||
@@ -32,7 +32,7 @@ Duration: %s
|
||||
=================================================`,
|
||||
p.Results.Data.Title,
|
||||
p.Results.Data.Creator,
|
||||
len(p.Results.Songs.Data),
|
||||
len(p.Results.Tracks.Data),
|
||||
time.Duration(p.Results.Data.Duration)*time.Second,
|
||||
)
|
||||
}
|
||||
@@ -45,12 +45,12 @@ func (p *Playlist) GetTitle() string {
|
||||
return p.Results.Data.Title
|
||||
}
|
||||
|
||||
func (p *Playlist) GetSongs() []*Song {
|
||||
return p.Results.Songs.Data
|
||||
func (p *Playlist) GetTracks() []*Track {
|
||||
return p.Results.Tracks.Data
|
||||
}
|
||||
|
||||
func (p *Playlist) SetSongs(s []*Song) {
|
||||
p.Results.Songs.Data = s
|
||||
func (p *Playlist) SetTracks(t []*Track) {
|
||||
p.Results.Tracks.Data = t
|
||||
}
|
||||
|
||||
func (p *Playlist) GetOutputDir(outputDir string) string {
|
||||
|
||||
@@ -3,8 +3,8 @@ package deezer
|
||||
type Resource interface {
|
||||
GetTitle() string
|
||||
GetType() string
|
||||
GetSongs() []*Song
|
||||
SetSongs(songs []*Song)
|
||||
GetTracks() []*Track
|
||||
SetTracks(tracks []*Track)
|
||||
GetOutputDir(outputDir string) string
|
||||
Unmarshal(data []byte) error
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package deezer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Single struct {
|
||||
Results struct {
|
||||
Data *Track `json:"DATA"`
|
||||
} `json:"results"`
|
||||
}
|
||||
|
||||
func (s *Single) String() string {
|
||||
if s.Results.Data == nil {
|
||||
return "Track: No data available"
|
||||
}
|
||||
|
||||
duration, err := strconv.Atoi(s.Results.Data.Duration)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
`================= [ Track Info ] =================
|
||||
Title: %s
|
||||
Artist: %s
|
||||
Duration: %s
|
||||
==================================================`,
|
||||
s.Results.Data.GetTitle(),
|
||||
s.Results.Data.Artist,
|
||||
time.Duration(duration)*time.Second,
|
||||
)
|
||||
}
|
||||
|
||||
func (s *Single) GetType() string {
|
||||
return "Track"
|
||||
}
|
||||
|
||||
func (s *Single) GetTitle() string {
|
||||
if s.Results.Data == nil {
|
||||
return ""
|
||||
}
|
||||
return s.Results.Data.GetTitle()
|
||||
}
|
||||
|
||||
func (s *Single) GetTracks() []*Track {
|
||||
if s.Results.Data == nil {
|
||||
return nil
|
||||
}
|
||||
return []*Track{s.Results.Data}
|
||||
}
|
||||
|
||||
func (s *Single) SetTracks(tracks []*Track) {}
|
||||
|
||||
func (s *Single) GetOutputDir(outputDir string) string {
|
||||
return path.Join(outputDir, "Singles")
|
||||
}
|
||||
|
||||
func (s *Single) Unmarshal(data []byte) error {
|
||||
return json.Unmarshal(data, s)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package deezer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/flytam/filenamify"
|
||||
)
|
||||
|
||||
type Contributors struct {
|
||||
MainArtists []string `json:"main_artist"`
|
||||
Composers []string `json:"composer"`
|
||||
Authors []string `json:"author"`
|
||||
}
|
||||
|
||||
func (c *Contributors) UnmarshalJSON(data []byte) error {
|
||||
if string(data) == "[]" {
|
||||
*c = Contributors{}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Alias Contributors
|
||||
aux := (*Alias)(c)
|
||||
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
type Song struct {
|
||||
ID string `json:"SNG_ID"`
|
||||
Artist string `json:"ART_NAME"`
|
||||
Title string `json:"SNG_TITLE"`
|
||||
Version string `json:"VERSION"`
|
||||
Cover string `json:"ALB_PICTURE"`
|
||||
Contributors Contributors `json:"SNG_CONTRIBUTORS"`
|
||||
Duration string `json:"DURATION"`
|
||||
Gain string `json:"GAIN"`
|
||||
ISRC string `json:"ISRC"`
|
||||
TrackNumber string `json:"TRACK_NUMBER"`
|
||||
TrackToken string `json:"TRACK_TOKEN"`
|
||||
}
|
||||
|
||||
func (s *Song) GetTitle() string {
|
||||
if s.Version != "" {
|
||||
return s.Title + " " + s.Version
|
||||
}
|
||||
return s.Title
|
||||
}
|
||||
|
||||
func (s *Song) GetFileName(resourceType, mediaFormat string) string {
|
||||
ext := "mp3"
|
||||
if mediaFormat == "FLAC" {
|
||||
ext = "flac"
|
||||
}
|
||||
|
||||
prefix := ""
|
||||
if resourceType == "album" {
|
||||
if n, err := strconv.Atoi(s.TrackNumber); err == nil {
|
||||
prefix = fmt.Sprintf("%02d. ", n)
|
||||
} else {
|
||||
prefix = s.TrackNumber + ". "
|
||||
}
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("%s%s - %s.%s", prefix, s.Artist, s.GetTitle(), ext)
|
||||
fileName, _ = filenamify.Filenamify(fileName, filenamify.Options{MaxLength: 255})
|
||||
return fileName
|
||||
}
|
||||
+49
-46
@@ -3,63 +3,66 @@ package deezer
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/flytam/filenamify"
|
||||
)
|
||||
|
||||
type Contributors struct {
|
||||
MainArtists []string `json:"main_artist"`
|
||||
Composers []string `json:"composer"`
|
||||
Authors []string `json:"author"`
|
||||
}
|
||||
|
||||
func (c *Contributors) UnmarshalJSON(data []byte) error {
|
||||
if string(data) == "[]" {
|
||||
*c = Contributors{}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Alias Contributors
|
||||
aux := (*Alias)(c)
|
||||
|
||||
return json.Unmarshal(data, aux)
|
||||
}
|
||||
|
||||
type Track struct {
|
||||
Results struct {
|
||||
Data *Song `json:"DATA"`
|
||||
} `json:"results"`
|
||||
}
|
||||
|
||||
func (t *Track) String() string {
|
||||
if t.Results.Data == nil {
|
||||
return "Track: No data available"
|
||||
}
|
||||
|
||||
duration, err := strconv.Atoi(t.Results.Data.Duration)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
`================= [ Track Info ] =================
|
||||
Title: %s
|
||||
Artist: %s
|
||||
Duration: %s
|
||||
==================================================`,
|
||||
t.Results.Data.GetTitle(),
|
||||
t.Results.Data.Artist,
|
||||
time.Duration(duration)*time.Second,
|
||||
)
|
||||
}
|
||||
|
||||
func (t *Track) GetType() string {
|
||||
return "Track"
|
||||
ID string `json:"SNG_ID"`
|
||||
Artist string `json:"ART_NAME"`
|
||||
Title string `json:"SNG_TITLE"`
|
||||
Version string `json:"VERSION"`
|
||||
Cover string `json:"ALB_PICTURE"`
|
||||
Contributors Contributors `json:"SNG_CONTRIBUTORS"`
|
||||
Duration string `json:"DURATION"`
|
||||
Gain string `json:"GAIN"`
|
||||
ISRC string `json:"ISRC"`
|
||||
TrackNumber string `json:"TRACK_NUMBER"`
|
||||
TrackToken string `json:"TRACK_TOKEN"`
|
||||
}
|
||||
|
||||
func (t *Track) GetTitle() string {
|
||||
if t.Results.Data == nil {
|
||||
return ""
|
||||
if t.Version != "" {
|
||||
return t.Title + " " + t.Version
|
||||
}
|
||||
return t.Results.Data.GetTitle()
|
||||
return t.Title
|
||||
}
|
||||
|
||||
func (t *Track) GetSongs() []*Song {
|
||||
if t.Results.Data == nil {
|
||||
return nil
|
||||
func (t *Track) GetFileName(resourceType, mediaFormat string) string {
|
||||
ext := "mp3"
|
||||
if mediaFormat == "FLAC" {
|
||||
ext = "flac"
|
||||
}
|
||||
return []*Song{t.Results.Data}
|
||||
}
|
||||
|
||||
func (t *Track) SetSongs(songs []*Song) {}
|
||||
prefix := ""
|
||||
if resourceType == "album" {
|
||||
if n, err := strconv.Atoi(t.TrackNumber); err == nil {
|
||||
prefix = fmt.Sprintf("%02d. ", n)
|
||||
} else {
|
||||
prefix = t.TrackNumber + ". "
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Track) GetOutputDir(outputDir string) string {
|
||||
return path.Join(outputDir, "Singles")
|
||||
}
|
||||
|
||||
func (t *Track) Unmarshal(data []byte) error {
|
||||
return json.Unmarshal(data, t)
|
||||
fileName := fmt.Sprintf("%s%s - %s.%s", prefix, t.Artist, t.GetTitle(), ext)
|
||||
fileName, _ = filenamify.Filenamify(fileName, filenamify.Options{MaxLength: 255})
|
||||
return fileName
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user