refactor: use track terminology instead of song

This commit is contained in:
Mathis Maquenne
2026-07-30 12:53:03 +02:00
parent 90b7bb25f0
commit 1fbbd60106
19 changed files with 230 additions and 230 deletions
+7 -7
View File
@@ -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
View File
@@ -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 {
+5 -5
View File
@@ -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
+7 -7
View File
@@ -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 {
+2 -2
View File
@@ -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
}
+65
View File
@@ -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)
}
-68
View File
@@ -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
View File
@@ -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
}