From 7ce3dc47d5ce1863eda5b8458b7ade60bd0b41e7 Mon Sep 17 00:00:00 2001 From: RGR09 <95591357+RGR09@users.noreply.github.com> Date: Tue, 18 Aug 2026 18:11:54 +0200 Subject: [PATCH] feat: enrich playlist album via file metadata (#307) * feat: enrich playlist album via file metadata * Refactor enrich command to use normalized source key - Rename 'from' option to 'source' in command documentation- Update PlaylistEnrich function to correctly handle normalized source keys- Improve source key handling logic for album metadata extraction- Clarify source usage in the 'cliamp playlist enrich' command description * feat: normalize song path Replacing forward-slash instead of backslash to have less interference when sorting playlist by path * feat: enrich elements year via file metadata --- cmd/playlist.go | 41 +++++++++++++++++++++++++++++++++++++---- commands.go | 7 +++++-- docs/cli.md | 5 +++-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/cmd/playlist.go b/cmd/playlist.go index 45ff5cc..701a257 100644 --- a/cmd/playlist.go +++ b/cmd/playlist.go @@ -607,7 +607,14 @@ func PlaylistBookmarks() error { } // PlaylistEnrich probes duration and derives album metadata for SSH tracks. -func PlaylistEnrich(name string) error { +func PlaylistEnrich(name string, source string) error { + src := normalizeSortKey(source) + switch src { + case "path", "metadata": + default: + return fmt.Errorf("unsupported source key %q (use path or metadata)", source) + } + prov, err := newProvider() if err != nil { return err @@ -637,9 +644,23 @@ func PlaylistEnrich(name string) error { } if t.Album == "" { - if dir := albumFromPath(t.Path); dir != "" { - tracks[i].Album = dir + if src == "path" { + if dir := albumFromPath(t.Path); dir != "" { + tracks[i].Album = dir + changed = true + } + } else if src == "metadata" { + if album := probeAlbum(t.Path); album != "" { + tracks[i].Album = album + changed = true + } + } + } + if t.Year == 0 { + if year := probeYear(t.Path); year != 0 { + tracks[i].Year = year changed = true + fmt.Fprintf(os.Stderr, " %s: %d\n", t.DisplayName(), year) } } @@ -717,6 +738,16 @@ func parseProbeDuration(out []byte) int { return int(dur) } +func probeYear(path string) int { + t := playlist.TrackFromPath(path) + return t.Year +} + +func probeAlbum(path string) string { + t := playlist.TrackFromPath(path) + return t.Album +} + func albumFromPath(path string) string { if path == "" || playlist.IsURL(path) { return "" @@ -744,7 +775,9 @@ func collectLocalAudio(paths []string) ([]string, error) { if err != nil { return nil, fmt.Errorf("scanning %q: %w", p, err) } - all = append(all, files...) + for _, f := range files { + all = append(all, strings.ReplaceAll(f, "\\", "/")) + } } return all, nil } diff --git a/commands.go b/commands.go index 3f7fabb..013c374 100644 --- a/commands.go +++ b/commands.go @@ -603,11 +603,14 @@ func playlistCommand() *cli.Command { Name: "enrich", Usage: "probe duration and album metadata for SSH tracks", ArgsUsage: "\"Name\"", + Flags: []cli.Flag{ + &cli.StringFlag{Name: "source", Usage: "source: metadata, path", Value: "path"}, + }, Action: func(ctx context.Context, c *cli.Command) error { if c.Args().Len() == 0 { - return fmt.Errorf("usage: cliamp playlist enrich \"Name\"") + return fmt.Errorf("usage: cliamp playlist enrich \"Name\" --source metadata") } - return cmd.PlaylistEnrich(c.Args().First()) + return cmd.PlaylistEnrich(c.Args().First(), c.String("source")) }, }, }, diff --git a/docs/cli.md b/docs/cli.md index 894b51e..43e8474 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -162,8 +162,9 @@ cliamp playlist export "Name" --format pls # export as PLS to stdout cliamp playlist import mix.m3u --name "Name" # import local M3U/M3U8/PLS cliamp playlist bookmark "Name" --index 3 # toggle bookmark flag cliamp playlist bookmarks # list bookmarked tracks -cliamp playlist enrich "Name" # probe duration/album metadata -cliamp playlist delete "Name" # delete entire playlist +cliamp playlist enrich "Name" # probe duration/album +cliamp playlist enrich "Name" --source metadata # probe duration/album (forces to use the file's metadata as source) +cliamp playlist delete "Name" # delete entire playlist ``` Sort keys: `track`, `title`, `artist`, `album`, `artist+album`, `path`.