search is now context aware (will only search in selected category or feed)

This commit is contained in:
Athou
2013-08-07 15:26:43 +02:00
parent 701a1903ba
commit 4520ef4078
6 changed files with 85 additions and 109 deletions

View File

@@ -14,6 +14,7 @@ import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
@@ -131,7 +132,7 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
if (keywords != null) {
Criteria contentJoin = criteria.createCriteria(FeedEntry_.content.getName(), "content", JoinType.INNER_JOIN);
for (String keyword : keywords.split(" ")) {
for (String keyword : StringUtils.split(keywords)) {
Disjunction or = Restrictions.disjunction();
or.add(Restrictions.ilike(FeedEntryContent_.content.getName(), keyword, MatchMode.ANYWHERE));
or.add(Restrictions.ilike(FeedEntryContent_.title.getName(), keyword, MatchMode.ANYWHERE));

View File

@@ -5,6 +5,7 @@ import java.io.StringReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
@@ -29,6 +30,7 @@ import org.w3c.dom.css.CSSStyleDeclaration;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.frontend.model.Entry;
import com.google.common.collect.Lists;
import com.google.gwt.i18n.client.HasDirection.Direction;
import com.google.gwt.i18n.shared.BidiUtils;
@@ -447,4 +449,27 @@ public class FeedUtils {
return rot13(new String(Base64.decodeBase64(code)));
}
public static void removeUnwantedFromSearch(List<Entry> entries, String keywords) {
if (StringUtils.isBlank(keywords)) {
return;
}
Iterator<Entry> it = entries.iterator();
while (it.hasNext()) {
Entry entry = it.next();
boolean keep = true;
for (String keyword : keywords.split(" ")) {
String title = Jsoup.parse(entry.getTitle()).text();
String content = Jsoup.parse(entry.getContent()).text();
if (!StringUtils.containsIgnoreCase(content, keyword) && !StringUtils.containsIgnoreCase(title, keyword)) {
keep = false;
break;
}
}
if (!keep) {
it.remove();
}
}
}
}

View File

@@ -27,6 +27,7 @@ import com.commafeed.backend.cache.CacheService;
import com.commafeed.backend.dao.FeedCategoryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.feeds.FeedUtils;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
@@ -84,7 +85,7 @@ public class CategoryREST extends AbstractREST {
@Inject
CacheService cache;
@Inject
ApplicationSettingsService applicationSettingsService;
@@ -103,9 +104,15 @@ public class CategoryREST extends AbstractREST {
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset, @ApiParam(
value = "limit for paging, default 20, maximum 50") @DefaultValue("20") @QueryParam("limit") int limit, @ApiParam(
value = "date ordering",
allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order) {
allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order, @ApiParam(
value = "keywords separated by spaces, 3 characters minimum",
required = true) @QueryParam("keywords") String keywords) {
Preconditions.checkNotNull(readType);
keywords = StringUtils.trimToNull(keywords);
Preconditions.checkArgument(keywords == null || StringUtils.length(keywords) >= 3);
limit = Math.min(limit, 50);
limit = Math.max(0, limit);
@@ -122,7 +129,7 @@ public class CategoryREST extends AbstractREST {
if (ALL.equals(id)) {
entries.setName("All");
List<FeedSubscription> subscriptions = feedSubscriptionDAO.findAll(getUser());
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(subscriptions, unreadOnly, null, newerThanDate, offset,
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(subscriptions, unreadOnly, keywords, newerThanDate, offset,
limit + 1, order, true);
for (FeedEntryStatus status : list) {
entries.getEntries().add(
@@ -143,7 +150,7 @@ public class CategoryREST extends AbstractREST {
if (parent != null) {
List<FeedCategory> categories = feedCategoryDAO.findAllChildrenCategories(getUser(), parent);
List<FeedSubscription> subs = feedSubscriptionDAO.findByCategories(getUser(), categories);
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(subs, unreadOnly, null, newerThanDate, offset,
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(subs, unreadOnly, keywords, newerThanDate, offset,
limit + 1, order, true);
for (FeedEntryStatus status : list) {
entries.getEntries().add(
@@ -162,6 +169,7 @@ public class CategoryREST extends AbstractREST {
}
entries.setTimestamp(System.currentTimeMillis());
FeedUtils.removeUnwantedFromSearch(entries.getEntries(), keywords);
return Response.ok(entries).build();
}
@@ -180,7 +188,7 @@ public class CategoryREST extends AbstractREST {
int offset = 0;
int limit = 20;
Entries entries = (Entries) getCategoryEntries(id, readType, null, offset, limit, order).getEntity();
Entries entries = (Entries) getCategoryEntries(id, readType, null, offset, limit, order, null).getEntity();
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss_2.0");

View File

@@ -1,29 +1,15 @@
package com.commafeed.frontend.rest.resources;
import java.util.Iterator;
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.UserSettings.ReadingOrder;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.commafeed.backend.services.FeedEntryService;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.Entry;
import com.commafeed.frontend.model.request.MarkRequest;
import com.commafeed.frontend.model.request.MultipleMarkRequest;
import com.commafeed.frontend.model.request.StarRequest;
@@ -87,63 +73,6 @@ public class EntryREST extends AbstractREST {
return Response.ok(Status.OK).build();
}
@Path("/search")
@GET
@ApiOperation(
value = "Search for entries",
notes = "Look through title and content of entries by keywords",
responseClass = "com.commafeed.frontend.model.Entries")
public Response searchEntries(
@ApiParam(value = "keywords separated by spaces, 3 characters minimum", required = true) @QueryParam("keywords") String keywords,
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset, @ApiParam(
value = "limit for paging") @DefaultValue("-1") @QueryParam("limit") int limit) {
keywords = StringUtils.trimToEmpty(keywords);
limit = Math.min(limit, 50);
Preconditions.checkArgument(StringUtils.length(keywords) >= 3);
Entries entries = new Entries();
entries.setOffset(offset);
entries.setLimit(limit);
List<FeedSubscription> subs = feedSubscriptionDAO.findAll(getUser());
List<FeedEntryStatus> entriesStatus = feedEntryStatusDAO.findBySubscriptions(subs, false, keywords, null, offset, limit + 1,
ReadingOrder.desc, true);
for (FeedEntryStatus status : entriesStatus) {
entries.getEntries().add(
Entry.build(status, applicationSettingsService.get().getPublicUrl(), applicationSettingsService.get()
.isImageProxyEnabled()));
}
boolean hasMore = entries.getEntries().size() > limit;
if (hasMore) {
entries.setHasMore(true);
entries.getEntries().remove(entries.getEntries().size() - 1);
}
removeUnwanted(entries.getEntries(), keywords);
entries.setName("Search for : " + keywords);
entries.setTimestamp(System.currentTimeMillis());
return Response.ok(entries).build();
}
private void removeUnwanted(List<Entry> entries, String keywords) {
Iterator<Entry> it = entries.iterator();
while (it.hasNext()) {
Entry entry = it.next();
boolean keep = true;
for (String keyword : keywords.split(" ")) {
String title = Jsoup.parse(entry.getTitle()).text();
String content = Jsoup.parse(entry.getContent()).text();
if (!StringUtils.containsIgnoreCase(content, keyword) && !StringUtils.containsIgnoreCase(title, keyword)) {
keep = false;
break;
}
}
if (!keep) {
it.remove();
}
}
}
}

View File

@@ -125,7 +125,7 @@ public class FeedREST extends AbstractREST {
@Context
private HttpServletRequest request;
@Inject
ApplicationSettingsService applicationSettingsService;
@@ -140,10 +140,15 @@ public class FeedREST extends AbstractREST {
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset, @ApiParam(
value = "limit for paging, default 20, maximum 50") @DefaultValue("20") @QueryParam("limit") int limit, @ApiParam(
value = "date ordering",
allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order) {
allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order, @ApiParam(
value = "keywords separated by spaces, 3 characters minimum",
required = true) @QueryParam("keywords") String keywords) {
Preconditions.checkNotNull(id);
Preconditions.checkNotNull(readType);
keywords = StringUtils.trimToNull(keywords);
Preconditions.checkArgument(keywords == null || StringUtils.length(keywords) >= 3);
limit = Math.min(limit, 50);
limit = Math.max(0, limit);
@@ -163,7 +168,7 @@ public class FeedREST extends AbstractREST {
entries.setErrorCount(subscription.getFeed().getErrorCount());
entries.setFeedLink(subscription.getFeed().getLink());
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(Arrays.asList(subscription), unreadOnly, null,
List<FeedEntryStatus> list = feedEntryStatusDAO.findBySubscriptions(Arrays.asList(subscription), unreadOnly, keywords,
newerThanDate, offset, limit + 1, order, true);
for (FeedEntryStatus status : list) {
@@ -180,6 +185,7 @@ public class FeedREST extends AbstractREST {
}
entries.setTimestamp(System.currentTimeMillis());
FeedUtils.removeUnwantedFromSearch(entries.getEntries(), keywords);
return Response.ok(entries).build();
}
@@ -197,7 +203,7 @@ public class FeedREST extends AbstractREST {
int offset = 0;
int limit = 20;
Entries entries = (Entries) getFeedEntries(id, readType, null, offset, limit, order).getEntity();
Entries entries = (Entries) getFeedEntries(id, readType, null, offset, limit, order, null).getEntity();
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss_2.0");