Add new command to save local song files to DB

This commit is contained in:
Chigozirim Igweamaka 2024-08-03 10:25:32 +01:00
parent 2fb960a2d7
commit f3afebc08a
2 changed files with 89 additions and 2 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"log"
"log/slog"
"math"
"net/http"
"os"
"path/filepath"
@ -13,6 +14,7 @@ import (
"song-recognition/spotify"
"song-recognition/utils"
"song-recognition/wav"
"strconv"
"strings"
"github.com/fatih/color"
@ -235,3 +237,77 @@ func erase(songsDir string) {
fmt.Println("Erase complete")
}
// index processes the path, whether it's a directory or a single file.
func save(path string, force bool) {
fileInfo, err := os.Stat(path)
if err != nil {
fmt.Printf("Error stating path %v: %v\n", path, err)
return
}
if fileInfo.IsDir() {
err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("Error walking the path %v: %v\n", filePath, err)
return err
}
// Process only files, skip directories
if !info.IsDir() {
err := saveSong(filePath, force)
if err != nil {
fmt.Printf("Error indexing song (%v): %v\n", filePath, err)
}
}
return nil
})
if err != nil {
fmt.Printf("Error walking the directory %v: %v\n", path, err)
}
} else {
// If it's a file, process it directly
err := saveSong(path, force)
if err != nil {
fmt.Printf("Error indexing song (%v): %v\n", path, err)
}
}
}
func saveSong(filePath string, force bool) error {
metadata, err := wav.GetMetadata(filePath)
if err != nil {
return err
}
durationFloat, err := strconv.ParseFloat(metadata.Format.Duration, 64)
if err != nil {
return fmt.Errorf("failed to parse duration to float: %v", err)
}
tags := metadata.Format.Tags
track := &spotify.Track{
Album: tags["album"],
Artist: tags["artist"],
Title: tags["title"],
Duration: int(math.Round(durationFloat)),
}
ytID, err := spotify.GetYoutubeId(*track)
if err != nil && !force {
return fmt.Errorf("failed to get YouTube ID for song: %v", err)
}
if track.Title == "" {
return fmt.Errorf("no title found in metadata")
}
if track.Artist == "" {
return fmt.Errorf("no artist found in metadata")
}
err = spotify.ProcessAndSaveSong(filePath, track.Title, track.Artist, ytID)
if err != nil {
return fmt.Errorf("failed to process or save song: %v", err)
}
return nil
}

15
main.go
View file

@ -30,7 +30,7 @@ func main() {
}
if len(os.Args) < 2 {
fmt.Println("Expected 'find', 'download', 'erase', or 'serve' subcommands")
fmt.Println("Expected 'find', 'download', 'erase', 'save', or 'serve' subcommands")
os.Exit(1)
}
@ -57,8 +57,19 @@ func main() {
serve(*protocol, *port)
case "erase":
erase(SONGS_DIR)
case "save":
indexCmd := flag.NewFlagSet("save", flag.ExitOnError)
force := indexCmd.Bool("force", false, "save song with or without YouTube ID")
indexCmd.BoolVar(force, "f", false, "save song with or without YouTube ID (shorthand)")
indexCmd.Parse(os.Args[2:])
if indexCmd.NArg() < 1 {
fmt.Println("Usage: main.go save [-f|--force] <path_to_wav_file_or_dir>")
os.Exit(1)
}
filePath := indexCmd.Arg(0)
save(filePath, *force)
default:
fmt.Println("Expected 'find', 'download', 'erase', or 'serve' subcommands")
fmt.Println("Expected 'find', 'download', 'erase', 'save', or 'serve' subcommands")
os.Exit(1)
}
}