implemented word search
This commit is contained in:
parent
8bad211f68
commit
7d99031706
@ -145,6 +145,7 @@
|
|||||||
<string name="search_results_label">Search results</string>
|
<string name="search_results_label">Search results</string>
|
||||||
<string name="search_term_label">You searched:\u0020</string>
|
<string name="search_term_label">You searched:\u0020</string>
|
||||||
<string name="search_label">Search</string>
|
<string name="search_label">Search</string>
|
||||||
|
<string name="found_in_title_label">Found in title</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -69,7 +69,7 @@ public class SearchActivity extends SherlockListActivity {
|
|||||||
Log.d(TAG, "Starting search");
|
Log.d(TAG, "Starting search");
|
||||||
String query = intent.getStringExtra(SearchManager.QUERY);
|
String query = intent.getStringExtra(SearchManager.QUERY);
|
||||||
getSupportActionBar().setSubtitle(
|
getSupportActionBar().setSubtitle(
|
||||||
getString(R.string.search_term_label) + query);
|
getString(R.string.search_term_label) + "\"" + query + "\"");
|
||||||
startSearch(query);
|
startSearch(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,13 @@ public class SearchlistAdapter extends ArrayAdapter<SearchResult> {
|
|||||||
} else if (component.getClass() == FeedItem.class) {
|
} else if (component.getClass() == FeedItem.class) {
|
||||||
FeedItem item = (FeedItem) component;
|
FeedItem item = (FeedItem) component;
|
||||||
holder.title.setText(item.getTitle());
|
holder.title.setText(item.getTitle());
|
||||||
holder.subtitle.setVisibility(View.VISIBLE);
|
if (result.getSubtitle() != null) {
|
||||||
holder.subtitle.setText(result.getSubtitle());
|
holder.subtitle.setVisibility(View.VISIBLE);
|
||||||
|
holder.subtitle.setText(result.getSubtitle());
|
||||||
|
}
|
||||||
FeedImageLoader.getInstance().loadBitmap(item.getFeed().getImage(),
|
FeedImageLoader.getInstance().loadBitmap(item.getFeed().getImage(),
|
||||||
holder.cover); }
|
holder.cover);
|
||||||
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,36 @@
|
|||||||
package de.danoeh.antennapod.feed;
|
package de.danoeh.antennapod.feed;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import de.danoeh.antennapod.AppConfig;
|
import de.danoeh.antennapod.AppConfig;
|
||||||
import de.danoeh.antennapod.PodcastApp;
|
import de.danoeh.antennapod.PodcastApp;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.util.SearchResultValueComparator;
|
||||||
|
|
||||||
/** Performs search on Feeds and FeedItems */
|
/** Performs search on Feeds and FeedItems */
|
||||||
public class FeedSearcher {
|
public class FeedSearcher {
|
||||||
private static final String TAG = "FeedSearcher";
|
private static final String TAG = "FeedSearcher";
|
||||||
|
|
||||||
|
// Search result values
|
||||||
|
private static final int VALUE_FEED_TITLE = 3;
|
||||||
|
private static final int VALUE_ITEM_TITLE = 2;
|
||||||
|
private static final int VALUE_ITEM_CHAPTER = 1;
|
||||||
|
private static final int VALUE_ITEM_DESCRIPTION = 0;
|
||||||
|
private static final int VALUE_WORD_MATCH = 4;
|
||||||
|
|
||||||
/** Performs a search in all feeds or one specific feed. */
|
/** Performs a search in all feeds or one specific feed. */
|
||||||
public static ArrayList<SearchResult> performSearch(final String query,
|
public static ArrayList<SearchResult> performSearch(final String query,
|
||||||
Feed selectedFeed) {
|
Feed selectedFeed) {
|
||||||
String lcQuery = query.toLowerCase();
|
String lcQuery = query.toLowerCase();
|
||||||
ArrayList<SearchResult> result = new ArrayList<SearchResult>();
|
ArrayList<SearchResult> result = new ArrayList<SearchResult>();
|
||||||
if (selectedFeed == null) {
|
if (selectedFeed == null) {
|
||||||
if (AppConfig.DEBUG) Log.d(TAG, "Performing global search");
|
if (AppConfig.DEBUG)
|
||||||
|
Log.d(TAG, "Performing global search");
|
||||||
if (AppConfig.DEBUG)
|
if (AppConfig.DEBUG)
|
||||||
Log.d(TAG, "Searching Feed titles");
|
Log.d(TAG, "Searching Feed titles");
|
||||||
searchFeedtitles(lcQuery, result);
|
searchFeedtitles(lcQuery, result);
|
||||||
@ -42,6 +54,10 @@ public class FeedSearcher {
|
|||||||
Log.d(TAG, "Searching item content encoded data");
|
Log.d(TAG, "Searching item content encoded data");
|
||||||
searchFeedItemContentEncoded(lcQuery, result, selectedFeed);
|
searchFeedItemContentEncoded(lcQuery, result, selectedFeed);
|
||||||
|
|
||||||
|
if (AppConfig.DEBUG)
|
||||||
|
Log.d(TAG, "Sorting results");
|
||||||
|
Collections.sort(result, new SearchResultValueComparator());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +65,10 @@ public class FeedSearcher {
|
|||||||
ArrayList<SearchResult> destination) {
|
ArrayList<SearchResult> destination) {
|
||||||
FeedManager manager = FeedManager.getInstance();
|
FeedManager manager = FeedManager.getInstance();
|
||||||
for (Feed feed : manager.getFeeds()) {
|
for (Feed feed : manager.getFeeds()) {
|
||||||
if (feed.getTitle().toLowerCase().contains(query)) {
|
SearchResult result = createSearchResult(feed, query, feed
|
||||||
destination.add(new SearchResult(feed, null));
|
.getTitle().toLowerCase(), VALUE_FEED_TITLE);
|
||||||
|
if (result != null) {
|
||||||
|
destination.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,11 +88,14 @@ public class FeedSearcher {
|
|||||||
private static void searchFeedItemTitlesSingleFeed(String query,
|
private static void searchFeedItemTitlesSingleFeed(String query,
|
||||||
ArrayList<SearchResult> destination, Feed feed) {
|
ArrayList<SearchResult> destination, Feed feed) {
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (item.getTitle().toLowerCase().contains(query)) {
|
SearchResult result = createSearchResult(item, query, item
|
||||||
destination.add(new SearchResult(item, PodcastApp.getInstance()
|
.getTitle().toLowerCase(), VALUE_ITEM_TITLE);
|
||||||
.getString(R.string.found_in_label)
|
if (result != null) {
|
||||||
+ item.getFeed().getTitle()));
|
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||||
|
R.string.found_in_title_label));
|
||||||
|
destination.add(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,10 +116,12 @@ public class FeedSearcher {
|
|||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (item.getSimpleChapters() != null) {
|
if (item.getSimpleChapters() != null) {
|
||||||
for (SimpleChapter sc : item.getSimpleChapters()) {
|
for (SimpleChapter sc : item.getSimpleChapters()) {
|
||||||
if (sc.getTitle().toLowerCase().contains(query)) {
|
SearchResult result = createSearchResult(item, query, sc
|
||||||
destination.add(new SearchResult(item, PodcastApp
|
.getTitle().toLowerCase(), VALUE_ITEM_CHAPTER);
|
||||||
.getInstance().getString(
|
if (result != null) {
|
||||||
R.string.found_in_chapters_label)));
|
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||||
|
R.string.found_in_chapters_label));
|
||||||
|
destination.add(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,10 +144,15 @@ public class FeedSearcher {
|
|||||||
private static void searchFeedItemDescriptionSingleFeed(String query,
|
private static void searchFeedItemDescriptionSingleFeed(String query,
|
||||||
ArrayList<SearchResult> destination, Feed feed) {
|
ArrayList<SearchResult> destination, Feed feed) {
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (item.getDescription() != null
|
if (item.getDescription() != null) {
|
||||||
&& item.getDescription().toLowerCase().contains(query)) {
|
SearchResult result = createSearchResult(item, query, item
|
||||||
destination.add(new SearchResult(item, PodcastApp.getInstance()
|
.getDescription().toLowerCase(), VALUE_ITEM_DESCRIPTION);
|
||||||
.getString(R.string.found_in_shownotes_label)));
|
if (result != null) {
|
||||||
|
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||||
|
R.string.found_in_shownotes_label));
|
||||||
|
destination.add(result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,19 +165,47 @@ public class FeedSearcher {
|
|||||||
searchFeedItemContentEncodedSingleFeed(query, destination, feed);
|
searchFeedItemContentEncodedSingleFeed(query, destination, feed);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
searchFeedItemContentEncodedSingleFeed(query, destination, selectedFeed);
|
searchFeedItemContentEncodedSingleFeed(query, destination,
|
||||||
|
selectedFeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void searchFeedItemContentEncodedSingleFeed(String query,
|
private static void searchFeedItemContentEncodedSingleFeed(String query,
|
||||||
ArrayList<SearchResult> destination, Feed feed) {
|
ArrayList<SearchResult> destination, Feed feed) {
|
||||||
for (FeedItem item : feed.getItems()) {
|
for (FeedItem item : feed.getItems()) {
|
||||||
if (!destination.contains(item) && item.getContentEncoded() != null
|
if (!destination.contains(item) && item.getContentEncoded() != null) {
|
||||||
&& item.getContentEncoded().toLowerCase().contains(query)) {
|
SearchResult result = createSearchResult(item, query, item
|
||||||
destination.add(new SearchResult(item, PodcastApp.getInstance()
|
.getContentEncoded().toLowerCase(),
|
||||||
.getString(R.string.found_in_shownotes_label)));
|
VALUE_ITEM_DESCRIPTION);
|
||||||
|
if (result != null) {
|
||||||
|
result.setSubtitle(PodcastApp.getInstance().getString(
|
||||||
|
R.string.found_in_shownotes_label));
|
||||||
|
destination.add(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SearchResult createSearchResult(FeedComponent component,
|
||||||
|
String query, String text, int baseValue) {
|
||||||
|
int bonus = 0;
|
||||||
|
boolean found = false;
|
||||||
|
// try word search
|
||||||
|
Pattern word = Pattern.compile("\b" + query + "\b");
|
||||||
|
Matcher matcher = word.matcher(text);
|
||||||
|
found = matcher.find();
|
||||||
|
if (found) {
|
||||||
|
bonus = VALUE_WORD_MATCH;
|
||||||
|
} else {
|
||||||
|
// search for other occurence
|
||||||
|
found = text.contains(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
return new SearchResult(component, baseValue + bonus);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,13 @@ public class SearchResult {
|
|||||||
private FeedComponent component;
|
private FeedComponent component;
|
||||||
/** Additional information (e.g. where it was found) */
|
/** Additional information (e.g. where it was found) */
|
||||||
private String subtitle;
|
private String subtitle;
|
||||||
|
/** Higher value means more importance */
|
||||||
|
private int value;
|
||||||
|
|
||||||
public SearchResult(FeedComponent component, String subtitle) {
|
public SearchResult(FeedComponent component, int value) {
|
||||||
super();
|
super();
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.subtitle = subtitle;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedComponent getComponent() {
|
public FeedComponent getComponent() {
|
||||||
@ -19,4 +21,13 @@ public class SearchResult {
|
|||||||
return subtitle;
|
return subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSubtitle(String subtitle) {
|
||||||
|
this.subtitle = subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
package de.danoeh.antennapod.util;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import de.danoeh.antennapod.feed.SearchResult;
|
||||||
|
|
||||||
|
public class SearchResultValueComparator implements Comparator<SearchResult> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(SearchResult lhs, SearchResult rhs) {
|
||||||
|
return rhs.getValue() - lhs.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user