mirror of
https://github.com/Superredstone/spotiflac-cli.git
synced 2026-03-08 04:28:07 +01:00
feat: improve metadata implementation for track
This commit is contained in:
@@ -1,9 +1,5 @@
|
|||||||
package lib
|
package lib
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DEFAULT_DOWNLOAD_SERVICE = "tidal"
|
DEFAULT_DOWNLOAD_SERVICE = "tidal"
|
||||||
DEFAULT_DOWNLOAD_OUTPUT_FOLDER = "."
|
DEFAULT_DOWNLOAD_OUTPUT_FOLDER = "."
|
||||||
@@ -30,14 +26,20 @@ func (app *App) Download(url string, outputFolder string, serviceString string)
|
|||||||
serviceString = DEFAULT_DOWNLOAD_SERVICE
|
serviceString = DEFAULT_DOWNLOAD_SERVICE
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := app.GetMetadata(url)
|
urlType, err := ParseUrlType(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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) {
|
func (app *App) DownloadTrack(dr DownloadRequest) (bool, error) {
|
||||||
|
|||||||
@@ -5,60 +5,34 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Metadata struct {
|
func (app *App) GetTrackMetadata(url string) (TrackMetadata, error) {
|
||||||
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 {
|
|
||||||
client := NewSpotifyClient()
|
client := NewSpotifyClient()
|
||||||
|
var result TrackMetadata
|
||||||
|
|
||||||
err := client.Initialize()
|
err := client.Initialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Unable to fetch Spotify metadata.")
|
return result, errors.New("Unable to fetch Spotify metadata.")
|
||||||
}
|
}
|
||||||
|
|
||||||
trackId, err := ParseTrackId(url)
|
trackId, err := ParseTrackId(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := BuildSpotifyReqPayloadTrack(trackId)
|
payload := BuildSpotifyReqPayloadTrack(trackId)
|
||||||
|
|
||||||
rawMetadata, err := client.Query(payload)
|
rawMetadata, err := client.Query(payload)
|
||||||
if err != nil {
|
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 {
|
func (app *App) PrintMetadata(url string) error {
|
||||||
|
|||||||
115
lib/types.go
Normal file
115
lib/types.go
Normal file
@@ -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"`
|
||||||
|
}
|
||||||
@@ -10,19 +10,18 @@ type UrlType int
|
|||||||
const (
|
const (
|
||||||
UrlTypeTrack UrlType = iota
|
UrlTypeTrack UrlType = iota
|
||||||
UrlTypePlaylist
|
UrlTypePlaylist
|
||||||
UrlTypeInvalid
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseUrlType(url string) UrlType {
|
func ParseUrlType(url string) (UrlType, error) {
|
||||||
if strings.Contains(url, "https://open.spotify.com/track") {
|
if strings.Contains(url, "https://open.spotify.com/track") {
|
||||||
return UrlTypeTrack
|
return UrlTypeTrack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(url, "https://open.spotify.com/playlist") {
|
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) {
|
func ParseTrackId(url string) (string, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user