added fix-comment subcommand
move the spotify url from comments to own tag (spotify)
This commit is contained in:
@@ -16,10 +16,16 @@ type SortCmd struct {
|
||||
Path string `arg:"positional,required"`
|
||||
}
|
||||
|
||||
type FixCommentCmd struct {
|
||||
Path string `arg:"positional,required"`
|
||||
}
|
||||
|
||||
type args struct {
|
||||
Info *InfoCmd `arg:"subcommand:info"`
|
||||
Sort *SortCmd `arg:"subcommand:sort"`
|
||||
FixCommentTag *FixCommentCmd `arg:"subcommand:fix-comment"`
|
||||
Verbose bool `arg:"-v" default:"false"`
|
||||
DryRun bool `arg:"--dry-run" default:"false"`
|
||||
}
|
||||
|
||||
func Run() {
|
||||
@@ -35,6 +41,8 @@ func Run() {
|
||||
ripsort.Scan(args.Info.File)
|
||||
case args.Sort != nil:
|
||||
ripsort.Sort(args.Sort.Dst, args.Sort.Path)
|
||||
case args.FixCommentTag != nil:
|
||||
ripsort.FixComment(args.FixCommentTag.Path, args.DryRun)
|
||||
default:
|
||||
p.Fail("Must specify command")
|
||||
}
|
||||
|
||||
103
internal/fixComment.go
Normal file
103
internal/fixComment.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package ripsort
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"git.kapelle.org/niklas/ripsort/internal/metadata"
|
||||
)
|
||||
|
||||
func FixComment(path string, dry bool) {
|
||||
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
slog.Error("Failed to stat path", "file", path, "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Handle single file
|
||||
if !info.IsDir() {
|
||||
if !fileSupported(path) {
|
||||
slog.Error("Unsupported file format", "file", path)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = fixCommentForFile(path, dry)
|
||||
if err != nil {
|
||||
slog.Error("Failed to fix comment on file", "file", path, "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Handle directory
|
||||
err = filepath.WalkDir(path, func(p string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
slog.Error("Failed to walk path", "path", path, "file", p, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if !d.IsDir() {
|
||||
if !fileSupported(p) {
|
||||
return nil
|
||||
}
|
||||
err = fixCommentForFile(p, dry)
|
||||
if err != nil {
|
||||
slog.Error("Failed to fix comment on file", "file", path, "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func fixCommentForFile(file string, dry bool) error {
|
||||
|
||||
info, err := metadata.ReadAudioTags(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var re = regexp.MustCompile(`(?m)(https:\/\/open\.spotify\.com\/track\/)(.*)`)
|
||||
|
||||
if info.Comment == nil {
|
||||
slog.Debug("Song does not contain comment", "file", file)
|
||||
return nil
|
||||
}
|
||||
|
||||
matches := re.FindAllStringSubmatch(*info.Comment, -1)
|
||||
|
||||
if len(matches) != 1 {
|
||||
slog.Debug("Song does not match regex", "file", file, "comment", info.Comment)
|
||||
return nil
|
||||
}
|
||||
|
||||
id := matches[0][2]
|
||||
|
||||
slog.Debug("Spotify tag found", "file", file, "id", id)
|
||||
|
||||
if dry {
|
||||
slog.Info("Dryrun: Don't wite id", "file", file, "id", id)
|
||||
return nil
|
||||
}
|
||||
|
||||
info.SpotifyID = &id
|
||||
info.Comment = nil
|
||||
|
||||
err = metadata.UpdateMetadata(file, file, *info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -20,6 +20,7 @@ type Metadata struct {
|
||||
Comment *string
|
||||
ISRC *string
|
||||
Date *string
|
||||
SpotifyID *string
|
||||
}
|
||||
|
||||
func ReadAudioTags(filePath string) (*Metadata, error) {
|
||||
|
||||
@@ -183,5 +183,9 @@ func createVorbisMetaBlock(m Metadata) flacvorbis.MetaDataBlockVorbisComment {
|
||||
vorbisMeta.Add("ALBUMARTIST", albumArtist)
|
||||
}
|
||||
|
||||
if m.SpotifyID != nil {
|
||||
vorbisMeta.Add("SPOTIFY", *m.SpotifyID)
|
||||
}
|
||||
|
||||
return *vorbisMeta
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user