From a5252bb7654af046dcc65a6e1a0e50ca0623a621 Mon Sep 17 00:00:00 2001 From: Christian Schabesberger Date: Wed, 15 Feb 2017 15:21:36 +0100 Subject: [PATCH] add search filter menu --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 6 +- .../java/org/schabi/newpipe/MainActivity.java | 12 ++- .../channel/ChannelInfoItemCollector.java | 63 +++++++------- .../search/InfoItemSearchCollector.java | 25 ++++-- .../youtube/YoutubeChannelExtractor.java | 2 +- .../YoutubeChannelInfoItemExtractor.java | 8 +- .../services/youtube/YoutubeSearchEngine.java | 5 +- .../YoutubeStreamInfoItemExtractor.java | 19 ++-- .../stream_info/StreamInfoItemCollector.java | 87 ++++++++++--------- .../newpipe/info_list/InfoItemBuilder.java | 2 + .../newpipe/info_list/InfoListAdapter.java | 24 ++++- .../SearchInfoItemFragment.java | 31 ++++++- app/src/main/res/menu/main_menu.xml | 8 +- app/src/main/res/menu/search_menu.xml | 11 +++ app/src/main/res/menu/videoitem_list.xml | 21 ----- app/src/main/res/values/strings.xml | 2 + 17 files changed, 205 insertions(+), 122 deletions(-) delete mode 100644 app/src/main/res/menu/videoitem_list.xml diff --git a/app/build.gradle b/app/build.gradle index 488012afc..c9ba8169f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,4 +48,5 @@ dependencies { testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.10.19' compile 'ch.acra:acra:4.9.0' + compile 'com.google.android.gms:play-services-appindexing:8.4.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2b44f0b53..af33d93f4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -170,7 +170,11 @@ - + + \ No newline at end of file diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 3621603de..15395290a 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -5,10 +5,14 @@ import android.media.AudioManager; import android.support.v4.app.Fragment; import android.support.v4.app.NavUtils; import android.os.Bundle; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.settings.SettingsActivity; import org.schabi.newpipe.util.PermissionHelper; @@ -33,8 +37,8 @@ import org.schabi.newpipe.util.PermissionHelper; */ public class MainActivity extends ThemableActivity { - private Fragment mainFragment = null; + private static final String TAG = MainActivity.class.toString(); @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,7 +62,7 @@ public class MainActivity extends ThemableActivity { public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); - switch(id) { + switch (id) { case android.R.id.home: { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -71,10 +75,10 @@ public class MainActivity extends ThemableActivity { return true; } case R.id.action_show_downloads: { - if(!PermissionHelper.checkStoragePermissions(this)) { + if (!PermissionHelper.checkStoragePermissions(this)) { return false; } - Intent intent = new Intent(this, org.schabi.newpipe.download.DownloadActivity.class); + Intent intent = new Intent(this, DownloadActivity.class); startActivity(intent); return true; } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java index 425b01a72..525820d44 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java @@ -32,38 +32,41 @@ public class ChannelInfoItemCollector extends InfoItemCollector { super(serviceId); } + public ChannelInfoItem extract(ChannelInfoItemExtractor extractor) throws ParsingException { + ChannelInfoItem resultItem = new ChannelInfoItem(); + // importand information + resultItem.channelName = extractor.getChannelName(); + + resultItem.serviceId = getServiceId(); + resultItem.webPageUrl = extractor.getWebPageUrl(); + + // optional information + try { + resultItem.subscriberCount = extractor.getSubscriberCount(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.videoAmount = extractor.getVideoAmount(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.thumbnailUrl = extractor.getThumbnailUrl(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.description = extractor.getDescription(); + } catch (Exception e) { + addError(e); + } + return resultItem; + } + public void commit(ChannelInfoItemExtractor extractor) throws ParsingException { try { - ChannelInfoItem resultItem = new ChannelInfoItem(); - // importand information - resultItem.channelName = extractor.getChannelName(); - - resultItem.serviceId = getServiceId(); - resultItem.webPageUrl = extractor.getWebPageUrl(); - - // optional information - try { - resultItem.subscriberCount = extractor.getSubscriberCount(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.videoAmount = extractor.getVideoAmount(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.thumbnailUrl = extractor.getThumbnailUrl(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.description = extractor.getDescription(); - } catch (Exception e) { - addError(e); - } - - addItem(resultItem); + addItem(extract(extractor)); } catch (Exception e) { addError(e); } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java index 01d4f655f..b7ec0e3c1 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java @@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.UrlIdHandler; import org.schabi.newpipe.extractor.channel.ChannelInfoItemCollector; import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ExtractionException; +import org.schabi.newpipe.extractor.exceptions.FoundAdException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector; import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor; @@ -34,6 +35,8 @@ public class InfoItemSearchCollector extends InfoItemCollector { private StreamInfoItemCollector streamCollector; private ChannelInfoItemCollector channelCollector; + SearchResult result = new SearchResult(); + InfoItemSearchCollector(UrlIdHandler handler, int serviceId) { super(serviceId); streamCollector = new StreamInfoItemCollector(handler, serviceId); @@ -45,22 +48,32 @@ public class InfoItemSearchCollector extends InfoItemCollector { } public SearchResult getSearchResult() throws ExtractionException { - SearchResult result = new SearchResult(); addFromCollector(channelCollector); addFromCollector(streamCollector); result.suggestion = suggestion; result.errors = getErrors(); - result.resultList = getItemList(); return result; } - public void commit(StreamInfoItemExtractor extractor) throws ParsingException { - streamCollector.commit(extractor); + public void commit(StreamInfoItemExtractor extractor) { + try { + result.resultList.add(streamCollector.extract(extractor)); + } catch(FoundAdException ae) { + System.err.println("Found add"); + } catch (Exception e) { + addError(e); + } } - public void commit(ChannelInfoItemExtractor extractor) throws ParsingException { - channelCollector.commit(extractor); + public void commit(ChannelInfoItemExtractor extractor) { + try { + result.resultList.add(channelCollector.extract(extractor)); + } catch(FoundAdException ae) { + System.err.println("Found add"); + } catch (Exception e) { + addError(e); + } } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractor.java index 1400b3258..413471eda 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractor.java @@ -136,7 +136,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor { if(!isAjaxPage) { Element el = doc.select("div[id=\"gh-banner\"]").first().select("style").first(); String cssContent = el.html(); - String url = Parser.matchGroup1("url\\(([^)]+)\\)", cssContent); + String url = "https:" + Parser.matchGroup1("url\\(([^)]+)\\)", cssContent); if (url.contains("s.ytimg.com") || url.contains("default_banner")) { bannerUrl = null; diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java index 10ce48a12..7dafb63e8 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java @@ -55,8 +55,12 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor } public long getSubscriberCount() throws ParsingException { - return Long.parseLong(el.select("span[class*=\"yt-subscriber-count\"]").first() - .text().replaceAll("\\D+","")); + Element subsEl = el.select("span[class*=\"yt-subscriber-count\"]").first(); + if(subsEl == null) { + return 0; + } else { + return Integer.parseInt(subsEl.text().replaceAll("\\D+","")); + } } public int getVideoAmount() throws ParsingException { diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java index f5feee629..bedb5df79 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java @@ -108,8 +108,9 @@ public class YoutubeSearchEngine extends SearchEngine { } else if((el = item.select("div[class*=\"yt-lockup-channel\"]").first()) != null) { collector.commit(new YoutubeChannelInfoItemExtractor(el)); } else { - //noinspection ConstantConditions - throw new ExtractionException("unexpected element found: \"" + el + "\""); + // noinspection ConstantConditions + // simply ignore not known items + // throw new ExtractionException("unexpected element found: \"" + item + "\""); } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamInfoItemExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamInfoItemExtractor.java index fbac1a6a0..1afb8f57d 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamInfoItemExtractor.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamInfoItemExtractor.java @@ -83,9 +83,12 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor { @Override public String getUploadDate() throws ParsingException { try { - return item.select("div[class=\"yt-lockup-meta\"]").first() - .select("li").first() - .text(); + Element div = item.select("div[class=\"yt-lockup-meta\"]").first(); + if(div == null) { + return null; + } else { + return div.select("li").first().text(); + } } catch(Exception e) { throw new ParsingException("Could not get uplaod date", e); } @@ -96,9 +99,13 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor { String output; String input; try { - input = item.select("div[class=\"yt-lockup-meta\"]").first() - .select("li").get(1) - .text(); + Element div = item.select("div[class=\"yt-lockup-meta\"]").first(); + if(div == null) { + return -1; + } else { + input = div.select("li").get(1) + .text(); + } } catch (IndexOutOfBoundsException e) { if(isLiveStream(item)) { // -1 for no view count diff --git a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java index 1fc44df50..15c11b850 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java @@ -42,49 +42,54 @@ public class StreamInfoItemCollector extends InfoItemCollector { return urlIdHandler; } + public StreamInfoItem extract(StreamInfoItemExtractor extractor) throws Exception { + + StreamInfoItem resultItem = new StreamInfoItem(); + // importand information + resultItem.service_id = getServiceId(); + resultItem.webpage_url = extractor.getWebPageUrl(); + if (getUrlIdHandler() == null) { + throw new ParsingException("Error: UrlIdHandler not set"); + } else if (!resultItem.webpage_url.isEmpty()) { + resultItem.id = NewPipe.getService(getServiceId()) + .getUrlIdHandlerInstance() + .getId(resultItem.webpage_url); + } + resultItem.title = extractor.getTitle(); + resultItem.stream_type = extractor.getStreamType(); + + // optional information + try { + resultItem.duration = extractor.getDuration(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.uploader = extractor.getUploader(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.upload_date = extractor.getUploadDate(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.view_count = extractor.getViewCount(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.thumbnail_url = extractor.getThumbnailUrl(); + } catch (Exception e) { + addError(e); + } + return resultItem; + } + public void commit(StreamInfoItemExtractor extractor) throws ParsingException { try { - StreamInfoItem resultItem = new StreamInfoItem(); - // importand information - resultItem.service_id = getServiceId(); - resultItem.webpage_url = extractor.getWebPageUrl(); - if (getUrlIdHandler() == null) { - throw new ParsingException("Error: UrlIdHandler not set"); - } else if(!resultItem.webpage_url.isEmpty()) { - resultItem.id = NewPipe.getService(getServiceId()) - .getUrlIdHandlerInstance() - .getId(resultItem.webpage_url); - } - resultItem.title = extractor.getTitle(); - resultItem.stream_type = extractor.getStreamType(); - - // optional information - try { - resultItem.duration = extractor.getDuration(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.uploader = extractor.getUploader(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.upload_date = extractor.getUploadDate(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.view_count = extractor.getViewCount(); - } catch (Exception e) { - addError(e); - } - try { - resultItem.thumbnail_url = extractor.getThumbnailUrl(); - } catch (Exception e) { - addError(e); - } - addItem(resultItem); + addItem(extract(extractor)); } catch(FoundAdException ae) { System.out.println("AD_WARNING: " + ae.getMessage()); } catch (Exception e) { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java index 518b3c18e..67b19520a 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java @@ -82,6 +82,8 @@ public class InfoItemBuilder { } public void buildByHolder(InfoItemHolder holder, final InfoItem i) { + if(i.infoType() != holder.infoType()) + return; switch(i.infoType()) { case STREAM: buildStreamInfoItem((StreamInfoItemHolder) holder, (StreamInfoItem) i); diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 6841a1734..adbdc22e7 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -71,16 +71,32 @@ public class InfoListAdapter extends RecyclerView.Adapter { return infoItemList.size(); } + // don't ask why we have to do that this way... it's android accept it -.- @Override - public InfoItemHolder onCreateViewHolder(ViewGroup parent, int i) { - switch(infoItemList.get(i).infoType()) { + public int getItemViewType(int position) { + switch(infoItemList.get(position).infoType()) { case STREAM: + return 0; + case CHANNEL: + return 1; + case PLAYLIST: + return 2; + default: + Log.e(TAG, "Trollolo"); + return -1; + } + } + + @Override + public InfoItemHolder onCreateViewHolder(ViewGroup parent, int type) { + switch(type) { + case 0: return new StreamInfoItemHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.stream_item, parent, false)); - case CHANNEL: + case 1: return new ChannelInfoItemHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.channel_item, parent, false)); - case PLAYLIST: + case 2: Log.e(TAG, "Playlist is not yet implemented"); return null; default: diff --git a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java index f0f4bc16d..461f7c981 100644 --- a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java +++ b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java @@ -60,6 +60,9 @@ public class SearchInfoItemFragment extends Fragment { private static final String TAG = SearchInfoItemFragment.class.toString(); + private EnumSet filter = + EnumSet.of(SearchEngine.Filter.CHANNEL, SearchEngine.Filter.VIDEO); + /** * Listener for search queries */ @@ -293,6 +296,32 @@ public class SearchInfoItemFragment extends Fragment { setupSearchView(searchView); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch(item.getItemId()) { + case R.id.menu_filter_all: + changeFilter(item, EnumSet.of(SearchEngine.Filter.VIDEO, SearchEngine.Filter.CHANNEL)); + return true; + case R.id.menu_filter_video: + changeFilter(item, EnumSet.of(SearchEngine.Filter.VIDEO)); + return true; + case R.id.menu_filter_channel: + changeFilter(item, EnumSet.of(SearchEngine.Filter.CHANNEL)); + return true; + default: + return false; + } + } + + private void changeFilter(MenuItem item, EnumSet filter) { + this.filter = filter; + item.setChecked(true); + if(searchQuery != null && !searchQuery.isEmpty()) { + Log.d(TAG, "Fuck+ " + searchQuery); + search(searchQuery); + } + } + private void setupSearchView(SearchView searchView) { suggestionListAdapter = new SuggestionListAdapter(getActivity()); searchView.setSuggestionsAdapter(suggestionListAdapter); @@ -320,7 +349,7 @@ public class SearchInfoItemFragment extends Fragment { query, page, getActivity(), - EnumSet.of(SearchEngine.Filter.CHANNEL)); + filter); } private void setDoneLoading() { diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml index b7e615bbc..10d3406d8 100644 --- a/app/src/main/res/menu/main_menu.xml +++ b/app/src/main/res/menu/main_menu.xml @@ -1,11 +1,13 @@ - + + + \ No newline at end of file diff --git a/app/src/main/res/menu/search_menu.xml b/app/src/main/res/menu/search_menu.xml index 79158063a..027df6668 100644 --- a/app/src/main/res/menu/search_menu.xml +++ b/app/src/main/res/menu/search_menu.xml @@ -6,4 +6,15 @@ app:showAsAction="ifRoom" android:title="@string/search" app:actionViewClass="android.support.v7.widget.SearchView" /> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/videoitem_list.xml b/app/src/main/res/menu/videoitem_list.xml deleted file mode 100644 index 8be1c5a4c..000000000 --- a/app/src/main/res/menu/videoitem_list.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5ff8b076b..b57a904ca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -84,6 +84,8 @@ Downloads Settings Error report + All + Channel Error