From b10f9d3573c3d8b8132d5e1fc5ff8a69e83c17d6 Mon Sep 17 00:00:00 2001 From: Jim Date: Fri, 1 Oct 2021 13:21:02 +0100 Subject: [PATCH] Searcher: load abbreviated name from YAML, and add functions to sort results by similarity. --- .../musicsearcher/providers/Searcher.java | 64 +++++++++++++++---- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/main/java/moe/nekojimi/musicsearcher/providers/Searcher.java b/src/main/java/moe/nekojimi/musicsearcher/providers/Searcher.java index 3763ff5..4771886 100644 --- a/src/main/java/moe/nekojimi/musicsearcher/providers/Searcher.java +++ b/src/main/java/moe/nekojimi/musicsearcher/providers/Searcher.java @@ -6,7 +6,10 @@ package moe.nekojimi.musicsearcher.providers; import com.amihaiemil.eoyaml.YamlMapping; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; @@ -15,62 +18,97 @@ import java.util.concurrent.TimeoutException; import moe.nekojimi.musicsearcher.Query; import moe.nekojimi.musicsearcher.QueryFieldUnsupportedException; import moe.nekojimi.musicsearcher.Result; +import org.apache.commons.lang3.StringUtils; /** * * @author jim */ -public abstract class Searcher +public abstract class Searcher { - final String name; + protected final String name; + protected String abbr; private final ForkJoinPool executor; - public Searcher(String name) + public Searcher(String name) { this.name = name; + this.abbr = name.substring(0, 2); this.executor = new ForkJoinPool(); } - + public Searcher(YamlMapping yaml) { this(yaml.string("name")); + abbr = yaml.string("abbr"); assert yaml.string("type").equals(this.getClass().getSimpleName()); } - public String getName() + public String getName() { return name; } - + public List searchAndWait(Query query) throws InterruptedException, ExecutionException { - try + try { return searchAndWait(query, Long.MAX_VALUE, TimeUnit.DAYS); - } catch (TimeoutException ex) + } catch (TimeoutException ex) { throw new RuntimeException("This should never happen!",ex); } } - + public List searchAndWait(Query query, long limit, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return search(query).get(limit, unit); } - + public CompletableFuture> search(Query query) { CompletableFuture> future = new CompletableFuture<>(); - future.completeAsync(()->doSearch(query), executor); + future.completeAsync(() -> searchWrapper(query), executor); return future; } + protected List searchWrapper(Query query) + { + List results = doSearch(query); + + for (Result result : results) + { + double artistScore = 1; + double titleScore = 1; + double albumScore = 1; + double fullTextScore = 0; + + Set toCompare = new HashSet<>(); + toCompare.add(result.getAlbum()); + toCompare.add(result.getArtist()); + toCompare.add(result.getTitle()); + + for (String comparison : toCompare) + { + if (comparison == null) + continue; + double score = StringUtils.getJaroWinklerDistance(query.getTextSearch(), comparison); + if (score > fullTextScore) + fullTextScore = score; + } + + result.setScore(albumScore * artistScore * titleScore * fullTextScore); + } + Collections.sort(results, Collections.reverseOrder()); + return results; + } + protected abstract List doSearch(Query query) throws QueryFieldUnsupportedException; @Override public String toString() { return this.getClass().getSimpleName() + "{" + "name=" + name + '}'; } - - + + }