From 1504e29919b21bab99ea5e78a35daa130cb8abb1 Mon Sep 17 00:00:00 2001 From: Superredstone Date: Tue, 17 Feb 2026 11:18:53 +0100 Subject: [PATCH] feat: improve metadata implementation for track --- lib/download.go | 16 ++++--- lib/metadata.go | 50 +++++---------------- lib/types.go | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/utils.go | 9 ++-- 4 files changed, 140 insertions(+), 50 deletions(-) create mode 100644 lib/types.go diff --git a/lib/download.go b/lib/download.go index 168bc9a..c407948 100644 --- a/lib/download.go +++ b/lib/download.go @@ -1,9 +1,5 @@ package lib -import ( - "errors" -) - const ( DEFAULT_DOWNLOAD_SERVICE = "tidal" DEFAULT_DOWNLOAD_OUTPUT_FOLDER = "." @@ -30,14 +26,20 @@ func (app *App) Download(url string, outputFolder string, serviceString string) serviceString = DEFAULT_DOWNLOAD_SERVICE } - _, err := app.GetMetadata(url) + urlType, err := ParseUrlType(url) if err != nil { return err } - _ = ParseUrlType(url) + switch urlType { + case UrlTypeTrack: + _, err := app.GetTrackMetadata(url) + if err != nil { + return err + } + } - return errors.New("Invalid URL.") + return nil } func (app *App) DownloadTrack(dr DownloadRequest) (bool, error) { diff --git a/lib/metadata.go b/lib/metadata.go index 751c271..270539f 100644 --- a/lib/metadata.go +++ b/lib/metadata.go @@ -5,60 +5,34 @@ import ( "errors" ) -type Metadata struct { - SpotifyID string `json:"spotify_id"` - Artists string `json:"artists"` - Name string `json:"name"` - AlbumName string `json:"album_name"` - AlbumArtist string `json:"album_artist"` - DurationMS int `json:"duration_ms"` - Images string `json:"images"` - ReleaseDate string `json:"release_date"` - TrackNumber int `json:"track_number"` - TotalTracks int `json:"total_tracks"` - DiscNumber int `json:"disc_number"` - TotalDiscs int `json:"total_discs"` - ExternalURLs string `json:"external_urls"` - Copyright string `json:"copyright"` - Publisher string `json:"publisher"` - Plays string `json:"plays"` - IsExplicit bool `json:"is_explicit"` -} - -func (app *App) GetMetadata(url string) (Metadata, error) { - urlType := ParseUrlType(url) - - switch urlType { - case UrlTypeTrack: - app.GetTrackMetadata(url) - } - - return Metadata{}, errors.New("Invalid URL.") -} - -func (app *App) GetTrackMetadata(url string) error { +func (app *App) GetTrackMetadata(url string) (TrackMetadata, error) { client := NewSpotifyClient() + var result TrackMetadata err := client.Initialize() if err != nil { - return errors.New("Unable to fetch Spotify metadata.") + return result, errors.New("Unable to fetch Spotify metadata.") } trackId, err := ParseTrackId(url) if err != nil { - return err + return result, err } payload := BuildSpotifyReqPayloadTrack(trackId) rawMetadata, err := client.Query(payload) if err != nil { - return err + return result, err } - a, err := json.Marshal(rawMetadata) - println(string(a)) - return nil + byteMetadata, err := json.Marshal(rawMetadata) + err = json.Unmarshal(byteMetadata, &result) + if err != nil { + return result, err + } + + return result, nil } func (app *App) PrintMetadata(url string) error { diff --git a/lib/types.go b/lib/types.go new file mode 100644 index 0000000..0fecf31 --- /dev/null +++ b/lib/types.go @@ -0,0 +1,115 @@ +package lib + +import "time" + +type Copyright struct { + Items []map[string]interface{} `json:"items"` + TotalCount int64 `json:"totalCount"` +} + +type ColorRaw struct { + Hex string `json:"hex"` +} + +type ExtractedColors struct { + ColorRaw ColorRaw `json:"colorRaw"` +} + +type CoverArt struct { + ExtractedColors ExtractedColors `json:"extractedColors"` + Sources []map[string]interface{} `json:"sources"` +} + +type Date struct { + IsoString time.Time `json:"isoString"` + Precision string `json:"precision"` + Year int64 `json:"year"` +} + +type SharingInfo struct { + ShareId string `json:"shareId"` + ShareUrl string `json:"shareUrl"` +} + +type Tracks struct { + Items []map[string]interface{} `json:"items"` + TotalCount int64 `json:"totalCount"` +} + +type AlbumOfTrack struct { + Copyright Copyright `json:"copyright"` + CourtesyLine string `json:"courtesyLine"` + CoverArt CoverArt `json:"coverArt"` + Date Date `json:"date"` + Id string `json:"id"` + Name string `json:"name"` + Playability Playability `json:"playability"` + SharingInfo SharingInfo `json:"sharingInfo"` + Tracks Tracks `json:"tracks"` + Type string `json:"type"` + Uri string `json:"uri"` +} + +type AudioAssociations struct { + TypeName string `json:"__typename"` + Items []interface{} `json:"items"` +} + +type VideoAssociations struct { + TotalCount int64 `json:"totalCount"` +} + +type AssociationsV3 struct { + AudioAssociations AudioAssociations `json:"audioAssociations"` + VideoAssociations VideoAssociations `json:"videoAssociations"` +} + +type ContentRating struct { + Label string `json:"label"` +} + +type Duration struct { + TotalMilliseconds int64 `json:"totalMilliseconds"` +} + +type FirstArtist struct { + Items []map[string]interface{} `json:"items"` + TotalCount int64 `json:"totalCount"` +} + +type OtherArtists struct { + Items []interface{} `json:"items"` +} + +type Playability struct { + Playable bool `json:"playable"` + Reason string `json:"reason"` +} + +type TrackUnion struct { + TypeName string `json:"__typename"` + AlbumOfTrack AlbumOfTrack `json:"albumOfTrack"` + AssociationsV3 AssociationsV3 `json:"associationsV3"` + ContentRating ContentRating `json:"contentRating"` + Duration Duration `json:"duration"` + FirstArtist FirstArtist `json:"firstArtist"` + Id string `json:"id"` + MediaType string `json:"mediaType"` + Name string `json:"name"` + OtherArtists OtherArtists `json:"otherArtists"` + Playability Playability `json:"playability"` + Playcount string `json:"playcount"` + Saved bool `json:"saved"` + SharingInfo interface{} `json:"sharingInfo"` + TrackNumber int64 `json:"trackNumber"` + Uri string `json:"uri"` + VisualIdentity interface{} `json:"visualIdentity"` +} + +type Data struct { + TrackUnion TrackUnion `json:"trackUnion"` +} + +type TrackMetadata struct { + Data Data `json:"data"` +} diff --git a/lib/utils.go b/lib/utils.go index 5deac84..59a2464 100644 --- a/lib/utils.go +++ b/lib/utils.go @@ -10,19 +10,18 @@ type UrlType int const ( UrlTypeTrack UrlType = iota UrlTypePlaylist - UrlTypeInvalid ) -func ParseUrlType(url string) UrlType { +func ParseUrlType(url string) (UrlType, error) { if strings.Contains(url, "https://open.spotify.com/track") { - return UrlTypeTrack + return UrlTypeTrack, nil } if strings.Contains(url, "https://open.spotify.com/playlist") { - return UrlTypePlaylist + return UrlTypePlaylist, nil } - return UrlTypeInvalid + return UrlTypeTrack, errors.New("Invalid URL, not a playlist nor a track.") } func ParseTrackId(url string) (string, error) {