Introduces the `godeez download track <ID>` command, allowing users to download individual songs directly. Single tracks are saved into a "Singles" folder by default to keep them organized. The README has been updated with documentation and examples for this new functionality.
92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/mathismqn/godeez/internal/config"
|
|
"github.com/mathismqn/godeez/internal/downloader"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
opts downloader.Options
|
|
cfgPath string
|
|
)
|
|
|
|
var downloadCmd = &cobra.Command{
|
|
Use: "download",
|
|
Short: "Download songs from Deezer",
|
|
}
|
|
|
|
func init() {
|
|
RootCmd.AddCommand(downloadCmd)
|
|
|
|
downloadCmd.PersistentFlags().StringVar(&cfgPath, "config", "", "config file (default ~/.godeez/config.toml)")
|
|
downloadCmd.PersistentFlags().StringVarP(&opts.Quality, "quality", "q", "mp3_320", "download quality [mp3_128, mp3_320, flac]")
|
|
downloadCmd.PersistentFlags().DurationVarP(&opts.Timeout, "timeout", "t", 2*time.Minute, "timeout for each download (e.g. 10s, 1m, 2m30s)")
|
|
downloadCmd.PersistentFlags().BoolVar(&opts.BPM, "bpm", false, "fetch BPM/key and add to file tags")
|
|
downloadCmd.PersistentFlags().BoolVar(&opts.Strict, "strict", false, "fail the song download if the quality is not available")
|
|
|
|
downloadCmd.AddCommand(
|
|
newDownloadCmd("album"),
|
|
newDownloadCmd("playlist"),
|
|
newDownloadCmd("artist"),
|
|
newDownloadCmd("track"),
|
|
)
|
|
}
|
|
|
|
func newDownloadCmd(resourceType string) *cobra.Command {
|
|
article := "a"
|
|
if resourceType == "album" {
|
|
article = "an"
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: fmt.Sprintf("%s <%s_id>", resourceType, resourceType),
|
|
Short: fmt.Sprintf("Download songs from %s %s", article, resourceType),
|
|
Args: cobra.ExactArgs(1),
|
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
appConfig, err := config.New(cfgPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmd.SetContext(context.WithValue(cmd.Context(), "appConfig", appConfig))
|
|
|
|
opts.Quality = strings.ToLower(opts.Quality)
|
|
|
|
return opts.Validate()
|
|
},
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
ctx := cmd.Context()
|
|
appConfigVal := ctx.Value("appConfig")
|
|
appConfig, _ := appConfigVal.(*config.Config)
|
|
|
|
dl := downloader.New(appConfig, resourceType)
|
|
if err := dl.Run(ctx, opts, args[0]); err != nil {
|
|
if errors.Is(err, context.Canceled) {
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
if resourceType == "artist" {
|
|
cmd.Flags().IntVarP(&opts.Limit, "limit", "l", 10, "number of songs to download")
|
|
cmd.Short = "Download top songs from an artist"
|
|
}
|
|
|
|
if resourceType == "track" {
|
|
cmd.Short = "Download a single track"
|
|
}
|
|
|
|
return cmd
|
|
}
|