From 62fc540bbbf89b18eba7b62e9aa09a5e92ae0a82 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 4 Jun 2026 14:03:51 -0500 Subject: [PATCH 1/2] feat: add search mbid to flags --- src/config/config.go | 1 + src/config/flags.go | 26 ++++++++++++++------------ src/discovery/listenbrainz.go | 8 +++++++- src/main/main.go | 32 +++++++++++++++++++++++++++++++- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index c60cb433..94ab52df 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -38,6 +38,7 @@ type Flags struct { ExcludeLocal bool Persist bool PersistSet bool + SearchMBID string } type ServerConfig struct { diff --git a/src/config/flags.go b/src/config/flags.go index 890f1993..aeab2229 100644 --- a/src/config/flags.go +++ b/src/config/flags.go @@ -4,9 +4,10 @@ import ( "fmt" "os" - flag "github.com/spf13/pflag" "slices" "strings" + + flag "github.com/spf13/pflag" ) var ( @@ -21,6 +22,7 @@ func (cfg *Config) GetFlags() error { var excludeLocal bool var persist bool var showVersion bool + var searchMBID string // Long flags flag.StringVarP(&configPath, "config", "c", ".env", "Path of the configuration file") flag.StringVarP(&playlist, "playlist", "p", "weekly-exploration", "Playlist where to get tracks. Supported: weekly-exploration, weekly-jams, daily-jams, on-repeat") @@ -28,7 +30,7 @@ func (cfg *Config) GetFlags() error { flag.BoolVarP(&excludeLocal, "exclude-local", "e", false, "Exclude locally found tracks from the imported playlist") flag.BoolVar(&persist, "persist", true, "Keep playlists between generations") flag.BoolVarP(&showVersion, "version", "v", false, "Print version and exit") - + flag.StringVar(&searchMBID, "search-mbid", "", "Test Plex search for a single recording MBID (resolves via ListenBrainz, then searches your library)") flag.Parse() if showVersion { @@ -39,24 +41,24 @@ func (cfg *Config) GetFlags() error { cfgSet := flag.Lookup("config").Changed // Validation for playlist - if !contains(validPlaylists, playlist) { - return fmt.Errorf("flag validation error: invalid playlist %s (must be one of: %s)", - playlist, strings.Join(validPlaylists, ", ")) - } - // Validation for download mode - if !contains(validDownloadMode, downloadMode) { - return fmt.Errorf("flag validation error: invalid download mode %s (must be one of: %s)", - downloadMode, strings.Join(validDownloadMode, ", ")) + if searchMBID == "" { + if !contains(validPlaylists, playlist) { + return fmt.Errorf("flag validation error: invalid playlist %s (must be one of: %s)", + playlist, strings.Join(validPlaylists, ", ")) + } + if !contains(validDownloadMode, downloadMode) { + return fmt.Errorf("flag validation error: invalid download mode %s (must be one of: %s)", + downloadMode, strings.Join(validDownloadMode, ", ")) + } } - cfg.Flags.CfgPath = configPath cfg.Flags.CfgSet = cfgSet cfg.Flags.Playlist = playlist cfg.Flags.DownloadMode = downloadMode cfg.Flags.ExcludeLocal = excludeLocal cfg.Flags.Persist = persist - + cfg.Flags.SearchMBID = searchMBID // for deprecation purposes (can be removed at a later date) cfg.Flags.PersistSet = persistSet diff --git a/src/discovery/listenbrainz.go b/src/discovery/listenbrainz.go index 98252b66..ebcd5675 100644 --- a/src/discovery/listenbrainz.go +++ b/src/discovery/listenbrainz.go @@ -289,7 +289,13 @@ func (c *ListenBrainz) getTopRecordings(user string) ([]*models.Track, error) { return tracks, nil } - +func (c *ListenBrainz) LookupRecording(mbid string) (*models.Track, error) { + tracks, err := c.getTracks([]string{mbid}, false) + if err != nil { + return nil, err + } + return tracks[0], nil +} func (c *ListenBrainz) getTracks(mbids []string, singleArtist bool) ([]*models.Track, error) { strMbids := strings.Join(mbids, ",") diff --git a/src/main/main.go b/src/main/main.go index 8354a347..500c3dbc 100644 --- a/src/main/main.go +++ b/src/main/main.go @@ -34,7 +34,29 @@ func setup(cfg *config.Config) { logging.Init(cfg.LogLevel, notifyClient) cfg.GenPlaylistName() } +func runSearchTest(cfg *config.Config, httpClient *util.HttpClient) { + lb := discovery.NewListenBrainz(cfg.DiscoveryCfg, httpClient) + track, err := lb.LookupRecording(cfg.Flags.SearchMBID) + if err != nil { + log.Fatalf("failed to resolve MBID %s from ListenBrainz: %s", cfg.Flags.SearchMBID, err) + } + slog.Info("resolved recording", "title", track.CleanTitle, "artist", track.MainArtist, "album", track.Album, "duration_ms", track.Duration) + + c, err := client.NewClient(cfg) + if err != nil { + log.Fatalf("failed to init client: %s", err) + } + tracks := []*models.Track{track} + if err := c.CheckTracks(tracks); err != nil { + slog.Warn("CheckTracks error", "err", err) + } + if track.Present { + slog.Info("FOUND in library", "system", cfg.System, "key", track.ID) + } else { + slog.Info("NOT FOUND in library", "system", cfg.System) + } +} func main() { var cfg config.Config if err := cfg.GetFlags(); err != nil { @@ -43,6 +65,14 @@ func main() { cfg.ReadEnv() cfg.MergeFlags() setup(&cfg) + + httpClient := initHttpClient() + + if cfg.Flags.SearchMBID != "" { + runSearchTest(&cfg, httpClient) + return + } + slog.Info("Starting Explo...") if err := os.MkdirAll(cfg.DownloadCfg.Youtube.CoversDir, 0755); err != nil { @@ -60,7 +90,7 @@ func main() { srv := backend.NewServer(cfg.ServerCfg) log.Fatal(srv.Start()) } - httpClient := initHttpClient() + discovery := discovery.NewDiscoverer(cfg.DiscoveryCfg, httpClient) tracks, err := discovery.Discover() if err != nil { From 921b74428d06772fa200ab158936c11a837d1867 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 4 Jun 2026 14:08:38 -0500 Subject: [PATCH 2/2] Update main.go --- src/main/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/main.go b/src/main/main.go index 99e0c241..468b3304 100644 --- a/src/main/main.go +++ b/src/main/main.go @@ -163,8 +163,6 @@ func main() { return } - httpClient := initHttpClient() - var tracks []*models.Track var err error if strings.HasPrefix(cfg.Flags.Playlist, "custom-") {