feat: filter artist albums by type, default to album|ep|single
This commit is contained in:
@@ -137,12 +137,17 @@ func (c *client) lookup(ctx context.Context, entity, id string, inc []string) ([
|
||||
}
|
||||
|
||||
func (c *client) browse(ctx context.Context, entity, linkedEntity, linkedID string, limit, offset int, inc []string) ([]byte, error) {
|
||||
return c.browseWithTypes(ctx, entity, linkedEntity, linkedID, limit, offset, inc, nil)
|
||||
}
|
||||
|
||||
func (c *client) browseWithTypes(ctx context.Context, entity, linkedEntity, linkedID string, limit, offset int, inc []string, types []string) ([]byte, error) {
|
||||
zerolog.Ctx(ctx).Debug().
|
||||
Str("entity", entity).
|
||||
Str("linked_entity", linkedEntity).
|
||||
Str("linked_id", linkedID).
|
||||
Int("limit", limit).
|
||||
Int("offset", offset).
|
||||
Strs("types", types).
|
||||
Msg("provider browse")
|
||||
|
||||
params := url.Values{}
|
||||
@@ -154,6 +159,10 @@ func (c *client) browse(ctx context.Context, entity, linkedEntity, linkedID stri
|
||||
params.Set("inc", joined)
|
||||
}
|
||||
|
||||
if typeStr := strings.Join(types, "|"); typeStr != "" {
|
||||
params.Set("type", typeStr)
|
||||
}
|
||||
|
||||
return c.get(ctx, entity, params)
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ func (p *Provider) GetAlbum(ctx context.Context, id string) (*domain.Album, erro
|
||||
return mapAlbum(mb, release), nil
|
||||
}
|
||||
|
||||
func (p *Provider) SearchAlbums(ctx context.Context, query string, artist string, limit, offset int) (*domain.SearchResult[domain.Album], error) {
|
||||
func (p *Provider) SearchAlbums(ctx context.Context, query string, artist string, limit, offset int, albumTypes []string) (*domain.SearchResult[domain.Album], error) {
|
||||
if limit <= 0 || limit > 100 {
|
||||
limit = 25
|
||||
}
|
||||
@@ -105,6 +105,10 @@ func (p *Provider) SearchAlbums(ctx context.Context, query string, artist string
|
||||
luceneQuery = fmt.Sprintf("releasegroup:%s", escapeQuery(query))
|
||||
}
|
||||
|
||||
if typeFilter := buildTypeFilter(albumTypes); typeFilter != "" {
|
||||
luceneQuery += " AND " + typeFilter
|
||||
}
|
||||
|
||||
data, err := p.client.search(ctx, "release-group", luceneQuery, limit, offset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("search albums: %w", err)
|
||||
@@ -134,12 +138,12 @@ func (p *Provider) SearchAlbums(ctx context.Context, query string, artist string
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Provider) GetArtistAlbums(ctx context.Context, artistID string, limit, offset int) (*domain.SearchResult[domain.Album], error) {
|
||||
func (p *Provider) GetArtistAlbums(ctx context.Context, artistID string, limit, offset int, albumTypes []string) (*domain.SearchResult[domain.Album], error) {
|
||||
if limit <= 0 || limit > 100 {
|
||||
limit = 25
|
||||
}
|
||||
|
||||
data, err := p.client.browse(ctx, "release-group", "artist", artistID, limit, offset, []string{"artist-credits"})
|
||||
data, err := p.client.browseWithTypes(ctx, "release-group", "artist", artistID, limit, offset, []string{"artist-credits"}, albumTypes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("browse release-groups: %w", err)
|
||||
}
|
||||
@@ -311,6 +315,20 @@ func selectCanonicalRelease(releases []*mbRelease) *mbRelease {
|
||||
return best
|
||||
}
|
||||
|
||||
func buildTypeFilter(types []string) string {
|
||||
if len(types) == 0 {
|
||||
return ""
|
||||
}
|
||||
if len(types) == 1 {
|
||||
return fmt.Sprintf("primarytype:%s", types[0])
|
||||
}
|
||||
escaped := make([]string, len(types))
|
||||
for i, t := range types {
|
||||
escaped[i] = fmt.Sprintf("primarytype:%s", t)
|
||||
}
|
||||
return "(" + strings.Join(escaped, " OR ") + ")"
|
||||
}
|
||||
|
||||
func escapeQuery(s string) string {
|
||||
special := []string{`+`, `-`, `&`, `|`, `!`, `(`, `)`, `{`, `}`, `[`, `]`, `^`, `"`, `~`, `*`, `?`, `:`, `/`, `\`}
|
||||
result := s
|
||||
|
||||
Reference in New Issue
Block a user