diff --git a/download/buffer.go b/download/buffer.go new file mode 100644 index 0000000..618a298 --- /dev/null +++ b/download/buffer.go @@ -0,0 +1,71 @@ +package download + +import ( + "bytes" + "fmt" + "io" + + "github.com/d-fi/GoFi/api" + "github.com/d-fi/GoFi/decrypt" + "github.com/d-fi/GoFi/logger" + "github.com/d-fi/GoFi/metadata" + "github.com/d-fi/GoFi/request" +) + +// DownloadTrackToBuffer downloads a track, decrypts if necessary, adds metadata, and returns the buffer. +func DownloadTrackToBuffer(options DownloadTrackToBufferOptions) ([]byte, error) { + logger.Debug("Starting download for track ID: %s with quality: %d", options.SngID, options.Quality) + track, err := api.GetTrackInfo(options.SngID) + if err != nil { + logger.Debug("Failed to fetch track info: %v", err) + return nil, fmt.Errorf("failed to fetch track info: %v", err) + } + + trackData, err := GetTrackDownloadUrl(track, options.Quality) + if err != nil || trackData == nil { + logger.Debug("Failed to retrieve downloadable URL: %v", err) + return nil, fmt.Errorf("failed to retrieve downloadable URL: %v", err) + } + logger.Debug("Download URL retrieved: %s", trackData.TrackUrl) + + // Download the track from the generated URL without saving to disk + resp, err := request.Client.R(). + SetDoNotParseResponse(true). + Get(trackData.TrackUrl) + + if err != nil { + logger.Debug("Failed to download track: %v", err) + return nil, fmt.Errorf("failed to download track: %v", err) + } + defer resp.RawBody().Close() + + logger.Debug("Track download started") + + // Buffer to store the downloaded content + var buffer bytes.Buffer + _, err = io.Copy(&buffer, resp.RawBody()) + if err != nil { + logger.Debug("Failed during download: %v", err) + return nil, fmt.Errorf("failed during download: %v", err) + } + + logger.Debug("Track downloaded successfully") + + // Read the buffer to decrypt if necessary + trackBody := buffer.Bytes() + if trackData.IsEncrypted { + logger.Debug("Track is encrypted, starting decryption process") + trackBody = decrypt.DecryptDownload(trackBody, track.SNG_ID) + logger.Debug("Track decrypted successfully") + } + + // Add metadata to the downloaded track + trackWithMetadata, err := metadata.AddTrackTags(trackBody, track, options.CoverSize) + if err != nil { + logger.Debug("Failed to add metadata: %v", err) + return nil, fmt.Errorf("failed to add metadata: %v", err) + } + logger.Debug("Metadata added successfully") + + return trackWithMetadata, nil +} diff --git a/download/download.go b/download/download.go index 6a183ee..a2defca 100644 --- a/download/download.go +++ b/download/download.go @@ -18,7 +18,7 @@ import ( ) // DownloadTrack downloads a track, adds metadata, and saves it to the specified directory. -func DownloadTrack(options TrackDownloadOptions) (string, error) { +func DownloadTrack(options DownloadTrackOptions) (string, error) { logger.Debug("Starting download for track ID: %s with quality: %d", options.SngID, options.Quality) track, err := api.GetTrackInfo(options.SngID) if err != nil { diff --git a/download/types.go b/download/types.go index 8e775db..0edae63 100644 --- a/download/types.go +++ b/download/types.go @@ -18,11 +18,18 @@ type TrackDownloadUrl struct { // ProgressCallback defines a function type for tracking download progress. type ProgressCallback func(progress float64, totalBytesRead, contentLength int64) -// TrackDownloadOptions contains all the details needed for downloading a track. -type TrackDownloadOptions struct { +// DownloadTrackOptions contains all the details needed for downloading a track. +type DownloadTrackOptions struct { SngID string // The ID of the track to download. Quality int // The quality of the track (e.g., 1 for MP3_128, 3 for MP3_320, 9 for FLAC). CoverSize int // The size of the album cover in pixels. SaveToDir string // The directory where the track will be saved. OnProgress func(progress float64, downloaded, total int64) // The progress callback function. } + +// DownloadTrackToBufferOptions contains all the details needed for downloading a track to a buffer. +type DownloadTrackToBufferOptions struct { + SngID string // The ID of the track to download. + Quality int // The quality of the track (e.g., 1 for MP3_128, 3 for MP3_320, 9 for FLAC). + CoverSize int // The size of the album cover in pixels. +}