mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-10-31 23:32:59 +00:00
setup core for search channel support
This commit is contained in:
@@ -92,7 +92,8 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(infoListAdapter);
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
infoListAdapter.setOnStreamItemSelectedListener(
|
||||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||
@@ -172,7 +173,7 @@ public class ChannelActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void addVideos(final ChannelInfo info) {
|
||||
infoListAdapter.addStreamItemList(info.related_streams);
|
||||
infoListAdapter.addInfoItemList(info.related_streams);
|
||||
}
|
||||
|
||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
||||
|
||||
@@ -28,11 +28,9 @@ import java.util.Vector;
|
||||
public class InfoItemCollector {
|
||||
private List<InfoItem> itemList = new Vector<>();
|
||||
private List<Throwable> errors = new Vector<>();
|
||||
private UrlIdHandler urlIdHandler;
|
||||
private int serviceId = -1;
|
||||
|
||||
public InfoItemCollector(UrlIdHandler handler, int serviceId) {
|
||||
urlIdHandler = handler;
|
||||
public InfoItemCollector(int serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
@@ -60,7 +58,4 @@ public class InfoItemCollector {
|
||||
protected int getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
protected UrlIdHandler getUrlIdHandler() {
|
||||
return urlIdHandler;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,18 @@ import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
||||
public class ChannelInfoItem implements InfoItem {
|
||||
|
||||
public int serviceId = -1;
|
||||
public String channelName = "";
|
||||
public String webPageUrl = "";
|
||||
public int subscriberCount = -1;
|
||||
public int videoAmount = -1;
|
||||
|
||||
public InfoType infoType() {
|
||||
return InfoType.CHANNEL;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getLink() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.FoundAdException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItemCollector.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class ChannelInfoItemCollector extends InfoItemCollector {
|
||||
public ChannelInfoItemCollector(int serviceId) {
|
||||
super(serviceId);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
addItem(resultItem);
|
||||
} catch (Exception e) {
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.schabi.newpipe.extractor.channel;
|
||||
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItemExtractor.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public interface ChannelInfoItemExtractor {
|
||||
String getChannelName() throws ParsingException;
|
||||
String getWebPageUrl() throws ParsingException;
|
||||
int getSubscriberCount() throws ParsingException;
|
||||
int getVideoAmount() throws ParsingException;
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package org.schabi.newpipe.extractor.search;
|
||||
|
||||
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||
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.ParsingException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
@@ -30,10 +32,12 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||
public class InfoItemSearchCollector extends InfoItemCollector {
|
||||
private String suggestion = "";
|
||||
private StreamInfoItemCollector streamCollector;
|
||||
private ChannelInfoItemCollector channelCollector;
|
||||
|
||||
InfoItemSearchCollector(UrlIdHandler handler, int serviceId) {
|
||||
super(handler, serviceId);
|
||||
super(serviceId);
|
||||
streamCollector = new StreamInfoItemCollector(handler, serviceId);
|
||||
channelCollector = new ChannelInfoItemCollector(serviceId);
|
||||
}
|
||||
|
||||
public void setSuggestion(String suggestion) {
|
||||
@@ -43,6 +47,7 @@ public class InfoItemSearchCollector extends InfoItemCollector {
|
||||
public SearchResult getSearchResult() throws ExtractionException {
|
||||
SearchResult result = new SearchResult();
|
||||
|
||||
addFromCollector(channelCollector);
|
||||
addFromCollector(streamCollector);
|
||||
|
||||
result.suggestion = suggestion;
|
||||
@@ -54,4 +59,8 @@ public class InfoItemSearchCollector extends InfoItemCollector {
|
||||
public void commit(StreamInfoItemExtractor extractor) throws ParsingException {
|
||||
streamCollector.commit(extractor);
|
||||
}
|
||||
|
||||
public void commit(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||
channelCollector.commit(extractor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 10.08.15.
|
||||
@@ -27,6 +28,10 @@ import java.io.IOException;
|
||||
*/
|
||||
|
||||
public abstract class SearchEngine {
|
||||
public enum Filter {
|
||||
VIDEO, CHANNEL, PLAY_LIST
|
||||
}
|
||||
|
||||
public static class NothingFoundException extends ExtractionException {
|
||||
public NothingFoundException(String message) {
|
||||
super(message);
|
||||
@@ -43,6 +48,6 @@ public abstract class SearchEngine {
|
||||
}
|
||||
//Result search(String query, int page);
|
||||
public abstract InfoItemSearchCollector search(
|
||||
String query, int page, String contentCountry)
|
||||
String query, int page, String contentCountry, EnumSet<Filter> filter)
|
||||
throws ExtractionException, IOException;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
@@ -30,10 +31,12 @@ import java.util.Vector;
|
||||
|
||||
public class SearchResult {
|
||||
public static SearchResult getSearchResult(SearchEngine engine, String query,
|
||||
int page, String languageCode)
|
||||
int page, String languageCode, EnumSet<SearchEngine.Filter> filter)
|
||||
throws ExtractionException, IOException {
|
||||
|
||||
SearchResult result = engine.search(query, page, languageCode).getSearchResult();
|
||||
SearchResult result = engine
|
||||
.search(query, page, languageCode, filter)
|
||||
.getSearchResult();
|
||||
if(result.resultList.isEmpty()) {
|
||||
if(result.suggestion.isEmpty()) {
|
||||
throw new ExtractionException("Empty result despite no error");
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.schabi.newpipe.extractor.services.youtube;
|
||||
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
|
||||
* YoutubeChannelInfoItemExtractor.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor {
|
||||
private Element el;
|
||||
|
||||
public YoutubeChannelInfoItemExtractor(Element el) {
|
||||
this.el = el;
|
||||
}
|
||||
|
||||
public String getChannelName() throws ParsingException {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getWebPageUrl() throws ParsingException {
|
||||
return "";
|
||||
}
|
||||
|
||||
public int getSubscriberCount() throws ParsingException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getVideoAmount() throws ParsingException {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,10 @@ import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.search.InfoItemSearchCollector;
|
||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
|
||||
/**
|
||||
@@ -46,7 +45,10 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemSearchCollector search(String query, int page, String languageCode)
|
||||
public InfoItemSearchCollector search(String query,
|
||||
int page,
|
||||
String languageCode,
|
||||
EnumSet<Filter> filter)
|
||||
throws IOException, ExtractionException {
|
||||
InfoItemSearchCollector collector = getInfoItemSearchCollector();
|
||||
|
||||
@@ -54,9 +56,13 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||
Downloader downloader = NewPipe.getDownloader();
|
||||
|
||||
String url = "https://www.youtube.com/results"
|
||||
+ "?search_query=" + URLEncoder.encode(query, CHARSET_UTF_8)
|
||||
+ "&page=" + Integer.toString(page + 1)
|
||||
+ "&filters=" + "video";
|
||||
+ "?q=" + URLEncoder.encode(query, CHARSET_UTF_8)
|
||||
+ "&page=" + Integer.toString(page + 1);
|
||||
if(filter.contains(Filter.VIDEO) && !filter.contains(Filter.CHANNEL)) {
|
||||
url += "&sp=EgIQAQ%253D%253D";
|
||||
} else if(!filter.contains(Filter.VIDEO) && filter.contains(Filter.CHANNEL)) {
|
||||
url += "&sp=EgIQAg%253D%253D";
|
||||
}
|
||||
|
||||
String site;
|
||||
//String url = builder.build().toString();
|
||||
@@ -94,12 +100,13 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||
}
|
||||
// search message item
|
||||
} else if ((el = item.select("div[class*=\"search-message\"]").first()) != null) {
|
||||
//result.errorMessage = el.text();
|
||||
throw new NothingFoundException(el.text());
|
||||
|
||||
// video item type
|
||||
} else if ((el = item.select("div[class*=\"yt-lockup-video\"").first()) != null) {
|
||||
} else if ((el = item.select("div[class*=\"yt-lockup-video\"]").first()) != null) {
|
||||
collector.commit(new YoutubeStreamInfoItemExtractor(el));
|
||||
} 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 + "\"");
|
||||
|
||||
@@ -31,8 +31,15 @@ import java.util.Vector;
|
||||
|
||||
public class StreamInfoItemCollector extends InfoItemCollector {
|
||||
|
||||
private UrlIdHandler urlIdHandler;
|
||||
|
||||
public StreamInfoItemCollector(UrlIdHandler handler, int serviceId) {
|
||||
super(handler, serviceId);
|
||||
super(serviceId);
|
||||
urlIdHandler = handler;
|
||||
}
|
||||
|
||||
private UrlIdHandler getUrlIdHandler() {
|
||||
return urlIdHandler;
|
||||
}
|
||||
|
||||
public void commit(StreamInfoItemExtractor extractor) throws ParsingException {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.schabi.newpipe.info_list;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
||||
import de.hdodenhof.circleimageview.CircleImageView;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* ChannelInfoItemHolder .java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class ChannelInfoItemHolder extends InfoItemHolder {
|
||||
public final CircleImageView itemThumbnailView;
|
||||
public final TextView itemChannelTitleView;
|
||||
public final Button itemButton;
|
||||
|
||||
ChannelInfoItemHolder(View v) {
|
||||
super(v);
|
||||
itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView);
|
||||
itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView);
|
||||
itemButton = (Button) v.findViewById(R.id.item_button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItem.InfoType infoType() {
|
||||
return InfoItem.InfoType.CHANNEL;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
@@ -13,6 +14,7 @@ import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.AbstractStreamInfo;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
|
||||
/**
|
||||
@@ -37,7 +39,8 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
|
||||
public class InfoItemBuilder {
|
||||
|
||||
public interface OnItemSelectedListener {
|
||||
private static final String TAG = InfoItemBuilder.class.toString();
|
||||
public interface OnInfoItemSelectedListener {
|
||||
void selected(String url);
|
||||
}
|
||||
|
||||
@@ -46,19 +49,64 @@ public class InfoItemBuilder {
|
||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||
private DisplayImageOptions displayImageOptions =
|
||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||
private OnItemSelectedListener onItemSelectedListener;
|
||||
private OnInfoItemSelectedListener onStreamInfoItemSelectedListener;
|
||||
private OnInfoItemSelectedListener onChannelInfoItemSelectedListener;
|
||||
|
||||
public InfoItemBuilder(Activity a, View rootView) {
|
||||
activity = a;
|
||||
this.rootView = rootView;
|
||||
}
|
||||
|
||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||
this.onItemSelectedListener = onItemSelectedListener;
|
||||
public void setOnStreamInfoItemSelectedListener(
|
||||
OnInfoItemSelectedListener listener) {
|
||||
this.onStreamInfoItemSelectedListener = listener;
|
||||
}
|
||||
|
||||
public void setOnChannelInfoItemSelectedListener(
|
||||
OnInfoItemSelectedListener listener) {
|
||||
this.onChannelInfoItemSelectedListener = listener;
|
||||
}
|
||||
|
||||
public void buildByHolder(InfoItemHolder holder, final InfoItem i) {
|
||||
final StreamInfoItem info = (StreamInfoItem) i;
|
||||
switch(i.infoType()) {
|
||||
case STREAM:
|
||||
buildStreamInfoItem((StreamInfoItemHolder) holder, (StreamInfoItem) i);
|
||||
break;
|
||||
case CHANNEL:
|
||||
buildChannelInfoItem((ChannelInfoItemHolder) holder, (ChannelInfoItem) i);
|
||||
break;
|
||||
case PLAYLIST:
|
||||
Log.e(TAG, "Not yet implemented");
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Trollolo");
|
||||
}
|
||||
}
|
||||
|
||||
public View buildView(ViewGroup parent, final InfoItem info) {
|
||||
View itemView = null;
|
||||
InfoItemHolder holder = null;
|
||||
switch(info.infoType()) {
|
||||
case STREAM:
|
||||
itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.stream_item, parent, false);
|
||||
holder = new StreamInfoItemHolder(itemView);
|
||||
break;
|
||||
case CHANNEL:
|
||||
itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.channel_item, parent, false);
|
||||
holder = new ChannelInfoItemHolder(itemView);
|
||||
break;
|
||||
case PLAYLIST:
|
||||
Log.e(TAG, "Not yet implemented");
|
||||
default:
|
||||
Log.e(TAG, "Trollolo");
|
||||
}
|
||||
buildByHolder(holder, info);
|
||||
return itemView;
|
||||
}
|
||||
|
||||
private void buildStreamInfoItem(StreamInfoItemHolder holder, final StreamInfoItem info) {
|
||||
if(info.infoType() != InfoItem.InfoType.STREAM) {
|
||||
Log.e("InfoItemBuilder", "Info type not yet supported");
|
||||
}
|
||||
@@ -98,20 +146,23 @@ public class InfoItemBuilder {
|
||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
onItemSelectedListener.selected(info.webpage_url);
|
||||
onStreamInfoItemSelectedListener.selected(info.webpage_url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public View buildView(ViewGroup parent, final InfoItem info) {
|
||||
View streamPreviewView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.video_item, parent, false);
|
||||
InfoItemHolder holder = new InfoItemHolder(streamPreviewView);
|
||||
buildByHolder(holder, info);
|
||||
return streamPreviewView;
|
||||
private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) {
|
||||
holder.itemChannelTitleView.setText(info.getTitle());
|
||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
onChannelInfoItemSelectedListener.selected(info.getLink());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String shortViewCount(Long viewCount){
|
||||
if(viewCount >= 1000000000){
|
||||
return Long.toString(viewCount/1000000000)+"B views";
|
||||
|
||||
@@ -2,14 +2,11 @@ package org.schabi.newpipe.info_list;
|
||||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 01.08.16.
|
||||
* Created by Christian Schabesberger on 12.02.17.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* InfoItemHolder.java is part of NewPipe.
|
||||
@@ -28,25 +25,9 @@ import org.schabi.newpipe.R;
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class InfoItemHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public final ImageView itemThumbnailView;
|
||||
public final TextView itemVideoTitleView,
|
||||
itemUploaderView,
|
||||
itemDurationView,
|
||||
itemUploadDateView,
|
||||
itemViewCountView;
|
||||
public final Button itemButton;
|
||||
|
||||
public abstract class InfoItemHolder extends RecyclerView.ViewHolder {
|
||||
public InfoItemHolder(View v) {
|
||||
super(v);
|
||||
itemThumbnailView = (ImageView) v.findViewById(R.id.itemThumbnailView);
|
||||
itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView);
|
||||
itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView);
|
||||
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
|
||||
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView);
|
||||
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
|
||||
itemButton = (Button) v.findViewById(R.id.item_button);
|
||||
}
|
||||
|
||||
public abstract InfoItem.InfoType infoType();
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package org.schabi.newpipe.info_list;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
@@ -34,47 +34,58 @@ import java.util.Vector;
|
||||
*/
|
||||
|
||||
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||
private static final String TAG = InfoListAdapter.class.toString();
|
||||
|
||||
private final InfoItemBuilder infoItemBuilder;
|
||||
private final List<InfoItem> streamList;
|
||||
private final List<InfoItem> infoItemList;
|
||||
|
||||
public InfoListAdapter(Activity a, View rootView) {
|
||||
infoItemBuilder = new InfoItemBuilder(a, rootView);
|
||||
streamList = new Vector<>();
|
||||
infoItemList = new Vector<>();
|
||||
}
|
||||
|
||||
public void setOnItemSelectedListener
|
||||
(InfoItemBuilder.OnItemSelectedListener onItemSelectedListener) {
|
||||
infoItemBuilder.setOnItemSelectedListener(onItemSelectedListener);
|
||||
public void setOnStreamItemSelectedListener
|
||||
(InfoItemBuilder.OnInfoItemSelectedListener onItemSelectedListener) {
|
||||
infoItemBuilder.setOnStreamInfoItemSelectedListener(onItemSelectedListener);
|
||||
}
|
||||
|
||||
public void addStreamItemList(List<InfoItem> videos) {
|
||||
public void addInfoItemList(List<InfoItem> videos) {
|
||||
if(videos!= null) {
|
||||
streamList.addAll(videos);
|
||||
infoItemList.addAll(videos);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSteamItemList() {
|
||||
streamList.clear();
|
||||
infoItemList.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return streamList.size();
|
||||
return infoItemList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItemHolder onCreateViewHolder(ViewGroup parent, int i) {
|
||||
View itemView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.video_item, parent, false);
|
||||
|
||||
return new InfoItemHolder(itemView);
|
||||
switch(infoItemList.get(i).infoType()) {
|
||||
case STREAM:
|
||||
return new StreamInfoItemHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.stream_item, parent, false));
|
||||
case CHANNEL:
|
||||
return new ChannelInfoItemHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.channel_item, parent, false));
|
||||
case PLAYLIST:
|
||||
Log.e(TAG, "Playlist is not yet implemented");
|
||||
return null;
|
||||
default:
|
||||
Log.e(TAG, "Trollolo");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
||||
infoItemBuilder.buildByHolder(holder, streamList.get(i));
|
||||
infoItemBuilder.buildByHolder(holder, infoItemList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.schabi.newpipe.info_list;
|
||||
|
||||
import android.icu.text.IDNA;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 01.08.16.
|
||||
*
|
||||
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||
* StreamInfoItemHolder.java is part of NewPipe.
|
||||
*
|
||||
* NewPipe is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NewPipe is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class StreamInfoItemHolder extends InfoItemHolder {
|
||||
|
||||
public final ImageView itemThumbnailView;
|
||||
public final TextView itemVideoTitleView,
|
||||
itemUploaderView,
|
||||
itemDurationView,
|
||||
itemUploadDateView,
|
||||
itemViewCountView;
|
||||
public final Button itemButton;
|
||||
|
||||
public StreamInfoItemHolder(View v) {
|
||||
super(v);
|
||||
itemThumbnailView = (ImageView) v.findViewById(R.id.itemThumbnailView);
|
||||
itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView);
|
||||
itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView);
|
||||
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
|
||||
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView);
|
||||
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
|
||||
itemButton = (Button) v.findViewById(R.id.item_button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfoItem.InfoType infoType() {
|
||||
return InfoItem.InfoType.STREAM;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import android.widget.Toast;
|
||||
|
||||
import org.schabi.newpipe.ReCaptchaActivity;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||
import org.schabi.newpipe.extractor.search.SearchResult;
|
||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
@@ -29,6 +30,8 @@ import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||
import org.schabi.newpipe.detail.VideoItemDetailFragment;
|
||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
||||
|
||||
@@ -166,7 +169,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||
sw.setSearchWorkerResultListener(new SearchWorker.SearchWorkerResultListener() {
|
||||
@Override
|
||||
public void onResult(SearchResult result) {
|
||||
infoListAdapter.addStreamItemList(result.resultList);
|
||||
infoListAdapter.addInfoItemList(result.resultList);
|
||||
setDoneLoading();
|
||||
}
|
||||
|
||||
@@ -213,7 +216,8 @@ public class SearchInfoItemFragment extends Fragment {
|
||||
|
||||
infoListAdapter = new InfoListAdapter(getActivity(),
|
||||
getActivity().findViewById(android.R.id.content));
|
||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||
infoListAdapter.setOnStreamItemSelectedListener(
|
||||
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||
@Override
|
||||
public void selected(String url) {
|
||||
startDetailActivity(url);
|
||||
@@ -298,7 +302,11 @@ public class SearchInfoItemFragment extends Fragment {
|
||||
private void search(String query, int page) {
|
||||
isLoading = true;
|
||||
SearchWorker sw = SearchWorker.getInstance();
|
||||
sw.search(streamingServiceId, query, page, getActivity());
|
||||
sw.search(streamingServiceId,
|
||||
query,
|
||||
page,
|
||||
getActivity(),
|
||||
EnumSet.of(SearchEngine.Filter.CHANNEL));
|
||||
}
|
||||
|
||||
private void setDoneLoading() {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Created by Christian Schabesberger on 02.08.16.
|
||||
@@ -67,14 +68,21 @@ public class SearchWorker {
|
||||
public static final String YOUTUBE = "Youtube";
|
||||
private final String query;
|
||||
private final int page;
|
||||
private final EnumSet<SearchEngine.Filter> filter;
|
||||
final Handler h = new Handler();
|
||||
private volatile boolean runs = true;
|
||||
private Activity a = null;
|
||||
private int serviceId = -1;
|
||||
public SearchRunnable(int serviceId, String query, int page, Activity activity, int requestId) {
|
||||
public SearchRunnable(int serviceId,
|
||||
String query,
|
||||
int page,
|
||||
EnumSet<SearchEngine.Filter> filter,
|
||||
Activity activity,
|
||||
int requestId) {
|
||||
this.serviceId = serviceId;
|
||||
this.query = query;
|
||||
this.page = page;
|
||||
this.filter = filter;
|
||||
this.a = activity;
|
||||
}
|
||||
void terminate() {
|
||||
@@ -102,7 +110,7 @@ public class SearchWorker {
|
||||
String searchLanguage = sp.getString(searchLanguageKey,
|
||||
a.getString(R.string.default_language_value));
|
||||
result = SearchResult
|
||||
.getSearchResult(engine, query, page, searchLanguage);
|
||||
.getSearchResult(engine, query, page, searchLanguage, filter);
|
||||
if(runs) {
|
||||
h.post(new ResultRunnable(result, requestId));
|
||||
}
|
||||
@@ -180,11 +188,15 @@ public class SearchWorker {
|
||||
|
||||
}
|
||||
|
||||
public void search(int serviceId, String query, int page, Activity a) {
|
||||
public void search(int serviceId,
|
||||
String query,
|
||||
int page,
|
||||
Activity a,
|
||||
EnumSet<SearchEngine.Filter> filter) {
|
||||
if(runnable != null) {
|
||||
terminate();
|
||||
}
|
||||
runnable = new SearchRunnable(serviceId, query, page, a, requestId);
|
||||
runnable = new SearchRunnable(serviceId, query, page, filter, a, requestId);
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user