78 lines
2.3 KiB
Go
78 lines
2.3 KiB
Go
package web
|
|
|
|
import (
|
|
"log"
|
|
"music-server/internal/backend"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
var soundtracks_added []string
|
|
|
|
func FindSoundtrackWebHandler(w http.ResponseWriter, r *http.Request) {
|
|
err := r.ParseForm()
|
|
if err != nil {
|
|
http.Error(w, "Bad Request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
search_term := r.FormValue("search_term")
|
|
search(search_term)
|
|
results := soundtracks_added
|
|
|
|
component := FoundSoundtracks(results)
|
|
err = component.Render(r.Context(), w)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
log.Fatalf("Error rendering in FindSoundtrackWebHandler: %e", err)
|
|
}
|
|
}
|
|
|
|
func search(searchText string) {
|
|
soundtracks_added = nil
|
|
soundtrackData := backend.GetSearchCache()
|
|
results := searchWithData(searchText, soundtrackData)
|
|
soundtracks_added = results
|
|
}
|
|
|
|
// searchWithData is a testable version of search that takes soundtrack data as a parameter
|
|
func searchWithData(searchText string, soundtrackData []backend.SoundtrackData) []string {
|
|
var results []string
|
|
seen := make(map[string]bool)
|
|
|
|
// Precompute cleaned and lowercase search terms once
|
|
cleanedSearchTerm := strings.ToLower(searchText)
|
|
cleanedSearchTerm = strings.ReplaceAll(cleanedSearchTerm, " ", "")
|
|
cleanedSearchTerm = strings.ReplaceAll(cleanedSearchTerm, "é", "e")
|
|
cleanedSearchTerm = strings.ReplaceAll(cleanedSearchTerm, "+", "plus")
|
|
cleanedSearchTerm = strings.ReplaceAll(cleanedSearchTerm, "&", "and")
|
|
cleanedSearchTerm = strings.ReplaceAll(cleanedSearchTerm, "'n", "and")
|
|
lowercaseSearchText := strings.ToLower(searchText)
|
|
|
|
// Pass 1: Exact match (case-insensitive contains)
|
|
for _, data := range soundtrackData {
|
|
if !seen[data.Original] && (searchText == "" || strings.Contains(data.Lowercase, lowercaseSearchText)) {
|
|
results = append(results, data.Original)
|
|
seen[data.Original] = true
|
|
}
|
|
}
|
|
|
|
// Pass 2: Contains match with cleaned terms
|
|
for _, data := range soundtrackData {
|
|
if !seen[data.Original] && (cleanedSearchTerm == "" || strings.Contains(data.Cleaned, cleanedSearchTerm)) {
|
|
results = append(results, data.Original)
|
|
seen[data.Original] = true
|
|
}
|
|
}
|
|
|
|
// Pass 3: Regex match with cleaned terms
|
|
for _, data := range soundtrackData {
|
|
if !seen[data.Original] && backend.MatchRegexCached(cleanedSearchTerm, data.Cleaned) {
|
|
results = append(results, data.Original)
|
|
seen[data.Original] = true
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|