Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Flags struct {
ExcludeLocal bool
Persist bool
PersistSet bool
SearchMBID string
RefreshOnly bool
}

Expand Down
29 changes: 18 additions & 11 deletions src/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (cfg *Config) GetFlags() error {
var excludeLocal bool
var persist bool
var showVersion bool
var searchMBID string
var refreshOnly bool
// Long flags
flag.StringVarP(&configPath, "config", "c", ".env", "Path of the configuration file")
Expand All @@ -30,9 +31,10 @@ 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.BoolVar(&refreshOnly, "refresh-only", false, "Trigger alibrary rescan and exit; skips discovery and downloads")

flag.Parse()
flag.Parse()

if showVersion {
fmt.Println(Version)
Expand All @@ -41,24 +43,29 @@ func (cfg *Config) GetFlags() error {
persistSet := flag.Lookup("persist").Changed
cfgSet := flag.Lookup("config").Changed

// Validation for playlist — built-in types or user-imported custom-* IDs
if !contains(validPlaylists, playlist) && !strings.HasPrefix(playlist, "custom-") {
return fmt.Errorf("flag validation error: invalid playlist %s (must be one of: %s, or a custom-* id)",
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, ", "))
}
if !contains(validPlaylists, playlist) && !strings.HasPrefix(playlist, "custom-") {
return fmt.Errorf("flag validation error: invalid playlist %s (must be one of: %s, or a custom-* id)",
playlist, strings.Join(validPlaylists, ", "))
}

}
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
cfg.Flags.RefreshOnly = refreshOnly

// for deprecation purposes (can be removed at a later date)
Expand Down
8 changes: 7 additions & 1 deletion src/discovery/listenbrainz.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, ",")

Expand Down
35 changes: 32 additions & 3 deletions src/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,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 {
Expand All @@ -106,6 +128,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 {
Expand Down Expand Up @@ -133,8 +163,6 @@ func main() {
return
}

httpClient := initHttpClient()

var tracks []*models.Track
var err error
if strings.HasPrefix(cfg.Flags.Playlist, "custom-") {
Expand All @@ -147,7 +175,8 @@ func main() {
disc := discovery.NewDiscoverer(cfg.DiscoveryCfg, httpClient)
tracks, err = disc.Discover()
}
if err != nil {

if err != nil {
slog.Error(err.Error(), "notify", true)
os.Exit(1)
}
Expand Down
Loading