X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fweb%2FSearchPage.java;h=903975dbd075996be17221c17e4732f571cf8d94;hb=8759d9a5f7e33303810ba50ad97746983d5b7d38;hp=bd0354f1ff1c11ba463ddedcc9ccc3bd6c2d039f;hpb=c67605d6ee939160420d176cba9571f442c14978;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/web/SearchPage.java b/src/main/java/net/pterodactylus/sone/web/SearchPage.java index bd0354f..903975d 100644 --- a/src/main/java/net/pterodactylus/sone/web/SearchPage.java +++ b/src/main/java/net/pterodactylus/sone/web/SearchPage.java @@ -35,6 +35,7 @@ import net.pterodactylus.util.collection.Converters; import net.pterodactylus.util.collection.Pagination; import net.pterodactylus.util.filter.Filter; import net.pterodactylus.util.filter.Filters; +import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.number.Numbers; import net.pterodactylus.util.template.Template; import net.pterodactylus.util.template.TemplateContext; @@ -65,6 +66,9 @@ public class SearchPage extends SoneTemplatePage { // SONETEMPLATEPAGE METHODS // + /** + * {@inheritDoc} + */ @Override protected void processTemplate(Request request, TemplateContext templateContext) throws RedirectException { super.processTemplate(request, templateContext); @@ -76,14 +80,14 @@ public class SearchPage extends SoneTemplatePage { List phrases = parseSearchPhrases(query); Set sones = webInterface.getCore().getSones(); - Set> soneHits = getHits(sones, phrases, SoneStringGenerator.GENERATOR); + Set> soneHits = getHits(sones, phrases, SoneStringGenerator.COMPLETE_GENERATOR); Set posts = new HashSet(); for (Sone sone : sones) { posts.addAll(sone.getPosts()); } @SuppressWarnings("synthetic-access") - Set> postHits = getHits(posts, phrases, new PostStringGenerator()); + Set> postHits = getHits(Filters.filteredSet(posts, Post.FUTURE_POSTS_FILTER), phrases, new PostStringGenerator()); /* now filter. */ soneHits = Filters.filteredSet(soneHits, Hit.POSITIVE_FILTER); @@ -100,8 +104,8 @@ public class SearchPage extends SoneTemplatePage { List resultPosts = Converters.convertList(sortedPostHits, new HitConverter()); /* pagination. */ - Pagination sonePagination = new Pagination(resultSones, 10).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("sonePage"), 0)); - Pagination postPagination = new Pagination(resultPosts, 10).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("postPage"), 0)); + Pagination sonePagination = new Pagination(resultSones, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("sonePage"), 0)); + Pagination postPagination = new Pagination(resultPosts, webInterface.getCore().getPreferences().getPostsPerPage()).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("postPage"), 0)); templateContext.set("sonePagination", sonePagination); templateContext.set("soneHits", sonePagination.getItems()); @@ -134,7 +138,7 @@ public class SearchPage extends SoneTemplatePage { Set> hits = new HashSet>(); for (T object : objects) { String objectString = stringGenerator.generateString(object); - int score = calculateScore(phrases, objectString); + double score = calculateScore(phrases, objectString); hits.add(new Hit(object, score)); } return hits; @@ -144,8 +148,8 @@ public class SearchPage extends SoneTemplatePage { * Parses the given query into search phrases. The query is split on * whitespace while allowing to group words using single or double quotes. * Isolated phrases starting with a “+” are - * {@link Phrase.Optionality#REQUIRED}, phrases with a - * “-” are {@link Phrase.Optionality#FORBIDDEN}. + * {@link Phrase.Optionality#REQUIRED}, phrases with a “-” are + * {@link Phrase.Optionality#FORBIDDEN}. * * @param query * The query to parse @@ -182,27 +186,39 @@ public class SearchPage extends SoneTemplatePage { * The expression to search * @return The score of the expression */ - private int calculateScore(List phrases, String expression) { - int optionalHits = 0; - int requiredHits = 0; + private double calculateScore(List phrases, String expression) { + double optionalHits = 0; + double requiredHits = 0; int forbiddenHits = 0; int requiredPhrases = 0; for (Phrase phrase : phrases) { + String phraseString = phrase.getPhrase().toLowerCase(); if (phrase.getOptionality() == Phrase.Optionality.REQUIRED) { ++requiredPhrases; } - boolean matches = expression.toLowerCase().contains(phrase.getPhrase().toLowerCase()); - if (!matches) { + int matches = 0; + int index = 0; + double score = 0; + while (index < expression.length()) { + int position = expression.toLowerCase().indexOf(phraseString, index); + if (position == -1) { + break; + } + score += Math.pow(1 - position / (double) expression.length(), 2); + index = position + phraseString.length(); + ++matches; + } + if (matches == 0) { continue; } if (phrase.getOptionality() == Phrase.Optionality.REQUIRED) { - ++requiredHits; + requiredHits += score; } if (phrase.getOptionality() == Phrase.Optionality.OPTIONAL) { - ++optionalHits; + optionalHits += score; } if (phrase.getOptionality() == Phrase.Optionality.FORBIDDEN) { - ++forbiddenHits; + forbiddenHits += matches; } } return requiredHits * 3 + optionalHits + (requiredHits - requiredPhrases) * 5 - (forbiddenHits * 2); @@ -236,8 +252,28 @@ public class SearchPage extends SoneTemplatePage { */ private static class SoneStringGenerator implements StringGenerator { - /** A static instance of the Sone string generator. */ - public static final SoneStringGenerator GENERATOR = new SoneStringGenerator(); + /** A static instance of a complete Sone string generator. */ + public static final SoneStringGenerator COMPLETE_GENERATOR = new SoneStringGenerator(true); + + /** + * A static instance of a Sone string generator that will only use the + * name of the Sone. + */ + public static final SoneStringGenerator NAME_GENERATOR = new SoneStringGenerator(false); + + /** Whether to generate a string from all data of a Sone. */ + private final boolean complete; + + /** + * Creates a new Sone string generator. + * + * @param complete + * {@code true} to use the profile’s fields, {@code false} to + * not to use the profile‘s fields + */ + private SoneStringGenerator(boolean complete) { + this.complete = complete; + } /** * {@inheritDoc} @@ -256,8 +292,10 @@ public class SearchPage extends SoneTemplatePage { if (soneProfile.getLastName() != null) { soneString.append(' ').append(soneProfile.getLastName()); } - for (Field field : soneProfile.getFields()) { - soneString.append(' ').append(field.getValue()); + if (complete) { + for (Field field : soneProfile.getFields()) { + soneString.append(' ').append(field.getValue()); + } } return soneString.toString(); } @@ -267,8 +305,7 @@ public class SearchPage extends SoneTemplatePage { /** * Generates a {@link String} from a {@link Post}, concatenating the text of * the post, the text of all {@link Reply}s, and the name of all - * {@link Sone}s that have - * replied. + * {@link Sone}s that have replied. * * @author David ‘Bombe’ Roden */ @@ -282,10 +319,10 @@ public class SearchPage extends SoneTemplatePage { StringBuilder postString = new StringBuilder(); postString.append(post.getText()); if (post.getRecipient() != null) { - postString.append(' ').append(SoneStringGenerator.GENERATOR.generateString(post.getRecipient())); + postString.append(' ').append(SoneStringGenerator.NAME_GENERATOR.generateString(post.getRecipient())); } - for (Reply reply : webInterface.getCore().getReplies(post)) { - postString.append(' ').append(SoneStringGenerator.GENERATOR.generateString(reply.getSone())); + for (Reply reply : Filters.filteredList(webInterface.getCore().getReplies(post), Reply.FUTURE_REPLIES_FILTER)) { + postString.append(' ').append(SoneStringGenerator.NAME_GENERATOR.generateString(reply.getSone())); postString.append(' ').append(reply.getText()); } return postString.toString(); @@ -384,7 +421,7 @@ public class SearchPage extends SoneTemplatePage { @Override public int compare(Hit leftHit, Hit rightHit) { - return rightHit.getScore() - leftHit.getScore(); + return (rightHit.getScore() < leftHit.getScore()) ? -1 : ((rightHit.getScore() > leftHit.getScore()) ? 1 : 0); } }; @@ -393,7 +430,7 @@ public class SearchPage extends SoneTemplatePage { private final T object; /** The score of the object. */ - private final int score; + private final double score; /** * Creates a new hit. @@ -403,7 +440,7 @@ public class SearchPage extends SoneTemplatePage { * @param score * The score of the object */ - public Hit(T object, int score) { + public Hit(T object, double score) { this.object = object; this.score = score; } @@ -422,7 +459,7 @@ public class SearchPage extends SoneTemplatePage { * * @return The score of the object */ - public int getScore() { + public double getScore() { return score; } @@ -437,6 +474,9 @@ public class SearchPage extends SoneTemplatePage { */ public static class HitConverter implements Converter, T> { + /** + * {@inheritDoc} + */ @Override public T convert(Hit input) { return input.getObject();