Do not search in chapters

This speeds up searching a LOT. I hope that most podcasts use good descriptions
and we do not need to search for chapters. Podcasts outside of Germany use chapters
only very infrequently.
This commit is contained in:
ByteHamster 2020-02-05 09:51:29 +01:00
parent 8d23571bba
commit f4cfe7bdca
8 changed files with 36 additions and 141 deletions

View File

@ -9,15 +9,12 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent; import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.ApGlideSettings;
/** /**
@ -40,7 +37,7 @@ public class SearchlistAdapter extends BaseAdapter {
} }
@Override @Override
public SearchResult getItem(int position) { public FeedComponent getItem(int position) {
return itemAccess.getItem(position); return itemAccess.getItem(position);
} }
@ -52,8 +49,7 @@ public class SearchlistAdapter extends BaseAdapter {
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
final Holder holder; final Holder holder;
SearchResult result = getItem(position); FeedComponent component = getItem(position);
FeedComponent component = result.getComponent();
// Inflate Layout // Inflate Layout
if (convertView == null) { if (convertView == null) {
@ -94,7 +90,6 @@ public class SearchlistAdapter extends BaseAdapter {
final FeedItem item = (FeedItem) component; final FeedItem item = (FeedItem) component;
holder.title.setText(item.getTitle()); holder.title.setText(item.getTitle());
holder.subtitle.setVisibility(View.VISIBLE); holder.subtitle.setVisibility(View.VISIBLE);
holder.subtitle.setText(result.getLocation().getDescription());
convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f); convertView.setAlpha(item.isPlayed() ? 0.5f : 1.0f);
@ -122,7 +117,7 @@ public class SearchlistAdapter extends BaseAdapter {
public interface ItemAccess { public interface ItemAccess {
int getCount(); int getCount();
SearchResult getItem(int position); FeedComponent getItem(int position);
} }
} }

View File

@ -25,7 +25,6 @@ import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent; import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.storage.FeedSearcher; import de.danoeh.antennapod.core.storage.FeedSearcher;
import de.danoeh.antennapod.view.EmptyViewHandler; import de.danoeh.antennapod.view.EmptyViewHandler;
import io.reactivex.Observable; import io.reactivex.Observable;
@ -47,9 +46,8 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
private static final String ARG_FEED = "feed"; private static final String ARG_FEED = "feed";
private SearchlistAdapter searchAdapter; private SearchlistAdapter searchAdapter;
private List<SearchResult> searchResults = new ArrayList<>(); private List<FeedComponent> searchResults = new ArrayList<>();
private Disposable disposable; private Disposable disposable;
private ListView listView;
private ProgressBar progressBar; private ProgressBar progressBar;
private EmptyViewHandler emptyViewHandler; private EmptyViewHandler emptyViewHandler;
@ -57,7 +55,9 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
* Create a new SearchFragment that searches all feeds. * Create a new SearchFragment that searches all feeds.
*/ */
public static SearchFragment newInstance(String query) { public static SearchFragment newInstance(String query) {
if (query == null) query = ""; if (query == null) {
query = "";
}
SearchFragment fragment = new SearchFragment(); SearchFragment fragment = new SearchFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ARG_QUERY, query); args.putString(ARG_QUERY, query);
@ -103,7 +103,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.search_label); ((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(R.string.search_label);
View layout = inflater.inflate(R.layout.search_fragment, container, false); View layout = inflater.inflate(R.layout.search_fragment, container, false);
listView = layout.findViewById(R.id.listview); ListView listView = layout.findViewById(R.id.listview);
progressBar = layout.findViewById(R.id.progressBar); progressBar = layout.findViewById(R.id.progressBar);
searchAdapter = new SearchlistAdapter(getActivity(), itemAccess); searchAdapter = new SearchlistAdapter(getActivity(), itemAccess);
listView.setAdapter(searchAdapter); listView.setAdapter(searchAdapter);
@ -125,15 +125,12 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SearchResult result = (SearchResult) listView.getAdapter().getItem(position); FeedComponent comp = searchAdapter.getItem(position);
FeedComponent comp = result.getComponent();
if (comp.getClass() == Feed.class) { if (comp.getClass() == Feed.class) {
((MainActivity) getActivity()).loadFeedFragmentById(comp.getId(), null); ((MainActivity) getActivity()).loadFeedFragmentById(comp.getId(), null);
} else { } else if (comp.getClass() == FeedItem.class) {
if (comp.getClass() == FeedItem.class) { FeedItem item = (FeedItem) comp;
FeedItem item = (FeedItem) comp; ((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(item.getId()));
((MainActivity) getActivity()).loadChildFragment(ItemPagerFragment.newInstance(item.getId()));
}
} }
} }
@ -167,7 +164,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
search(); search();
} }
private void onSearchResults(List<SearchResult> results) { private void onSearchResults(List<FeedComponent> results) {
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
searchResults = results; searchResults = results;
searchAdapter.notifyDataSetChanged(); searchAdapter.notifyDataSetChanged();
@ -182,7 +179,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
} }
@Override @Override
public SearchResult getItem(int position) { public FeedComponent getItem(int position) {
if (0 <= position && position < searchResults.size()) { if (0 <= position && position < searchResults.size()) {
return searchResults.get(position); return searchResults.get(position);
} else { } else {
@ -204,7 +201,7 @@ public class SearchFragment extends Fragment implements AdapterView.OnItemClickL
} }
@NonNull @NonNull
private List<SearchResult> performSearch() { private List<FeedComponent> performSearch() {
Bundle args = getArguments(); Bundle args = getArguments();
String query = args.getString(ARG_QUERY); String query = args.getString(ARG_QUERY);
long feed = args.getLong(ARG_FEED); long feed = args.getLong(ARG_FEED);

View File

@ -1,22 +0,0 @@
package de.danoeh.antennapod.core.feed;
import de.danoeh.antennapod.core.storage.SearchLocation;
public class SearchResult {
private final FeedComponent component;
private SearchLocation location;
public SearchResult(FeedComponent component, SearchLocation location) {
super();
this.component = component;
this.location = location;
}
public FeedComponent getComponent() {
return component;
}
public SearchLocation getLocation() {
return location;
}
}

View File

@ -54,10 +54,10 @@ import de.danoeh.antennapod.core.event.settings.SpeedPresetChangedEvent;
import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent; import de.danoeh.antennapod.core.event.settings.VolumeAdaptionChangedEvent;
import de.danoeh.antennapod.core.feed.Chapter; import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.MediaType; import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.SleepTimerPreferences; import de.danoeh.antennapod.core.preferences.SleepTimerPreferences;
@ -1634,16 +1634,17 @@ public class PlaybackService extends MediaBrowserServiceCompat {
public void onPlayFromSearch(String query, Bundle extras) { public void onPlayFromSearch(String query, Bundle extras) {
Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString()); Log.d(TAG, "onPlayFromSearch query=" + query + " extras=" + extras.toString());
List<SearchResult> results = FeedSearcher.performSearch(getBaseContext(), query, 0); List<FeedComponent> results = FeedSearcher.performSearch(getBaseContext(), query, 0);
for (SearchResult result : results) { for (FeedComponent result : results) {
try { if (result instanceof FeedItem) {
FeedMedia p = ((FeedItem) (result.getComponent())).getMedia(); try {
mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true); FeedMedia media = ((FeedItem) result).getMedia();
return; mediaPlayer.playMediaObject(media, !media.localFileAvailable(), true, true);
} catch (Exception e) { return;
Log.d(TAG, e.getMessage()); } catch (Exception e) {
e.printStackTrace(); Log.d(TAG, e.getMessage());
continue; e.printStackTrace();
}
} }
} }
onPlay(); onPlay();

View File

@ -2,10 +2,9 @@ package de.danoeh.antennapod.core.storage;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedComponent;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -32,50 +31,19 @@ public class FeedSearcher {
* @return list of episodes containing the query * @return list of episodes containing the query
*/ */
@NonNull @NonNull
public static List<SearchResult> performSearch(final Context context, final String query, final long selectedFeed) { public static List<FeedComponent> performSearch(final Context context, final String query, final long selectedFeed) {
final List<SearchResult> result = new ArrayList<>(); final List<FeedComponent> result = new ArrayList<>();
try { try {
FutureTask<List<FeedItem>> itemSearchTask = DBTasks.searchFeedItems(context, selectedFeed, query); FutureTask<List<FeedItem>> itemSearchTask = DBTasks.searchFeedItems(context, selectedFeed, query);
FutureTask<List<Feed>> feedSearchTask = DBTasks.searchFeeds(context, query); FutureTask<List<Feed>> feedSearchTask = DBTasks.searchFeeds(context, query);
itemSearchTask.run(); itemSearchTask.run();
feedSearchTask.run(); feedSearchTask.run();
final List<Feed> feeds = feedSearchTask.get(); result.addAll(feedSearchTask.get());
for (Feed item : feeds) { result.addAll(itemSearchTask.get());
result.add(new SearchResult(item, null));
}
final List<FeedItem> items = itemSearchTask.get();
for (FeedItem item : items) {
SearchLocation location;
if (safeContains(item.getTitle(), query)) {
location = SearchLocation.TITLE;
} else if (safeContains(item.getChapters(), query)) {
location = SearchLocation.CHAPTERS;
} else {
location = SearchLocation.SHOWNOTES;
}
result.add(new SearchResult(item, location));
}
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
} }
return result; return result;
} }
private static boolean safeContains(String haystack, String needle) {
return haystack != null && haystack.contains(needle);
}
private static boolean safeContains(List<Chapter> haystack, String needle) {
if (haystack == null) {
return false;
}
for (Chapter chapter : haystack) {
if (safeContains(chapter.getTitle(), needle)) {
return true;
}
}
return false;
}
} }

View File

@ -1276,15 +1276,11 @@ public class PodDBAdapter {
queryFeedId = "1 = 1"; queryFeedId = "1 = 1";
} }
String query = "SELECT DISTINCT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS String query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS
+ " LEFT JOIN " + TABLE_NAME_SIMPLECHAPTERS
+ " ON " + TABLE_NAME_SIMPLECHAPTERS + "." + KEY_FEEDITEM
+ "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_ID
+ " WHERE " + queryFeedId + " AND (" + " WHERE " + queryFeedId + " AND ("
+ TABLE_NAME_FEED_ITEMS + "." + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' OR " + KEY_DESCRIPTION + " LIKE '%" + preparedQuery + "%' OR "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_CONTENT_ENCODED + " LIKE '%" + preparedQuery + "%' OR " + KEY_CONTENT_ENCODED + " LIKE '%" + preparedQuery + "%' OR "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_TITLE + " LIKE '%" + preparedQuery + "%' OR " + KEY_TITLE + " LIKE '%" + preparedQuery + "%'"
+ TABLE_NAME_SIMPLECHAPTERS + "." + KEY_TITLE + " LIKE '%" + preparedQuery + "%'"
+ ") ORDER BY " + KEY_PUBDATE + " DESC " + ") ORDER BY " + KEY_PUBDATE + " DESC "
+ "LIMIT 300"; + "LIMIT 300";
return db.rawQuery(query, null); return db.rawQuery(query, null);

View File

@ -1,19 +0,0 @@
package de.danoeh.antennapod.core.storage;
import androidx.annotation.StringRes;
import de.danoeh.antennapod.core.R;
public enum SearchLocation {
TITLE(R.string.found_in_title_label),
CHAPTERS(R.string.found_in_chapters_label),
SHOWNOTES(R.string.found_in_shownotes_label);
private int description;
SearchLocation(@StringRes int description) {
this.description = description;
}
public @StringRes int getDescription() {
return description;
}
}

View File

@ -1,21 +0,0 @@
package de.danoeh.antennapod.core.util.comparator;
import java.util.Comparator;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
public class InReverseChronologicalOrder implements Comparator<SearchResult> {
/**
* Compare items and sort it on chronological order.
*/
@Override
public int compare(SearchResult o1, SearchResult o2) {
if ((o1.getComponent() instanceof FeedItem) && (o2.getComponent() instanceof FeedItem)) {
FeedItem item1 = (FeedItem) o1.getComponent();
FeedItem item2 = (FeedItem) o2.getComponent();
return item2.getPubDate().compareTo(item1.getPubDate());
}
return 0;
}
}