WIP ranking of search results

This commit is contained in:
Drew Weymouth
2023-11-05 14:08:48 -08:00
parent 3238aad65a
commit 5fd3f96129
4 changed files with 45 additions and 7 deletions
+41 -7
View File
@@ -6,6 +6,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/deluan/sanitize"
"github.com/dweymouth/go-subsonic/subsonic" "github.com/dweymouth/go-subsonic/subsonic"
"github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/backend/mediaprovider"
"github.com/dweymouth/supersonic/sharedutil" "github.com/dweymouth/supersonic/sharedutil"
@@ -34,14 +35,14 @@ func (s *subsonicMediaProvider) SearchAll(searchQuery string, maxResults int) ([
wg.Done() wg.Done()
}() }()
queryLowerWords := strings.Fields(strings.ToLower(searchQuery)) queryLowerWords := strings.Fields(strings.ToLower(sanitize.Accents(searchQuery)))
wg.Add(1) wg.Add(1)
go func() { go func() {
p, e := s.client.GetPlaylists(nil) p, e := s.client.GetPlaylists(nil)
if e == nil { if e == nil {
playlists = sharedutil.FilterSlice(p, func(p *subsonic.Playlist) bool { playlists = sharedutil.FilterSlice(p, func(p *subsonic.Playlist) bool {
return allTermsMatch(strings.ToLower(p.Name), queryLowerWords) return allTermsMatch(strings.ToLower(sanitize.Accents(p.Name)), queryLowerWords)
}) })
} }
wg.Done() wg.Done()
@@ -52,7 +53,7 @@ func (s *subsonicMediaProvider) SearchAll(searchQuery string, maxResults int) ([
g, e := s.client.GetGenres() g, e := s.client.GetGenres()
if e == nil { if e == nil {
genres = sharedutil.FilterSlice(g, func(g *subsonic.Genre) bool { genres = sharedutil.FilterSlice(g, func(g *subsonic.Genre) bool {
return allTermsMatch(strings.ToLower(g.Name), queryLowerWords) return allTermsMatch(strings.ToLower(sanitize.Accents(g.Name)), queryLowerWords)
}) })
} }
wg.Done() wg.Done()
@@ -64,7 +65,7 @@ func (s *subsonicMediaProvider) SearchAll(searchQuery string, maxResults int) ([
} }
results := mergeResults(result, playlists, genres) results := mergeResults(result, playlists, genres)
//rankResults(results, queryLowerWords) // TODO rankResults(results, queryLowerWords)
if len(results) > maxResults { if len(results) > maxResults {
results = results[:maxResults] results = results[:maxResults]
} }
@@ -143,9 +144,42 @@ func mergeResults(
} }
func rankResults(results []*mediaprovider.SearchResult, queryTerms []string) { func rankResults(results []*mediaprovider.SearchResult, queryTerms []string) {
// TODO if len(queryTerms) == 0 || len(results) < 2 {
sort.Slice(results, func(a, b int) bool { return
return false }
sanitizeMemo := make([]string, len(results))
sanitized := func(s string, i int) string {
if x := sanitizeMemo[i]; x != "" {
return x
}
x := strings.ToLower(sanitize.Accents(s))
sanitizeMemo[i] = x
return x
}
sort.Slice(results, func(i, j int) bool {
// Compare by search query terms
a, b := results[i], results[j]
aName := sanitized(a.Name, i)
bName := sanitized(b.Name, j)
for _, term := range queryTerms {
firstTermIdxA, firstTermIdxB := strings.Index(aName, term), strings.Index(bName, term)
if firstTermIdxA >= 0 && firstTermIdxB < 0 {
return true // item A has a direct match with the query term and B does not
} else if firstTermIdxB >= 0 && firstTermIdxA < 0 {
return false // item B matches but not A
}
if firstTermIdxA < firstTermIdxB {
return true // item A matches the query term starting at an earlier position
} else if firstTermIdxB < firstTermIdxA {
return false // item B matches first
}
}
// Defer to item type for priority order
return a.Type < b.Type
}) })
} }
+1
View File
@@ -5,6 +5,7 @@ go 1.19
require ( require (
fyne.io/fyne/v2 v2.4.1 fyne.io/fyne/v2 v2.4.1
github.com/20after4/configdir v0.1.1 github.com/20after4/configdir v0.1.1
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee
github.com/dweymouth/go-subsonic v0.0.0-20231105161622-54b5aec28363 github.com/dweymouth/go-subsonic v0.0.0-20231105161622-54b5aec28363
github.com/fsnotify/fsnotify v1.6.0 github.com/fsnotify/fsnotify v1.6.0
+2
View File
@@ -67,6 +67,8 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1 h1:mGvOb3zxl4vCLv+dbf7JA6CAaM2UH/AGP1KX4DsJmTI=
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1/go.mod h1:ZNCLJfehvEf34B7BbLKjgpsL9lyW7q938w/GY1XgV4E=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231104060932-f124004dd651 h1:szaOWq1a8gthqA55qq1egRj660DQM3Pp0nkrmjUwR48= github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231104060932-f124004dd651 h1:szaOWq1a8gthqA55qq1egRj660DQM3Pp0nkrmjUwR48=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231104060932-f124004dd651/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro= github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231104060932-f124004dd651/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro=
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee h1:ZGyJ6wp7CAfT31BugypcF/TPKEy2RrGR9JFq1JOjOpY= github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee h1:ZGyJ6wp7CAfT31BugypcF/TPKEy2RrGR9JFq1JOjOpY=
+1
View File
@@ -136,6 +136,7 @@ func (q *QuickSearch) onSearched(query string) {
q.resultsMutex.Unlock() q.resultsMutex.Unlock()
q.list.Refresh() q.list.Refresh()
q.list.ScrollToTop() q.list.ScrollToTop()
q.selectedIndex = 0
q.list.Select(0) q.list.Select(0)
} }