Searcher: load abbreviated name from YAML, and add functions to sort results by similarity.

master
Jim 3 years ago
parent 7e41eb1105
commit b10f9d3573
  1. 64
      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<Result> 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<Result> searchAndWait(Query query, long limit, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
{
return search(query).get(limit, unit);
}
public CompletableFuture<List<Result>> search(Query query)
{
CompletableFuture<List<Result>> future = new CompletableFuture<>();
future.completeAsync(()->doSearch(query), executor);
future.completeAsync(() -> searchWrapper(query), executor);
return future;
}
protected List<Result> searchWrapper(Query query)
{
List<Result> results = doSearch(query);
for (Result result : results)
{
double artistScore = 1;
double titleScore = 1;
double albumScore = 1;
double fullTextScore = 0;
Set<String> 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<Result> doSearch(Query query) throws QueryFieldUnsupportedException;
@Override
public String toString() {
return this.getClass().getSimpleName() + "{" + "name=" + name + '}';
}
}

Loading…
Cancel
Save